Gmsh有限元网格剖分(Python)—任意点、直线、平面的创建

Gmsh有限元网格剖分(Python)—点、直线、平面的创建

最近在学习有限元的网格剖分算法,主要还是要参考老外的开源Gmsh库进行,写一些博客记录下学习过程,方便以后回忆嘞。

Gmsh的官方英文文档可以参考:gmsh.pdf

但咋就说,这里面东西太多了,不太适合初学者去看,因此分享下自己学习的过程吧。

目录

  • Gmsh有限元网格剖分(Python)—点、直线、平面的创建
  • 0、Gmsh的Python接口基础
  • 1、Gmsh中点的创建
  • 2、Gmsh中线的创建-连点成线
  • 3、Gmsh中面的创建-连线成面
  • 4、简单调整平面剖分精度
  • 0、Gmsh的Python接口基础

    使用Gmsh的Python接口一般有下面几个步骤:

    Step1:导入包

    import gmsh
    import sys
    

    Step2:初始化gmsh引擎、给整个结构命名(此处命名为my_t1)

    gmsh.initialize()
    gmsh.model.add("my_t1")
    

    Step3:设置创建结构使用的引擎
    ——gmsh.model.geo是GMSH自带的几何定义接口,适用于简单的几何定义和修改
    ——gmsh.model.occ基于Open CASCADE,模型修改更加高级

    # gmsh.model.geo是GMSH自带的几何定义接口,适用于简单的几何定义和修改;
    # gmsh.model.occ基于Open CASCADE,模型修改更加高级
    # kernel = gmsh.model.geo
    kernel = gmsh.model.occ
    

    Step4:创建结构,如点、线、面等,此处给出例子

    mesh_size = 1e-2
    point1_tag = kernel.addPoint(0, 0, 0, meshSize=mesh_size)
    point2_tag = kernel.addPoint(0, 1, 0, meshSize=mesh_size)
    point3_tag = kernel.addPoint(1, 0, 0, meshSize=mesh_size)
    point4_tag = kernel.addPoint(1, 1, 0, meshSize=mesh_size)
    

    Step5:模型同步,并将结构赋予实际的物理分组

    # GMSH模型同步
    kernel.synchronize()
    # 创建点集合,命名为My point
    gmsh.model.addPhysicalGroup(0, [point1_tag, point2_tag, point3_tag, point4_tag], name="My point")
    

    Step6:进行剖分、保存、调用gui显示、退出

    # 2维网格剖分
    gmsh.model.mesh.generate(2)
    # 保存一下
    gmsh.write("my_t1.msh")
    # 默认启动gui界面
    if '-nopopup' not in sys.argv:
        gmsh.fltk.run()
    # 结束gmsh
    gmsh.finalize()
    

    1、Gmsh中点的创建

    gmsh.model.geo.addPoint函数可以进行点的创建,函数的解释如下:

    1. 前三个参数是点的坐标(x, y, z) 输入mesh_size是目标网格大小,它指定了在点附近期望的网格尺寸
    2. 可以手动设置创建的点的标签,如gmsh.model.geo.addPoint(x=0, y=0, z=0, meshSize=mesh_size, tag=1)
    3. 不手动设置标签,创建时会自动返回标签,如point1_tag = gmsh.model.geo.addPoint(x=0, y=0, z=0, meshSize=mesh_size)

    实际的使用代码:

    point1_tag = kernel.addPoint(0, 0, 0, meshSize=mesh_size)
    point2_tag = kernel.addPoint(0, 1, 0, meshSize=mesh_size)
    point3_tag = kernel.addPoint(1, 0, 0, meshSize=mesh_size)
    point4_tag = kernel.addPoint(1, 1, 0, meshSize=mesh_size)
    
    # GMSH模型同步
    kernel.synchronize()
    # 创建点集合,命名为My point
    gmsh.model.addPhysicalGroup(0, [point1_tag, point2_tag, point3_tag, point4_tag], name="My point")
    

    运行代码可以调用gmsh的UI界面进行显示,可以查看到四个点被成功创建:

    双击空白位置,打开坐标轴:

    结构更加清晰明了了:

    在菜单栏的Tool中可以查看结构中各个元素的可视化选项:

    My point元素组刚好对应四个点的集合:

    全部代码:

    import gmsh
    import sys
    
    gmsh.initialize()
    # 新建模型,命名为t1,t1指的是整个结构
    gmsh.model.add("my_t1")
    
    # gmsh.model.geo是GMSH自带的几何定义接口,适用于简单的几何定义和修改;
    # gmsh.model.occ基于Open CASCADE,模型修改更加高级
    # kernel = gmsh.model.geo
    kernel = gmsh.model.occ
    
    mesh_size = 1e-2
    # 前三个参数是点的坐标(x, y, z)
    # 输入mesh_size是目标网格大小,它指定了在点附近期望的网格尺寸
    # 可以手动设置创建的点的标签,如gmsh.model.geo.addPoint(x=0, y=0, z=0, meshSize=mesh_size, tag=1)
    # 不手动设置标签,创建时会自动返回标签,如point1_tag = gmsh.model.geo.addPoint(x=0, y=0, z=0, meshSize=mesh_size)
    point1_tag = kernel.addPoint(0, 0, 0, meshSize=mesh_size)
    point2_tag = kernel.addPoint(0, 1, 0, meshSize=mesh_size)
    point3_tag = kernel.addPoint(1, 0, 0, meshSize=mesh_size)
    point4_tag = kernel.addPoint(1, 1, 0, meshSize=mesh_size)
    
    # GMSH模型同步
    kernel.synchronize()
    # 创建点集合,命名为My point,第一个输入是0代表是0维的点
    gmsh.model.addPhysicalGroup(0, [point1_tag, point2_tag, point3_tag, point4_tag], name="My point")
    
    # 2维网格剖分
    gmsh.model.mesh.generate(2)
    # 保存一下
    gmsh.write("my_t1.msh")
    # 默认启动gui界面
    if '-nopopup' not in sys.argv:
        gmsh.fltk.run()
    # 结束gmsh
    gmsh.finalize()
    

    2、Gmsh中线的创建-连点成线

    使用下面的案例代码,line1是点1和点2相连得到,line2是点2和点4相连得到,其余类似:

    line1_tag = kernel.addLine(point1_tag, point2_tag)
    line2_tag = kernel.addLine(point2_tag, point4_tag)
    line3_tag = kernel.addLine(point4_tag, point3_tag)
    line4_tag = kernel.addLine(point3_tag, point1_tag)
    

    使用下面的代码创建物理集合,第一个输入参数是1代表输入的是1维的线

    gmsh.model.addPhysicalGroup(1, [line1_tag, line2_tag, line3_tag, line4_tag], name="My line")
    

    创建后运行代码,可以看到gmsh识别到全部的点和线:

    全部代码:

    import gmsh
    import sys
    
    gmsh.initialize()
    # 新建模型,命名为t1,t1指的是整个结构
    gmsh.model.add("my_t1")
    
    # gmsh.model.geo是GMSH自带的几何定义接口,适用于简单的几何定义和修改;
    # gmsh.model.occ基于Open CASCADE,模型修改更加高级
    # kernel = gmsh.model.geo
    kernel = gmsh.model.occ
    
    mesh_size = 1e-2
    # 前三个参数是点的坐标(x, y, z)
    # 输入mesh_size是目标网格大小,它指定了在点附近期望的网格尺寸
    # 可以手动设置创建的点的标签,如gmsh.model.geo.addPoint(x=0, y=0, z=0, meshSize=mesh_size, tag=1)
    # 不手动设置标签,创建时会自动返回标签,如point1_tag = gmsh.model.geo.addPoint(x=0, y=0, z=0, meshSize=mesh_size)
    point1_tag = kernel.addPoint(0, 0, 0, meshSize=mesh_size)
    point2_tag = kernel.addPoint(0, 1, 0, meshSize=mesh_size)
    point3_tag = kernel.addPoint(1, 0, 0, meshSize=mesh_size)
    point4_tag = kernel.addPoint(1, 1, 0, meshSize=mesh_size)
    
    line1_tag = kernel.addLine(point1_tag, point2_tag)
    line2_tag = kernel.addLine(point2_tag, point4_tag)
    line3_tag = kernel.addLine(point4_tag, point3_tag)
    line4_tag = kernel.addLine(point3_tag, point1_tag)
    
    
    # GMSH模型同步
    kernel.synchronize()
    # 创建点集合,命名为My point
    gmsh.model.addPhysicalGroup(0, [point1_tag, point2_tag, point3_tag, point4_tag], name="My point")
    
    gmsh.model.addPhysicalGroup(1, [line1_tag, line2_tag, line3_tag, line4_tag], name="My line")
    
    # 2维网格剖分
    gmsh.model.mesh.generate(2)
    # 保存一下
    gmsh.write("my_t1.msh")
    # 默认启动gui界面
    if '-nopopup' not in sys.argv:
        gmsh.fltk.run()
    # 结束gmsh
    gmsh.finalize()
    
    

    3、Gmsh中面的创建-连线成面

    首先要把线的集合变成封闭的曲线(CurveLoop函数):

    line1_tag = kernel.addLine(point1_tag, point2_tag)
    line2_tag = kernel.addLine(point2_tag, point4_tag)
    line3_tag = kernel.addLine(point4_tag, point3_tag)
    line4_tag = kernel.addLine(point3_tag, point1_tag)
    
    curve_loop_tag = kernel.addCurveLoop([line1_tag, line2_tag, line3_tag, line4_tag])
    

    随后从封闭的曲线创建平面:

    surface_tag = kernel.addPlaneSurface([curve_loop_tag])
    

    创建的封闭线、平面全部全部添加到实际物理Group:

    gmsh.model.addPhysicalGroup(1, [curve_loop_tag], name="My CurveLoop")
    gmsh.model.addPhysicalGroup(2, [surface_tag], name="My Surface")
    

    运行代码,案例如下:

    全部代码如下:

    import gmsh
    import sys
    
    gmsh.initialize()
    # 新建模型,命名为t1,t1指的是整个结构
    gmsh.model.add("my_t1")
    
    # gmsh.model.geo是GMSH自带的几何定义接口,适用于简单的几何定义和修改;
    # gmsh.model.occ基于Open CASCADE,模型修改更加高级
    # kernel = gmsh.model.geo
    kernel = gmsh.model.occ
    
    mesh_size = 1e-1
    # 前三个参数是点的坐标(x, y, z)
    # 输入mesh_size是目标网格大小,它指定了在点附近期望的网格尺寸
    # 可以手动设置创建的点的标签,如gmsh.model.geo.addPoint(x=0, y=0, z=0, meshSize=mesh_size, tag=1)
    # 不手动设置标签,创建时会自动返回标签,如point1_tag = gmsh.model.geo.addPoint(x=0, y=0, z=0, meshSize=mesh_size)
    point1_tag = kernel.addPoint(0, 0, 0, meshSize=mesh_size)
    point2_tag = kernel.addPoint(0, 1, 0, meshSize=mesh_size)
    point3_tag = kernel.addPoint(1, 0, 0, meshSize=mesh_size)
    point4_tag = kernel.addPoint(1, 1, 0, meshSize=mesh_size)
    
    line1_tag = kernel.addLine(point1_tag, point2_tag)
    line2_tag = kernel.addLine(point2_tag, point4_tag)
    line3_tag = kernel.addLine(point4_tag, point3_tag)
    line4_tag = kernel.addLine(point3_tag, point1_tag)
    
    curve_loop_tag = kernel.addCurveLoop([line1_tag, line2_tag, line3_tag, line4_tag])
    
    surface_tag = kernel.addPlaneSurface([curve_loop_tag])
    
    
    # GMSH模型同步
    kernel.synchronize()
    # 创建点集合,命名为My point
    gmsh.model.addPhysicalGroup(0, [point1_tag, point2_tag, point3_tag, point4_tag], name="My point")
    
    gmsh.model.addPhysicalGroup(1, [line1_tag, line2_tag, line3_tag, line4_tag], name="My line")
    
    gmsh.model.addPhysicalGroup(1, [curve_loop_tag], name="My CurveLoop")
    
    gmsh.model.addPhysicalGroup(2, [surface_tag], name="My Surface")
    
    # 2维网格剖分
    gmsh.model.mesh.generate(2)
    # 保存一下
    gmsh.write("my_t1.msh")
    # 默认启动gui界面
    if '-nopopup' not in sys.argv:
        gmsh.fltk.run()
    # 结束gmsh
    gmsh.finalize()
    
    

    4、简单调整平面剖分精度

    gmsh.model.geo.addPoint函数可以进行点的创建,函数的解释如下:

    1. 前三个参数是点的坐标(x, y, z) 输入mesh_size是目标网格大小,它指定了在点附近期望的网格尺寸
    2. 可以手动设置创建的点的标签,如gmsh.model.geo.addPoint(x=0, y=0, z=0, meshSize=mesh_size, tag=1)
    3. 不手动设置标签,创建时会自动返回标签,如point1_tag = gmsh.model.geo.addPoint(x=0, y=0, z=0, meshSize=mesh_size)

    注意到,调整函数的meshSize输入参数可以设置网格精度,上面最后代码按照0.1进行剖分,如果我们修改上面代码设置:

    mesh_size = 5e-1
    

    结果为:

    作者:怡步晓心l

    物联沃分享整理
    物联沃-IOTWORD物联网 » Gmsh有限元网格剖分(Python)—任意点、直线、平面的创建

    发表回复