Code of the Week #28: type fixedValue

#201915

在 OpenFOAM 中,指定 A 边界的 p 为固定值时,会使用以下一段代码来设置:

A
{
    type    fixedValue;
    value   uniform 5;
}

尽管我们在前面的 Code of the Week #10: boundaryField p U 中也讲到了边界条件,但仅是边界条件的设置,还没有涉及到边界条件的实现。现在我们还看看边界条件是如何在 OpenFOAM 中实现的,又是如何同其他网格内部的信息一起组成方程的。

Code of the Week #1: div(phi,U),我们也看到边界条件是固定值的情况下,是如何与其他信息相互作用的:在对流项中

\int_V \nabla\cdot(\phi\boldsymbol{U})dV=\sum_f V_f\phi_f

式中, V 为体积流量, f 代表网格的面。当组成某网格的某些面为边界时,其值就会用于上式。

在扩散项中

\int_V\nabla\cdot(\Gamma\,\nabla\phi)dV=\sum_f(\Gamma\,\nabla\phi)_f\cdot \boldsymbol{S}_f

则需要用到边界上的梯度 \nabla \phi\boldsymbol{S}_f 为面的面积向量。

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

\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

我们先来看看栗子这个 fixedValue 边界如何完成设置?

如果写成表达式的话,则有

p_A = \text{value} =5\\ \nabla p_A = (\text{value} - \phi_c)/d = (5-p_c)/d = A_2\phi_c + B_2 = -1/d\times p_c + 1/d \times \text{value}

d 为网格面到网格中心的距离。

这些参数是如何传给系统进行计算的?来看构造函数,位于 src/finiteVolume/fields/fvPatchFields/basic/fixedValue/fixedValuePatchField.C

template<class Type>
fixedValueFvPatchField<Type>::fixedValueFvPatchField
(
    const fvPatch& p,                          // 变量
    const DimensionedField<Type, volMesh>& iF, // value 值
    const dictionary& dict                     // 边界文件
)
:
    fvPatchField<Type>(p, iF, dict, true)
{}

在每一种边界类型中中,都有相应的四个函数来确定边界上的值,对于 fixedValue 来说,其为

template<class Type>
tmp<Field<Type> > fixedValueFvPatchField<Type>::valueInternalCoeffs
(
    const tmp<scalarField>&
) const
{
    return tmp<Field<Type> >
    (
        new Field<Type>(this->size(), pTraits<Type>::zero)
    ); // 指定 A1 为 0
}


template<class Type>
tmp<Field<Type> > fixedValueFvPatchField<Type>::valueBoundaryCoeffs
(
    const tmp<scalarField>&
) const
{
    return *this;
} // 返回当前边界上的值。在构造函数中进行了初始化


template<class Type>
tmp<Field<Type> > fixedValueFvPatchField<Type>::gradientInternalCoeffs() const
{
    return -pTraits<Type>::one*this->patch().deltaCoeffs();
} // 返回 -delta, delta 为 边界面到其所属网格中心的距离的倒数


template<class Type>
tmp<Field<Type> > fixedValueFvPatchField<Type>::gradientBoundaryCoeffs() const
{
    return this->patch().deltaCoeffs()*(*this);
} // 返回 delta * value


template<class Type>
void fixedValueFvPatchField<Type>::write(Ostream& os) const
{
    fvPatchField<Type>::write(os);
    this->writeEntry("value", os);
} // 写入边界

fixedValue 是在所有边界中最简单的边界,对于边界上的值由于已知,所以不需要更新。如果是其他边界类型,则需要其他函数的帮助来更新边界值。因此,OpenFOAM 提供了 updateCoeffs 函数来显式更新边界上的值或 (系数)。其他类型的边界将会在未来几周进行详解。

Jasak 在 CFD-online.com 上提到如何调用边界条件:

[2]
Easy:

  • on correctBoundaryConditions() for a field
  • on updateCoeffs() at matrix creation

correctBoundaryConditions is also called after the linear solver call automatically.

参考文献

  1. OpenFOAM 中的边界条件(一)
  2. How the boundary conditions are called in the OpenFOAM solvers?
1 Like