2
2
3
3
import numpy
4
4
5
+ from ._common import _topological_dimension
6
+
5
7
6
8
class CellBlock (collections .namedtuple ("CellBlock" , ["type" , "data" ])):
7
9
def __repr__ (self ):
@@ -77,30 +79,39 @@ def __repr__(self):
77
79
78
80
return "\n " .join (lines )
79
81
80
- def prune (self ):
81
- prune_list = [ "vertex" , "line" , "line3" ]
82
- if any ([ c . type in [ "tetra" , "tetra10" ] for c in self . cells ]):
83
- prune_list += [ "triangle" , "triangle6" ]
84
-
82
+ def remove_lower_dimensional_cells (self ):
83
+ """Remove all cells of topological dimension lower than the max dimension in the
84
+ mesh, i.e., in a mesh that contains tetrahedra, remove triangles, lines, etc.
85
+ """
86
+ max_topological_dim = max ( _topological_dimension [ c . type ] for c in self . cells )
85
87
new_cells = []
86
88
new_cell_data = {}
87
- for block_counter , c in enumerate (self .cells ):
88
- if c .type not in prune_list :
89
+ new_cell_sets = {}
90
+ prune_set = set ()
91
+ for idx , c in enumerate (self .cells ):
92
+ if _topological_dimension [c .type ] == max_topological_dim :
89
93
new_cells .append (c )
94
+
90
95
for name , data in self .cell_data .items ():
91
96
if name not in new_cell_data :
92
97
new_cell_data [name ] = []
93
- new_cell_data [name ] += [data [block_counter ]]
98
+ new_cell_data [name ] += [data [idx ]]
99
+
100
+ for name , data in self .cell_sets .items ():
101
+ if name not in new_cell_sets :
102
+ new_cell_sets [name ] = []
103
+ new_cell_sets [name ] += [data [idx ]]
104
+ else :
105
+ prune_set .add (c .type )
94
106
95
107
self .cells = new_cells
96
108
self .cell_data = new_cell_data
109
+ self .cell_sets = new_cell_sets
110
+ return prune_set
97
111
98
- pruned = ", " .join (prune_list )
99
- print (f"Pruned cell types: { pruned } " )
100
-
101
- # remove_orphaned_nodes.
102
- # find which nodes are not mentioned in the cells and remove them
103
- all_cells_flat = numpy .concatenate ([c .data for c in self .cells ]).flatten ()
112
+ def remove_orphaned_nodes (self ):
113
+ """Remove nodes which don't belong to any cell."""
114
+ all_cells_flat = numpy .concatenate ([c .data .flat for c in self .cells ])
104
115
orphaned_nodes = numpy .setdiff1d (numpy .arange (len (self .points )), all_cells_flat )
105
116
self .points = numpy .delete (self .points , orphaned_nodes , axis = 0 )
106
117
# also adapt the point data
@@ -125,6 +136,13 @@ def prune(self):
125
136
self .cells [k ] = CellBlock (c .type , all_cells_flat [k : k + n ].reshape (s ))
126
137
k += n
127
138
139
+ def prune_z_0 (self , tol = 1.0e-13 ):
140
+ """Remove third (z) component of points if it is 0 everywhere (up to a
141
+ tolerance).
142
+ """
143
+ if self .points .shape [1 ] == 3 and numpy .all (numpy .abs (self .points [:, 2 ]) < tol ):
144
+ self .points = self .points [:, :2 ]
145
+
128
146
def write (self , path_or_buf , file_format = None , ** kwargs ):
129
147
# avoid circular import
130
148
from ._helpers import write
@@ -204,14 +222,23 @@ def sets_to_int_data(self):
204
222
# If possible, convert cell sets to integer cell data. This is possible if all
205
223
# cells appear exactly in one group.
206
224
intfun = []
207
- for c in zip (* self .cell_sets .values ()):
225
+ for k , c in enumerate (zip (* self .cell_sets .values ())):
226
+ # `c` contains the values of all cell sets for a particular cell block
227
+ c = [([] if cc is None else cc ) for cc in c ]
208
228
# check if all numbers appear exactly once in the groups
209
229
d = numpy .sort (numpy .concatenate (c ))
210
- is_convertible = numpy .all (d [ 1 :] == d [: - 1 ] + 1 ) and len (d ) == d [ - 1 ] + 1
211
- if is_convertible :
212
- intfun . append ( numpy . zeros ( len ( d ), dtype = int ))
230
+ if numpy .all (d == numpy . arange ( len (d ))):
231
+ arr = numpy . empty ( len ( d ), dtype = int )
232
+ arr [:] = numpy . nan
213
233
for k , cc in enumerate (c ):
214
- intfun [- 1 ][cc ] = k
234
+ arr [cc ] = k
235
+ else :
236
+ # We could just append None, but some mesh formats expect _something_
237
+ # here. Go for an array of NaNs.
238
+ arr = numpy .empty (len (self .cells [k ]), dtype = int )
239
+ arr [:] = numpy .nan
240
+
241
+ intfun .append (arr )
215
242
216
243
data_name = "-" .join (self .cell_sets .keys ())
217
244
self .cell_data = {data_name : intfun }
0 commit comments