链接:http://xiaopingqiu.github.io/2016/04/02/Boundary-conditions-in-OpenFOAM1/
本系列解读 OpenFOAM 中边界条件的实现。主要关心一些几个问题:
- OpenFOAM 中边界条件是怎样与有限体积离散部分交互的?
- 怎么从代码看懂一个边界条件具体是怎么计算边界上的值的?
- 怎么定制一个边界条件?
本篇先阐述第一个问题。
从有限体积离散的角度来看,离散过程中,可能要用到的边界信息包括两类:一是某个场在边界上的值,另一是某个场在边界上的梯度。前者在对流项的离散中需要用到,举例说
当组成体积元的面中有边界面时,需要用到这些边界面上的值 ϕf。
而在扩散项的离散过程中
这时,如果组成体积元的某个面是边界面,就需要该边界面上 ϕ的梯度值 ∇ϕf 了。
边界上的某个场值,或者梯度值,其计算方法可以用如下通式表示
这里,ϕC表示ϕ在邻近边界的网格中心的值,A1 ,B1,A2,B2是系数。
OpenFOAM 中的边界条件类中,有四个函数分别对应上面四个系数:valueInternalCoeffs 对应A1,valueBoundaryCoeffs 对应 B1,gradientInternalCoeffs对应 A2,gradientBoundaryCoeffs对应B2。
所以,看懂 OpenFOAM 中的边界条件,很关键的一步就是看懂这四个函数的定义。
此外,还有一个函数,updateCoeffs, 也很重要。这个函数负责对边界条件进行显式地更新。浏览一下 OpenFOAM 边界条件的代码,会发现很多边界条件都是在 updateCoeffs 这个函数中进行边界值的计算的。
另外,还有些边界条件,似乎是在 evaluate 函数中进行边界值的指定的。
至于边界条件是在什么地方调用的,cfd-online 上有一个帖子,Hrvoje Jasak 对这个问题的回答是:
"
Easy:
- on correctBoundaryConditions() for a field
- on updateCoeffs() at matrix creation
correctBoundaryConditions is also called after the linear solver call automatically.
"
其他网友还提供了一些有价值的信息,比如,在 correctBoundaryConditions 函数中,
template<class Type, template<class> class PatchField, class GeoMesh>
void Foam::GeometricField<Type, PatchField, GeoMesh>::
correctBoundaryConditions()
{
this->setUpToDate();
storeOldTimes();
boundaryField_.evaluate();
}
调用了 evaluate 函数。
为什么有些边界条件用 updateCoeffs(),而有些则用 evaluate() 呢?目前的理解是这样的: updateCoeffs() 主要用来显式地计算并更新变量在边界上的值,当边界上的值是通过某个依赖于外部参数的公式来计算,并且值会随着迭代的进行而不断改变时,则需要用 updateCoeffs()。有些边界条件,比如最基本的 zeroGradient(),不需要外部的参数,只需要每一次将临近网格的值赋给边界就可以了,这时就可以用 evaluate()。
关于边界条件调用的具体过程,需要在看了 fvMatrix 类以后才能更深入地理解,博主目前只能给出一个粗浅的理解。
参考资料:
The Finite Volume Method in Computational Fluid Dynamics: An Advanced Introduction with OpenFOAM® and Matlab®