OpenFOAM 提供了许多并行区域划分的方法,常用的有 simple,scotch 等。但是,有时候希望能手动地将指定区域指派给一个进程,幸运的是 OpenFOAM 提供了这样的功能。本篇就来介绍一下如何进行手动并行分块。
以自带的 dambreak 算例为例,首先,将分块方法设置为 simple,1
2
3
4
5
6
7
8
9numberOfSubdomains 4;
method simple;
simpleCoeffs
{
n ( 2 2 1 );
delta 0.001;
}
然后,运行1
decomposePar -cellDist
于是便在 0 下面得到一个 volScalarField
:cellDist
。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
41FoamFile
{
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 自带的设置初始场的工具是 setFields
, swak4Foam
中的 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
32defaultFieldValues
(
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
22defaultFieldValues ( 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
40FoamFile
{
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
8numberOfSubdomains 4;
method manual;
manualCoeffs
{
dataFile "cellDecomposition";
}
然后再运行 decomposePar -force
,这样就得到了根据 cellDist
值来指定的分块方式,如下
注意看这里的进程边界,跟上图中 cellDist
的值的边界是一样的。