-
Notifications
You must be signed in to change notification settings - Fork 86
/
Copy pathmeshio.py
104 lines (80 loc) · 3.1 KB
/
meshio.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
"""Import any formats supported by meshio."""
from typing import Tuple
import warnings
import numpy as np
import skfem
import meshio
def from_meshio(m):
"""Convert meshio mesh into :class:`skfem.mesh.Mesh`."""
meshio_type, mesh_type = detect_type(m)
def strip_extra_coordinates(p):
if meshio_type == "line":
return p[:, :1]
if meshio_type in ("quad", "triangle"):
return p[:, :2]
return p
# create p and t
p = np.ascontiguousarray(strip_extra_coordinates(m.points).T)
t = np.ascontiguousarray(m.cells[meshio_type].T)
mtmp = mesh_type(p, t)
try:
# element to boundary element type mapping
bnd_type = {
'line': 'vertex',
'triangle': 'line',
'quad': 'line',
'tetra': 'triangle',
'hexahedron': 'quad',
}[meshio_type]
def find_tagname(tag):
for key in m.field_data:
if m.field_data[key][0] == tag:
return key
return None
# find subdomains
if meshio_type in m.cell_data and 'gmsh:physical' in m.cell_data[meshio_type]:
elements_tag = m.cell_data[meshio_type]['gmsh:physical']
subdomains = {}
tags = np.unique(elements_tag)
for tag in tags:
t_set = np.nonzero(tag == elements_tag)[0]
subdomains[find_tagname(tag)] = t_set
# find tagged boundaries
if bnd_type in m.cell_data and 'gmsh:physical' in m.cell_data[bnd_type]:
facets = m.cells[bnd_type]
facets_tag = m.cell_data[bnd_type]['gmsh:physical']
bndfacets = mtmp.boundary_facets()
# put meshio facets to dict
dic = {tuple(np.sort(facets[i])): facets_tag[i]
for i in range(facets.shape[0])}
# get index of corresponding Mesh.facets for each meshio
# facet found in the dict
index = np.array([[dic[tuple(np.sort(mtmp.facets[:, i]))], i]
for i in bndfacets
if tuple(np.sort(mtmp.facets[:, i])) in dic])
# read meshio tag numbers and names
tags = index[:, 0]
boundaries = {}
for tag in np.unique(tags):
tagindex = np.nonzero(tags == tag)[0]
boundaries[find_tagname(tag)] = index[tagindex, 1]
mtmp.boundaries = boundaries
mtmp.subdomains = subdomains
except Exception as e:
warnings.warn("Unable to load tagged boundaries/subdomains.")
return mtmp
def from_file(filename):
return from_meshio(meshio.read(filename))
def detect_type(m: meshio.Mesh) -> Tuple[str, skfem.Mesh]:
if 'tetra' in m.cells:
return 'tetra', skfem.MeshTet
elif 'hexahedron' in m.cells:
return 'hexahedron', skfem.MeshHex
elif 'triangle' in m.cells:
return 'triangle', skfem.MeshTri
elif 'quad' in m.cells:
return 'quad', skfem.MeshQuad
elif 'line' in m.cells:
return 'line', skfem.MeshLine
else:
raise Exception("Unknown mesh type.")