本章将详细介绍如何利用Gmsh进行后处理分析,包括查看仿真结果(如温度场、应力场)、提取数据,以及与第三方工具(如ParaView)的集成,并提供完整的代码示例。
1.1 Gmsh内置可视化工具
1.1.1 查看网格与物理组
import gmsh
gmsh.initialize()
model = gmsh.model
# 生成几何和网格(示例:带孔的矩形板)
model.add("post_process")
rect = model.occ.addRectangle(0, 0, 0, 10, 10)
circle = model.occ.addCircle(5, 5, 0, 2)
circle_loop = model.occ.addCurveLoop([circle])
hole = model.occ.addPlaneSurface([circle_loop])
model.occ.cut([(2, rect)], [(2, hole)])
model.occ.synchronize()
model.mesh.generate(2)
# 显示网格和物理组标签
gmsh.fltk.run() # 启动图形界面
gmsh.finalize()
- 操作提示:
- 按
Alt + 鼠标左键
旋转视图。 - 按
w
切换网格显示模式(线框/实体)。 - 按
v
查看物理组标签。
- 按
1.2 标量场与矢量场可视化
1.2.1 添加标量场数据(如温度场)
# 假设节点温度数据存储在列表`node_temperatures`
node_tags, coords, _ = model.mesh.getNodes()
node_temperatures = [abs(x) for x in coords[::3]] # 示例:温度随x坐标变化
# 创建温度场标签
tag = model.mesh.addField("scalar", 1)
model.mesh.setField(tag, "NodeData", node_temperatures, "Temperature")
# 可视化标量场
gmsh.view.add("Temperature Field")
gmsh.view.addModelData(0, 0, "NodeData", tag, "Temperature")
gmsh.fltk.run()
1.2.2 添加矢量场数据(如速度场)
# 假设节点速度数据存储在列表`node_velocities`
node_velocities = []
for i in range(len(node_tags)):
node_velocities.extend([1.0, 0.0, 0.0]) # 示例:x方向速度=1
# 创建矢量场标签
tag = model.mesh.addField("vector", 1)
model.mesh.setField(tag, "NodeData", node_velocities, "Velocity")
# 可视化矢量场
gmsh.view.add("Velocity Field")
gmsh.view.addModelData(0, 0, "NodeData", tag, "Velocity")
gmsh.fltk.run()
1.3 数据提取与分析
1.3.1 提取节点数据
# 获取所有节点坐标
node_tags, node_coords, _ = model.mesh.getNodes()
# 按物理组提取节点(例如标记为"inlet"的边界)
inlet_nodes = []
physical_groups = model.getPhysicalGroups()
for dim, tag in physical_groups:
name = model.getPhysicalName(dim, tag)
if name == "inlet":
entities = model.getEntitiesForPhysicalGroup(dim, tag)
nodes = model.mesh.getNodes(dim, entities[0])
inlet_nodes.extend(nodes[0])
print("入口边界节点数量:", len(inlet_nodes))
1.3.2 提取单元数据
# 获取所有三角形单元
elem_types, elem_tags, elem_nodes = model.mesh.getElements(2)
triangles = elem_nodes[0] # 三角形单元节点索引
# 计算单元面积(示例)
for i in range(0, len(triangles), 3):
n1 = triangles[i] - 1 # 节点索引从1开始
n2 = triangles[i+1] - 1
n3 = triangles[i+2] - 1
x1, y1 = node_coords[n1 * 3], node_coords[n1 * 3+1]
x2, y2 = node_coords[n2 * 3], node_coords[n2 * 3+1]
x3, y3 = node_coords[n3 * 3], node_coords[n3 * 3+1]
area = 0.5 * abs((x2-x1)*(y3-y1) - (x3-x1)*(y2-y1))
print(f"单元 {i//3} 面积: {area:.4f}")
1.4 导出结果供ParaView使用
1.4.1 导出为VTK格式
gmsh.option.setNumber("Mesh.SaveAll", 1)
gmsh.write("result.vtk") # ParaView可直接打开
1.4.2 导出时间序列数据
# 模拟不同时间步的温度场
for step in range(0, 5):
current_temperatures = [t + step * 10 for t in node_temperatures]
model.mesh.setField(tag, "NodeData", current_temperatures, f"Temperature_Step{step}")
gmsh.write(f"result_step{step}.vtk")
1.5 完整案例:热传导分析后处理
import gmsh
gmsh.initialize()
model = gmsh.model
model.add("thermal_analysis")
# 生成几何和网格(带热源的板)
rect = model.occ.addRectangle(0, 0, 0, 10, 10)
heat_source = model.occ.addDisk(5, 5, 0, 1, 1)
model.occ.cut([(2, rect)], [(2, heat_source)])
model.occ.synchronize()
model.mesh.generate(2)
# 添加假想温度场(热源中心温度最高)
node_tags, coords, _ = model.mesh.getNodes()
temps = []
for x, y in zip(coords[::3], coords[1::3]):
temps.append(100 - ((x-5)**2 + (y-5)**2)) # 温度随距离热源中心递减
# 创建温度场视图
tag = model.mesh.addField("scalar", 1)
model.mesh.setField(tag, "NodeData", temps, "Temperature")
gmsh.view.add("Thermal Field")
gmsh.view.addModelData(0, 0, "NodeData", tag, "Temperature")
# 导出并可视化
gmsh.write("thermal_result.vtk")
gmsh.fltk.run()
gmsh.finalize()
1.6 常见问题
-
颜色映射不清晰
- 解决:调整色标范围:
gmsh.view.option.setNumber(tag_view, "RangeMin", 0) gmsh.view.option.setNumber(tag_view, "RangeMax", 100)
- 解决:调整色标范围:
-
矢量场箭头不可见
- 原因:箭头尺寸过小。
- 解决:调整箭头比例:
gmsh.view.option.setNumber(tag_view, "VectorType", 1) # 箭头类型 gmsh.view.option.setNumber(tag_view, "ArrowSize", 0.5) # 箭头大小
-
导出的VTK文件缺少数据
- 原因:未启用
Mesh.SaveAll
选项。 - 解决:添加
gmsh.option.setNumber("Mesh.SaveAll", 1)
。
- 原因:未启用
1.7 本章小结
本章详细讲解了Gmsh的后处理功能,包括标量场/矢量场可视化、数据提取及与ParaView的集成。通过热传导分析案例,读者可掌握从结果生成到可视化的完整流程。