Code of the Week #30: type inletOutlet

#201917

在 OpenFOAM 中,指定速度向量的边界值为 inletOutlet 时,会用以下代码:

UA
{
    type            inletOutlet;
    value           $internalField;
    inletValue      uniform (0 0 0);
}

inletOutlet 基本上与 zeroGradient 相同,但是,如果该边界的网格的速度指向内部时,其设置为 fixedValue (backward flow). fixedValue 的值是 inletValue. 下图描述了这样的情况:


(from https://www.cfdsupport.com/OpenFOAM-Training-by-CFD-Support/node114.html)

符号规则:

  • 正通量 (流出流域): 应用 zeroGradient 条件
  • 负通量 (进入流域): 应用 inletValue 固定值

我们来看一看 inletOutlet 是如何实现的。

在第 28 期 Code of the Week #28: type fixedValue,我们谈到一个边界上有四个系数要确定,当这四个系数确定了,这个边界也就确定了。再将这四个系数及其公式表述一下:

边界上的值或梯度,一般采用以下方式

\phi_f = A_1 \phi_c + B_1\\ \nabla\phi_f = A_2 \phi_c + B_2

其中 \phi_c 表示边界所在的网格的中心值,其余为系数。

OpenFOAM 中,对应于上式中的四个系数的函数有

Func Coefficient
valueInternalCoeffs A_1
valueBoundaryCoeffs B_1
gradientInternalCoeffs A_2
gradientBoundaryCoeffs B_2

inletOutlet 边界继承自 mixed 类型,我们先来看看 mixed 类型,源程序位于 src/finiteVolume/fields/fvPatchFields/basic/mixed

template<class Type>
tmp<Field<Type> > mixedFvPatchField<Type>::valueInternalCoeffs
(
    const tmp<scalarField>&
) const
{
    return pTraits<Type>::one*(1.0 - valueFraction_);

}


template<class Type>
tmp<Field<Type> > mixedFvPatchField<Type>::valueBoundaryCoeffs
(
    const tmp<scalarField>&
) const
{
    return
         valueFraction_*refValue_
       + (1.0 - valueFraction_)*refGrad_/this->patch().deltaCoeffs();
}

template<class Type>
tmp<Field<Type> > mixedFvPatchField<Type>::gradientInternalCoeffs() const
{
    return -pTraits<Type>::one*valueFraction_*this->patch().deltaCoeffs();
}


template<class Type>
tmp<Field<Type> > mixedFvPatchField<Type>::gradientBoundaryCoeffs() const
{
    return
        valueFraction_*this->patch().deltaCoeffs()*refValue_
      + (1.0 - valueFraction_)*refGrad_;
}

可以总结出来表达式:

\begin{align} A_1 &= 1- A\\ B_1 &= A\times \text{refValue_} +(1-A)\times \frac{\text{refGrad_}}{\text{deltaCoeffs()}}\\ A_2 &= A\times \text{deltaCoeffs()}\\ B_2 &= A\times \text{deltaCoeffs()}\times\text{refValue_} + (1-A)\times \text{refGrad_} \end{align}

AvalueFraction_

说明只要确定了上述几个参数:refValue_,refGrad_,inletOutlet 边界也就确定了。deltaCoeffs 为该边界到其所属网格中心的距离的倒数,具体的可参考:
src/finiteVolume/interpolation/surfaceInterpolation/surfaceInterpolation/surfaceInterpolation.C

作业: 写出 deltaCoeff 的表达式。

inletOutlet 边界的源代码位于 src/finiteVolume/fields/fvPatchFields/derived/inletOutlet/inletOutletPatchField.C

template<class Type>
inletOutletFvPatchField<Type>::inletOutletFvPatchField
(
    const fvPatch& p,
    const DimensionedField<Type, volMesh>& iF,
    const dictionary& dict
)
:
    mixedFvPatchField<Type>(p, iF),
    phiName_(dict.lookupOrDefault<word>("phi", "phi"))
{
    this->refValue() = Field<Type>("inletValue", dict, p.size());

    if (dict.found("value"))
    {
        fvPatchField<Type>::operator=
        (
            Field<Type>("value", dict, p.size())
        );
    }
    else
    {
        fvPatchField<Type>::operator=(this->refValue());
    }

    this->refGrad() = pTraits<Type>::zero;
    this->valueFraction() = 0.0;
}

在初始时, inletValue 的赋给 refValue ,refGrad() = 0, A=0,

当更新时,

template<class Type>
void inletOutletFvPatchField<Type>::updateCoeffs()
{
    if (this->updated())
    {
        return;
    }

    if (!this->db().objectRegistry::found(phiName_))
    {
        // Flux not available, do not update
        InfoIn
        (
            "void inletOutletFvPatchField<Type>::"
            "updateCoeffs()"
        )   << "Flux field " << phiName_ << " not found.  "
            << "Performing mixed update" << endl;

        mixedFvPatchField<Type>::updateCoeffs();

        return;
    }

    const scalarField& phip = this->lookupPatchField
    (
        phiName_,
        reinterpret_cast<const surfaceScalarField*>(0),
        reinterpret_cast<const scalar*>(0)
    );

    this->valueFraction() = 1.0 - pos(phip);  // 这个是重点,

    mixedFvPatchField<Type>::updateCoeffs();
}

当 phi < 0 时, valueFraction (A=1),当 phi>0 时, valueFraction (A=0)

    this->valueFraction() = 1.0 - pos(phip);

大家可以尝试把这个边界的表达式写下来。

参考文献

  1. https://www.cfdsupport.com/OpenFOAM-Training-by-CFD-Support/node114.html
  2. https://cpp.openfoam.org/v4/classFoam_1_1inletOutletFvPatchField.html