使用Gmsh的gmsh.model.occ.cut()命令时为何生成超出预期的曲面?
关于Gmsh Python API切割圆柱后曲面异常的问题
我正在使用Gmsh的Python API,通过从一个大圆柱中切割若干小圆柱来创建体。执行操作后,我预期每个切割区域对应一个曲面,但实际结果中部分区域生成了两个甚至大小不一的曲面(问题区域已用红色标注)。我想了解:
- Gmsh出现该现象的原因是什么?
- 如何修复以获得可预测的行为?
问题原因
- 重复切割重叠区域:代码中
angle_vector = np.linspace(0,2*np.pi,number_of_hp+1)会生成number_of_hp+1个角度,最后一个角度与初始角度(0)完全重合,导致最后一个小圆柱和第一个小圆柱位置重叠。重复切割同一区域时,Gmsh几何引擎会将重叠处的曲面拆分,产生多余曲面。 - 实体标签管理错误:循环中手动用
heat_pipe+1指定新的core_tag,未遵循Gmsh内部实体标签的自动分配规则,可能引发标签冲突或实体识别错误,干扰曲面的正常合并。 - 未清理冗余几何:每次
cut操作后可能产生微小几何碎片或未合并曲面,未调用清理函数处理这些冗余,导致曲面异常。
修复方案
1. 修正角度生成逻辑
去掉重复角度,确保小圆柱位置不重叠:
angle_vector = np.linspace(0, 2*np.pi, number_of_hp, endpoint=False)
2. 正确管理实体标签
直接使用cut操作返回的实体标签,而非手动计算:
# 循环内修改为: old_core_tag = core_tag heat_pipe = gmsh.model.occ.addCylinder(pos_x[ii], pos_y[ii], pos_z, 0, 0, core_height, hp_outer_radius, tag=-1) # 获取切割后的新核心体标签 core = gmsh.model.occ.cut([(3, old_core_tag)], [(3, heat_pipe)]) core_tag = core[0][0][1]
3. 添加几何清理步骤
在synchronize前添加冗余几何清理:
gmsh.model.occ.removeAllDuplicates() gmsh.model.occ.healShapes() gmsh.model.occ.synchronize()
4. 优化切割流程(可选)
先创建所有小圆柱,再一次性切割,提升几何处理效率:
# 先创建所有小圆柱 heat_pipes = [] for ii in range(number_of_hp): hp = gmsh.model.occ.addCylinder(pos_x[ii], pos_y[ii], pos_z, 0, 0, core_height, hp_outer_radius, tag=-1) heat_pipes.append((3, hp)) # 一次性切割 core = gmsh.model.occ.cut([(3, core_tag)], heat_pipes) core_tag = core[0][0][1]
修改后的完整代码
import sys import numpy as np import gmsh gmsh.initialize(sys.argv) gmsh.clear() gmsh.model.add("circle_extrusion") inner_cyl_tag = 1 outer_cyl_tag = 2 inner_cyl = gmsh.model.occ.addCylinder(0,0,0, 0, 0, core_height, core_inner_radius, tag=inner_cyl_tag) outer_cyl = gmsh.model.occ.addCylinder(0,0,0, 0, 0, core_height, core_outer_radius, tag=outer_cyl_tag) core_tag = 3 cut1 = gmsh.model.occ.cut([(3, outer_cyl)], [(3, inner_cyl)], tag=core_tag) core_tag = cut1[0][0][1] # 正确获取切割后的核心体标签 # 创建小圆柱位置 angle_vector = np.linspace(0, 2*np.pi, number_of_hp, endpoint=False) pos_x = hp_radial_position * np.cos(angle_vector) pos_y = hp_radial_position * np.sin(angle_vector) pos_z = 0.0 # 循环切割,正确管理标签 for ii in range(number_of_hp): old_core_tag = core_tag heat_pipe = gmsh.model.occ.addCylinder(pos_x[ii], pos_y[ii], pos_z, 0, 0, core_height, hp_outer_radius, tag=-1) core = gmsh.model.occ.cut([(3, old_core_tag)], [(3, heat_pipe)]) core_tag = core[0][0][1] # 清理冗余几何并同步 gmsh.model.occ.removeAllDuplicates() gmsh.model.occ.healShapes() gmsh.model.occ.synchronize() # 分配物理组 volumes = gmsh.model.getEntities(dim=3) solid_marker = 1 gmsh.model.addPhysicalGroup(volumes[0][0], [volumes[0][1]], solid_marker) gmsh.model.setPhysicalName(volumes[0][0], solid_marker, "solid_volume") surfaces = gmsh.model.getEntities(dim=2) surface_markers = np.arange(1, len(surfaces)+1, 1) for ii in range(len(surfaces)): gmsh.model.addPhysicalGroup(2, [surfaces[ii][1]], tag=surface_markers[ii]) # 生成网格并保存 gmsh.model.mesh.generate(3) gmsh.model.mesh.refine() gmsh.model.mesh.refine() gmsh.option.setNumber("Mesh.MshFileVersion", 2.2) gmsh.write(mesh_name + ".msh") # 启动GUI查看结果(可选) #if '-nopopup' not in sys.argv: # gmsh.fltk.run() gmsh.finalize()
内容的提问来源于stack exchange,提问作者Rbocce
相关产品推荐
相关产品推荐

