You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在Gmsh Python API中创建周期性边界(无需指定仿射变换)?

如何在Gmsh Python API中创建周期性边界(无需指定仿射变换)?

我刚好踩过这个坑!其实问题根源有两个:一是没有把OpenCASCADE创建的几何同步到Gmsh的核心模型,二是参数传递的小细节没跟上,完全不需要手动推导仿射变换,Gmsh能自动帮你识别出边界间的对应关系。

先来给你拆解解决方案:

关键修正步骤

  1. 同步OpenCASCADE几何到Gmsh模型
    gmsh.model.occ.add*创建的几何是存在OpenCASCADE的临时上下文里的,并没有直接进入Gmsh的核心模型数据库。如果不做同步,setPeriodic找不到对应的实体,就会强制要求你手动指定仿射变换。所以在创建完曲面后,必须加一行:

    gmsh.model.occ.synchronize()
    
  2. 调整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

火山引擎 最新活动