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环境