dsmcFoam solver分析
dsmcFoam 的架构:
主要的源文件:
dsmcFoma
源码:
|
|
DsmcCloud 关键函数分析
DsmcCloud::evolve()
主要演化过程在这里
|
|
DsmcCloud::resetFields()
每个演化步都需要重置这些场为0,为开始统计做准备
|
|
DsmcCloud::calculateFields()
: 统计场
|
|
看看DsmcCloud
的构造函数,可以发现它主要存储哪些东西:
|
|
可以发现DsmcCloud
的演化过程十分清晰明了。就是内部记录了一些extensive fields,和 particle的位置、速度。然后每个演化步统计这些 extensive fields,然后执行迁移和碰撞,边界处理。这些extensive fields完全由新时刻的particle速度计算出来。
fieldAverage 分析
在一个dsmcFoam的case里面,controlDict
文件里面要设置在求解过程中输出一些时间平均的场, 这由OpenFOAM本身提供的fieldAverage
和dsmcFOAM提供的dsmcField
这两个Function object来完成。
NOTE: 关于fieldAverage
Function object到底是怎样进行时间平均的, 这篇博文有很好的分析。
下面这个例子是一个dsmcFoam case里controlDict
文件的functions
部分:
|
|
这里面设置每个需要计算时均值的场的设置。包括mean
,prome2Mean
,base
,window
。时均场输出的文件名后面会多一个Mean。 如momentum的时均场为momentumMean。
上面的设置中base
为time
,发现计算过程中每个演化步(DsmcCloud::evolve()
)都计算了时均场,log里面每个演化都会出现:
|
|
- 如果不设置
window
: 每次计算的时均场都是从求解开始到目前所有步的时均场。 - 如果设置了
window
:base用来指定作时间平均的基础,是基于时间步数(ITER)还是物理时间(time); window用来作平均的时间段的长度,如果不设定,则求的是从开始到当前时间这个时间段的平均值。window的数值的实际含义依base而定,如果base是ITER,则window=20表示当前步及其前 19 个时间步从 20 个时间步内的平均,而如果base是time,则表示的是 20s 内的平均。
在输出数据文件时(每evolve 100次)还会输出fieldAverage1
设置的时均场(writing average fields
):
|
|
NOTE: 可以发现在writing average fields
的时候dsmcFields
function object被触发了,它计算UMean
,translationalT
,internalT
,overallT
,pressure
等场。
可以定义两个开关分别是resetOnOutput
和resetOnRestart
, 其意义是:
resetOnRestart的值决定当solver继续运行时,是否要读取最近一个时间步的meanField的值来计算接下来时刻的时均值;>resetOnOutput,顾名思义,是否要在每一次输出到文件以后重置meanField的值。这两个开关的默认值都是false。”
这里可能有个疑问,如果不做这两个时均计算会怎样?会不会影响计算过程?毕竟dsmc的计算过程不依赖于这些宏观量场以及它们的时均场。这个疑问是很自然的。可以通过一个例子分析一下:
如果在controlDict
文件里面如下设置
|
|
表示计算1000步,每100步输出。
- 如果我们再注释掉
functions
部分, 也就是不求平均。运行dsmcFoam,也没有问题,不会报错。运行完会产生10个数据文件目录(1000/100=10)。
|
|
每个目录里面只有当前步的统计出来的场(非时均):
|
|
- 但是如果我们如果只注释掉
functions
里面的fieldAverage1
部分,或者只去掉fieldAverage1
里面的任何一个时均场,则会报错。比如去掉fD
的时均计算,会有Fatal Error如下:
|
|
这个错误应该是在执行dsmcFields
function object 时产生的。下面我们分析dsmcFields
。
dsmcFields分析
dsmcFields.H
|
|
|
|
dsmcFields::write()
|
|
明显可以发现dsmcFields
所做的只是根据fieldAverage1
输出的时均场来求出其他时均场,例如根据时均密度场和时均动量场来求出时均速度场。这个工作也可以由后处理工具dsmcFieldsCalc
完成,而不是写成controlDict
里面的function object。
总结
综上分析,有以下总结:
- 用
fieldAverage
对宏观量场求时均是dsmcFoam里面输出宏观量场的最重要步骤。 window
控制对那一段时间求平均。如果不设置window
就是从开始到当前所有步的平均。
如果设置window
, 结合base
(ITER
/time
),可以设置 从当前时间/步 往前多少s/步 求时均值。dsmcFields
辅助计算其他时均场如UMean
,overallT
等等,它只是对fieldAverage
输出的时均场做简单的加减乘除计算。