[关闭]
@daidezhi 2021-04-22T00:48:02.000000Z 字数 1992 阅读 827

无标题 (04/21/2021)

未分类


CFD中非结构网格的数据格式与代数方程组的装配

OpenFOAM,Fluent,Star都采取了类似的数据结构,FVM中很多体积分通过散度定理转变为了面积分,在装配代数方程组的时候,只需要考虑存储在面单元上的变量的符号即可。

以不可压流动中的连续方程为例:

其中控制体的面积矢量,其方向必须向外。(控制体一般就是几何体单元(格心格式),CFX例外,CFX使用节点存储变量,重新构造了以节点为中心的控制体(格点格式)

OpenFOAM中存储于面单元,上述积分代码实现为fvc::div(phi).具体计算就是进行面循环,分别将加进左右单元。

fvc::div算子源代码

  1. template<class Type>
  2. tmp<GeometricField<Type, fvPatchField, volMesh>>
  3. div
  4. (
  5. const GeometricField<Type, fvsPatchField, surfaceMesh>& ssf
  6. )
  7. {
  8. return tmp<GeometricField<Type, fvPatchField, volMesh>>
  9. (
  10. new GeometricField<Type, fvPatchField, volMesh>
  11. (
  12. "div("+ssf.name()+')',
  13. fvc::surfaceIntegrate(ssf)
  14. )
  15. );
  16. }

fvc::surfaceIntegrate算子源代码

  1. template<class Type>
  2. tmp<GeometricField<Type, fvPatchField, volMesh>>
  3. surfaceIntegrate
  4. (
  5. const GeometricField<Type, fvsPatchField, surfaceMesh>& ssf
  6. )
  7. {
  8. const fvMesh& mesh = ssf.mesh();
  9. tmp<GeometricField<Type, fvPatchField, volMesh>> tvf
  10. (
  11. new GeometricField<Type, fvPatchField, volMesh>
  12. (
  13. IOobject
  14. (
  15. "surfaceIntegrate("+ssf.name()+')',
  16. ssf.instance(),
  17. mesh,
  18. IOobject::NO_READ,
  19. IOobject::NO_WRITE
  20. ),
  21. mesh,
  22. dimensioned<Type>(ssf.dimensions()/dimVol, Zero),
  23. extrapolatedCalculatedFvPatchField<Type>::typeName
  24. )
  25. );
  26. GeometricField<Type, fvPatchField, volMesh>& vf = tvf.ref();
  27. surfaceIntegrate(vf.primitiveFieldRef(), ssf);
  28. vf.correctBoundaryConditions();
  29. return tvf;
  30. }

具体实现

  1. template<class Type>
  2. void surfaceIntegrate
  3. (
  4. Field<Type>& ivf,
  5. const GeometricField<Type, fvsPatchField, surfaceMesh>& ssf
  6. )
  7. {
  8. const fvMesh& mesh = ssf.mesh();
  9. const labelUList& owner = mesh.owner(); // lduAddr().lowerAddr()
  10. const labelUList& neighbour = mesh.neighbour();
  11. const Field<Type>& issf = ssf;
  12. // 内场面循环,一次循环即可完成计算,如果基于体单元循环,每个面其实循环了两次
  13. forAll(owner, facei)
  14. {
  15. ivf[owner[facei]] += issf[facei];
  16. ivf[neighbour[facei]] -= issf[facei];
  17. }
  18. forAll(mesh.boundary(), patchi)
  19. {
  20. const labelUList& pFaceCells =
  21. mesh.boundary()[patchi].faceCells();
  22. const fvsPatchField<Type>& pssf = ssf.boundaryField()[patchi];
  23. forAll(mesh.boundary()[patchi], facei)
  24. {
  25. ivf[pFaceCells[facei]] += pssf[facei];
  26. }
  27. }
  28. ivf /= mesh.Vsc();
  29. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注