You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Gmsh的gmsh.model.occ.cut()命令时为何生成超出预期的曲面?

关于Gmsh Python API切割圆柱后曲面异常的问题

我正在使用Gmsh的Python API,通过从一个大圆柱中切割若干小圆柱来创建体。执行操作后,我预期每个切割区域对应一个曲面,但实际结果中部分区域生成了两个甚至大小不一的曲面(问题区域已用红色标注)。我想了解:

  1. Gmsh出现该现象的原因是什么?
  2. 如何修复以获得可预测的行为?

问题原因

  • 重复切割重叠区域:代码中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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 11:10:26