netgen/python/read_gmsh.py

284 lines
11 KiB
Python
Raw Normal View History

from netgen.meshing import *
2017-09-12 11:38:49 +09:00
import re
import shutil
import os
2017-09-12 11:38:49 +09:00
def import_gmsh(filename, extension, dim):
""" filename: name of the filename
extension: geo or msh
dim: dimension of the mesh
"""
if extension == "geo":
filename_tmp = check_geofile(filename)
if dim == 1:
os.system("gmsh -1 -saveall -format msh -o ./" + filename + ".msh ./" + filename_tmp + ".geo")
elif dim == 2:
os.system("gmsh -2 -saveall -format msh -o ./" + filename + ".msh ./" + filename_tmp + ".geo")
elif dim == 3:
os.system("gmsh -3 -saveall -format msh -o ./" + filename + ".msh ./" + filename_tmp + ".geo")
return ReadGmsh(filename)
def check_geofile(filename):
mod = False
with open(filename + ".geo", 'r') as f:
with open(filename + "_tmp.geo", 'w') as fw:
line = "start"
while line:
line = f.readline()
if line[0:8] == "Physical":
print('WARNING: Physical groups detected - Physical names are not taken into account.')
print('The physical group is discarded.')
fw.write("//" + line)
mod = True
else:
fw.write(line)
if mod:
filename_tmp = filename + "_tmp"
else:
filename_tmp = filename
os.remove(filename + "_tmp.geo")
return filename_tmp
def complete_geofile(filename):
line_entity = []
surf_entity = []
vol_entity = []
line_phys_gr = []
surf_phys_gr = []
vol_phys_gr = []
num_lines = sum(1 for line in open(filename + ".geo", 'r')) + 1
with open(filename + ".geo", 'r') as f:
for i in range(num_lines):
line = f.readline()
if not line:
line = [" "]
if line[0:2] == '//':
pass
elif line[0:5] == 'Line(':
line_entity += {line.split()[0][5:-1]}
elif line[0:14] == 'Plane Surface(':
surf_entity += {line.split()[1][8:-1]}
elif line[0:7] == 'Volume(':
vol_entity += {line.split()[0][7:-1]}
elif line[0:13] == "Physical Line":
start = line.index('{')
end = line.index('}')
number = re.sub(r"\s", "", line[start + 1:end]).split(sep=",")
line_phys_gr += number
elif line[0:16] == "Physical Surface":
start = line.index('{')
end = line.index('}')
number = re.sub(r"\s", "", line[start + 1:end]).split(sep=",")
surf_phys_gr += number
elif line[0:15] == "Physical Volume":
start = line.index('{')
end = line.index('}')
number = re.sub(r"\s", "", line[start + 1:end]).split(sep=",")
vol_phys_gr += number
line_diff = list(set(line_entity) - set(line_phys_gr))
surf_diff = list(set(surf_entity) - set(surf_phys_gr))
vol_diff = list(set(vol_entity) - set(vol_phys_gr))
filename_geo = filename
if line_diff or surf_diff or vol_diff:
shutil.copy2(filename + '.geo', filename + '_tmp.geo')
filename_geo = filename + "_tmp"
if line_diff:
fid = open(filename + ".geo", 'a')
fid.write('//+\n// Added by NGSolve\n')
fid.write('Physical Line("Remaining_line") = {' + re.sub(r'[\']', '', str(line_diff))[1:-1] + '}; \n')
fid.close()
if surf_diff:
fid = open(filename + ".geo", 'a')
fid.write('//+\n// Added by NGSolve\n')
fid.write('Physical Surface("Remaining_surf") = {' + re.sub(r'[\']', '', str(surf_diff))[1:-1] + '}; \n')
fid.close()
if vol_diff:
fid = open(filename + ".geo", 'a')
fid.write('//+\n// Added by NGSolve\n')
fid.write('Physical Volume("Remaining_vol") = {' + re.sub(r'[\']', '', str(vol_diff))[1:-1] + '}; \n')
fid.close()
return filename_geo
def ReadGmsh(filename):
meshdim = 1
with open(filename + ".msh", '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 + ".msh", 'r')
mesh = Mesh(dim=meshdim)
pointmap = {}
facedescriptormap = {}
namemap = {}
materialmap = {}
bbcmap = {}
while True:
line = f.readline()
2017-09-12 11:38:49 +09:00
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()[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()
2017-09-12 11:38:49 +09:00
nodenum, x, y, z = line.split()[0:4]
pnum = mesh.Add(MeshPoint(Pnt(float(x), float(y), float(z))))
pointmap[int(nodenum)] = pnum
2017-09-12 11:38:49 +09:00
if line.split()[0] == "$Elements":
num = int(f.readline().split()[0])
2017-09-12 11:38:49 +09:00
for i in range(num):
line = f.readline().split()
elmnum = int(line[0])
elmtype = int(line[1])
numtags = int(line[2])
2017-09-12 11:38:49 +09:00
# 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 == 1: # 2-node line
num_nodes = 2
elif elmtype == 2: # 3-node trig
num_nodes = 3
2017-09-12 11:38:49 +09:00
elif elmtype == 3: # 4-node quad
num_nodes = 4
2017-09-12 11:38:49 +09:00
elif elmtype == 4: # 4-node tet
num_nodes = 4
2017-09-12 11:38:49 +09:00
elif elmtype == 5: # 8-node hex
num_nodes = 8
elif elmtype == 6: # 6-node prism
num_nodes = 6
elif elmtype == 7: # 5-node pyramid
num_nodes = 5
elif elmtype == 15: # 1-node point
num_nodes = 1
else:
2017-09-12 11:38:49 +09:00
raise Exception("element type", elmtype, "not implemented")
2017-09-12 11:38:49 +09:00
nodenums = line[3 + numtags:3 + numtags + num_nodes]
nodenums2 = [pointmap[int(nn)] for nn in nodenums]
2017-09-12 11:38:49 +09:00
if elmtype == 1:
if meshdim == 3:
if tags[1] in bbcmap:
index = bbcmap[tags[1]]
else:
index = len(bbcmap)
if len(namemap):
mesh.SetCD2Name(index + 1, namemap[tags[0]])
else:
mesh.SetCD2Name(index+1, "line" + str(tags[1]))
bbcmap[tags[1]] = index
2017-09-12 11:38:49 +09:00
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[tags[0]]
else:
fd.bcname = 'line' + str(tags[1])
mesh.SetBCName(index - 1, fd.bcname)
mesh.Add(fd)
facedescriptormap[tags[1]] = index
else:
2017-09-12 11:38:49 +09:00
if tags[1] in materialmap:
index = materialmap[tags[1]]
else:
index = len(materialmap) + 1
if len(namemap):
mesh.SetMaterial(index, namemap[tags[0]])
else:
mesh.SetMaterial(index, "line" + str(tags[1]))
materialmap[tags[1]] = index
2017-09-12 11:38:49 +09:00
mesh.Add(Element1D(index=index, vertices=nodenums2))
if elmtype in [2, 3]: # 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[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[tags[0]])
else:
mesh.SetMaterial(index, "surf" + str(tags[1]))
materialmap[tags[1]] = index
mesh.Add(Element2D(index, nodenums2))
2017-09-12 11:38:49 +09:00
if elmtype in [4, 5, 6, 7]: # volume elements
if tags[1] in materialmap:
index = materialmap[tags[1]]
else:
index = len(materialmap) + 1
if len(namemap):
mesh.SetMaterial(index, namemap[tags[0]])
else:
mesh.SetMaterial(index, "vol" + str(tags[1]))
materialmap[tags[1]] = index
nodenums2 = [pointmap[int(nn)] for nn in nodenums]
if elmtype == 4:
mesh.Add(Element3D(index, [nodenums2[0], nodenums2[1], nodenums2[3], nodenums2[2]]))
elif elmtype in [5, 6, 7]:
mesh.Add(Element3D(index, nodenums2))
return mesh