OpenFOAM 中用手动并行分块的方法

OpenFOAM 提供了许多并行区域划分的方法,常用的有 simple,scotch 等。但是,有时候希望能手动地将指定区域指派给一个进程,幸运的是 OpenFOAM 提供了这样的功能。本篇就来介绍一下如何进行手动并行分块。

以自带的 dambreak 算例为例,首先,将分块方法设置为 simple,

1
2
3
4
5
6
7
8
9
numberOfSubdomains 4;

method simple;

simpleCoeffs
{
n ( 2 2 1 );
delta 0.001;
}

然后,运行

1
decomposePar -cellDist

于是便在 0 下面得到一个 volScalarFieldcellDist

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
FoamFile
{
version 2.0;
format ascii;
class volScalarField;
location "0";
object cellDist;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

dimensions [0 0 0 0 0 0 0];

internalField nonuniform List<scalar>
2268
(
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
0
0
0
0
...
);
boundaryField
{
......
}

注意,上面可以看到, cellDist 的值是 1 和 0 等,这个值,对应着将来该网格将被分配到的 processor 的id。

所以,如果将 cellDist 当成是一个标量场,然后用设置初始场的工具对其值进行初始化,将来就能将对应网格手动分配到 cellDist 的值对应的进程。

OpenFOAM 自带的设置初始场的工具是 setFieldsswak4Foam 中的 funkySetField 也是可以的。这里介绍 setFields 的用法。

使用 setFields ,需要编写 setFieldsDict,示例如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
defaultFieldValues
(
volScalarFieldValue cellDist 0
);

regions
(
boxToCell
{
box (0 0 -1) (0.2 0.2 1);
fieldValues
(
volScalarFieldValue cellDist 1
);
}
boxToCell
{
box (0 0.2 -1) (0.2 0.6 1);
fieldValues
(
volScalarFieldValue cellDist 2
);
}
boxToCell
{
box (0.2 0.2 -1) (0.6 0.6 1);
fieldValues
(
volScalarFieldValue cellDist 3
);
}
);

这里,用的是最简单的 boxToCell,即指定一个 box 中的网格的 cellDist 值。 setFields 还有很多种方式来设置初始值。这里再举一个例子,可以先用 topoSet 来将指定区域的网格先提取到 cellSet ,然后,对整个 cellSet 的网格的 cellDist 值进行指定,示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
defaultFieldValues ( volScalarFieldValue cellDist 0 );

regions
(
cellToCell
{
set cellSet1 ;
fieldValues
(
volScalarFieldValue cellDist 1
);

}

cellToCell1
{
set cellSet2 ;
fieldValues
(
volScalarFieldValue cellDist 2
);

}
);

topoSet 的用法这里不举例了,有很多花样,详细的信息可以参考 applications/utilities/mesh/manipulation/topoSet/topoSetDict 中的说明。

设置好 setFieldDict以后,运行 setFields,便对 cellDist 的值进行了修改,可视化如下

下一步,需要根据 cellDist 的值来创建一个 labelList,因为手动分块的时候,需要的是一个 labelList
在constant下创建一个文件, cellDecomposition ,内容如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
FoamFile
{
version 2.0;
format ascii;
class labelList;
location "constant";
object cellDecomposition;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //


2268
(
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
0
0
0
0
0
0
0
1
1
......
)

注意文件头的写法。 () 内的内容与 cellDist 文件中 () 内的内容一样。

再下一步,就是修改 decomposeParDict

1
2
3
4
5
6
7
8
numberOfSubdomains 4;

method manual;

manualCoeffs
{
dataFile "cellDecomposition";
}

然后再运行 decomposePar -force,这样就得到了根据 cellDist 值来指定的分块方式,如下

注意看这里的进程边界,跟上图中 cellDist 的值的边界是一样的。