利用functionObjects对指定区域内进行后处理

CFD中很重要的一个环节是模拟结果的后处理。而后处理过程中,常常涉及到对某个指定区域的某个物理量进行操作,比如,求指定截面上的流率,或者求某个区域内的平均空隙率,等等。这里介绍一种利用 OpenFOAM 中的 functionObjects 来对指定区域进行后处理的方法。本方法一共分三步:1). 将指定区域内的网格(或者面)提取到 cellZone(或faceZone); 2). 在 controlDict 里写后处理 functions;3). 运行后处理。

1. 将指定区域的网格(或面)提取到 cellZone (或faceZone)

这一步有很多方法可以实现,这里介绍用setSet结合setsToZones的方法。

1.1 setSet的基本用法

setSet是 OpenFOAM 提供的一个用于生成网格集合(cellSet)、面集合(faceSet)以及点集合(pointSet)的交互式工具,终端里运行setSet,便进入交互模式:

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
$ setSet

/*---------------------------------------------------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: 2.3.1 |
| \\ / A nd | Web: www.OpenFOAM.org |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/

Build : 2.3.1-bcfaaa7b8660
Exec : setSet
Date : May 09 2015
Time : 13:50:44
Host : "xxxxx"
PID : 11255
Case : /home/xxxxx/OpenFOAM/xxxx-2.3.1/run/volField/cavity
nProcs : 1
sigFpe : Enabling floating point exception trapping (FOAM_SIGFPE).
fileModificationChecking : Monitoring run-time modified files using timeStampMaster
allowSystemOperations : Allowing user-supplied system call operations

// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
Create time

Create polyMesh for time = 0

Time:0 cells:9 faces:42 points:32 patches:3 bb:(0 0 0) (0.1 0.1 0.01)


Successfully read history from .setSet
Time = 0
mesh not changed.
Please type 'help', 'quit' or a set command after prompt.
readline>

setSet的基本语法是:cellSet|faceSet|pointSet <setName> <action> <source>。第一个字段,是选择需要建立的是哪一类集合(cellSet|faceSet|pointSet),第二个字段是setName,顾名思义,给集合取个名字,第三个字段是action,即具体的操作,比如new(新建),add(增加)等,最后一个字段是source,即指定cell(face,point)的来源,比如有一种是boxToCell,这种来源要求定义一个box,并将中心在这个box里的网格当作操作的对象。下面举几个例子:

  • faceSet f0 new boxToFace (0 0 0) (1 1 1): 建立一个新的面集f0,并将面心落在对角线顶点分别为(0 0 0)和(1 1 1)的立方体中的面提取出来放到该集合中;
  • cellSet f0 new boxToCell (0 0 0) (1 1 1):建立一个新的网格集f0,并将面心落在对角线顶点分别为(0 0 0)和(1 1 1)的立方体中的网格提取出来放到该集合中;
  • faceSet f0 new patchToFace movingWall:新建一个面集f0,并将边界movingWall的所有面放到该集合中;
  • cellSet c0 new faceToCell f0 any: 新建一个网格集合c0,并将面集f0中所有的面对应的网格放到网格集合c0中;
  • cellSet c0 add pointToCell p0 any,将点集p0中所有的点对应的网格添加到已经存在的网格集c0中。

如果要一次建立很多个集合,那么可以将建立规则写在一个文本文件里,每个规则一行,写好后的文件大致是这样

1
2
3
4
faceSet f0 new boxToFace (0 0 0) (1 1 1)
faceSet f1 new boxToFace (1 1 1) (2 2 2)
cellSet c0 new faceToCell f0 any
cellSet c1 new faceToCell f1 any

然后运行命令

1
setSet -batch <filename>

进行批处理。但是这样会针对每一个时间步都运行一次,如果只想运行一次,可以指定时间

1
2
3
setSet -batch <filename> -time 0
或者
setSet -batch <filename> -latestTime

运行结束以后,程序会将sets信息放在polyMesh/sets目录下,同时生成相应的vtk文件在算例根目录下的VTK目录里,方便在paraview中查看。
关于setSet更详细的信息可以参考setSet提供的 help(终端里运行setSet进入交互模式以后输入help)。

1.2 setsToZones

这一步非常简单,只需要在终端里运行

1
setsToZones

就可以将前面建立好的 cellSet(faceSet,pointSet)转换成 cellZone(faceZone,pointZone)。

其实除了setSetsetsToZones结合的方法,还可以用topoSet来生成cellZone,本篇不详述了,可以参考 OpenFOAMWiki

2. 在 controlDict 里写 functions

有了前面建立好的cellZone (faceZone,pointZone) 以后,就可以在 controlDict 写 functions 来对指定的区域进行后处理了。funtions 的基本写法是在 controlDict 文件的最后,添加类似如下的信息:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
functions
(
cell0
{
type cellSource; // 指定操作区域的类型,cellsource 表示是操作区域是一个基于网格(cell)的,比如cellZone。
functionObjectLibs // 指定需要加载的动态库
(
//"libsimpleFunctionObjects.so" // swak4Foam 提供的一个函数库
"libfieldFunctionObjects.so" // OpenFOAM自带的一个函数库
);
verbose true; //是否要在终端里输出程序运行过程
//outputControl timeStep; // 每一个时间步都运行
outputControl outputTime; // 只在需要输出的时间步才运行,参考controlDict的 writeControl和writeInterval
log true; // 是否生成 log
valueOutput true; // 是否需要在每一个时间步对应的数据文件夹里(0.1 0.2 之类的) 将指定 source 的值输出来。
source cellZone; //指定操作区域的具体的组成,这里cellZone表示操作区域是由一个cellZone组成的。
sourceName f0; // cellZone 的名字
operation volAverage; //操作方法,这里是体积平均
fields // 需要进行操作的物理量
(
T
);
}
);

注意这里的结构,

1
2
3
4
functions
(
...
);

是最外一层,包括在其中的就是各种功能的 functionObjects了。

1
2
3
4
cell0
{
...
}

代表的是一个functionObject,其中cell0是该functionObject的名字。里面内容的含义参照上面示例中的注释。如果需要写多个functionObjects,那只需要依次都写下来就好了,注意functionObjects的名字不能重复,结构如下

1
2
3
4
5
6
7
8
9
10
11
12
functions
(
cell0
{
...
}

cell1
{
...
}
);

3. 运行后处理

写好functions以后,就可以运行后处理了。在终端里运行

1
execFlowFunctionObjects

就能执行定义在controlDict里的后处理函数了。
有时候,可能会报错,说找不到phi,那这时可以加上-noFlow选项

1
execFlowFunctionObjects  -noFlow

当然,时间相关的选项也是可以用的

1
2
execFlowFunctionObjects  -noFlow -time 3
execFlowFunctionObjects -noFlow -latestTime

注意,本篇强调的是后处理,即算例运行完以后对数据进行的处理。实际上,熟悉OpenFOAM都知道,写在 controlDict 的functions是会随着算例的运行而同时运行的,所以,如果是运行一个新算例,那么你也完全可以事先规划好后处理相关的操作,然后在controlDict写好functions,这样等算例运行结束,所需要的后处理结果也同时生成了。

有人会问,我怎么知道那些 type,source,operation 等有哪些选项可用呢?这里介绍一种的方法,即所谓的香蕉大法。比如对于 type,你不知道有哪些可用,那么将type设置为 banana (将上面第2节示例的中 type cellSource改成type banana),然后运行execFlowFunctionObjects,这时,会得到如下信息:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
--> FOAM FATAL ERROR: 
Unknown function type banana
Valid functions are :
14
(
cellSource
faceSource
fieldAverage
fieldCoordinateSystemTransform
fieldMinMax
initSwakFunctionObject
nearWallFields
patchProbes
probes
readFields
sets
streamLine
surfaceInterpolateFields
surfaces
)

这回就知道了所有可用选项了吧。对于 source 和 operation 也可以同样的方法得到所有可用的选项。注意,source和operation的可用选项,是随着type的不同而不同的,这里就不详述了。
P.S:banana不是OpenFOAM定义的特殊字符串,改成任意非有效的字符串,效果都一样。

最后,上面只是介绍了一些一般性的原则,如果读者想参考一些实际的例子,可以去 OpenFOAM 的 tutorials 里挖掘,这里给一个找出 OpenFOAM 中有哪些算例运用了 functions 的方法,供大家参考。

1
find $WM_PROJECT_DIR -name controlDict | xargs grep "functions"

在我的电脑上,运行结果如下:

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
42
43
44
45
46
47
48
49
50
51
52
53
/opt/openfoam231/src/postProcessing/functionObjects/systemCall/controlDict:functions
/opt/openfoam231/src/postProcessing/functionObjects/utilities/timeActivatedFileUpdate/controlDict:functions
/opt/openfoam231/src/postProcessing/functionObjects/field/fieldAverage/controlDict:functions
/opt/openfoam231/src/postProcessing/functionObjects/field/nearWallFields/controlDict:functions
/opt/openfoam231/src/postProcessing/functionObjects/field/fieldValues/controlDict:functions
/opt/openfoam231/src/postProcessing/functionObjects/field/streamLine/controlDict:functions
/opt/openfoam231/src/postProcessing/functionObjects/field/fieldMinMax/controlDict:functions
/opt/openfoam231/src/postProcessing/functionObjects/field/wallBoundedStreamLine/controlDict:functions
/opt/openfoam231/src/postProcessing/functionObjects/IO/controlDict:functions
/opt/openfoam231/tutorials/incompressible/pimpleFoam/TJunctionFan/system/controlDict:functions
/opt/openfoam231/tutorials/incompressible/pimpleFoam/channel395/system/controlDict:functions
/opt/openfoam231/tutorials/incompressible/pimpleFoam/TJunction/system/controlDict:functions
/opt/openfoam231/tutorials/incompressible/pisoFoam/les/pitzDailyMapped/system/controlDict:functions
/opt/openfoam231/tutorials/incompressible/pisoFoam/les/pitzDaily/system/controlDict:functions
/opt/openfoam231/tutorials/incompressible/pisoFoam/les/motorBike/lesFiles/controlDict:functions
/opt/openfoam231/tutorials/incompressible/pisoFoam/les/motorBike/motorBike/system/controlDict:functions
/opt/openfoam231/tutorials/incompressible/pimpleDyMFoam/wingMotion/wingMotion2D_simpleFoam/system/controlDict:functions
/opt/openfoam231/tutorials/incompressible/pimpleDyMFoam/propeller/system/controlDict:functions
/opt/openfoam231/tutorials/incompressible/pimpleDyMFoam/movingCone/system/controlDict:functions
/opt/openfoam231/tutorials/incompressible/simpleFoam/pitzDaily/system/controlDict:functions
/opt/openfoam231/tutorials/incompressible/simpleFoam/pitzDailyExptInlet/system/controlDict:functions
/opt/openfoam231/tutorials/incompressible/simpleFoam/motorBike/system/controlDict:functions
/opt/openfoam231/tutorials/lagrangian/reactingParcelFoam/verticalChannel/system/controlDict:functions
/opt/openfoam231/tutorials/lagrangian/LTSReactingParcelFoam/verticalChannel/system/controlDict:functions
/opt/openfoam231/tutorials/lagrangian/simpleReactingParcelFoam/verticalChannel/system/controlDict:functions
/opt/openfoam231/tutorials/multiphase/interFoam/ras/waterChannel/LTSInterFoam/system/controlDict:functions
/opt/openfoam231/tutorials/multiphase/interFoam/ras/waterChannel/system/controlDict:functions
/opt/openfoam231/tutorials/multiphase/interDyMFoam/ras/sloshingTank3D3DoF/system/controlDict:functions
/opt/openfoam231/tutorials/multiphase/interDyMFoam/ras/sloshingTank3D6DoF/system/controlDict:functions
/opt/openfoam231/tutorials/multiphase/interDyMFoam/ras/sloshingTank2D3DoF/system/controlDict:functions
/opt/openfoam231/tutorials/multiphase/interDyMFoam/ras/DTCHull/system/controlDict:functions
/opt/openfoam231/tutorials/multiphase/interDyMFoam/ras/sloshingTank3D/system/controlDict:functions
/opt/openfoam231/tutorials/multiphase/interDyMFoam/ras/sloshingTank2D/system/controlDict:functions
/opt/openfoam231/tutorials/multiphase/twoPhaseEulerFoam/laminar/bubbleColumn/system/controlDict:functions
/opt/openfoam231/tutorials/multiphase/twoPhaseEulerFoam/laminar/bubbleColumnIATE/system/controlDict:functions
/opt/openfoam231/tutorials/multiphase/twoPhaseEulerFoam/laminar/fluidisedBed/system/controlDict:functions
/opt/openfoam231/tutorials/multiphase/twoPhaseEulerFoam/LES/bubbleColumn/system/controlDict:functions
/opt/openfoam231/tutorials/multiphase/twoPhaseEulerFoam/RAS/bubbleColumn/system/controlDict:functions
/opt/openfoam231/tutorials/multiphase/twoPhaseEulerFoam/RAS/fluidisedBed/system/controlDict:functions
/opt/openfoam231/tutorials/multiphase/potentialFreeSurfaceDyMFoam/oscillatingBox/system/controlDict:functions
/opt/openfoam231/tutorials/multiphase/LTSInterFoam/DTCHull/system/controlDict:functions
/opt/openfoam231/tutorials/multiphase/cavitatingFoam/les/throttle3D/system/controlDict:functions
/opt/openfoam231/tutorials/multiphase/cavitatingFoam/les/throttle/system/controlDict:functions
/opt/openfoam231/tutorials/multiphase/compressibleInterDyMFoam/ras/sloshingTank2D/system/controlDict:functions
/opt/openfoam231/tutorials/multiphase/potentialFreeSurfaceFoam/oscillatingBox/system/controlDict:functions
/opt/openfoam231/tutorials/multiphase/multiphaseEulerFoam/bubbleColumn/system/controlDict:functions
/opt/openfoam231/tutorials/discreteMethods/dsmcFoam/freeSpaceStream/system/controlDict:functions
/opt/openfoam231/tutorials/discreteMethods/dsmcFoam/wedge15Ma5/system/controlDict:functions
/opt/openfoam231/tutorials/discreteMethods/dsmcFoam/supersonicCorner/system/controlDict:functions
/opt/openfoam231/tutorials/discreteMethods/dsmcFoam/freeSpacePeriodic/system/controlDict:functions
/opt/openfoam231/tutorials/basic/potentialFoam/cylinder/system/controlDict:functions
/opt/openfoam231/tutorials/compressible/rhoPimpleFoam/les/pitzDaily/system/controlDict:functions
/opt/openfoam231/tutorials/compressible/sonicFoam/ras/nacaAirfoil/system/controlDict:functions