bound 函数的实现方法
-
很多有界变量在计算过程中为了防止数值问题,需要限定下限值,在OpenFOAM中一般都是使用bound 函数,代码见:src/finiteVolume/cfdTools/general/bound/bound.C。然而这个 bound 函数的实现却有些让人摸不着头脑:
Foam::volScalarField& Foam::bound(volScalarField& vsf, const dimensionedScalar& lowerBound) { const scalar minVsf = min(vsf).value(); if (minVsf < lowerBound.value()) { Info<< "bounding " << vsf.name() << ", min: " << minVsf << " max: " << max(vsf).value() << " average: " << gAverage(vsf.primitiveField()) << endl; vsf.primitiveFieldRef() = max ( max ( vsf.primitiveField(), fvc::average(max(vsf, lowerBound))().primitiveField() * pos0(-vsf.primitiveField()) ), lowerBound.value() ); vsf.boundaryFieldRef() = max(vsf.boundaryField(), lowerBound.value()); } return vsf; }
一般的想法是,直接把小于 lowerBound 的重置为 lowerBound 就行了。但是 OpenFOAM 的实现是,对于某个变量v,当 0 < v < lowerBound的,令 v=lowBound (与预期一致);当 v < 0 时,
pos0(-vsf.primitiveField())
为 1,也就意味着用如下公式重新计算了下限值fvc::average(max(vsf, lowerBound))().primitiveField()
这种做法有什么数学上的解释吗?
-
fvc::average(max(vsf, lowerBound))().primitiveField()
$v_{celli}=\frac{\sum (|\bfS_f| v_f)}{\sum |\bfS_f|}$
应该是基金会自己拍脑袋定的。
这种做法有什么数学上的解释吗?
大佬这不就是
average
的实现么?
考虑这么几个网格|3|-1|2|
max(vsf, lowerBound)
变成了|3|0|2|fvc::average(max(vsf, lowerBound))().primitiveField()
变成了|3|1.25|2| -
帮李老师补充一下OpenFOAM里面average的实现,对于vol场要先插值成surface场
template<class Type> tmp<GeometricField<Type, fvPatchField, volMesh>> average ( const GeometricField<Type, fvPatchField, volMesh>& vtf ) { return fvc::average(linearInterpolate(vtf)); }
所以|3|0|2|到average函数里面以后要先插值成
| 3 | 0 | 2 | 1.5 1
再基于
$v_{celli}=\frac{\sum (|\bfS_f| v_f)}{\sum |\bfS_f|}$
得到中间网格的值为1.25