Code of the Week #29: type zeroGradient

#201916

在 OpenFOAM 中,指定某一变量的边界值为零梯度时,会用以下代码:

A
{
    type    zeroGradient;
}

我们来看一看 zeroGradient 是如何实现的。
上一期 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

现在,来看看栗子这个 zeroGradient 边界上这四个系数如何确定。

template<class Type>
tmp<Field<Type> > zeroGradientFvPatchField<Type>::valueInternalCoeffs
(
    const tmp<scalarField>&
) const
{
    return tmp<Field<Type> >
    (   // 将本边界上的 A_1 设为 1
        new Field<Type>(this->size(), pTraits<Type>::one)
    );
}


template<class Type>
tmp<Field<Type> > zeroGradientFvPatchField<Type>::valueBoundaryCoeffs
(
    const tmp<scalarField>&
) const
{
    return tmp<Field<Type> >
    (
        new Field<Type>(this->size(), pTraits<Type>::zero)
    );
}

valueInternal 将 A_1 确定为 1,将 B_1 设为 0,也就是 \phi_f=1\times\phi_c+0=\phi_c

template<class Type>
tmp<Field<Type> >
zeroGradientFvPatchField<Type>::gradientInternalCoeffs() const
{
    return tmp<Field<Type> >
    (
        new Field<Type>(this->size(), pTraits<Type>::zero)
    );
}


template<class Type>
tmp<Field<Type> >
zeroGradientFvPatchField<Type>::gradientBoundaryCoeffs() const
{
    return tmp<Field<Type> >
    (
        new Field<Type>(this->size(), pTraits<Type>::zero)
    );
}

A_2 设为 0,将 B_2 也设为 0,因此 \nabla\phi_f = 0\times\phi_c+0=0

在 zeroGradient 里面,要更新边界值,使用的是 evaluate() 函数:

template<class Type>
void zeroGradientFvPatchField<Type>::evaluate(const Pstream::commsTypes)
{
    if (!this->updated())
    {
        this->updateCoeffs();
    }

    fvPatchField<Type>::operator==(this->patchInternalField());
    fvPatchField<Type>::evaluate();
}


本文程序段来自于 foam-extend-3.1