关于压力场边界更新的实现机制的疑问
-
大家好,我的问题是在计算过程中,压力场的边界何时更新?因为我发现在 multiphase 类的求解器中,compressibleInterFoam 在 pEqn.H 中分别调用速度场和压力场的 corrrectBoundaryConditions 函数来更新与边界相关的值,即
U.correctBoundaryConditions();
p_rgh.correctBoundaryConditions();
但是 interFoam 在 pEqn.H 中只会调用速度场的 correctBoundaryConditions 函数,不会调用压力场,其他地方也没有,只有
U.correctBoundaryConditions();
类似的,twoPhaseEulerFoam, reactingTwoPhaseEulerFoam, reactingMultiphaseEulerFoam, cavitatingFoam, compressibleMultiphaseInterFoam 这些求解器都会调用速度场和压力场的 correctBoundaryConditions 函数。但是 twoLiquidMixingFoam, driftFluxFoam, potentialFreeSurfaceFoam, multiphaseEulerFoam, interPhaseChangeFoam, MPPICInterFoam 只会调用速度场的 correctBoundaryConditions 函数,不会调用压力场的。
我也查看了源代码,目前我掌握到的信息如下:
GeometricField 类型的 correctBoundaryConditions 函数的定义是template<class Type, template<class> class PatchField, class GeoMesh> void Foam::GeometricField<Type, PatchField, GeoMesh>:: correctBoundaryConditions() { this->setUpToDate(); storeOldTimes(); boundaryField_.evaluate(); }
可以看出具体的操作是交给成员 boundaryField_ 的 evaluate 函数执行的,boundaryField_ 声明如下:
//- Boundary Type field containing boundary field values Boundary boundaryField_;
Boundary 类型是各个边界块的集合。每一个边界块根据不同的边界条件类型对应有不同的边界条件类,比如 zeroGradient 类型的边界条件对应 zeroGradientFvPatchField 类,他们共同的基类是 fvPatchField,evaluate 函数是这个派生体系的虚函数,不同的边界条件派生类会重新定义自己的这个虚函数,实现了多态,从而实现不同的边界更新方式。而 boundaryField_ 的 evaluate 函数会遍历各个边界块,调用各自的 evaluate 函数实现更新。代码如下:
template<class Type, template<class> class PatchField, class GeoMesh> void Foam::GeometricField<Type, PatchField, GeoMesh>::Boundary:: evaluate() { ...... forAll(*this, patchi) { this->operator[](patchi).evaluate(Pstream::defaultCommsType); } ...... }
我想请教各位,如果没有调用压力场的 correctBoundaryConditions 函数,那么压力场是怎么更新边界的呢?我所指定的不同的压力边界条件,又是如何生效的呢?问题有点长,十分感谢您的耐心阅读与解答!!
-
correctBoundaryConditions
这个函数的作用非常简单。比如你通过下面的代码计算速度场:U=Ua+Ub;
在这种情况下并没有计算U的边界条件,因此你需要
U.correctBoundaryConditions()
但是如果你通过
UEqn.solve()
的方式计算,solve()
函数里面自动调用了correctBoundaryConditions
。多相流求解器里面也一样,比如
// Correct p_rgh for consistency with p and the updated densities p_rgh = p - rho*gh; p_rgh.correctBoundaryConditions();
是因为前面存在赋值
p_rgh = p - rho*gh;
因此,我的个人习惯是,如果是
solve()
出来的,不需要调用,如果是=
赋值出来的,都需要correctBoundaryConditions
。 -
@李东岳 哦,明白了,谢谢东岳老师,我再去好好看看相关的代码。那 "calculated" 类型的边界条件对应的类是 calculatedFvPatchField ,但是并没有重新定义虚函数 evaluate,肯定是基类 fvPatchField 的 evaluate 函数被调用了,可是那个 evaluate 函数并没有做什么计算,所以即使调用了场对象的 correctBoundaryConditions 函数,在 calculated 类型的边界也没有发生计算,这样理解对吗?
另外,经常会遇到这样的边界条件:inlet { type fixedValue; value $internalField; }
这里的 $internalField 是什么意思呢,我认为是这块边界的值取邻近内场的值,但是一直也没有找到代码的依据,并且这样的边界条件和 zeroGradient 又有什么区别呢?
-
@东岳
我也想了解关于 correctBoundaryConditions 使用的知识。
但是我发现等于号操作符也更新了边界场呀:template<class Type, template<class> class PatchField, class GeoMesh> void Foam::GeometricField<Type, PatchField, GeoMesh>::operator= ( const GeometricField<Type, PatchField, GeoMesh>& gf ) { if (this == &gf) { FatalErrorInFunction << "attempted assignment to self" << abort(FatalError); } checkField(*this, gf, "="); // Only assign field contents not ID ref() = gf(); boundaryFieldRef() = gf.boundaryField(); }