13、在没有底层CAD模型的情况下重新擦除STL文件
import gmsh # 导入Gmsh库,用于几何建模和网格划分
import math # 导入数学库,用于计算
import os # 导入操作系统库,用于处理文件路径
import sys # 导入系统库,用于处理命令行参数 gmsh.initialize() # 初始化Gmsh环境 def createGeometryAndMesh(): # 清除之前的模型和数据 gmsh.clear() # 获取当前脚本的目录,并合并上级目录中的't13_data.stl'文件路径 path = os.path.dirname(os.path.abspath(__file__)) gmsh.merge(os.path.join(path, os.pardir, 't13_data.stl')) # 从Gmsh的ONELAB接口获取用户输入的角度参数 angle = gmsh.onelab.getNumber('Parameters/Angle for surface detection')[0] # 获取是否创建可参数化曲面的用户输入 forceParametrizablePatches = gmsh.onelab.getNumber( 'Parameters/Create surfaces guaranteed to be parametrizable')[0] # 设置包含边界和曲线角度的参数 includeBoundary = True curveAngle = 180 # 对模型表面进行分类,准备创建几何体 gmsh.model.mesh.classifySurfaces(angle * math.pi / 180., includeBoundary, forceParametrizablePatches, curveAngle * math.pi / 180.) # 创建几何体 gmsh.model.mesh.createGeometry() # 获取所有曲面,并创建一个曲面环和体积 s = gmsh.model.getEntities(2) l = gmsh.model.geo.addSurfaceLoop([e[1] for e in s]) gmsh.model.geo.addVolume([l]) # 同步几何模型 gmsh.model.geo.synchronize() # 添加一个网格大小字段,根据用户选择应用不同的网格大小函数 f = gmsh.model.mesh.field.add("MathEval") if gmsh.onelab.getNumber('Parameters/Apply funny mesh size field?')[0]: gmsh.model.mesh.field.setString(f, "F", "2*Sin((x+y)/5) + 3") else: gmsh.model.mesh.field.setString(f, "F", "4") gmsh.model.mesh.field.setAsBackgroundMesh(f) # 生成三维网格 gmsh.model.mesh.generate(3) # 将网格写入文件 gmsh.write('t13.msh') # 设置用户可调的参数
gmsh.onelab.set("""[ # 角度参数,用于表面检测 { "type":"number", "name":"Parameters/Angle for surface detection", "values":[40], "min":20, "max":120, "step":1 }, # 是否创建可参数化曲面的选项 { "type":"number", "name":"Parameters/Create surfaces guaranteed to be parametrizable", "values":[0], "choices":[0, 1] }, # 是否应用有趣的网格大小字段的选项 { "type":"number", "name":"Parameters/Apply funny mesh size field?", "values":[0], "choices":[0, 1] }
]""") # 调用函数创建几何模型和网格
createGeometryAndMesh() def checkForEvent(): # 检查是否有用户操作事件,如果有则重新创建几何模型和网格,并刷新图形界面 action = gmsh.onelab.getString("ONELAB/Action") if len(action) and action[0] == "check": gmsh.onelab.setString("ONELAB/Action", [""]) createGeometryAndMesh() gmsh.graphics.draw() return True # 如果命令行参数中没有'-nopopup',则初始化图形界面,并循环检查用户事件
if "-nopopup" not in sys.argv: gmsh.fltk.initialize() while gmsh.fltk.isAvailable() and checkForEvent(): gmsh.fltk.wait() # 清理并结束Gmsh环境
gmsh.finalize()
14、同源和共同源计算
import gmsh # 导入gmsh库
import sys # 导入sys库,用于访问与Python解释器紧密相关的变量和函数 gmsh.initialize(sys.argv) # 初始化gmsh,并传递命令行参数 gmsh.model.add("t14") # 添加一个新的模型,并命名为"t14" # 定义网格大小和几何高度
m = 0.5 # 网格大小
h = 2 # 几何体在z方向的高度 # 添加模型的点,并指定它们的坐标和网格大小
gmsh.model.geo.addPoint(0, 0, 0, m, 1)
# ...(此处省略了其他点的添加,类似上面的格式) # 添加模型的线,连接之前定义的点
gmsh.model.geo.addLine(1, 9, 1)
# ...(此处省略了其他线的添加,类似上面的格式) # 添加曲线环和平面表面
gmsh.model.geo.addCurveLoop([...], 13)
gmsh.model.geo.addCurveLoop([...], 14)
gmsh.model.geo.addPlaneSurface([13, 14], 15) # 对平面进行拉伸操作,创建一个三维体
e = gmsh.model.geo.extrude([(2, 15)], 0, 0, h) gmsh.model.geo.synchronize() # 同步几何模型 # 添加物理组,用于后续的有限元分析
domain_tag = e[1][1] # 获取域的标签
domain_physical_tag = 1001 # 定义域的物理标签
gmsh.model.addPhysicalGroup(3, [domain_tag], domain_physical_tag, "Whole domain") # ...(此处省略了其他物理组的添加,类似上面的格式) # 添加同调请求,用于后续的网格划分和同调分析
gmsh.model.mesh.addHomologyRequest("Homology", [...], [...], [...])
# ...(此处省略了其他同调请求的添加,类似上面的格式) # 生成网格
gmsh.model.mesh.generate(3) # 将模型写入文件
gmsh.write("t14.msh") # 如果命令行参数中没有'-nopopup',则运行Gmsh的FLTK图形界面
if '-nopopup' not in sys.argv: gmsh.fltk.run() # 清理Gmsh资源
gmsh.finalize()
15、嵌入式点、线和面
import gmsh # 导入gmsh库
import sys # 导入sys库,用于访问与Python解释器紧密相关的变量和函数 gmsh.initialize() # 初始化gmsh lc = 1e-2 # 定义网格特征长度
# 添加四个点,并指定它们的坐标和特征长度
gmsh.model.geo.addPoint(0, 0, 0, lc, 1)
gmsh.model.geo.addPoint(.1, 0, 0, lc, 2)
gmsh.model.geo.addPoint(.1, .3, 0, lc, 3)
gmsh.model.geo.addPoint(0, .3, 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.addPlaneSurface([1], 1) lc = lc * 4 # 更新网格特征长度
# 设置特定线的网格大小
gmsh.model.geo.mesh.setSize([(0, 1), (0, 2), (0, 3), (0, 4)], lc) # 添加一个新的点
gmsh.model.geo.addPoint(0.02, 0.02, 0., lc, 5) gmsh.model.geo.synchronize() # 同步几何模型 # 将点5嵌入到表面网格中
gmsh.model.mesh.embed(0, [5], 2, 1) # 添加更多的点和线
gmsh.model.geo.addPoint(0.02, 0.12, 0., lc, 6)
gmsh.model.geo.addPoint(0.04, 0.18, 0., lc, 7)
gmsh.model.geo.addLine(6, 7, 5) gmsh.model.geo.synchronize() # 同步几何模型
# 将线5嵌入到网格中
gmsh.model.mesh.embed(1, [5], 2, 1) # 对之前的平面进行拉伸操作,创建一个三维体
gmsh.model.geo.extrude([(2, 1)], 0, 0, 0.1) # 添加一个新的点,并获取其ID
p = gmsh.model.geo.addPoint(0.07, 0.15, 0.025, lc) gmsh.model.geo.synchronize() # 同步几何模型
# 将点p嵌入到网格中
gmsh.model.mesh.embed(0, [p], 3, 1) # 添加更多的点和线
gmsh.model.geo.addPoint(0.025, 0.15, 0.025, lc, p + 1)
l = gmsh.model.geo.addLine(7, p + 1) gmsh.model.geo.synchronize() # 同步几何模型
# 将线l嵌入到网格中
gmsh.model.mesh.embed(1, [l], 3, 1) # 添加更多的点,用于定义一个新的平面
gmsh.model.geo.addPoint(0.02, 0.12, 0.05, lc, p + 2)
gmsh.model.geo.addPoint(0.04, 0.12, 0.05, lc, p + 3)
gmsh.model.geo.addPoint(0.04, 0.18, 0.05, lc, p + 4)
gmsh.model.geo.addPoint(0.02, 0.18, 0.05, lc, p + 5) # 添加四条线,连接之前定义的点
gmsh.model.geo.addLine(p + 2, p + 3, l + 1)
gmsh.model.geo.addLine(p + 3, p + 4, l + 2)
gmsh.model.geo.addLine(p + 4, p + 5, l + 3)
gmsh.model.geo.addLine(p + 5, p + 2, l + 4) # 添加一个曲线环
ll = gmsh.model.geo.addCurveLoop([l + 1, l + 2, l + 3, l + 4])
# 添加一个平面表面
s = gmsh.model.geo.addPlaneSurface([ll]) gmsh.model.geo.synchronize() # 同步几何模型
# 将表面s嵌入到网格中
gmsh.model.mesh.embed(2, [s], 3, 1) # 生成网格
gmsh.model.mesh.generate(3) # 将模型写入文件
gmsh.write("t15.msh") # 如果命令行参数中没有'-nopopup',则运行Gmsh的FLTK图形界面
if '-nopopup' not in sys.argv: gmsh.fltk.run() # 清理Gmsh资源
gmsh.finalize()
16、构造性立体几何,OpenCASCADE几何内核
import gmsh # 导入Gmsh库
import math # 导入数学库,虽然在这段代码中未使用
import sys # 导入系统库,用于处理命令行参数 gmsh.initialize() # 初始化Gmsh环境 gmsh.model.add("t16") # 创建一个名为"t16"的新模型 gmsh.logger.start() # 启动日志记录 # 添加两个盒子,一个边长为1,一个边长为0.5
gmsh.model.occ.addBox(0, 0, 0, 1, 1, 1, 1)
gmsh.model.occ.addBox(0, 0, 0, 0.5, 0.5, 0.5, 2) # 使用布尔操作"cut"从大盒子中减去小盒子
gmsh.model.occ.cut([(3, 1)], [(3, 2)], 3) # 在剩余的大盒子顶部添加5个小球
x = 0
y = 0.75
z = 0
r = 0.09
holes = []
for t in range(1, 6): x += 0.166 z += 0.166 gmsh.model.occ.addSphere(x, y, z, r, 3 + t) holes.append((3, 3 + t)) # 使用fragment操作从剩余的大盒子中减去所有小球
ov, ovv = gmsh.model.occ.fragment([(3, 3)], holes) # 打印fragment操作产生的体积和前后关系
print("fragment produced volumes:")
for e in ov: print(e) print("before/after fragment relations:")
for e in zip([(3, 3)] + holes, ovv): print("parent " + str(e[0]) + " -> child " + str(e[1])) gmsh.model.occ.synchronize() # 同步几何模型 # 为每个小球和剩余的体积添加物理组
for i in range(1, 6): gmsh.model.addPhysicalGroup(3, [3 + i], i) gmsh.model.addPhysicalGroup(3, [ov[-1][1]], 10) # 设置网格大小
lcar1 = .1
lcar2 = .0005
lcar3 = .055 gmsh.model.mesh.setSize(gmsh.model.getEntities(0), lcar1) # 设置整个模型的网格大小 gmsh.model.mesh.setSize(gmsh.model.getBoundary(holes, False, False, True), lcar3) # 设置小球边界的网格大小 eps = 1e-3
ov = gmsh.model.getEntitiesInBoundingBox(0.5 - eps, 0.5 - eps, 0.5 - eps, 0.5 + eps, 0.5 + eps, 0.5 + eps, 0)
gmsh.model.mesh.setSize(ov, lcar2) # 设置特定区域的网格大小 gmsh.model.mesh.generate(3) # 生成三维网格 gmsh.write("t16.msh") # 将网格写入文件 log = gmsh.logger.get() # 获取日志记录
print("Logger has recorded " + str(len(log)) + " lines")
gmsh.logger.stop() # 停止日志记录 if '-nopopup' not in sys.argv: gmsh.fltk.run() # 如果命令行参数中没有'-nopopup',则运行图形界面 gmsh.finalize() # 清理并结束Gmsh环境