本章将详细介绍Gmsh的几何建模核心概念,包括基本几何实体的创建、布尔操作、几何变换等,并提供完整的代码示例。
3.1 几何实体与层次结构
Gmsh的几何模型基于实体层次结构,分为四个层级:
- 点(Point):几何的基本单元,通过坐标定义。
- 曲线(Curve):由点连接而成,可以是直线、圆弧、样条曲线等。
- 曲面(Surface):由闭合曲线围成,如矩形、圆形、复杂多边形。
- 体积(Volume):由闭合曲面围成的三维区域。
所有实体均有维度标签:0
(点)、1
(曲线)、2
(曲面)、3
(体积)。
3.2 创建基本几何
3.2.1 点与直线
import gmsh
gmsh.initialize()
model = gmsh.model
model.add("basic_points")
# 创建三个点(x, y, z, 网格尺寸)
p1 = model.geo.addPoint(0, 0, 0, 0.1) # 点ID=1
p2 = model.geo.addPoint(1, 0, 0, 0.1) # 点ID=2
p3 = model.geo.addPoint(1, 1, 0, 0.1) # 点ID=3
# 连接点创建直线
l1 = model.geo.addLine(p1, p2) # 直线ID=1(p1→p2)
l2 = model.geo.addLine(p2, p3) # 直线ID=2(p2→p3)
# 同步几何模型(将几何操作提交到内核)
model.geo.synchronize()
3.2.2 创建矩形
使用addRectangle
快速生成矩形:
# 创建矩形(左下角坐标(x,y,z), 宽度, 高度)
rect = model.occ.addRectangle(0, 0, 0, 5, 3)
model.occ.synchronize()
3.2.3 创建圆与圆弧
# 创建圆心和半径
center = model.occ.addPoint(0, 0, 0, 0.1)
circle = model.occ.addCircle(center, 0, 0, 2.0) # 圆心、半径=2.0
# 创建圆弧(起点、终点、中心点,角度)
arc = model.occ.addArc(center, p1, p2) # 从p1到p2,以center为中心
model.occ.synchronize()
3.3 几何操作
3.3.1 布尔运算
- 并集(Fuse):合并两个实体。
- 差集(Cut):从目标中减去工具实体。
- 交集(Intersect):保留重叠部分。
# 创建两个矩形并进行差集操作
rect1 = model.occ.addRectangle(0, 0, 0, 5, 5)
rect2 = model.occ.addRectangle(1, 1, 0, 3, 3)
result, _ = model.occ.cut([(2, rect1)], [(2, rect2)]) # 从rect1中减去rect2
model.occ.synchronize()
3.3.2 几何变换
- 平移(Translate):
# 将实体平移(dx, dy, dz) model.occ.translate([(2, rect1)], 2, 0, 0)
- 旋转(Rotate):
# 绕轴(axis_point, axis_dir)旋转角度(弧度) axis = (0, 0, 1) # z轴方向 model.occ.rotate([(2, rect1)], 0, 0, 0, *axis, angle=math.pi/4)
- 镜像(Mirror):
# 关于平面(plane_point, plane_normal)镜像 model.occ.mirror([(2, rect1)], 0, 0, 0, 1, 0, 0) # 关于x=0平面镜像
3.4 定义物理组
物理组(Physical Group)用于标记边界或区域,供后续求解器识别。
# 获取所有曲面
surfaces = model.getEntities(2)
# 标记外边界为"boundary"
boundary_curves = model.getBoundary([surfaces[0]])
model.addPhysicalGroup(1, [c[1] for c in boundary_curves], name="boundary")
# 标记体积为"domain"
model.addPhysicalGroup(3, [rect1], name="domain")
3.5 完整示例:带孔的矩形板
import gmsh
import math
gmsh.initialize()
model = gmsh.model
model.add("plate_with_hole")
# 创建矩形板(尺寸10x10)
plate = model.occ.addRectangle(0, 0, 0, 10, 10)
# 创建圆形孔(半径2,位置在中心)
circle = model.occ.addCircle(5, 5, 0, 2)
circle_loop = model.occ.addCurveLoop([circle])
hole = model.occ.addPlaneSurface([circle_loop])
# 从板中减去孔
result, _ = model.occ.cut([(2, plate)], [(2, hole)])
model.occ.synchronize()
# 设置全局网格尺寸
gmsh.option.setNumber("Mesh.CharacteristicLengthMin", 0.5)
gmsh.option.setNumber("Mesh.CharacteristicLengthMax", 0.5)
# 标记外边界和孔边界
surfaces = model.getEntities(2)
boundary_curves = model.getBoundary(surfaces)
model.addPhysicalGroup(1, [c[1] for c in boundary_curves], name="outer_boundary")
model.addPhysicalGroup(1, [circle], name="hole_boundary")
# 生成并保存网格
model.mesh.generate(2)
gmsh.write("plate_with_hole.msh")
# 可视化
gmsh.fltk.run()
gmsh.finalize()
3.6 常见问题
-
几何不闭合导致网格生成失败
- 原因:曲线未闭合或曲面存在缺口。
- 解决:使用
model.occ.healShapes()
修复几何,或手动检查实体连接。
-
布尔操作后实体消失
- 原因:工具实体完全覆盖目标实体。
- 解决:调整工具实体位置或尺寸。
-
物理组标记错误
- 原因:实体ID未正确传递。
- 解决:通过
model.getEntities()
获取实体列表后再标记。
3.7 本章小结
本章通过基础几何创建、布尔操作、物理组定义等步骤,讲解了Gmsh几何建模的核心方法。通过“带孔的矩形板”示例,读者可以掌握从几何设计到网格生成的完整流程。