netgen/python/read_gmsh.py
2024-01-29 08:58:07 +01:00

219 lines
8.4 KiB
Python

from netgen.meshing import *
def ReadGmsh(filename):
if not filename.endswith(".msh"):
filename += ".msh"
meshdim = 1
with open(filename, 'r') as f:
while f.readline().split()[0] != "$Elements":
pass
nelem = int(f.readline())
for i in range(nelem):
line = f.readline()
eltype = int(line.split()[1])
if eltype > 1 and eltype != 15:
meshdim = 2
if eltype > 3 and eltype != 15:
meshdim = 3
break
f = open(filename, 'r')
mesh = Mesh(dim=meshdim)
pointmap = {}
facedescriptormap = {}
namemap = { 0 : { 0 : "default" },
1: { 0 : "default" },
2: { 0 : "default" },
3: { 0 : "default" } }
materialmap = {}
bbcmap = {}
segm = 1
trig = 2
quad = 3
tet = 4
hex = 5
prism = 6
pyramid = 7
segm3 = 8 # 2nd order line
trig6 = 9 # 2nd order trig
tet10 = 11 # 2nd order tet
point = 15
quad8 = 16 # 2nd order quad
hex20 = 17 # 2nd order hex
prism15 = 18 # 2nd order prism
pyramid13 = 19 # 2nd order pyramid
segms = [segm, segm3]
trigs = [trig, trig6]
quads = [quad, quad8]
tets = [tet, tet10]
hexes = [hex, hex20]
prisms = [prism, prism15]
pyramids = [pyramid, pyramid13]
elem0d = [point]
elem1d = segms
elem2d = trigs + quads
elem3d = tets + hexes + prisms + pyramids
num_nodes_map = { segm : 2,
trig : 3,
quad : 4,
tet : 4,
hex : 8,
prism : 6,
pyramid : 5,
segm3 : 3,
trig6 : 6,
tet10 : 10,
point : 1,
quad8 : 8,
hex20 : 20,
prism15 : 18,
pyramid13 : 19 }
while True:
line = f.readline()
if line == "":
break
if line.split()[0] == "$PhysicalNames":
print('WARNING: Physical groups detected - Be sure to define them for every geometrical entity.')
numnames = int(f.readline())
for i in range(numnames):
f.readline
line = f.readline()
namemap[int(line.split()[0])][int(line.split()[1])] = line.split()[2][1:-1]
if line.split()[0] == "$Nodes":
num = int(f.readline().split()[0])
for i in range(num):
line = f.readline()
nodenum, x, y, z = line.split()[0:4]
pnum = mesh.Add(MeshPoint(Pnt(float(x), float(y), float(z))))
pointmap[int(nodenum)] = pnum
if line.split()[0] == "$Elements":
num = int(f.readline().split()[0])
for i in range(num):
line = f.readline().split()
elmnum = int(line[0])
elmtype = int(line[1])
numtags = int(line[2])
# the first tag is the physical group nr, the second tag is the group nr of the dim
tags = [int(line[3 + k]) for k in range(numtags)]
if elmtype not in num_nodes_map:
raise Exception("element type", elmtype, "not implemented")
num_nodes = num_nodes_map[elmtype]
nodenums = line[3 + numtags:3 + numtags + num_nodes]
nodenums2 = [pointmap[int(nn)] for nn in nodenums]
if elmtype in elem1d:
if meshdim == 3:
if tags[1] in bbcmap:
index = bbcmap[tags[1]]
else:
index = len(bbcmap) + 1
if len(namemap):
mesh.SetCD2Name(index, namemap[1][tags[0]])
else:
mesh.SetCD2Name(index, "line" + str(tags[1]))
bbcmap[tags[1]] = index
elif meshdim == 2:
if tags[1] in facedescriptormap.keys():
index = facedescriptormap[tags[1]]
else:
index = len(facedescriptormap) + 1
fd = FaceDescriptor(bc=index)
if len(namemap):
fd.bcname = namemap[1][tags[0]]
else:
fd.bcname = 'line' + str(tags[1])
mesh.SetBCName(index - 1, fd.bcname)
mesh.Add(fd)
facedescriptormap[tags[1]] = index
else:
if tags[1] in materialmap:
index = materialmap[tags[1]]
else:
index = len(materialmap) + 1
if len(namemap):
mesh.SetMaterial(index, namemap[1][tags[0]])
else:
mesh.SetMaterial(index, "line" + str(tags[1]))
materialmap[tags[1]] = index
mesh.Add(Element1D(index=index, vertices=nodenums2))
if elmtype in elem2d: # 2d elements
if meshdim == 3:
if tags[1] in facedescriptormap.keys():
index = facedescriptormap[tags[1]]
else:
index = len(facedescriptormap) + 1
fd = FaceDescriptor(bc=index)
if len(namemap):
fd.bcname = namemap[2][tags[0]]
else:
fd.bcname = "surf" + str(tags[1])
mesh.SetBCName(index - 1, fd.bcname)
mesh.Add(fd)
facedescriptormap[tags[1]] = index
else:
if tags[1] in materialmap:
index = materialmap[tags[1]]
else:
index = len(materialmap) + 1
if len(namemap):
mesh.SetMaterial(index, namemap[2][tags[0]])
else:
mesh.SetMaterial(index, "surf" + str(tags[1]))
materialmap[tags[1]] = index
if elmtype in trigs:
ordering = [i for i in range(3)]
if elmtype == trig6:
ordering += [4,5,3]
if elmtype in quads:
ordering = [i for i in range(4)]
if elmtype == quad8:
ordering += [4, 6, 7, 5]
mesh.Add(Element2D(index, [nodenums2[i] for i in ordering]))
if elmtype in elem3d: # volume elements
if tags[1] in materialmap:
index = materialmap[tags[1]]
else:
index = len(materialmap) + 1
if len(namemap):
mesh.SetMaterial(index, namemap[3][tags[0]])
else:
mesh.SetMaterial(index, "vol" + str(tags[1]))
materialmap[tags[1]] = index
nodenums2 = [pointmap[int(nn)] for nn in nodenums]
if elmtype in tets:
ordering = [0,1,2,3]
if elmtype == tet10:
ordering += [4,6,7,5,9,8]
elif elmtype in hexes:
ordering = [0,1,5,4,3,2,6,7]
if elmtype == hex20:
ordering += [8,16,10,12,13,19,15,14,9,11,18,17]
elif elmtype in prisms:
ordering = [0,2,1,3,5,4]
if elmtype == prism15:
ordering += [7,6,9,8,11,10,13,12,14]
elif elmtype in pyramids:
ordering = [3,2,1,0,4]
if elmtype == pyramid13:
ordering += [10,5,6,8,12,11,9,7]
mesh.Add(Element3D(index, [nodenums2[i] for i in ordering]))
return mesh