Skip to content

Commit 6477c3f

Browse files
committed
arbitrary mesh loading in create_gmsh_mesh
1 parent 43129f1 commit 6477c3f

15 files changed

Lines changed: 750 additions & 188 deletions

File tree

doc/devsim.pdf

18.3 KB
Binary file not shown.

examples/diode/pythonmesh3d.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
from ds import *
2+
import python_packages.pythonmesh
3+
4+
5+
def gmsh_reader(mesh, device, filename="", coordinates="", physical_names="", elements=""):
6+
if (filename):
7+
create_gmsh_mesh(mesh=mesh, file=filename)
8+
else:
9+
create_gmsh_mesh(mesh=mesh, coordinates=coordinates, physical_names=physical_names, elements=elements)
10+
add_gmsh_region (mesh=mesh, gmsh_name="Bulk", region="bulk", material="Silicon")
11+
add_gmsh_contact (mesh=mesh, gmsh_name="Base", region="bulk", material="metal", name="top")
12+
add_gmsh_contact (mesh=mesh, gmsh_name="Emitter", region="bulk", material="metal", name="bot")
13+
finalize_mesh (mesh=mesh)
14+
create_device (mesh=mesh, device=device)
15+
16+
data = python_packages.pythonmesh.read_gmsh_file("gmsh_diode3d.msh")
17+
coordinates=data['coordinates']
18+
elements=data['elements']
19+
physical_names=data['physical_names']
20+
21+
gmsh_reader(mesh="gmsh_diode3da", device="gmsh_diode3da", coordinates=coordinates, physical_names=physical_names, elements=elements)
22+
gmsh_reader(mesh="gmsh_diode3db", device="gmsh_diode3db", filename="gmsh_diode3d.msh")
23+
24+
write_devices(device="gmsh_diode3da", file="gmsh_diode3da.msh")
25+
write_devices(device="gmsh_diode3db", file="gmsh_diode3db.msh")
26+
27+
with open('gmsh_diode3da.msh', 'r') as f:
28+
file1 = f.read()
29+
with open('gmsh_diode3db.msh', 'r') as f:
30+
file2 = f.read()
31+
32+
file2=file2.replace('gmsh_diode3db', 'gmsh_diode3da')
33+
34+
if (file1 != file2):
35+
raise RuntimeError('gmsh_diode3da.msh and gmsh_diode3db.msh do not match')
36+
37+
38+

examples/mobility/pythonmesh2d.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
from ds import *
2+
import python_packages.pythonmesh
3+
4+
def gmsh_reader(mesh, device, filename="", coordinates="", physical_names="", elements=""):
5+
if (filename):
6+
create_gmsh_mesh(file=filename, mesh=mesh)
7+
else:
8+
create_gmsh_mesh(mesh=mesh, coordinates=coordinates, physical_names=physical_names, elements=elements)
9+
add_gmsh_region (mesh=mesh, gmsh_name="bulk", region="bulk", material="Silicon")
10+
add_gmsh_region (mesh=mesh, gmsh_name="oxide", region="oxide", material="Silicon")
11+
add_gmsh_region (mesh=mesh, gmsh_name="gate", region="gate", material="Silicon")
12+
add_gmsh_contact (mesh=mesh, gmsh_name="drain_contact", region="bulk", name="drain", material="metal")
13+
add_gmsh_contact (mesh=mesh, gmsh_name="source_contact", region="bulk", name="source", material="metal")
14+
add_gmsh_contact (mesh=mesh, gmsh_name="body_contact", region="bulk", name="body", material="metal")
15+
add_gmsh_contact (mesh=mesh, gmsh_name="gate_contact", region="gate", name="gate", material="metal")
16+
add_gmsh_interface (mesh=mesh, gmsh_name="gate_oxide_interface", region0="gate", region1="oxide", name="gate_oxide")
17+
add_gmsh_interface (mesh=mesh, gmsh_name="bulk_oxide_interface", region0="bulk", region1="oxide", name="bulk_oxide")
18+
finalize_mesh(mesh=mesh)
19+
create_device(mesh=mesh, device=device)
20+
21+
data = python_packages.pythonmesh.read_gmsh_file("gmsh_mos2d.msh")
22+
coordinates=data['coordinates']
23+
elements=data['elements']
24+
physical_names=data['physical_names']
25+
26+
gmsh_reader(mesh="mos2da", device="mos2da", coordinates=coordinates, physical_names=physical_names, elements=elements)
27+
gmsh_reader(mesh="mos2db", device="mos2db", filename="gmsh_mos2d.msh")
28+
29+
write_devices(device="mos2da", file="mos2da.msh")
30+
write_devices(device="mos2db", file="mos2db.msh")
31+
32+
with open('mos2da.msh', 'r') as f:
33+
file1 = f.read()
34+
with open('mos2db.msh', 'r') as f:
35+
file2 = f.read()
36+
37+
file2=file2.replace('mos2db', 'mos2da')
38+
39+
if (file1 != file2):
40+
raise RuntimeError('mos2da.msh and mos2db.msh do not match')
41+
42+
43+

python_packages/pythonmesh.py

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
from ds import *
2+
3+
def parse_gmsh_file(file):
4+
sections=set(['$MeshFormat', '$PhysicalNames', '$Nodes', '$Elements'])
5+
lineno = 0
6+
section_count = 0
7+
section_expected = 0
8+
dimension = 0
9+
with open(file, 'r') as ih:
10+
state = 'begin'
11+
for line in ih:
12+
line = line.rstrip()
13+
lineno += 1
14+
if state == 'begin':
15+
if line in sections:
16+
state = line
17+
else:
18+
raise RuntimeError("Error Line %d" % lineno)
19+
elif line.find('$End') == 0:
20+
state = 'begin'
21+
section_count = 0
22+
section_expected = None
23+
elif state == '$MeshFormat':
24+
continue
25+
elif state == '$PhysicalNames':
26+
if not section_expected:
27+
section_expected=int(line)
28+
physical_names = []
29+
else:
30+
line = line.split()
31+
name = line[2][1:-1]
32+
physical_names.append((name, int(line[0]), int(line[1])))
33+
section_count += 1
34+
elif state == '$Nodes':
35+
if not section_expected:
36+
section_expected=int(line)
37+
nodes = []
38+
else:
39+
line = line.split()
40+
nodes.append([int(line[0]), float(line[1]), float(line[2]), float(line[3])])
41+
section_count += 1
42+
elif state == '$Elements':
43+
if not section_expected:
44+
section_expected=int(line)
45+
elements = [None]*section_expected
46+
else:
47+
elements[section_count] = [int(x) for x in line.split()]
48+
section_count += 1
49+
else:
50+
raise RuntimeError("Unknown %s" % line)
51+
dimension = max([x[1] for x in physical_names])
52+
return {
53+
'dimension' : dimension,
54+
'physical_names' : physical_names,
55+
'coordinates' : nodes,
56+
'elements' : elements
57+
}
58+
59+
def read_gmsh_file(filename):
60+
'''reads gmsh file and converts to python representation'''
61+
data = parse_gmsh_file(filename)
62+
#namemap = {}
63+
print '%d dimension' % data['dimension']
64+
print '%d coordinates' % len(data['coordinates'])
65+
#for i in sorted(data['physical_names'].keys()):
66+
# print "%s %s %d" % (i, data['physical_names'][i], len(data['elements'][i]))
67+
# namemap[data['physical_names'][i]] = i
68+
69+
coordinate_indexes = [x[0] for x in data['coordinates']]
70+
max_coordinate_index = max(coordinate_indexes)
71+
coordinate_to_index = [-1] * (max_coordinate_index+1)
72+
for i,j in enumerate(coordinate_indexes):
73+
coordinate_to_index[j] = i
74+
75+
coordinates=[]
76+
for i in data['coordinates']:
77+
coordinates.extend(i[1:])
78+
79+
all_physical_numbers = sorted(set([x[3] for x in data['elements']]))
80+
sorted_physical_names = sorted(data['physical_names'],key = lambda x : x[0])
81+
physical_number_map = {
82+
1 : {},
83+
2 : {},
84+
3 : {},
85+
}
86+
for i, j in enumerate(sorted_physical_names):
87+
# mapped dimension, physical number, new index
88+
physical_number_map[j[1]][j[2]] = i
89+
physical_names = [x[0] for x in sorted_physical_names]
90+
91+
92+
#gmsh format
93+
#elm-number elm-type number-of-tags < tag > ... node-number-list
94+
#our format
95+
elements = []
96+
for i in data['elements']:
97+
t = i[1]
98+
if (t == 4):
99+
#tetrahedron
100+
etype = 3
101+
dimension = 3
102+
elif (t == 2):
103+
#triangle
104+
etype = 2
105+
dimension = 2
106+
elif (t == 1):
107+
#edge
108+
etype = 1
109+
dimension = 1
110+
elif (t == 15):
111+
#point
112+
etype = 0
113+
else:
114+
raise RuntimeError("Cannot handle element type " % i)
115+
116+
#physical number
117+
# will be remapped later
118+
pnum = physical_number_map[dimension][i[3]]
119+
120+
#nodes
121+
# position 2 + number of tags
122+
nodes = i[i[2]+3:]
123+
nodes = [coordinate_to_index[x] for x in nodes]
124+
elements.extend([etype, pnum])
125+
elements.extend(nodes)
126+
127+
return {
128+
'physical_names' : physical_names,
129+
'coordinates' : coordinates,
130+
'elements' : elements,
131+
}
132+

scripts/pythonmesh.py

Lines changed: 0 additions & 129 deletions
This file was deleted.

0 commit comments

Comments
 (0)