关于压力场边界更新的实现机制的疑问



  • 大家好,我的问题是在计算过程中,压力场的边界何时更新?因为我发现在 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 函数,那么压力场是怎么更新边界的呢?我所指定的不同的压力边界条件,又是如何生效的呢?问题有点长,十分感谢您的耐心阅读与解答!!


  • 网格教授 OpenFOAM教授 管理员

    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 又有什么区别呢?


  • OpenFOAM副教授

    @千里之行 这是一个宏,意思是该处的value采用的是“internalField”这个变量的值。你在这个文件里开头的部分,会有类似internalfield uniform 100这样的语句。



  • @dzw05 哦,懂了,原来如此,十分感谢!!