Gmsh 是一款带有简单 CAD 和后处理功能的三维有限元网格生成软件。 在遵守 GPL 条款的前提下,用户可以修改或重新发布其源代码。 初学者可以直接下载运行预编译版。
本文档是基于《Gmsh Reference Manual》编写的阅读笔记,不是原文的完整翻译,也没有严格遵循原文的结构。部分术语保留英文是为了方便读者查阅原始文档。
Gmsh 可以按三种方式来使用:
其中脚本驱动程序是学习性价比最高的一种:
Modules
Geometry
Reload script
Edit script
在终端中,可以直接令 Gmsh 完成网格生成和输出操作:
gmsh t1.geo -2
常用命令行参数:
参数 | 功能 |
---|---|
-1 /-2 /-3 | 生成相应维数的网格 |
-o filename | 将网格输出到指定文件 |
-format string | 选择网格文件格式,例如 msh4 、msh2 、vtk |
-bin | 以二进制模式输出 |
-part n | 将网格分割为 n 块 (用于并行计算) |
详见《Gmsh command-line interface》。
Gmsh 自定义了一种脚本语言,用各种命令驱动主程序完成
这些命令以字符形式存储于 GEO 文件(即 .geo
文件)中。当 GEO 文件被加载时,文本解析器 (parser) 会将字符形式的命令解析到对应的可执行代码。 GEO 命令的语法与 C++ 较为接近。在代码编辑器(如 Visual Studio Code)中,将 GEO 文件的语言设置为 C++,可以高亮显示一些信息,有助于提高可读性。
《Gmsh Reference Manual》采用如下符号约定:
UpperCamelCase
或 Upper Camel Case
表示。lowerCamelCase
表示。:
分隔。< >
中。|
分隔。...
表示。在这里,通用指的是某项功能不专属于几何、网格、求解器、后处理模块。
注释是给人阅读的辅助信息,parser 会忽略这些内容。 GEO 文件里的注释采用 C++ 风格:
//
后一行以内的内容均为注释;/*
到 */
之间的所有内容均为注释。除注释以外,所有空白字符(空格 ' '
,制表符 \t
,换行符 \n
)也都被 parser 忽略。
GEO 表达式的取值有两种类型:字符型,浮点型(没有整型)。 对于计算结果有确定取值类型的表达式,可以根据计算结果的类型将其归为浮点型表达式 (Floating Point Expressions) 或字符型表达式 (Character Expressions)。 此外,还有一种计算结果类型不定的表达式,专门用于表示颜色信息,因此称为颜色表达式 (Color Expressions)。
符号后接 ~{floatExpr}
表示用 _
将该符号和 floatExpr
的计算结果串接 (concatenate) 起来。例如:
For i In {1:3}
x~{i} = i;
EndFor
其中 i
的取值为 1
、2
、3
,所以 x~{i}
等价于 x_1
、x_2
、x_3
,而上述循环等价于:
x_1 = 1;
x_2 = 2;
x_3 = 3;
[]
用于从列表中抽取一项,#
用于获取列表长度。
Entity{:}
表示提取所有同类实体。其中 Entity
可以是 Point
、Curve
、Surface
、Volume
之一。
预定义的浮点型表达式:
Pi // 3.1415926535897932
GMSH_MAJOR_VERSION // Gmsh 主版本号
GMSH_MINOR_VERSION // Gmsh 次版本号
GMSH_PATCH_VERSION // Gmsh 补丁版本号
MPI_Size // 总进程数,通常为 1, 除非编译时设置了 ENABLE_MPI
MPI_Rank // 当前进程的 rank
Cpu // 当前 CPU 时间,单位为 second
Memory // 当前内存用量,单位为 MB
TotalMemory // 可用内存总量,单位为 MB
newp // 下一个可用的 Point tag
newl // 下一个可用的 Curve tag,较早的版本里将 Curve 称为 Line,因此这里为 l
news // 下一个可用的 Surface tag
newv // 下一个可用的 Volume tag
newll // 下一个可用的 Curve Loop tag,较早的版本里将 Curve 称为 Line,因此这里为 l
newsl // 下一个可用的 Surface Loop tag
newreg // 下一个可用的 REGion tag,即 max(new*,physicalTags)
预定义的字符型表达式:
Today // 以字符形式表示的当前日期
GmshExecutableName // 当前所用 Gmsh 可执行文件的完整路径
CurrentDirectory | CurrentDir // 当前 GEO 文件所在目录
预定义的返回字符型结果的函数:
// 提取文件名前缀,即除去扩展名:
StrPrefix("hello.geo") // 返回 "hello"
// 提取相对路径,即除去文件名前的路径:
StrRelative("/usr/bin/gcc") // 返回 "gcc"
// 串接字符串:
StrCat("hello", ", ", "world") // 返回 "hello, world"
// 串接字符串,但字符串之间添加换行符 '\n'
Str("hello", ", ", "world") // 返回 "hello\n, \nworld"
// 根据第一个表达式的值是否为零,输出后两个字符串之一:
StrChoice(1, "hello", "world") // 返回 "hello"
StrChoice(0, "hello", "world") // 返回 "world"
// 提取子字符串:
StrSub("hello, world", 7, 11) // 返回 "world"
StrSub("hello, world", 7) // 返回 "world"
// 转换为大写形式:
UpperCase("hello, world") // 返回 "HELLO, WORLD"
// 类似于 C 标准库函数 sprintf:
Sprintf("%g", Pi) // 返回 "3.14159"
// 获取环境变量的值:
GetEnv("HOME") // 返回当前用户家目录绝对路径
// 子字符串替换:
StrReplace("hello, world", "o", "O") // 返回 "hellO, wOrld"
// 其他一些不常用的函数:
AbsolutePath(filename)
DirName(filename)
GetString(charExpr<, charExpr>)
GetStringValue(charExpr, charExpr)
NameToString(string)
N2S(string)
DefineString(charExpr, onelabOptions)
颜色表达式 (Colors Expressions) 用于表示颜色信息,可以是以下任意一种形式:
colorName
{red, green, blue} // [0, 255] 之间的整数,表示红绿蓝分量数值
{red, green, blue, alpha} // 前三个同上,最后一个表示透明度
colorOption
GEO 文件里的运算符与 C/C++ 里的同名运算符类似。 但有一个例外:这里的逻辑或 (logical or) 运算符 ||
总是会对其两侧的表达式求值;而在 C/C++ 里,只要第一个表达式的值为 true
,则不会对第二个表达式求值。
运算符优先级:
()
, []
, .
, #
^
!
, ++
, --
, -
(单目)*
, /
, %
+
, -
(双目)<
, >
, <=
, >=
==
, !=
&&
||
?:
=
, +=
, -=
, *=
, /=
所有函数名的首字母均为大写,除以下几个函数以 F
为首字母外,其余函数均为其本名(如 Sin
、Cos
、Tan
):
函数 | 功能 |
---|---|
Fabs(x) | 绝对值 |
Fmod(X, y) | x % y ,结果与 x 同号 |
详见《Built-in functions》。
暂时不用。
从 begin
到 end
,含起止项,步进为 step
(默认值为 1
):
// 不使用循环指标时:
For (begin : end : step)
...
EndFor
// 使用循环指标时:
For i In {begin : end : step}
...
EndFor
条件分支:
If (condition)
...
ElseIf (condition)
...
Else
...
EndIf
一些常用命令:
Abort; // 中断解析当前脚本
Exit; // 退出 Gmsh
Merge filename; // 将指定文件中的数据合并到当前模型
// 相当于 C 标准库函数 printf:
Printf("%g", Pi); // 在终端或 GUI 信息栏输出 "3.14159"
Printf("%g", Pi) > "temp.txt"; // 输出到指定文件
详见《General scripting commands》
暂时不用。
CAD 内核可以在 GEO 文件头部通过以下命令之一设定:
SetFactory("Built-in");
SetFactory("OpenCASCADE");
第一种为 Gmsh 自带的简易 CAD 内核,只支持一些简单几何对象的创建和操作。 由于采用了边界表示法 (Boundary Representation),所有几何实体必须自底向上 (bottom-up) 创建:
Point
,Point
s 为边界或控制点创建 Curve
,Curve
s 为边界创建 Surface
,Surface
s 为边界创建 Volume
。第二种为开源 CAD 系统 OpenCASCADE 的内核,支持一些高级几何对象的创建和操作。 如果没有特殊的需求,建议使用这种内核。
只具有几何意义的对象称为初等实体 (elementary entity)。 初等实体在创建时,被赋予一个正整数(非正整数为系统保留)编号,《Gmsh Reference Manual》称其为标签 (tag)。 这些 tag
满足:
Point
具有唯一的 tag
Curve
具有唯一的 tag
Surface
具有唯一的 tag
Volume
具有唯一的 tag
多数命令的语法与 C++ 相同,尤其要注意:每个语句最后的 ;
不能省略。
()
中的编号表示创建一个新的实体。{}
中的编号表示引用一个已有的实体。<>
中的内容为可选项。Point
s创建三维点:
Point(pointTag) ={
x, y, z // 直角坐标分量
<, /* 单元尺寸 */elementSize>
};
Curve
s通过连接两点创建直线段:
Line(curveTag) = {startPointTag, endPointTag};
通过一组点创建样条曲线:
Bezier(curveTag) = {pointTagList};
BSpline(curveTag) = {pointTagList};
Spline(curveTag) = {pointTagList};
创建圆弧:
// Built-in 或 OpenCASCADE 均可。
// 如果使用 Built-in 内核,则弧度必须严格小于 Pi:
Circle(curveTag) ={
startPointTag,
centerPointTag,
endPointTag
};
// 必须用 OpenCASCADE 内核:
Circle(curveTag) ={
centerX, centerY, centerZ,
radius<, startAngle, endAngle>
};
Surface
s如果使用 built-in 内核,必须按以下流程:
// 先创建一个或多个“曲线环 (Curve Loop)”:
Curve Loop(curveLoopTag) = {curveTagList};
// 再创建平面区域:
Plane Surface(surfaceTag) = {curveLoopTagList};
其中,第一个曲线环表示外边界,其余曲线环表示内边界。一个有效的曲线环必须满足:
如果使用 OpenCASCADE 内核,可以通过以下命令快速创建平面区域:
Disk(surfaceTag) = {
centerX, centerY, centerZ,
radius // 圆
};
Disk(surfaceTag) = {
centerX, centerY, centerZ,
radiusX, radiusY // 椭圆
};
Rectangle(surfaceTag) = {
cornerX, cornerY, cornerZ, // 左下角
width, height<, /* 圆角半径 */radius>
};
Volume
s如果使用 built-in 内核,必须按以下流程:
// 先创建一个或多个“曲面环 (Surface Loop)”:
Surface Loop(surfaceLoopTag) = {surfaceTagList};
// 再创建空间区域(三维流形):
Volume(volumeTag) = {surfaceLoopTagList};
其中,第一个曲面环表示外边界,其余曲面环表示内边界。一个有效的曲面环必须满足:
如果使用 OpenCASCADE 内核,可以通过以下命令快速创建空间区域(三维流形):
Sphere(volumeTag) = {
centerX, centerY, centerZ,
radius
};
Box(volumeTag) = {
cornerX, cornerY, cornerZ,
dX, dY, dZ
};
Cylinder(volumeTag) = {
centerX, centerY, centerZ,
axisX, axisY, axisZ,
radius<, angle>
};
Torus(volumeTag) = {
centerX, centerY, centerZ,
radiusOuter, radiusInner<, angle>
};
Cone(volumeTag) = {
centerX, centerY, centerZ,
axisX, axisY, axisZ,
radiusOuter, radiusInner<, angle>
};
Wedge(volumeTag) = {
cornerX, cornerY, cornerZ,
dX, dY, /* 延伸方向 */dZ<, /* 顶面宽度 */topX>
};
复合实体仍然是几何实体,它由多个具有相同维度的初等实体组成。 在生成网格时,这些初等实体的整体将被视作一个几何实体,即允许一个单元跨越多个初等实体的边界。
Compound Curve(curveTag) = {curveTagList};
Compound Surface(surfaceTag) = {surfaceTagList};
通过拉伸低维实体来创建高维实体:
// 通过 平移 拉伸:
Extrude{
vectorX, vectorY, vectorZ // 平移向量
}{
entityList // 被拉伸对象
}
// 通过 旋转 拉伸:
Extrude{
{axisX, axisY, axisZ}, // 旋转轴
{pointX, pointY, pointZ}, // 旋转轴上任意一点
angle
}{
entityList // 被拉伸对象
}
// 通过 平移 + 旋转 拉伸:
Extrude{
{vectorX, vectorY, vectorZ}, // 平移向量
{axisX, axisY, axisZ}, // 旋转轴
{pointX, pointY, pointZ}, // 旋转轴上任意一点
angle
}{
entityList // 被拉伸对象
}
一组相同维度的初等实体可以组合成一个物理实体 (physical entity),以便赋予它们物理意义。 例如:材料属性、载荷分布、边界条件等。
每个物理实体也有唯一的 tag
,这里的唯一也是针对同一维度的物理实体而言的。 除此之外,每个物理实体还可以有一个字符串表示的名称。
Physical Entity(tag | name<, tag>) <+|->= {entityTagList};
这里的 Entity
可以是 Point
、Curve
、Surface
、Volume
中的任意一个。
布尔运算 (Boolean Operation) 就是将几何区域看作点集的集合运算。 只有 OpenCASCADE 内核支持布尔运算。 所有布尔运算都是通过一条作用在两个实体列表上的指令来完成的:
BooleanOperation{passiveEntityList}{toolEntityList}
BooleanOperation
代表某种布尔运算,可以是 BooleanIntersection
、BooleanUnion
、BooleanDifference
之一。passiveEntityList
代表被动 (passive) 实体列表,toolEntityList
代表工具 (tool) 实体列表,它们可以是
<Physical> Curve | Surface | Volume{tagList}; // ; 不能省略
<... | Delete;> // 运算完成后删去对应的实体
新版 Gmsh 支持将运算结果存储为新的实体:
BooleanOperation(newEntityTag) = {passiveEntityList}{toolEntityList};
示例:
SetFactory("OpenCASCADE");
Rectangle(1) = {-5, -5, 0, 10, 10};
Disk(2) = {0, 0, 0, 2};
BooleanDifference(news) = {Surface{1}; Delete;}{Surface{2}; Delete;};
Mesh 2;
demos/boolean 中有更多示例。
// 按相同比例放缩:
Dilate{
{centerX, centerY, centerZ},
factor
}{entityList}
// 按不同比例放缩:
Dilate{
{centerX, centerY, centerZ},
{factorX, factorY, factorZ}
}{entityList}
// 旋转:
Rotate{
{axisX, axisY, axisZ},
{pointX, pointY, pointZ},
angle
}{entityList}
// 关于平面对称:
Symmetry{
A,B,C,D // A*x + B*y + C*z + D = 0
}{entityList}
// 平移:
Translate{
{vectorX, vectorY, vectorZ}, // 平移向量
}{entityList}
其中 entityList
可以是
<Physical> Point | Curve | Surface | Volume{tagList}; ...
// 或
Duplicata{<Physical> Point | Curve | Surface | Volume{tagList}; ...};
// 提取边界上低一维的实体,返回其标签:
Boundary{entityList}
// 提取边界上低一维的实体,作为一个复合实体返回其标签:
CombinedBoundary{entityList}
// 提取边界上的点,返回其标签:
PointsOf{entityList}
删除坐标相同的冗余点:
Coherence;
删除列表中的实体:
<Recursive> Delete{Entity{tagList}; ...};
这里的 Entity
可以是 Point
、Curve
、Surface
、Volume
中的任意一个。 如果列表中的某个实体被列表以外的其他实体所依赖,则不执行 Delete
命令。 Recursive
表示 Delete
命令递归地作用到所有次级实体上。
详见《Geometry options》。
Mesh.SaveAll
选项或使用命令行参数 -save_all
可以保存所有单元。⚠️ 自 v4.7.0 起,CharacteristicLength
与 Characteristic Length
分别被重命名为 MeshSize
与 Mesh Size
。
单元尺寸可以通过以下三种方式设定:
Mesh.CharacteristicLengthFromPoints
,那么可以为每个 Point
设定一个特征长度 (Characteristic Length)。Mesh.CharacteristicLengthFromCurvature
,那么网格尺寸将与曲率 (Curvature) 相适应。常用命令:
// 修改点的特征长度:
Characteristic Length{pointTagList} = length;
详见《Mesh element sizes》。
Gmsh 所生成的网格都是非结构的 (unstructured),即各单元的取向和结点邻接关系完全由其结点列表决定,而不要求相邻单元之间有其他形式的关联,因此不能算是真正意义上的结构 (structured) 网格。
所有结构网格单元(四边形、六面体、三棱柱)都是通过合并单纯形(三角形、四面体)而得到的:
// 将指定曲面上的 三角形 合并为 四边形:
Recombine Surface{surfaceTagList};
// 将指定空间区域里的 四面体 合并为 六面体 或 三棱柱:
Recombine Volume{volumeTagList};
与几何模块中的同名函数类似,只是多了一个 layers
参数:
// 通过 平移 拉伸:
Extrude{
vectorX, vectorY, vectorZ // 平移向量
}{
entityList // 被拉伸对象
layers
};
// 通过 旋转 拉伸:
Extrude{
{axisX, axisY, axisZ}, // 旋转轴
{pointX, pointY, pointZ}, // 旋转轴上任意一点
angle
}{
entityList // 被拉伸对象
layers
};
// 通过 平移 + 旋转 拉伸:
Extrude{
{vectorX, vectorY, vectorZ}, // 平移向量
{axisX, axisY, axisZ}, // 旋转轴
{pointX, pointY, pointZ}, // 旋转轴上任意一点
angle
}{
entityList // 被拉伸对象
layers
};
layers
用于设定拉伸方式,有以下几种形式可以选择:
Layers{elementNumber}; // 拉伸方向的单元数
Layers { // 两个列表的长度必须一致
{elementNumberList}, // 各层的单元数
{normalizedHeightList} // 各层的相对高度
};
Recombine Surface{surfaceTagList}; // 将指定曲面上的 三角形 合并为 四边形
Recombine Volume{volumeTagList}; // 将指定空间区域里的 四面体 合并为 三棱柱 或 六面体
获取拉伸所得实体的标签:
num[] = Extrude {0,0,1} { Surface{1}; Layers{10}; };
// num[0] 为拉伸后的顶面
// num[1] 为拉伸出的空间区域
生成一维结构网格:
Transfinite Curve{curveTagList} = nodeNumber <Using direction ratio>;
其中 direction
用于表示结点间距的变化方向,可以是:
Progression // 结点间距按几何级数 从一端向另一端 递增/递减
Bump // 结点间距按几何级数 从两端向中间 递增/递减
示例:
Point(1) = {0, 0, 0};
Point(2) = {1, 0, 0};
Line(1) = {1, 2};
Transfinite Curve{1} = 20 Using Progression 2;
Mesh 1;
生成二维结构网格:
Transfinite Surface{surfaceTagList}
<= {/* 三个或四个顶点 */pointTagList}>
<orientation>;
其中 orientation
表示三角形的取向:
Left // 全部向左倾斜
Right // 全部向右倾斜
Alternate // 倾斜方向交错变化
示例:
SetFactory("OpenCASCADE");
Rectangle(1) = {0.0, 0.0, 0.0, 3.0, 2.0};
Transfinite Surface{1} = { PointsOf{ Surface{1}; } } Right;
Mesh 2;
生成三维结构网格(必须先在三维实体的表面生成结构网格):
Transfinite Volume{volumeTagList}
<= {/* 六个或八个顶点 */pointTagList}>;
示例:
SetFactory("OpenCASCADE");
Box(1) = {0.0, 0.0, 0.0, 3.0, 2.0, 1.0};
Transfinite Surface{Boundary{Volume{1};}};
Recombine Surface{:};
Transfinite Volume{1};
Recombine Volume{1};
Mesh 3;
// 生成 dim 维网格:
Mesh dim;
// 通过分裂细化网格:
RefineMesh;
// 选择网格优化算法,algorithm 可以是 Gmsh 或 Netgen:
OptimizeMesh algorithm;
// 设置单元阶数:
SetOrder order;
// 删去冗余结点:
Coherence Mesh;
// 将网格分为 part 块:
PartitionMesh part;
详见《Mesh options》。
MSH 文件 (即扩展名为 .msh
的文件) 用于存储网格信息 (结点位置和连接关系) 以及与之关联的属性数据 (位移, 速度, 应力等). MSH 文件有两种模式:
一个 MSH
文件由以下一个或多个段落组成. 每个段落都是以一对起始符
和结束符
为界的 ASCII 字符或二进制数据块. 起始符有以下几种:
起始符 | 内容 |
---|---|
$MeshFormat | 网格格式 |
$PhysicalName (optional) | 物理名 |
$Entities | 实体 |
$PartitionedEntities (optional) | 分块实体 |
$Nodes | 结点 |
$Elements | 单元 |
$Periodic (optional) | 周期关系 |
$GhostElements (optional) | 幽灵单元 |
$NodeData (optional) | 结点数据 |
$ElementData (optional) | 单元数据 |
$ElementNodeData (optional) | 单元结点数据 |
起始符的 $
后加上 End
就是对应的结束符, 例如: 起始符 $Nodes
所对应的结束符为 $EndNodes
. 相同类型的段落可以重复多次, 属性数据可以分属不同文件, 但要求 Nodes
位于 Elements
之前.
凡是未识别的起始符都视作开启一个注释段, 直到对应的结束符, 例如:
$Comments
...
$EndComments
结点和单元的标签不要求连续.
下面以脚本文件 rectangle.geo
生成的网格文件 rectangle.msh
为例来说明 MSH 文件格式.
MeshFormat
$MeshFormat
4 0 8
$EndMeshFormat
三个数 (即使在二进制模式下, 也用字符表示) 的含义依次为:
版本
;模式
, 0
为文本模式, 1
为二进制模式;字长
, 即 sizeof(double)
的值, 一般为 8
.PhysicalNames
这一段用于描述物理对象信息, 以便后面按物理对象查找结点和单元.
$PhysicalNames
3
1 1 "LeftBoundary"
1 2 "RightBoundary"
2 3 "Domain"
$EndPhysicalNames
各行的含义依次为:
3
表示本文件中有 3
个物理实体;维度
和标签
;127
个字符) 为名称
.Entities
这一段用于描述初等实体信息, 以便后面按初等实体查找结点和单元.
第一行表示各维度初等实体的个数:
4 4 1 0
4
个零维初等实体, 即初等点;4
个一维初等实体, 即初等曲线;1
个二维初等实体, 即初等曲面;0
个三维初等实体, 即初等空间区域.随后各行依次表示各初等实体的信息.
Point
s前 4
行表示初等 Point
s:
1 0 0 0 0 0 0 0
2 2 0 0 2 0 0 0
3 2 1 0 2 1 0 0
4 0 1 0 0 1 0 0
各行含义如下:
int
表示该 Point
的标签
.double
s 表示包围盒顶点坐标的最小值
.double
s 表示包围盒顶点坐标的最大值
.unsigned long
表示物理标签的个数
: 0
, 则该行到此结束, 例如: 这里的所有各行.0
, 则给出相应个数 int
, 表示该点所属物理实体的标签
.Curve
s随后 4
行表示初等 Curve
s:
1 0 0 0 0 0 0 0 0
2 2 0 0 2 1 0 1 2 2 2 -3
3 0 1 0 2 1 0 0 2 3 -4
4 0 0 0 0 1 0 1 1 2 4 -1
各行含义如下:
int
表示该 Curve
的标签
.double
s 表示包围盒顶点坐标的最小值
.double
s 表示包围盒顶点坐标的最大值
.unsigned long
表示物理标签的个数
: 0
, 则进入下一项, 例如: 这里的第 1
, 3
行.0
, 则给出相应个数 int
, 表示该 Curve
所属物理实体的标签
, 例如: Curve{2}
属于 Physical Curve{2}
.Curve{4}
属于 Physical Curve{1}
.unsigned long
表示边界点的个数
: 0
, 则该行到此结束, 例如这里的第 1
行.0
, 则给出相应个数 int
, 表示该 Curve
所拥有的边界点的标签
, 负标签值表示终点, 例如: Curve{2}
有两个边界 Point
s: Point{2, -3}
.Curve{3}
有两个边界 Point
s: Point{3, -4}
.Curve{4}
有两个边界 Point
s: Point{4, -1}
.Surface
sSurface
段的格式与 Curve
段类似, 只不过把最后的边界点
替换为边界曲线
.
这里有 1
行表示初等 Surface
:
1 -1.8e+308 -1.8e+308 -1.8e+308 1.8e+308 1.8e+308 1.8e+308 1 3 4 1 2 3 4
各行含义如下:
int
表示该 Surface
的标签
.double
s 表示包围盒顶点坐标的最小值
, 这里是负无穷.double
s 表示包围盒顶点坐标的最大值
, 这里是正无穷.unsigned long
表示物理标签的个数
: 0
, 则进入下一项.0
, 则给出相应个数 int
, 表示该 Surface
所属物理实体的标签
. 例如这里的 Surface{1}
属于 Physical Surface{3}
.unsigned long
表示边界曲面的个数
: 0
, 则该行到此结束, 例如这里的第 1
行.0
, 则给出相应个数 int
, 表示该 Surface
所拥有的边界曲线的标签
, 负标签值表示取向相反. 例如: Surface{1}
拥有 4
条边界 Curve
s: Curve{1, 2, 3, 4}
.Volume
sVolume
段的格式与 Surface
段类似, 只不过把最后的边界曲线
替换为边界曲面
.
PartitionedEntities
暂时不用.
Nodes
这一段用于描述结点位置
以及结点与实体的归属关系
.
第一行表示各维度实体的个数:
15 6
unsigned long
表示实体总数
. 这里有 15
个实体: 6
个 Point
s,7
条 Curve
s,2
片 Surface
s,0
块 Volume
.unsigned long
表示结点总数
. 这里有 6
个 Node
s.然后以每个实体为一组, 依次列出各组所拥有的结点. 例如第一行:
5 0 0 1
int
表示实体标签
.int
表示实体维度
.int
表示参数个数
.unsigned long
表示该实体上的结点个数
. 这里为 1
, 因此紧随其后的 1
行表示该实体上的 1
个结点的信息:1 0 0 0
int
表示结点标签
.double
s 表示结点坐标
.其他实体上的结点信息可以按同样的方法读出.
Elements
这一段用于描述单元类型
, 结点与单元的归属关系
以及单元与实体的归属关系
.
第一行表示各维度实体的个数:
5 5
unsigned long
表示实体总数
. 这里有 5
个实体: 0
个 Point
s,3
条 Curve
s,2
片 Surface
s,0
块 Volume
.unsigned long
表示单元总数
. 这里有 5
个 Element
s: 0
个零维单元,3
个一维单元,2
个二维单元,0
个三维单元.然后以每个实体为一组, 依次列出各组所拥有的单元. 例如第一行:
7 1 1 1
int
表示实体标签
.int
表示实体维度
.int
表示单元类型
. 这里为 1
, 表示二结点直线单元
.unsigned long
表示该实体上的单元个数
. 这里为 1
, 因此紧随其后的 1
行表示该实体上的 1
个单元的信息:7 2 3
int
表示单元标签
.int
s 表示结点标签
.7
号单元有 2
个结点 (从单元类型推断), 结点标签分别为 2
和 3
.接下来四行表示另外两个一维单元:
10 1 1 1
10 4 1
11 1 1 1
13 6 5
最后四行表示两个二维 (四结点四边形) 单元:
$Elements
2 2 3 1
11 1 5 6 4
3 2 3 1
12 5 2 3 6
$EndElements
详见《Node ordering》。