Gmsh有限元网格剖分(Python)—任意点、直线、平面的创建
Gmsh有限元网格剖分(Python)—点、直线、平面的创建
最近在学习有限元的网格剖分算法,主要还是要参考老外的开源Gmsh库进行,写一些博客记录下学习过程,方便以后回忆嘞。
Gmsh的官方英文文档可以参考:gmsh.pdf
但咋就说,这里面东西太多了,不太适合初学者去看,因此分享下自己学习的过程吧。
目录
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函数可以进行点的创建,函数的解释如下:
- 前三个参数是点的坐标(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
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函数可以进行点的创建,函数的解释如下:
- 前三个参数是点的坐标(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)
注意到,调整函数的meshSize输入参数可以设置网格精度,上面最后代码按照0.1进行剖分,如果我们修改上面代码设置:
mesh_size = 5e-1
结果为:
作者:怡步晓心l