OpenFOAM 中的边界条件(二)【转载】
转载链接:http://xiaopingqiu.github.io/2016/04/02/Boundary-conditions-in-OpenFOAM2/
本篇在上一篇的基础上来解读 OpenFOAM 中的基础边界条件。基础边界条件一般包括三类,一是Dirichlet 边界,二是 Neumann 边界,三是混合 Dirichlet 和 Neumann 的边界。
1. fixedValue
这个是 OpenFOAM 中的 Dirichlet 边界条件。
- 构造函数
template<class Type>
fixedValueFvPatchField<Type>::fixedValueFvPatchField
(
const fvPatch& p,
const DimensionedField<Type, volMesh>& iF,
const dictionary& dict
)
:
fvPatchField<Type>(p, iF, dict, true)
{}
熟悉 OpenFOAM 的人都知道, fixedValue 这个边界条件需要用 value 关键字来指定边界的值。value 这个关键字是通过 DimensionedField 类来处理的。 DimensionedField 这个类将读取 value 关键字对应的场的值用来初始化边界上的值。
- Coefficients
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)
);
}
template<class Type>
tmp<Field<Type> > fixedValueFvPatchField<Type>::valueBoundaryCoeffs
(
const tmp<scalarField>&
) const
{
return *this;
}
这里 "*this" 表示类本身,即当前边界上的值。这个值在上面的构造函数中进行了初始化,所以,可以理解为 valueBoundaryCoeffs 函数返回的正是关键字 "value" 所对应的值。
template<class Type>
tmp<Field<Type> > fixedValueFvPatchField<Type>::gradientInternalCoeffs() const
{
return -pTraits<Type>::one*this->patch().deltaCoeffs();
}
template<class Type>
tmp<Field<Type> > fixedValueFvPatchField<Type>::gradientBoundaryCoeffs() const
{
return this->patch().deltaCoeffs()*(*this);
}
其中 delta为面心与面所属网格中心的距离的倒数。
从上述系数,可以知道,fixedValue 边界条件对边界的值和梯度值的计算为如下:
这与预期是一致的。
2. zeroGradient
这个是 OpenFOAM 中的一种特殊的 Neumann 边界条件,即边界的梯度为零。
-
evaluate 函数
template<class Type>
void
zeroGradientFvPatchField
{
if (!this->updated())
{
this->updateCoeffs();
}
fvPatchField<Type>::operator==(this->patchInternalField());
fvPatchField<Type>::evaluate();
}
注意,这里的 operator== 与 operator= 的作用是一样的,都是赋值运算,而不是比较。
-
coefficients
template<class Type>
tmp<Field<Type>
>
zeroGradientFvPatchField
(
const tmp<scalarField>&
) const
{
return tmp<Field<Type> >
(
new Field<Type>(this->size(), pTraits<Type>::one)
);
}
template<class Type>
tmp<Field<Type>
>
zeroGradientFvPatchField
(
const tmp<scalarField>&
) const
{
return tmp<Field<Type> >
(
new Field<Type>(this->size(), pTraits<Type>::zero)
);
}
template<class Type>
tmp<Field<Type>
>
zeroGradientFvPatchField
{
return tmp<Field<Type> >
(
new Field<Type>(this->size(), pTraits<Type>::zero)
);
}
template<class Type>
tmp<Field<Type>
>
zeroGradientFvPatchField
{
return tmp<Field<Type> >
(
new Field<Type>(this->size(), pTraits<Type>::zero)
);
}
从上述系数,可以知道,fixedValue 边界条件对边界的值和梯度值的计算为如下:
这与预期是一致的。
3. fixedGradient
这个是 OpenFOAM 中的 Neumann 边界条件,可以指定边界上的梯度值。
-
构造函数
template<class Type>
fixedGradientFvPatchFiel
(
const fvPatch& p,
const DimensionedField<Type, volMesh>& iF,
const dictionary& dict
)
:
fvPatchField<Type>(p, iF, dict),
gradient_("gradient", dict, p.size())
{
evaluate();
}
需要读取关键字 "gradient" 对应的值来初始化变量 gradient_。
-
evaluate 函数
template<class Type>
void
fixedGradientFvPatchFiel
{
if (!this->updated())
{
this->updateCoeffs();
}
Field<Type>::operator=
(
this->patchInternalField() + gradient_/this->patch().deltaCoeffs()
);
fvPatchField<Type>::evaluate();
}
其中 delta 为面心与面所属网格中心的距离的倒数。
-
coefficients
template<class Type>
tmp<Field<Type>
>
fixedGradientFvPatchFiel
(
const tmp<scalarField>&
) const
{
return tmp<Field<Type> >(new Field<Type>(this->size(), pTraits<Type>::one));
}
template<class Type>
tmp<Field<Type>
>
fixedGradientFvPatchFiel
(
const tmp<scalarField>&
) const
{
return gradient()/this->patch().deltaCoeffs();
}
template<class Type>
tmp<Field<Type>
>
fixedGradientFvPatchFiel
gradientInternalCoeffs() const
{
return tmp<Field<Type> >
(
new Field<Type>(this->size(), pTraits<Type>::zero)
);
}
template<class Type>
tmp<Field<Type>
>
fixedGradientFvPatchFiel
4. mixed
这是 OpenFOAM 中的混合边界条件。
-
构造函数
template<class Type>
mixedFvPatchField<Type>::mixedFvPatchField
(
const fvPatch& p,
const DimensionedField<Type, volMesh>& iF,
const dictionary& dict
)
:
fvPatchField<Type>(p, iF, dict),
refValue_("refValue", dict, p.size()),
refGrad_("refGradient", dict, p.size()),
valueFraction_("valueFraction", dict, p.size())
{
evaluate();
}
需要读取三个参数。
-
Evaluate
template<class Type>
void mixedFvPatchField<Type>::evaluate(const Pstream::commsTypes)
{
if (!this->updated())
{
this->updateCoeffs();
}
Field<Type>::operator=
(
valueFraction_*refValue_
+
(1.0 - valueFraction_)*
(
this->patchInternalField()
+ refGrad_/this->patch().deltaCoeffs()
)
);
fvPatchField<Type>::evaluate();
}
-
Coefficients
template<class Type>
tmp<Field<Type> > mixedFvPatchField<Type>::valueInternalCoeffs
(
const tmp<scalarField>&
) const
{
return Type(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 -Type(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_;
}
附注:本篇中所有的下标 pp 都表示当前边界(present boundary patch),下标 CC 表示当前边界所属的网格的中心。