首页/文章/ 详情

Gmsh 使用入门:几何模型构建简介

1年前浏览2320

Gmsh 简介

  Gmsh 是一个开源的 3D 有限元网格生成器,内置 CAD 引擎和后处理器。其设计目标是提供一种快速、轻便且用户友好的网格划分工具,具有参数输入和高级可视化功能。Gmsh 围绕几何、网格、求解器和后处理四个模块构建。对这些模块的任何输入的规范可以使用图形用户界面交互地完成,也可以使用 Gmsh 自己的脚本语言(.geo 文件)完成,或者使用 C++、C、Python 或 Julia 应用程序编程接口(API)。

  本文主要介绍 Gmsh 在 Python 接口下构建几何模型的一些基本操作,阅读完本文,可以学会使用 Gmsh 构建简单的几何模型并生成网格。

  Gmsh 的 Python 接口使用 pip 命令即可安装

pip3 install --upgrade gmsh

  Gmsh 有两个几何内核用于构造几何,一个是内置的 built-in 几何内核,另一个是第三方的 OCC 内核,其中 build-in 内核仅支持自下而上构建几何体,即以 点-线-边-面 的顺序逐步构建几何;OCC 内核不但支持自下而上构建几何,同时还支持使用建模函数来构建几何体。

构建几何

Built-in 内核

  使用 Gmsh 的 Python API,首先导入 gmsh 模块

import gmsh

若想使用 gmsh,还需要对其进行初始化,使用初始化命令

gmsh.initialize() # 若想使用gmsh,首先需要初始化

之后,我们创建一个模型

gmsh.model.add("test") # 创建模型并命名

自下而上构建几何对象,首先需要构建点对象

gmsh.model.geo.addPoint(0, 0, 0, 0.1, 1)
gmsh.model.geo.addPoint(1, 0, 0, 0.1, 2)
gmsh.model.geo.addPoint(1, 1, 0, 0.1, 3)
gmsh.model.geo.addPoint(0, 1, 0, 0.1, 4)

其中前三个参数是点的坐标,gmsh 的几何都是在三维下创建的,若想建立二维的几何对象,只需要把所有点的 z 坐标设为 0 即可,第四个参数为该点处的参考网格尺寸值,第五个参数为该点的标号,标号从 1 开始。

  创建完点,创建线

gmsh.model.geo.addLine(1, 2, 1) 
gmsh.model.geo.addLine(3, 2, 2)
gmsh.model.geo.addLine(3, 4, 3)
gmsh.model.geo.addLine(4, 1, 4)

前两个参数是点的标号,即边的两个端点的标号,同时还给定了线的方向,即从第一个点指向第二个点;第三个参数为该边的标号。不同类型的对象的标号是不通用的,也就是说,虽然点已经有了标号 1 到 4,但边和点是不同类型的几何对象,因此还可以使用标号 1 到 4。

  之后,我们创建边对象与面对象

gmsh.model.geo.addCurveLoop([1, -2, 3, 4], 1) # 线环,边
gmsh.model.geo.addPlaneSurface([1], 1) #面

Line 对象只是线,若想生成面,则首先需要创建边对象,也称其为线环(CurveLoop),即将 Line 组成边界,其中第一个变量为一个列表,里面按顺序放置组成边界的线的标号,线之间需要首尾相连,由于 2 号边的方向是由 3 号点指向 2 号点,因此在 2 前面加一个负号,表示其相反的方向;第二个参数为边的编号。创建边界后,我们创建面对象,其中第一个参数是一个列表,里面放置组成面的边界的编号;第二个参数为面的编号。

  我们将上面的设置同步到我们创建的模型,生成二维网格并将网格数据输出到 .msh 文件

gmsh.model.geo.synchronize() # 同步到模型
gmsh.model.mesh.generate(2) # 生成网格
gmsh.write("t1.msh")

最后,在图形界面显示结果,并结束使用 gmsh

gmsh.fltk.run() # 图形界面显示
gmsh.finalize() # 结束使用gmsh

完整代码如下

import gmsh

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

lc = 1e-1 # 网格尺寸

gmsh.model.geo.addPoint(0, 0, 0, lc, 1)
gmsh.model.geo.addPoint(1, 0, 0, lc, 2)
gmsh.model.geo.addPoint(1, 1, 0, lc, 3)
gmsh.model.geo.addPoint(0, 1, 0, lc, 4)

gmsh.model.geo.addLine(1, 2, 1) # 线
gmsh.model.geo.addLine(2, 3, 2)
gmsh.model.geo.addLine(3, 4, 3)
gmsh.model.geo.addLine(4, 1, 4)

gmsh.model.geo.addCurveLoop([1, 2, 3, 4], 1)
gmsh.model.geo.addPlaneSurface([1], 1)

gmsh.model.geo.synchronize()
gmsh.model.mesh.generate(2)

gmsh.write("t1.msh")

gmsh.fltk.run()
gmsh.finalize()

结果如下

  我们还可以生成内部有洞的区域,下面给出相应的代码

import gmsh

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

lc = 0.05
# 构建几何
gmsh.model.geo.addPoint(0, 0, 0, lc, 1)
gmsh.model.geo.addPoint(1, 0, 0, lc, 2)
gmsh.model.geo.addPoint(1, 1, 0, lc, 3)
gmsh.model.geo.addPoint(0, 1, 0, lc, 4)

gmsh.model.geo.addLine(1, 2, 1)
gmsh.model.geo.addLine(3, 2, 2)
gmsh.model.geo.addLine(3, 4, 3)
gmsh.model.geo.addLine(4, 1, 4)

gmsh.model.geo.addCurveLoop([4, 1, -2, 3], 1)

gmsh.model.geo.addPoint(0.5,0.5,0,lc,5)
gmsh.model.geo.addPoint(0.3,0.5,0,lc,6)
gmsh.model.geo.addPoint(0.7,0.5,0,lc,7)

gmsh.model.geo.addCircleArc(6,5,7,tag=5) # 生成圆弧
gmsh.model.geo.addCircleArc(7,5,6,tag=6)# 该函数只能生成弧度小于等于180度的圆弧

gmsh.model.geo.addCurveLoop([5,6],2)

gmsh.model.geo.addPlaneSurface([1,2], 1)
#gmsh.model.geo.addPlaneSurface([2],2)

gmsh.model.geo.synchronize()

gmsh.model.mesh.generate(2)

gmsh.fltk.run()
gmsh.finalize()

结果如下

  上面的代码中,使用了 addCircleArc 函数,该函数用来生成圆弧线,第一个和第三个参数是圆弧两端点的标号,第二个参数是圆弧的圆心标号,最后一个参数是圆弧的标号,由于圆弧也属于线类型,故其和 Line 类型共用标号。由于该函数表达圆弧的弧度范围为  ,因此我们调用该函数两次才能拼接成一个圆。

  在构建面对象时,所用的边列表为[1,2],边 1 为外边界,边 2 则为内部的洞边界,Gmsh 默认列表的第一个边标号为外边界,之后的边都为内部的洞边界。如果我们想生成界面网格,只需把洞也构建成为一个面对象,即去掉 gmsh.model.geo.addPlaneSurface([2],2) 的注释即可,效果如下

OCC 内核

除了使用 built-in 内核来构建几何,我们还可以使用 OCC 内核来构建几何,OCC 也支持自下而上构建几何,在上面的代码中,把 gmsh.model.geo 改为 gmsh.model.occ 即可。除此以外,OCC 还支持使用函数来构建几何,以生成正方形对象   为例,代码如下

import gmsh

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

gmsh.model.occ.addRectangle(0,0,0,1,1)
gmsh.model.occ.synchronize()

gmsh.model.mesh.setSize(gmsh.model.getEntities(0),0.05)
gmsh.model.mesh.generate(2)

gmsh.fltk.run()
gmsh.finalize()

  在上面的代码中,使用函数 addRectangle 可以构建矩形对象,前三个参数是矩形左下角点的坐标,第四个,第五个参数分别是矩形的长和高。

  由于不是自下而上构建几何,不能逐点去设置网格的尺寸值,因此使用 gmsh.model.getEntities 来获得所有点对象。若不输入任何参数,则该函数表示获得所有实体,若输入 0,则获取所有点对象,输入大于 0 的整数,表示获取所有该维度下的对象。之后,使用函数 gmsh.model.occ.setSize 来对所有点对象赋予网格尺寸值。

  gmsh 提供了许多函数来构建几何对象,除了 addRectangle,还有构造圆形的 addDisk,构造球的 addSphere,构造立方体的 addBox 等等。

  我们还可以利用布尔运算,同时使用这些基本的构造几何函数来构建更为复杂的几何模型,首先构造两个矩形,与一个椭圆

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

gmsh.model.occ.addRectangle(-1,-1,0,2,2,1)
gmsh.model.occ.addRectangle(0, -1,0,1,1,2)
gmsh.model.occ.addDisk(0.5,0.5,0,0.3,0.2,3)

其中 addDisk 函数可以用来构造一个圆或者椭圆,前三个参数为圆心的坐标,后两个参数分别为 x 方向的半径和 y 方向的半径。我们想构造一个有椭圆洞的L形区域,因此我们使用布尔差运算

gmsh.model.occ.cut([(2,1)],[(2,2),(2,3)],4)

cut 函数的作用是计算几何体之间的差,并构建出新的几何体。第一个参数为布尔差的被减项,第二个参数为布尔差的减项,均为列表形式,列表中的每一个元素表示一个几何体对象,在 Python 中,gmsh 的几何对象使用元组表示,元组的第一个元素为几何对象的维数,第二个元素为几何对象的标号,因此 (2,1) 就表示标号为 1 的面;第三项为新生成几何对象的标号。上面函数的作用即为面 1 减去面 2 与面 3 所在的区域。默认情况下,使用 cut 函数后,使用的对象会被删除,即面 1,面 2,面 3 都会被删除,只保留面 4,如果想保留,则可以设置第五个与第六个参数为 False

  我们还想在区域内构造一个圆形的界面,因此使用 fragment 函数

gmsh.model.occ.addDisk(-0.5,-0.5,0,0.2,0.2,5)
gmsh.model.occ.fragment([(2,4)],[(2,5)])
gmsh.model.occ.synchronize()

类似于 cut 函数,第一、二个参数为包含几何对象的列表,fragment 函数的作用为将输入的几何对象进行组合,下面的结果中可以看到,圆形区域界面嵌入了L形区域中。

  之后设置网格尺寸

gmsh.model.mesh.setSize(gmsh.model.getEntities(0), 0.05)

ov = gmsh.model.getEntitiesInBoundingBox(-0.1,-0.1,-0.1, 0.1,0.1,0.1, 0)
gmsh.model.mesh.setSize(ov, 0.01)

其中 gmsh.model.getEntitiesInBoundingBox 函数会以列表形式返回在给定 Box 内的几何对象的标号,前三个参数为 Box 左下角点的坐标,后三个参数为 Box 右上角点的坐标,最后一个参数为几何对象的维数,0 则返回在 Box 内所有点的标号。

  完整代码如下:

import gmsh

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

gmsh.model.occ.addRectangle(-1,-1,0,2,2,1)
gmsh.model.occ.addRectangle(0, -1,0,1,1,2)
gmsh.model.occ.addDisk(0.5,0.5,0,0.3,0.2,3)

gmsh.model.occ.cut([(2,1)],[(2,2),(2,3)],4)

gmsh.model.occ.addDisk(-0.5,-0.5,0,0.2,0.2,5)
gmsh.model.occ.fragment([(2,4)],[(2,5)])

gmsh.model.occ.synchronize()

gmsh.model.mesh.setSize(gmsh.model.getEntities(0), 0.05)

ov = gmsh.model.getEntitiesInBoundingBox(-0.1,-0.1,-0.1, 0.1,0.1,0.1, 0)
gmsh.model.mesh.setSize(ov, 0.01)

gmsh.model.mesh.generate(2)

gmsh.fltk.run()
gmsh.finalize()

结果如下

构造更复杂的几何

  Gmsh 还支持构建贝塞尔曲线、样条曲线以及B-样条曲线以及曲面,同时,Gmsh 还支持拉伸、旋转等操作,使用这些功能我们就可以构造更加复杂的几何。举一个简单的示例

import gmsh
import numpy as np
from math import pi

def f(x):
   return x**2
x = np.linspace(-1,1,20)
y = f(x)

gmsh.initialize()
gmsh.model.add("t5")
for i in range(len(x)):
   gmsh.model.geo.addPoint(x[i],y[i],0,tag = i+1)
gmsh.model.geo.addSpline(range(1,len(x)+1),1)

gmsh.model.geo.twist([(1,1)],0,1,0,0,0,1,0,0,1,pi/6)
gmsh.model.geo.synchronize()

gmsh.model.mesh.setSize(gmsh.model.getEntities(0), 0.05)
gmsh.model.mesh.generate(2)

gmsh.fltk.run()
gmsh.finalize()

上述代码中,我们构造了一条抛物线并将其沿 (0,0,1) 方向进行拉伸旋转,结果如下

  构造抛物线时,我们利用函数 addSpline,使用样条曲线来拟合抛物线,第一个参数是一个列表或数组,里面按顺序存放样条曲线拟合点的标号,第二个参数是线的标号。Gmsh 还提供了 addBSpline,addBezier 等函数,可以构造B-样条曲线、贝塞尔曲线等。

  进行拉伸旋转时,使用了 twist 函数,该函数可以将几何对象进行拉伸旋转,第一个参数是要操作的对象,第二到四个参数是旋转轴通过一点的坐标,第五到七个参数是旋转轴的方向,第八到十个参数是拉伸的方向,最后一个参数是旋转的角度。Gmsh 还提供了平移、旋转、拉伸等多个函数用于操作几何对象,合理使用这些函数,可以构建复杂的几何对象。

来源:易木木响叮当
通用曲面
著作权归作者所有,欢迎分享,未经许可,不得转载
首次发布时间:2023-05-30
最近编辑:1年前
易木木响叮当
硕士 有限元爱好者
获赞 222粉丝 266文章 351课程 2
点赞
收藏
未登录
还没有评论
课程
培训
服务
行家
VIP会员 学习 福利任务 兑换礼品
下载APP
联系我们
帮助与反馈