1. 网格模块概述
模型的有限元网格是通过各种形状的简单几何元素(在 Gmsh 中为线段、三角形、四边形、四面体、棱柱、六面体和金字塔)对其几何进行分割,排列方式使得如果它们相交,则沿着一个面、一个边或一个节点相交,而不是其他方式。这定义了所谓的“协调网格”。网格模块实现了多种算法来自动生成这种网格。
默认情况下,由 Gmsh 生成的网格被视为非结构化的,即使它们是以结构化方式生成的(例如,通过挤压)。这意味着网格元素完全由它们节点的有序列表定义,并且在任何两个元素之间都没有预定义的顺序关系。
为了保证网格的协调性,网格生成是以自下而上的方式进行的:首先对曲线进行离散化;然后使用曲线的网格来网格化曲面;然后使用曲面的网格来网格化体积。在这个过程中,实体的网格仅受到其边界网格的约束,除非较低维度的实体显式地嵌入到较高维度的实体中。例如,在三维空间中,如果一个表面是体积的边界的一部分,或者该表面已被显式嵌入到体积中,则离散化表面的三角形将被强制成为最终 3D 网格中四面体的面。这在例如两个体积共享一个公共表面时自动确保了网格的一致性。网格元素的定向与底层实体的几何定向相一致。
每个网格化步骤都受到网格尺寸场的约束,该尺寸场规定了网格中元素的期望大小。这个尺寸场可以是均匀的,由几何中的点关联的值指定,也可以由一般的网格尺寸场(例如与另一个网格上的某些边界的距离、与任意标量场相关联等)定义。
1.1 网格尺寸场和算法选择
网格尺寸场可以根据距离某些边界、另一个网格上定义的任意标量场等来定义。对于每个网格化步骤,所有结构化网格指令都首先执行,并作为非结构化部分的附加约束。
1.2 网格算法概述
Gmsh 的网格模块整合了多种一维、二维和三维网格算法:
- 二维非结构化算法生成三角形和/或四边形(当使用重组命令或选项时)。三维非结构化算法生成四面体,或者在边界网格包含四边形时生成四面体和金字塔。
- 二维结构化算法(横向和挤压)默认生成三角形,但可以通过使用重组命令或选项来获得四边形。三维结构化算法根据其基于的表面网格的类型生成四面体、六面体、棱柱和金字塔。
所有网格都可以细分以生成完全四边形或完全六面体网格,使用 Mesh.SubdivisionAlgorithm 选项。
1.3 选择正确的非结构化算法
Gmsh 提供了多种二维和三维非结构化算法可供选择。每种算法都有其优缺点。
- 对于所有二维非结构化算法,初始构建包含所有一维网格点的 Delaunay 网格,使用分而治之算法。缺失的边通过边交换进行恢复。在此初始步骤之后,可以应用多种算法来生成最终网格:
- “MeshAdapt” 算法基于局部网格修改。该技术利用边交换、分割和折叠:长边被分割,短边被折叠,并且如果得到更好的几何配置,则进行边交换。
- “Delaunay” 算法受到 INRIA GAMMA 团队工作的启发。新点按照具有最大无量纲外接圆半径的单元的圆心按顺序插入。然后使用各向异性 Delaunay 标准重新连接网格。
- “Frontal-Delaunay” 算法受 S. Rebay 工作的启发。
- 还有其他具有特定特征的实验性算法可供选择。特别是,“Frontal-Delaunay for Quads” 是 “Frontal-Delaunay” 算法的变体,旨在生成适合重组的直角三角形;而 “BAMG” 允许生成各向异性三角形。
1.4 选择合适的算法
针对非常复杂的曲面,最健壮的算法是“MeshAdapt”。当元素质量至关重要时,应尝试使用“Frontal-Delaunay”算法。对于非常大的平面曲面网格,使用“Delaunay”算法是最快的;通常它也比“Frontal-Delaunay”更好地处理复杂的网格尺寸场。当“Delaunay”或“Frontal-Delaunay”算法失败时,会自动触发“MeshAdapt”。“Automatic”算法对于平面曲面使用“Delaunay”,对于所有其他曲面使用“MeshAdapt”。
同时也提供了几种三维非结构化算法:
- “Delaunay”算法分为三个独立的步骤。首先,在模型中所有体积的联合体上执行初始网格,而不在体积中插入点。然后使用 H. Si 的边界恢复算法 Tetgen/BR 恢复表面网格。然后,将上述描述的二维 Delaunay 算法的三维版本应用于在体积中插入点以满足网格大小约束。
- “Frontal”算法使用 J. Schoeberl 的 Netgen 算法。
- “HXT”算法是对Delaunay算法的一种新的高效且并行的重新实现。
- 还提供了其他具有特定特征的实验性算法。特别地,“MMG3D”允许生成各向异性四面体网格。
目前,“Delaunay”算法是最健壮的,也是唯一支持自动生成具有金字塔的混合网格的算法。嵌入式模型实体和一般的网格尺寸场。目前仅受“Delaunay”和“HXT”算法支持。当使用 OpenMP 支持配置 Gmsh 时,大多数网格化步骤可以并行执行:
- 使用粗粒度方法并行化一维和二维网格化,即曲线(分别是曲面)按顺序网格化,但可以同时网格化多条曲线(分别是多个曲面)。
- 使用细粒度方法并行化 HXT 的三维网格化,即单个体积的实际网格化过程是并行进行的。
可以使用命令行上的 -nt 标志,或者使用 General.NumThreads、Mesh.MaxNumThreads1D、Mesh.MaxNumThreads2D 和 Mesh.MaxNumThreads3D 选项来控制线程数量。
1.5 指定网格元素大小
有几种方法可以指定给定几何体的网格元素大小:
首先,如果设置了选项 Mesh.MeshSizeFromPoints 和 Mesh.MeshSizeExtendFromBoundary,您可以简单地在模型的几何点处指定所需的网格元素大小。然后,在网格生成过程中,在域内插值这些值来计算网格元素的大小。这有时可能会导致某些区域过度细化,因此您可能需要在模型中添加“虚拟”几何实体,以获得所需的元素大小,或者使用下面解释的更高级方法。
第二种方法是,如果 Mesh.MeshSizeFromCurvature 被设置为正值(默认设置为 0),则网格将根据模型实体的曲率进行自适应,该值表示每 2 Pi 弧度的目标元素数量。
您还可以指定一个通用的目标网格大小,表示为网格大小字段的组合(参见第8章 [Gmsh 网格大小字段]):
- Box 字段指定了一个平行六面体区域内外的元素大小。
- Distance 字段根据到某些模型实体的距离指定了网格的大小。
- MathEval 字段使用显式的数学函数指定了网格的大小。
- PostView 字段指定了一个显式的背景网格,以标量后处理视图的形式呈现。其中节点值是目标元素大小。这种方法非常通用,但它需要一个第一次(通常是粗略的)网格和一种方法来计算该网格上的目标大小(通常是通过错误估计过程,例如在网格适应的迭代过程中)。
- Min 字段将大小指定为使用其他字段计算的大小的最小值。
-
网格大小也受结构化网格约束的限制(例如,变形或挤压网格),以及未配备几何形状的任何离散模型实体的限制,因此在网格生成期间将保留其网格。
-
边界网格大小在表面和/或体积内部进行插值,具体取决于 Mesh.MeshSizeExtendFromBoundary 的值。
-
为了确定模型中任意给定点的实际网格大小,Gmsh 评估所有上述网格大小约束,并选择最小值。使用 Gmsh API,可以通过 gmsh/model/mesh/setSizeCallback 提供的 C++、C、Python、Julia 或 Fortran 网格大小回调函数进一步修改该值。
最终结果受限于区间 [ Mesh.MeshSizeMin, Mesh.MeshSizeMax ](还可以在命令行中使用 -clmin 和 -clmax 提供)。最终结果最后乘以 Mesh.MeshSizeFactor(命令行上的 -clscale)。
需要注意的是,当网格大小完全由网格大小字段指定时,通常希望设置
-
Mesh.MeshSizeFromPoints = 0;
-
Mesh.MeshSizeFromCurvature = 0;
-
Mesh.MeshSizeExtendFromBoundary = 0;
以防止由于边界上的小网格大小而导致实体内部的过度细化。
1.6 初级实体与物理组
通常将初级几何实体组合成更有意义的组,例如定义某些数学(“区域”,“带有 Neumann 条件的边界”)、功能(“左机翼”,“机身”)或材料(“钢”,“碳”)属性。这样的分组在 Gmsh 的几何模块中完成(请参阅[几何模块])通过定义“物理组”。
默认情况下,在原生的 Gmsh MSH 网格文件格式中,以及大多数其他网格格式中,如果定义了物理组,则输出网格仅包含至少属于一个物理组的那些元素。 (不同的网格文件格式对物理组的处理略有不同,这取决于它们定义组的能力)。要保存所有网格元素,无论是否定义了物理组,请使用 Mesh.SaveAll 选项或在命令行上指定 -save_all。在某些格式中(例如 MSH2),设置 Mesh.SaveAll 将会丢弃所有物理组定义。
1.7 基本实体 vs 物理组
通常将基本几何实体组合成更有意义的组是很方便的,例如定义一些数学(“域”,“带有 Neumann 条件的边界”),功能性(“左翼”,“机身”)或材料性(“钢”,“碳”)属性。这样的分组是通过在 Gmsh 的几何模块中定义“物理组”来完成的。
在默认情况下,在本机 Gmsh MSH 网格文件格式,以及大多数其他网格格式中,如果定义了物理组,则输出网格只包含属于至少一个物理组的元素。(不同的网格文件格式以稍有不同的方式处理物理组,这取决于它们定义组的能力。)要保存所有网格元素,无论是否定义了物理组,请使用 Mesh.SaveAll 选项。或在命令行上指定 -save_all。但在某些格式中(例如 MSH2),设置 Mesh.SaveAll 将丢弃所有物理组定义。
2. 求解器模块
Gmsh中的ONELAB服务器促进了Gmsh与外部求解器或其他代码之间的通信,这是通过一个服务器端数据库和客户端之间的交互模型实现的,客户端可以通过内存或TCP/IP套接字进行通信。与典型的求解器接口不同,ONELAB服务器不需要事先了解客户端的具体细节,例如输入文件格式或语法。
相反,在任何模拟之前,会启动一个分析阶段,在此阶段客户端将其参数集上传到服务器。这些参数集的完整性和一致性在客户端上得到确保。ONELAB的主要作用是数据的集中、修改和重新分发。
使用Gmsh API,您可以直接将Gmsh集成到您的C++、C、Python、Julia或Fortran求解器中。ONELAB促进了交互式参数定义和修改,以及即时后处理数据的创建。在prepro.py、custom gui.py和custom gui.cpp中提供了示例。
如果您更喜欢保持代码之间的分离,您还可以通过套接字与Gmsh进行通信,方法是指定求解器名称(Solver.Name0、Solver.Name1等)和可执行文件的路径(Solver.Executable0、Solver.Executable1等)。然后可以使用ONELAB协议交换参数。以这种方式进行接口化的一个值得注意的求解器是GetDP,它是一个使用混合有限元的通用有限元求解器
3. 后处理模块
后处理模块允许在Gmsh中处理标量、矢量或张量数据集,以及几何和网格信息。数据集可以以多种格式提供,包括解析格式、本机MSH文件或标准的第三方格式。一旦加载到Gmsh中,标量场可以显示为等值线、等值面或颜色图,矢量场可以用三维箭头或位移图表示,张量场可以显示为Von-Mises有效应力、最小/最大特征值、特征向量、椭圆或椭球。每个数据集和可视化选项称为“后处理视图”,可以单独操作或全局操作。后处理视图的操作包括剖面计算、偏移、高程、边界和组件提取、颜色图和范围修改、动画、矢量图输出等。
默认情况下,Gmsh将所有后处理视图视为三维图,即在三维空间中绘制标量、矢量和张量基元(点、曲线、三角形、四面体等)。但是,Gmsh也可以将包含标量点的每个后处理视图表示为二维(“X-Y”)图,可以是空间方向或时间方向的:
- 在“2D空间”图中,标量点按照它们在后处理视图中定义的顺序获取:二维图的横坐标是点序列定义的曲线的曲线坐标,只绘制一条曲线,使用与点相关联的值。如果有多个时间步长可用,则每个时间步长会生成一条新曲线;
- 在“2D时间”图中,每个标量点在视图中绘制一条曲线,横坐标是时间步长。
Gmsh在以下几个方面表现出色:
- 利用内置的脚本语言快速描述简单和/或“重复”的几何结构,包括用户定义的宏、循环、条件语句和包含文件。
- 对几何结构进行参数化,使得命令和参数可以依赖于先前的计算结果,并通过OpenCASCADE几何核心提供所有常规的实体几何运算。
- 使用OpenCASCADE从其他CAD软件中导入标准交换格式的几何结构,包括从STEP和IGES文件中提取标签和颜色信息。
- 生成1D、2D和3D的非结构化有限元网格,可对元素尺寸进行精细控制。
- 创建简单的拉伸几何结构和网格,并自动将结构化网格与非结构化网格耦合起来。
- 生成符合CAD模型几何的高阶曲线网格,提供用于高阶网格优化的工具。
- 通过定义ONELAB参数与外部求解器交互,这些参数在Gmsh和求解器之间共享,并且可以在GUI中轻松修改。
- 可视化和导出计算结果的多种方式,包括标量、矢量和张量数据集,以及以不同格式导出绘图,并且可以生成复杂的动画。
- 在低端机器或没有图形界面的机器上运行,可以选择编译带有或不带有GUI的Gmsh版本,并且所有版本都可以通过交互式方式或命令行直接使用。
- 配置首选项。Gmsh具有大量的配置选项,可以通过GUI交互设置,在脚本文件中分散设置,通过API更改,设置在用户配置文件中,并在命令行上指定。
然而,Gmsh也有一些不足之处:
- Gmsh不是多块网格生成器,它生成的所有网格都符合有限元网格的概念。
- Gmsh的图形用户界面仅暴露了有限数量的可用功能,界面的某些方面可能需要改进。
- 其他不足之处可能会根据用户的体验和需求而有所不同。
为了解决这些不足之处,欢迎用户加入并贡献代码,改进Gmsh。Gmsh可以作为独立应用程序或库来安装和运行,提供可下载的二进制版本,并提供了从源代码编译的说明。