OpenFOAM类库介绍(一)网格和场

发布于:2023-01-22 ⋅ 阅读:(2) ⋅ 点赞:(0) ⋅ 评论:(0)

Part1 网格

primitive系列

1 Foam::primitiveMesh

Foam::primitiveMesh这个类的官方介绍是

Cell-face mesh analysis engine

是一个抽象类,用于组织网格并处理网格的基本计算,如面积、体积。它的构造函数很简单,如下

 //- Construct from components
 primitiveMesh
 (
     const label nPoints,
     const label nInternalFaces,
     const label nFaces,
     const label nCells
 );

甚至其中一些函数是纯虚函数,只有函数原型,只能在派生类中定义

// Primitive mesh data

//- Return mesh points
virtual const pointField& points() const = 0;

//- Return faces
virtual const faceList& faces() const = 0;

//- Face face-owner addressing
virtual const labelList& faceOwner() const = 0;

//- Face face-neighbour addressing
virtual const labelList& faceNeighbour() const = 0;

//- Return old points for mesh motion
virtual const pointField& oldPoints() const = 0;

2 Foam::PrimitivePatch

Foam::primitiveMesh类比较类似的是Foam::PrimitivePatch,其官方介绍为:

A list of faces which address into the list of points.
The class is templated on the face type (e.g. triangle, polygon etc.)
and on the list type of faces and points so that it can refer to
existing lists using UList and const pointField& or hold the storage
using List and pointField.

用于储存一个边界面(patch)的点坐标和面,可以执行一些基本几何计算,构造函数很简单

 //- Construct from components
 PrimitivePatch
 (
     const FaceList& faces,
     const Field<PointType>& points
 );

poly系列

1 Foam::polyMesh

Foam::polyMeshFoam::primitiveMesh唯一派生类。其官方介绍为

Mesh consisting of general polyhedral cells.

可以根据IOobject构造

//- Construct from IOobject
explicit polyMesh(const IOobject& io);

该构造函数的实现见https://cpp.openfoam.org/v9/polyMesh_8C_source.html#l00163
也就是Foam::polyMesh可以从文件中读取网格,这是基类Foam::primitiveMesh不能做到的。除此之外,Foam::polyMesh还定义了基类中的纯虚函数

 //- Return raw points
 virtual const pointField& points() const;

 //- Return raw faces
 virtual const faceList& faces() const;

 //- Return face owner
 virtual const labelList& faceOwner() const;

 //- Return face neighbour
 virtual const labelList& faceNeighbour() const;
 
 //- Return old points for mesh motion
 virtual const pointField& oldPoints() const;

还需注意的是,该类的私有数据成员包含了边界网格

//- Boundary mesh
mutable polyBoundaryMesh boundary_;

Foam::polyBoundaryMesh派生自Foam::polyPatchList,而Foam::polyPatchListFoam::polyPatch的列表。Foam::polyPatch派生自上文中提及的Foam::PrimitivePatch
简单理解:polyBoundaryMesh是一个列表,该列表中的每一个元素都是polyPatch类型的,而polyPatch类型来自PrimitivePatch

2 Foam::polyPatch

Foam::polyPatch派生自Foam::primitivePatch,其官方介绍为:

A patch is a list of labels that address the faces in the global face list.
The patch can calculate its own edges based on the global faces.
Patch also contains all addressing between the faces.

构造函数如下:

 //- Construct from components
 polyPatch
 (
     const word& name,
     const label size,
     const label start,
     const label index,
     const polyBoundaryMesh& bm,
     const word& patchType
 );

 //- Construct from dictionary
 polyPatch
 (
     const word& name,
     const dictionary& dict,
     const label index,
     const polyBoundaryMesh& bm,
     const word& patchType
 );

也就是说,该类可以从文件(dictionary)构造,形成边界网格

fv系列

1 Foam::fvMesh

Foam::fvMesh派生自Foam::polyMesh(当然也派生自其他基类),是最重要也最常用的网格类。其官方介绍如下:

Mesh data needed to do the Finite Volume discretisation.
NOTE ON USAGE:
fvMesh contains all the topological and geometric information
related to the mesh. It is also responsible for keeping the data
up-to-date. This is done by deleting the cell volume, face area,
cell/face centre, addressing and other derived information as
required and recalculating it as necessary. The fvMesh therefore
reserves the right to delete the derived information upon every
topological (mesh refinement/morphing) or geometric change (mesh
motion). It is therefore unsafe to keep local references to the
derived data outside of the time loop.

可从IOobject构造

//- Construct from IOobject
explicit fvMesh(const IOobject& io);

一个经典的例子是位于/opt/openfoam9/src/OpenFOAM/includecreateMesh.H文件。该文件包含了创建fvMesh网格的代码,是所有求解器必须使用的

Foam::Info
    << "Create mesh for time = "
    << runTime.timeName() << Foam::nl << Foam::endl;

Foam::fvMesh mesh
(
    Foam::IOobject
    (
        Foam::fvMesh::defaultRegion,
        runTime.timeName(),
        runTime,
        Foam::IOobject::MUST_READ
    )
);

所以说,读取网格文件是很简单的,如果项目中有网格文件const/polyMesh(该文件一般由blockMesh命令生成,具体见手册),那么只要运行上述代码,即可读入网格对象。

需要注意的是,Foam::fvMesh中包含有关边界的私有数据

//- Boundary mesh
fvBoundaryMesh boundary_; 

Foam::fvBoundaryMesh派生自Foam::fvPatchList,而Foam::fvPatchListFoam::fvPatch的列表。有趣的是,Foam::fvPatch并不派生自上文中提及的Foam::polyPatch
简单理解:fvBoundaryMesh是一个列表,该列表中的每一个元素都是fvPatch类型的。

2 Foam::fvPatch

Foam::fvPatch不是派生自Foam::polyPatch,其官方介绍如下:

A finiteVolume patch using a polyPatch and a fvBoundaryMesh

构造函数如下

//- Construct from polyPatch and fvBoundaryMesh
fvPatch(const polyPatch&, const fvBoundaryMesh&);

Part2 场

记住:场就是增强版本的数组

Foam::Field派生自List<Type>,是一个数组(列表),既没有网格也没有量纲,但是可以完成场之间的计算(比如max,sum,sqr,pow,+,- )
对于不同类型的场,Foam::Field的别名如下:

 template<class Type> class Field;
 
 typedef Field<label> labelField;
 typedef Field<scalar> scalarField;
 typedef Field<vector> vectorField;
 typedef Field<sphericalTensor> sphericalTensorField;
 typedef Field<symmTensor> symmTensorField;
 typedef Field<tensor> tensorField;

Foam::DimensionedField派生自Foam::Field,添加了网格和量纲,但是没有边界条件
Foam::GeometricField派生自Foam::DimensionedField,内置boundary类,考虑了边界条件,是使用最广泛的场类型,它有许多别名:

 typedef GeometricField<scalar, fvPatchField, volMesh> volScalarField;
 typedef GeometricField<vector, fvPatchField, volMesh> volVectorField;
 typedef GeometricField<sphericalTensor, fvPatchField, volMesh>
     volSphericalTensorField;
 typedef GeometricField<symmTensor, fvPatchField, volMesh> volSymmTensorField;
 typedef GeometricField<tensor, fvPatchField, volMesh> volTensorField;
 typedef GeometricField<scalar, fvsPatchField, surfaceMesh> surfaceScalarField;
 typedef GeometricField<vector, fvsPatchField, surfaceMesh> surfaceVectorField;
 typedef GeometricField<sphericalTensor, fvsPatchField, surfaceMesh>
     surfaceSphericalTensorField;
 typedef GeometricField<symmTensor, fvsPatchField, surfaceMesh>
     surfaceSymmTensorField;
 typedef GeometricField<tensor, fvsPatchField, surfaceMesh> surfaceTensorField;
 typedef GeometricField<scalar, pointPatchField, pointMesh> pointScalarField;
 typedef GeometricField<vector, pointPatchField, pointMesh> pointVectorField;
 typedef GeometricField<sphericalTensor, pointPatchField, pointMesh>
     pointSphericalTensorField;
 typedef GeometricField<symmTensor, pointPatchField, pointMesh>
     pointSymmTensorField;
 typedef GeometricField<tensor, pointPatchField, pointMesh> pointTensorField;

其中类Foam::fvPatchFieldFoam::fvsPatchField用于考虑边界条件

一个经典的案例是读取初始温度场:

Info << "Reading field T\n"
     << endl;

volScalarField T //温度场
    (
        IOobject(
            "T",
            runTime.timeName(),
            mesh,
            IOobject::MUST_READ,
            IOobject::AUTO_WRITE),
        mesh);