#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_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_;
}
可以总结出来表达式:
A 为 valueFraction_
。
说明只要确定了上述几个参数: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);
大家可以尝试把这个边界的表达式写下来。