@daidezhi
2021-04-22T00:48:02.000000Z
字数 1992
阅读 827
未分类
CFD中非结构网格的数据格式与代数方程组的装配
OpenFOAM,Fluent,Star都采取了类似的数据结构,FVM中很多体积分通过散度定理转变为了面积分,在装配代数方程组的时候,只需要考虑存储在面单元上的变量的符号即可。
以不可压流动中的连续方程为例:
其中是控制体
的面积矢量,其方向必须向外。(控制体一般就是几何体单元(格心格式),CFX例外,CFX使用节点存储变量,重新构造了以节点为中心的控制体(格点格式))
OpenFOAM中存储于面单元,上述积分代码实现为fvc::div(phi)
.具体计算就是进行面循环,分别将加进左右单元。
fvc::div
算子源代码
template<class Type>
tmp<GeometricField<Type, fvPatchField, volMesh>>
div
(
const GeometricField<Type, fvsPatchField, surfaceMesh>& ssf
)
{
return tmp<GeometricField<Type, fvPatchField, volMesh>>
(
new GeometricField<Type, fvPatchField, volMesh>
(
"div("+ssf.name()+')',
fvc::surfaceIntegrate(ssf)
)
);
}
fvc::surfaceIntegrate
算子源代码
template<class Type>
tmp<GeometricField<Type, fvPatchField, volMesh>>
surfaceIntegrate
(
const GeometricField<Type, fvsPatchField, surfaceMesh>& ssf
)
{
const fvMesh& mesh = ssf.mesh();
tmp<GeometricField<Type, fvPatchField, volMesh>> tvf
(
new GeometricField<Type, fvPatchField, volMesh>
(
IOobject
(
"surfaceIntegrate("+ssf.name()+')',
ssf.instance(),
mesh,
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh,
dimensioned<Type>(ssf.dimensions()/dimVol, Zero),
extrapolatedCalculatedFvPatchField<Type>::typeName
)
);
GeometricField<Type, fvPatchField, volMesh>& vf = tvf.ref();
surfaceIntegrate(vf.primitiveFieldRef(), ssf);
vf.correctBoundaryConditions();
return tvf;
}
具体实现
template<class Type>
void surfaceIntegrate
(
Field<Type>& ivf,
const GeometricField<Type, fvsPatchField, surfaceMesh>& ssf
)
{
const fvMesh& mesh = ssf.mesh();
const labelUList& owner = mesh.owner(); // lduAddr().lowerAddr()
const labelUList& neighbour = mesh.neighbour();
const Field<Type>& issf = ssf;
// 内场面循环,一次循环即可完成计算,如果基于体单元循环,每个面其实循环了两次
forAll(owner, facei)
{
ivf[owner[facei]] += issf[facei];
ivf[neighbour[facei]] -= issf[facei];
}
forAll(mesh.boundary(), patchi)
{
const labelUList& pFaceCells =
mesh.boundary()[patchi].faceCells();
const fvsPatchField<Type>& pssf = ssf.boundaryField()[patchi];
forAll(mesh.boundary()[patchi], facei)
{
ivf[pFaceCells[facei]] += pssf[facei];
}
}
ivf /= mesh.Vsc();
}