如何在Gmsh Python API中创建周期性边界(无需指定仿射变换)?
如何在Gmsh Python API中创建周期性边界(无需指定仿射变换)?
我刚好踩过这个坑!其实问题根源有两个:一是没有把OpenCASCADE创建的几何同步到Gmsh的核心模型,二是参数传递的小细节没跟上,完全不需要手动推导仿射变换,Gmsh能自动帮你识别出边界间的对应关系。
先来给你拆解解决方案:
关键修正步骤
同步OpenCASCADE几何到Gmsh模型
用gmsh.model.occ.add*创建的几何是存在OpenCASCADE的临时上下文里的,并没有直接进入Gmsh的核心模型数据库。如果不做同步,setPeriodic找不到对应的实体,就会强制要求你手动指定仿射变换。所以在创建完曲面后,必须加一行:gmsh.model.occ.synchronize()调整
setPeriodic的参数格式
和你在.geo文件里的逻辑对应,源边界和目标边界的列表要正确传递,负号表示边界方向相反(和geo里的{-3}对应)。
修正后的完整代码
import gmsh gmsh.initialize() gmsh.model.add("example") # Define points (different meshSizes to check periodicity) points = [ gmsh.model.occ.addPoint(0, 0, 0, 0.005), gmsh.model.occ.addPoint(1, 0, 0, 0.05), gmsh.model.occ.addPoint(1, 1, 0, 0.2), gmsh.model.occ.addPoint(0, 1, 0, 0.2), ] # Define lines lines = [ gmsh.model.occ.addLine(points[0], points[1]), gmsh.model.occ.addLine(points[1], points[2]), gmsh.model.occ.addLine(points[2], points[3]), gmsh.model.occ.addLine(points[3], points[0]) ] # Create line loop, turn into a surface line_loop = gmsh.model.occ.addCurveLoop(lines) plane_surface = gmsh.model.occ.addPlaneSurface([line_loop]) # 关键步骤:同步OpenCASCADE几何到Gmsh模型 gmsh.model.occ.synchronize() # Set the periodic boundary conditions # 对应geo里的 Periodic Line {1} = {-3}; gmsh.model.mesh.setPeriodic(1, [lines[0]], [-lines[2]]) # 对应geo里的 Periodic Line {2} = {-4}; gmsh.model.mesh.setPeriodic(1, [lines[1]], [-lines[3]]) # Generate mesh of dim 2 gmsh.model.mesh.generate(2) # Write mesh to file gmsh.write(r"example.msh") # Launch the GUI to see the results: gmsh.fltk.run() # Finalize Gmsh gmsh.finalize()
为什么这个方案可行?
在你原来的.geo文件里,所有几何操作都是直接在Gmsh模型里完成的,不需要同步步骤;但Python的OpenCASCADE接口是独立的上下文,必须显式同步才能让Gmsh识别到这些几何实体。同步之后,Gmsh会自动分析边界间的几何变换(比如这里的水平/垂直平移),完全不需要你手动输入仿射变换矩阵。
你运行修正后的代码后,生成的网格会和.geo文件的结果完全一致:左右边界、上下边界的节点会一一对应,不同的网格尺寸也会正确匹配周期性要求。
备注:内容来源于stack exchange,提问作者Albacete




