有很多专门为 OpenFOAM 设计的开源网格生成器,分布在两个主要开发分支(vanilla OpenFOAM 和foam-extend)中。这包括 blockMesh、snappyHexMesh、foamyHexMesh、foamyQuadMesh 和 cfMesh。还有一些其他的工具,如extrudeMesh 和 extrude2DMesh,但在本节中没有讨论,因为多数 OpenFOAM 用户不使用它们。此外,它们主要属于网格实用程序,而不是本章讨论的核心网格生成器。本节将简要介绍 blockMesh 和 snappyHexMesh,并回顾它们的用法和工作原理。一般来说,网格生成器的目的是以用户友好的方式生成上一节中描述的 polyMesh 数据结构。两个网格生成器具有相似的输入和输出,因为它们读取字典文件并将最终网格写入constant/polyMesh文件中。

2.2.1 blockMesh

当调用可执行的 blockMesh 时,会自动从 constant/polyMesh 目录中读取blockMeshDict ,因此该目录文件必须存在。

blockMesh 生成块结构的六面体网格,然后将其转换为 OpenFOAM 所需的任意非结构化格式。使用 blockMesh 为复杂的几何图形生成网格通常是一项非常乏味和困难的任务,有时甚至是不可能的。对于复杂的几何图形,用户生成 blockMeshDict 所花费的精力会大大增加。因此,通常只使用 blockMesh 生成简单的网格,然后将实际几何的离散化转移到 snappyHexMesh。这使得 blockMesh 成为生成网格的好工具,这些网格要么由相当简单的几何体组成,要么为 snappyHexMesh 生成背景网格。

blockMesh 用于构建网格的示例块如图 2.5 所示。每个块由称为顶点的 8 个角组成。六面体块是从这些角点及边线构建的。

图 2.5:具有顶点和边命名约定的 blockMesh 基础块

如图 2.5 所示,将顶点相互连接。最后,块的表面由patch定义,尽管这些patch仅必须为没有相邻块的块边界显式指定。两个块之间的边界不得在patch定义中列出,因为根据定义,它们不是patch。特定边上的节点的长度和数量必须匹配,以保持拓扑一致。实际模拟的边界条件稍后将应用于这些patch。

请注意,可以生成少于 8 个顶点的块并且在patch上具有不匹配的节点(请参阅 [4]),但是,本指南不涵盖这一点。块的边缘默认为直线,但可以替换为不同的线类型,例如圆弧、多段线或样条线。选择例如圆弧确实会影响块边缘拓扑的形状,但该边缘上最终网格点之间的连接保持直线(见图 2.6)。

图2.6:灰色虚线弧表示块的边缘

1、坐标系统

最终网格在全局(右手)坐标系中构建,该坐标系是笛卡尔坐标系并与主要坐标轴对齐:x、y 和 z。当块必须在空间中任意对齐和定位时,这会导致问题。为了避免这个问题,每个块都分配有自己的右手坐标系,根据定义,这并不要求三个轴正交。这三个轴标记为 x1、x2、x3(参见 [4] 和图 2.5)。根据图 2.5 所示的符号定义局部坐标系:顶点 0 定义原点,顶点对 (0, 1) 表示 x1,而 x2 和 x3 由顶点对 (0, 3) 和 (0, 4)分别定义。

2、节点分布

在网格划分过程中,每个块被细分为单元。单元由块坐标系的三个坐标轴中每个坐标轴的边缘上的节点定义,并遵循下式给出的关系: 用户可以在 blockMeshDict 中定义在某条边上将出现多少个单元格。边上的单元可以均匀分布,也可以基于分级分布在非均匀分布上。存在两种类型的分级:simpleGrading 和 edgeGrading based。 simpleGrading 描述了基于特定边缘上最后一个网格与第一个网格的大小比对边缘的分级(见图 2.7):

图2.7:膨胀比示意图

如果 ,所有节点都在该指定边上均匀分布,则不存在分级。当膨胀比 时,节点间距从边的开始到结束增加。从 blockMesh 的 C++ 源代码中可以发现,由用户 (er) 定义的扩展比由以下关系缩放:

其中表示该指定边上的节点数。通第个节点在边上的相对位置可以通过下式计算:

{\lambda(r, i)=\frac{1-r^{i}}{1-r^{n}} \quad \text { with } \lambda \in[0,1]}\tag{2.4}\label{2.4}

尽管对于BlockMeshdict中的所有块来说,这看起来太费力了,但当需要在相邻的两个块之间平滑地转换网格大小时,这就派上了用场。 在许多情况下,简单的试错通常就足够了。

3、为最小示例定义字典

作为如何正确设置BlockMeshdict的一个小例子,对一个体积为1m3的立方体进行了离散化。 可以在示例案例存储库的chapter2/blockMesh目录中找到准备好的案例。字典由一个关键字和四个子字典组成。 第一个关键字是convertTometers,通常为1。 所有的点位置都是按这个因子缩放的,如果几何尺寸很大或很小,这就派上了用场。 在任何这种情况下,我们最终都会键入大量的前导零或后导零,这是一项乏味的任务。 通过相应地设置convertTometers,我们可以节省一些键入。blockmeshdict的第一个相关行是:

convertToMeters 1;

其次,必须定义顶点。 重要的是要记住BlockMesh中的顶点不同于所创建的PolyMesh中的点,尽管它们的定义相当相似。 对于单位立方体示例,顶点定义为

vertices
(
    (0 0 0)
    (1 0 0)
    (1 1 0)
    (0 1 0)
    (0 0 1)
    (1 0 1)
    (1 1 1)
    (0 1 1)
);

通过查看上面的定义,可以清楚地看出该语法是一个列表,类似于polymesh定义中的点列表。 这是由于在OpenFoam中圆括号指示列表,而花括号则定义字典。 前四行定义了平面中的所有四个顶点,下面的行定义了平面中的所有四个顶点。 与polymesh中的点类似,每个元素都是通过其在列表中的位置而不是坐标来访问的。 请注意,每个顶点必须是唯一的,因此在列表中只出现一次。

下一步,必须定义这些块。 图2.5可以作为参考。 单位多维数据集的示例块定义如下所示:

blocks
(
    hex (0 1 2 3 4 5 6 7) (10 10 10) simpleGrading (1 1 1);
);

同样,由于圆括号的存在,这是一个包含块的列表,而不是字典。 这个定义乍一看可能有点奇怪,但实际上很直截了当。 第一个单词hex和第一组包含八个数字的圆括号告诉blockMesh在顶点0到7中生成一个六面体。 这些顶点正是上面顶点部分中指定的顶点,并通过它们的标签进行访问。 它们的顺序不是任意的,而是由如下所示的局部块坐标系定义的:

  1. 对于局部平面,列出所有从原点开始并按照右手坐标系移动的四个顶点标记。
  2. 对局部平面执行相同操作

通过打乱特定块定义中顶点列表的顺序可以获得有效的块定义。 生成的块将看起来扭曲或使用不正确的全局坐标方向。 一旦执行blockMesh和checkMesh并在后处理器(例如Paraview)中分析网格,就检测到这一点。

注:checkMesh是一种原生的OpenFOAM工具,用于根据各种标准检查网格的完整性和质量。如果checkMesh的输出指出网格不正常,则必须对其进行改进。

第二组圆形括号定义了在块的每个特定方向上分布多少单元格。 在这个示例中,块每个方向有10个网格格。 若修改方向为2个网格,中为20个网格,中为1337个单元格,则块定义可以写为:

hex (0 1 2 3 4 5 6 7) (2 20 1337) simpleGrading (1 1 1);

最后剩下的是SimpleGrading部分,与圆括号中的最后一组数字结合在一起。 如前所述,这是定义分级(或扩展比率)的最简单的方法。 在本例中,关键字simpleGrading定义了三个局部坐标系轴方向上所有四条边的等级分为相同。 因此simpleGrading后面括号中的三个数字分别定义了方向的分级。 不过,有时这还不够通用。 这就是可以使用edgeGrading的地方。 这种更先进的分级方法本质上与simpleGrading相同,但可以明确指定六面体上12条边中每条边的分级,此时最后一组括号不会列出3个数字,而是3乘以4。 现在,每个边都可以单独设置。

保存blockMeshdict文件并在之后执行blockMesh,将得到一个与blockMeshdict中定义的类似的有效网格。 但是blockMesh会警告未定义的patches,这些patch默认被放入DefaultFaces中。

手动指定patch是通过在名为patches的列表中定义它们来完成的,对于示例patch 0:

patches
(
    XMIN
    {
        type patch;
        faces
        (
            (4 7 3 0)
        );
    }
);

这将指示blockMesh根据从顶点4、7、3和0构造的面生成名为Xmin的patch类型的patch。在内部,patch名称定义为word,并且此数据类型会定期显示在错误消息中。不过,顶点的排序方式不是任意的。它们需要从块内部看以顺时针方向指定。图2.8显示了示例的单位立方体的图像,该立方体由1000个小立方体组成,带有突出显示的XMIN,YMIN和ZMAX的patch。用于生成此网格的文件可以在chapter2/blockMesh下的示例存储库中找到。

图2.8:用块网格划分的单位立方体,每个方向的边缘分辨率为10个网格

如前所述,缺省情况下,块的边是行,因此包含边定义的列表是可选的。 与上面定义的块和patch非常类似,通过弧线而不是默认线连接两个顶点将如下所示:

edges
(
    arc 0 1 (0.5 -0.5 0)
);

包含边定义的列表中的每个项都以指示边类型的关键字开始,然后是开始和结束顶点的标签。 在本例中,这条线被构造弧所需的第三个点闭合。 对于任何其他边形状(例如折线或样条),该点将被一系列支撑点所取代。

图2.9:用块网和一个圆弧作为一条边划分的单位立方体

插入上面列出的代码如何改变单位立方体的形状(参见图2.8),在图2.9中给出了一个示例。

要继续SnappyHexMesh部分,需要生成一个由每个方向的50个单元格组成的单位立方体。

2.2.2 snappyHexMesh

与BlockMesh相比,snappyHexMesh可能不需要太多繁琐的工作,比如添加和连接块。 另一方面,对最终网格的控制较少。 使用snappyHexMesh,可以轻松生成六面体占优网格,只需要两件事:一个六面体背景网格,第二个是一个或多个兼容曲面格式的几何图形。 snappyHexMesh支持由各种体积形状定义的局部网格细化(见表2.1),边界层单元(棱镜和多面体)的应用以及并行执行。

snappyHexmesh是一个复杂的程序,由大量的控制参数控制。 详细描述这些超出了本书的范围。 请结合本书阅读[4],以获得对snappyHexMesh更深入的讨论。 其他信息可以在这里[5]找到。

图2.10: 在第一网格划分步骤之后用snappyHexMesh划分的STL球体 (D = 0.25 m)。六面体尚未与体表面对齐。

snappyHexMesh的执行流程可以分为三个主要步骤,然后依次执行。可以通过在snappyHexMeshDict的开头将相应的关键字设置为false来禁用这些步骤中的每个步骤。这三个步骤可以概括如下:

  1. castellateMesh。这是第一阶段,执行两个主要操作。首先,它将几何形状添加到网格中,并删除不在流动域内的单元。其次,根据用户的指定对现有单元格进行拆分和细化。结果是一个仅由或多或少类似于几何形状的六面体组成的网格。但是,应该放置在几何图形表面上的大多数网格点都不与它对齐。在图2.10中示出了在网格划分过程的这一阶段的后面示例的屏幕截图。
  2. snap。通过执行捕捉步骤,表面附近的网格点被移动到表面上。 这一点在图2.11中可见一斑。 在此过程中,这些网格的拓扑结构可能由六面体变为多面体。 靠近表面的网格可能被删除或合并在一起。

图2.11:与上面相同的球体,但在snap过程后。 所有的点都与体表对齐。

  1. addLayers。最后,在几何表面上引入额外的单元,通常用于细化近壁流动(见图2.12)。 将预先存在的单元从几何图形中移开,以便为额外的单元创造空间。 那些网格很可能是棱柱层。

上述所有设置以及更多设置都在system/snappyHexMeshDict中定义,该字典包含snappyHexMesh所需的所有参数。在网格化/snappyHexMesh下的OpenFOAM教程目录中可以找到一些有用的教程。与其他OpenFOAM字典相比,snappyHexMeshDict非常长,由许多层次结构级别组成,这些层次结构级别由嵌套的子词典表示。对于上述每个步骤 (假设您具有标准配置),将一个时间步骤写入case目录。这三个步骤中的每一个将在下一节中单独讨论。

2.2.2.1 Cell levels

网格级别用于描述背景网格单元格的细化状态。 启动snappyHexMesh时,将读取背景网格,并将所有单元格分配为单元格级别0(图2.12中为蓝色单元格)。

图2.12:棱镜层被应用到球面,通过拉伸面。

如果一个网格被细化一个级别,每个边缘被减半,从前一个“父”单元格生成八个单元格。 这种细化方法基于八叉树,只适用于六面体,这就是为什么snappyHexmesh需要六面体背景网格。 使用snappyHexmesh不可能只在一个方向上细化单元格,因为八叉树无法覆盖这一点。 因此根据定义,它们在所有三个空间方向上都是一致的。

2.2.2.2 定义几何图形

在snappyHexMeshdict中定义任何内容,constant/polymesh中的现有网格将自动读取并用作背景网格。 如果没有这样的网格可用,或者如果它不是纯粹基于六面体,snappyHexmesh将无法运行。 对于外部流动模拟,由背景网格定义的外部边界不如内部流动重要。 因此,它们可以保持由背景网格定义,而不需要在它们上花费更多的工作。 另一方面,在内部流动模拟中,背景网格的外部形状是由实际几何形状定义的,因此它是不受关注的。

STL几何图形可以使用几乎任何CAD程序生成。 Paraview可用于生成基本形状的STL表示,如圆柱、球体或锥体。 在sources菜单下,可以使用file菜单下的save data项导出各种形状。

对于现实世界的几何学,当然有各种方法来生成曲面网格并将其存储为STL。 然而,请记住,表面网格的质量对获得良好的体积网格至关重要。

作为一个简单的例子,在前一节中准备的单位立方体网格被重用,并在其中插入一个球体。 球体是使用STL文件生成的,而不是表2.1中列出的形状。 加载STL几何图形可以以直接的方式完成,只需将几何图形复制到case的constant/triSurface,并在snappyHexMeshdict中添加以下几何图形子字典。 一个这样的示例如下所示:

geometry
{
    sphere.stl // Name of the STL file
    {
        type triSurfaceMesh; // Type that deals with STL import
        name SPHERE; // Name access the geometry from now on
    }
}

上面的行告诉snappyHexMesh从constant/triSurface中读取spher.stl作为triSurfaceMesh,并将该STL中包含的几何体引用为sphere。一些简单的几何对象可以在不需要打开任何CAD程序的情况下直接在snappyHexMesh中构建。表2.1列出了这些几何形状。

表2.1 单元格选择形状列表

表2.1中列出的任何形状都可以在geometry子字典中构造,方法是简单地追加到现有的子字典中。例如,要将一个box添加到几何子字典中,该子字典由最小点和最大点构成。使用此方法时,不可能直接旋转长方体,它将始终与坐标轴对齐。

smallerBox
{
    type searchableBox;
    min (0.2 0.2 0.2);
    max (0.8 0.8 0.8);
}

与STL定义类似,定义searchableBox的子字典的前导字符串是用于稍后访问该几何体的名称。有时候,我们希望用表2-1中列出的形状组合一个几何体,但要将其视为一个几何体而不是多个几何体。这是可以使用searchableSurfaceCollection的地方。通过在已经存在的几何体组件上使用此方法,可以组合、旋转、平移和缩放曲面。在任何情况下,将SPHERE和smallerBox合并为一个,并将fancybox放大2倍,将如下所示:

geometry
{
    ...
    fancyBox
    {
        type searchableSurfaceCollection;
        mergeSubRegions true;
        SPHERE2
        {
            surface SPHERE
            scale (1 1 1);
        }
        smallerBox2
        {
            surface smallerBox;
            scale (2 2 2);
        }
    }
}

2.2.2.3 设置castellatedMesh步骤

这是执行snappyHexMesh期间三个步骤中的第一个步骤。它包括以下两个主要步骤:根据用户规范分割单元并删除网格区域之外的单元。图2.13给出了这一过程的示意图。

图2.13 castellatedMesh步骤期间执行的操作示意图

现有的背景网格(图2.13中的黑色)从constant/polyMesh中读取。根据snappyHexMeshDict的castellatedMeshControls子字典中的参数细化网格。区分由几何曲面定义的细化和体积细化是很重要的。曲面细分可确保表示几何图形的边界面细分到定义的层级。需要注意的是,这不仅会影响拥有特定单元的单元,还会影响邻近的单元。因此,表面细化可能看起来有点类似于体积细化,但是,它是明显不同的。对SPHERE应用这样的曲面细化由castellatedMeshControls中的条目控制,如下所示:

castellatedMeshControls
{
    ...
    refinementSurfaces
    {
        SPHERE // Name of the surface
        {
            level (1 1); // Min and max refinement level
        }
    }
    ...
}

这会将球体的表面细化到1级。圆括号之间的两个数字定义了此曲面的最小和最大细化级别。snappyHexMesh根据曲面曲率在两者之间进行选择:高度弯曲的表面区域被细化到较高水平,较小弯曲的表面区域被细化到较低水平。

snappyHexMesh中的细化不限于曲面定义。在几何子字典中定义的任何几何也可以用作体积细化的定义形状。这些体积细化称为refinementRegions,并在castellatedMesh控件中的同名子字典中定义。与refinementSurfaces相比,refinementRegions提供了更高级别的多功能性,因此需要定义更多选项。

模式有三种选择:inside、outside和distance。 顾名思义,inside只影响选定几何体内的单元格,而outside则恰恰相反。 第三个选项,距离,是两者的组合,并在表面的向外和向内法线方向上计算。 除了modes,还有一个levels选项,它比refinementSurface更复杂。 从名称上已经可以猜到,它确实支持任意数量的级别。 每个级别必须结合distance来定义。 随着在列表中位置的增加,级别必须减少,distance必须增加。 将smallerBox中的任何内容细化到级别1可以通过向castellatedMeshControls添加以下行来完成:

castellatedMeshControls
{
    ...
    refinementRegions
    {
        smallerBox // Geometry name
        {
            mode inside; // inside, outside, distance
            levels ((1E15 1)); // distance and level
        }
    }
    ...
}

上述代码使用 m的距离,以便安全地选择几何体内部的所有网格单元。

如果不指定位于最终网格体积内的点,snappyHexMesh就无法确定用户要离散化球体的哪一侧。这就是为什么locationInMesh关键字也必须在castellatedMeshControls子字典中定义的原因。此点不得放置在背景网格的面上。对于单位立方体示例,该点定义为:

locationInMesh (0.987654 0.987654 0.987654);

下一步是调整snappyHexMeshDict中snap子字典的参数。

2.2.2.4 设置捕捉步骤

与snappyHexMesh的其他两个步骤相比,这不需要大量的用户输入。此步骤负责通过将新点引入网格并替换它们来将纯六面体网格面与几何体对齐(请参见图2.11)。这是一个高度迭代的过程,这就是为什么不需要太多用户交互的原因。snappyHexMeshDict的示例snapControls子字典如下:

snapControls
{
    nSmoothPatch 3;
    tolerance 2.0;
    nSolveIter 30;
    nRelaxIter 5;
    // Feature snapping
    nFeatureSnapIter 10;
    implicitFeatureSnap false;
    explicitFeatureSnap true;
    multiRegionFeatureSnap false;
}

只定义了迭代计数器、容差和标志。 一半的参数处理到几何体边缘的对齐,这不是本描述的一部分。 然而,对此的描述可以在[3]中找到。 根据具体情况,增加迭代计数器通常会得到更高质量的网格,但也会显著增加网格划分时间。

所有参数在OpenFOAM提供的snappyHexMeshDicts中有更详细的解释。

2.2.2.5 设置addLayers步骤

addLayers步骤的所有设置都在snappyHexMeshDict的addLayersControls子字典中定义。可以使用任何表面从挤出棱柱层,而不论其类型为何。首先,需要通过layers子字典指定每个边界要拉伸的单元层数。示例条目如下所示:

addLayersControls
{
    ...
    layers
    {
        "SPHERE_.*" // Patch name with regular expressions
        {
            nSurfaceLayers 3; // Number of cell layers
        }
    }
    ...
}

每个patch名称后跟一个包含nSurfaceLayers关键字的子字典。此关键字定义要拉伸的网格层数,因此后面跟一个整数,表示要拉伸的网格层数。在上面的示例中,使用正则表达式来匹配以SPHERE_开头的任何patch程序名称。在这种情况下,它只是球体本身,但是以这种方式使用通配符可以大大减少设置时间。最终网格的横截面如图2.12所示。

snappyHexMesh的各种参数(尤其是与层挤出相关的参数)需要进行调整,以获得符合要求的网格。下面简要解释其中的几个。

  • relativeSizes可以针对以下值从绝对标注切换到相对标注。默认情况下为true。
  • expansionRatio定义从一个网格层到下一个网格层的扩展因子。
  • finalLayerThickness是最后一个网格层(距离壁面最远)相对于网格的下一个网格的厚度,或以绝对米为单位,具体取决于对relativeSizes参数的选择。
  • minThickness如果层的厚度不能大于minThickness,则不会拉伸该层。

在该示例中,采用了以下所示的设置。

relativeSizes            true;
expansionRatio            1.0;
finalLayerThickness      0.5;
minThickness            0.25;

最后,必须在case目录中执行snappyHexMesh以开始网格化过程。每个步骤都会生成一个新的时间点目录,其中包含该特定阶段的网格。如果选择通过调整snappyHexMeshDict中的参数来更改网格,请记住在重新运行snappyHexMesh之前删除旧的时间点。

  1. 另一个用于OpenFOAM的高质量网格生成器是enGrid,可以从www.example.com免费获得http://engits.eu/en/engrid。
  2. cfMesh应用程序是一个分布式内存并行OpenFOAM网格工具,它与snappyHexMesh一样,将STL曲面作为输入。此软件包由Creative Fields Ltd.开发,可在www.c-fields.com上与文档一起下载。

2.2.3 cfMesh

cfMesh库是一个跨平台库,用于自动生成网格,它构建在OpenFOAM之上。它与OpenFOAM和foam-extend的所有最新版本兼容,并根据通用公共许可证(GPL)授权。该库由Franjo Juretić博士开发,并由Creative Fields Ltd.发布,可从http://www.c-fields.com 下载。

本节简要概述了库、控制网格生成过程的选项以及cfMesh附带的一些实用程序。它绝不是项目的完整文档。有关更多信息,请访问上述项目网页。

cfMesh库支持使用主库中的组件构建的各种3D和2D工作流,这些组件是可扩展的,可以组合到各种网格化工作流中。核心库基于网格修改器的概念,可通过消息传递接口(MPI)使用对称多处理器(SMP)与分布式内存并行(DMP)实现高效的并行化。此外,还特别注意内存使用,通过实现数据容器(列表、图形等)来保持较低的内存使用。其在网格化处理期间不需要许多动态存储器分配操作。

cfMesh中的网格化过程是自动进行的,需要输入三角剖分和包含各种网格化参数(设置)的字典。给定曲面网格和设置后,网格化过程将从控制台启动,并且自动运行,无需任何用户干预。该库经过优化,网格化工作流需要的设置较少,并且语法简单。目前,cfMesh可以在内部创建体积网格,请参见图2.14,它不需要几何封闭。

(a)流形域(B)有孔流形域图2. 14:cfMesh中允许的几何类型

2.2.3.1 可用网格化工作流

所有工作流都针对共享内存计算机进行并行化处理,并在运行时使用所有可用的CPU内核。使用的核心数可由OMP_NUM_THREADS环境变量控制,该变量可设置为所需的核心数。

可用的网格划分工作流通过从输入几何图形和用户指定的设置创建所谓的网格模板来启动网格划分过程。 模板随后被调整以匹配输入几何图形。 将模板拟合到输入几何形状的过程被设计为能够容忍质量差的输入数据,这不需要封闭几何。 可用的工作流因模板中生成的网格类型而不同。

笛卡尔工作流生成的三维网格主要由六面体单元组成,不同尺寸单元之间的过渡区域为多面体。 它是通过在shell窗口中键入CartesianMesh开始的。 默认情况下,它生成一个边界层,可以根据用户的要求进一步细化。 此外,该工作流可以使用MPI并行化来运行,该并行化用于生成不适合于单个可用计算机内存的大型网格。

该工作流将生成2D笛卡尔网格。在控制台中键入cartesian 2DMesh可启动网格生成器。依预设,它会产生一个边界层,可进一步细分。此网格化工作流需要带状几何体,如图2.16a所示,该几何体在x-y平面中延伸并在z方向上拉伸。

图2.15 三维笛卡尔网格划分

图2.16 2D笛卡尔网格化

四面体工作流生成由四面体单元组成的网格,如图2.17所示,并通过在控制台中键入tetMesh启动。默认情况下,它不生成任何边界图层,并且可以根据用户请求添加和优化边界层。

图2.17 四面体网格划分

2.2.3.2 输入几何

cfMesh使用的几何尺寸需要以曲面三角剖分的形式定义。对于2D情况,几何图形以三角形带的形式给出,其边界边位于x-y平面中(不支持其他方向)。几何由下列对象组成:

  • List of points。包含曲面三角剖分中的所有点。
  • List of triangles。包含曲面网格中的所有三角形。
  • Patches。在网格划分过程中转移到体网格上的实体。 曲面中的每一个三角形都分配给单个的patch,不能分配给多个patch。 每个patch由其名称和类型标识。 默认情况下,所有patch名称和类型都被转移到体积网格中,并且很容易用于定义模拟的边界条件。
  • Facet subsets。在网格划分过程中没有转移到体网格上的实体。 它们用于定义网格划分设置。 每个面子集包含曲面网格中三角形的索引。 请注意,曲面网格中的三角形可以包含在多个子集中。 刻面子集可以由cfSuite生成,cfSuite是由Creative物理场有限公司开发的商业应用程序。
  • Feature edges。特征边在网格化过程中被视为约束。三条或更多特征边相交的曲面点被视为角点。特征边可以通过surfaceFeatureEdges工具或cfSuite生成。

图2.18显示了一个带有高亮显示的patch的曲面网格。

图2.18 几何与patch和子集的一个例子

由cfMesh转换的所有尖锐特征必须在网格化过程之前由用户定义。在网格划分过程中,两个面片之间的边界边缘(图2.19a)和特征边缘作为尖锐特征进行处理(见图2.19b)。三角剖分中的其他边不受约束。

图2.19 捕捉特征边的可能方法

网格的文件格式建议:fms、ftr和stl。此外几何可以在所有支持的格式导入带有OpenFOAM surfaceConvert效用。然而这三个建议格式支持定义的patch转移到默认体网格。其他格式还可以用于网格划分但是他们不支持定义输入几何和patch的面上产生的体积网格边界的结束在一个patch。

cfMesh的首选格式为fms,用于保存设置网格作业的所有相关信息。它将补片、子集和特征边存储在单个文件中。此外,它是唯一一种可以将所有几何实体存储到单个文件中的格式,强烈建议用户使用它。

2.2.3.3 字典和可用的设置

网格划分过程由位于案例的系统目录中的meshDict字典中提供的设置来指导。 对于使用MPI的并行网格划分,需要一个位于case的系统目录中的decomposePardict,并且用于并行运行的节点数必须与decomposepardict中的numberofsubdomains条目匹配。 decomposePardict中的其他条目不是必需的。 生成的卷网格写在constant/polyMesh目录中。 meshDict中可用的设置将在本节的其余部分中更详细地解释。

cfMesh库只需要两个强制设置就可以启动网格划分过程:

  • surfaceFile。指向几何文件。 几何文件的路径相对于case目录的路径。
  • maxCellSize。表示用于网格划分的默认网格大小。 它是域中生成的最大单元格大小。

2.2.3.4 细化设置

当统一的单元大小不令人满意时,cfMesh中有许多用于局部细化源的选项。

  • boundaryCellSize选项用于优化边界处的单元格。这是一个全局选项,所请求的网格大小将应用于边界的所有位置。
  • minCellSize是一个全局选项,可激活网格模板的自动细化。此选项在像元大于估计要素大小的区域中执行优化。此设置提供的标量值指定此过程可生成的最小像元大小。此选项对于快速模拟非常有用,因为它可以在复杂几何图形中生成网格,用户只需很少的工作。但是,如果需要高网格质量,它会在需要进行网格细化的位置提供提示。
  • localRefinement允许在边界处进行局部细化区域。它是一个字典的字典,并且localRefinement主字典中的每个字典都由用于细化的几何图形中的面片或面子集命名。实体的请求像元大小由cellSize关键字和标量值控制,或通过指定additionalRefinementLevels关键字和相对于maxCellSize的所需细化数来控制。
  • objectRefinement用于指定体积块内的细化区域。可用于优化的支持对象包括:直线、球体、长方体和截锥。它被指定为字典的字典,其中objectRefinement字典中的每个字典都表示用于细化的对象的名称。

cfMesh中实现的网格化工作流基于由内向外网格化,网格化过程从基于用户指定的单元尺寸生成所谓的网格模板开始。但是,如果网格尺寸局部大于几何要素尺寸,则可能导致该几何形状由网格填充。相反,如果指定的网格大小大于局部特征大小,则几何体中较薄部分的网格可能会丢失。

图2.20 通过面片/子集进行局部细化

图2.21 通过基本对象进行局部细化

keepCellsIntersectingBoundary选项是一个全局选项,可确保模板中与边界相交的所有单元仍是模板的一部分。默认情况下,所有网格化工作流仅保留模板中完全位于几何体内部的单元。keepCellsIntersectingBoundary关键字后面必须跟1(活动)或0(非活动)。激活此选项可能会导致局部连接的网格超过间隙,该问题可以通过checkForGluedMesh选项解决,该选项后面还必须跟有1(活动)或0(非活动)。

keepCellsIntersectingPatches选项是在用户指定的区域中保留模板中的单元的选项。它是字典的字典,主字典中的每个字典都以patch或面子集命名。启用keepCellsIntersectingBoundary选项时,此选项处于非活动状态。

removeCellsIntersectingPatches选项是从模板中删除用户指定区域中的单元格的选项。 它是一个字典的字典,主字典中的每个字典都由一个patch或一个方面子集命名。 当KeepCellsIntersectingBoundary选项打开时,该选项处于活动状态。

图2.22 删除由补丁/子集相交的单元格

cfMesh中的边界层从体积网格的边界面向内部拉伸,在网格划分过程之前不能拉伸。 此外,它们的厚度由边界处指定的单元尺寸控制,网格生成器倾向于生成与单元尺寸相似厚度的层。 CFMesh中的层可以跨越多个补丁,如果它们共享凹边或角,且价大于3。 此外,CFMESH从不对边界层的拓扑进行Breask,其最终几何形状依赖于光滑过程。 所有边界层设置都在BoundaryLayers字典中提供。 选项有:

  • nlayers指定将在网格中生成的层数。 它不是强制性的。 如果没有指定,网格划分工作流将生成默认的层数,该层数要么为一,要么为零。
  • thicknessRatio是连续两层厚度之间的比值。 它不是强制性的。 该比率必须大于或等于1。
  • maxFirstLayerThickness确保第一边界层的厚度永远不会超过指定值。 它不是强制性的。
  • patchBoundaryLayers设置是一个字典,用于指定单个斑块边界层的局部属性。

可以在名称与patch名称相同的字典中分别为每个面片指定nLayers,thicknessRatio与maxFirstLayerThickness选项。默认情况下,在面片处生成的层数由全局层数控制,或由在与现有面片一起形成连续层的任何面片处指定的最大层数控制。allowDiscontinuity选项可确保patch所需的层数不会扩展到同一层中的其他patch。

图2.23 边界层

本节中提供的设置用于在网格生成过程中更改patch名称和类型。这些设置在renameBoundary字典中提供,其中包含以下选项:

  • newPatchNames是renameBoundary字典内的字典。它包含带有应重命名的patch名称的词典。对于每个patch,可以使用以下设置指定新名称或新patch类型:
    • newName关键字后跟给定patch的新名称。该设置不是必需的。
    • type关键字后跟给定patch的新类型。该设置不是必需的。
  • defaultName是除newPatchNames字典中指定的patch之外的所有patch的新名称。该设置不是必需的。
  • defaultType为所有patch(newPatchNames目录中指定的patch除外)设置新类型。该设置不是必需的。

2.2.3.5 cfMesh中的各种实用程序

目前,cfMesh项目提供了以下实用程序:

  • FLMAToSurface将几何体从AVL的flma格式转换为cfMesh可读的格式。输入文件中定义的单元选择将作为面子集进行传输。
  • FPMAToMesh是用于从AVL的fpma格式导入体积网格的实用程序。在输入网格上定义的选择将作为子集传递。
  • copySurfaceParts将指定多面子集中的曲面多面复制到新曲面网格中。
  • extrudeEdgesInto2DSurface将几何图形中作为特征边写入的边拉伸到生成2D网格所需的三角形带中。生成的三角形存储在单个面片中。
  • meshToFPMA将网格转换为AVL的fpma格式。
  • patchesToSubsets将几何中的曲面片转换为多面子集。
  • preparePar创建MPI并行化所需的处理器目录。处理器目录的数目取决于在decomposeParDict中指定的numberOfSubdmains。
  • removeSurfaceFacets是用于从曲面网格中移除镶嵌面的工具。应移除的面由面片名称或面子集给出。
  • subsetToPatch在曲面网格中创建由给定小平面子集中的小平面组成的patch。
  • SurfaceFeatureEdges用于生成几何中的特征边。 如果输出是FMS文件,则生成的边缘存储为特征边缘。 否则,它将生成以所选特征边缘为界的patch。
  • SurfaceGenerateBoundingBox在几何图形周围生成一个box。 它不会解决自交集,以防盒子与几何的其余部分相交。