Skip to content

Commit e53369a

Browse files
committed
fix: updating tetmesh class for new indexing
1 parent 0a49817 commit e53369a

File tree

5 files changed

+105
-152
lines changed

5 files changed

+105
-152
lines changed

LoopStructural/interpolators/_python/dsi_helper.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
import numpy as np
22

33

4-
def cg(EG, neighbours, elements, nodes, region):
4+
def cg(EG: np.ndarray, neighbours: np.ndarray, elements: np.ndarray, nodes, region):
5+
if EG.shape[0] != neighbours.shape[0] and EG.shape[0] != elements.shape[0]:
6+
raise ValueError("EG and neighbours must have the same number of elements")
7+
if EG.shape[2] != 4:
8+
raise ValueError("EG must have 4 columns")
59
Nc = 5 # numer of constraints shared nodes + independent
610
Na = 4 # number of nodes
711
Ns = Na - 1

LoopStructural/interpolators/supports/_3d_base_structured.py

Lines changed: 36 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -233,32 +233,42 @@ def _global_indicies(self, indexes: np.ndarray, nsteps: np.ndarray) -> np.ndarra
233233
"""
234234
if len(indexes.shape) == 1:
235235
raise ValueError("Cell indexes needs to be Nx3")
236-
if len(indexes.shape) == 2:
237-
if indexes.shape[1] != 3 and indexes.shape[0] == 3:
238-
indexes = indexes.swapaxes(0, 1)
239-
if indexes.shape[1] != 3:
240-
logger.error("Indexes shape {}".format(indexes.shape))
241-
raise ValueError("Cell indexes needs to be Nx3")
242-
return (
243-
indexes[:, 0]
244-
+ nsteps[None, 0] * indexes[:, 1]
245-
+ nsteps[None, 0] * nsteps[None, 1] * indexes[:, 2]
246-
)
247-
if len(indexes.shape) == 3:
248-
# if indexes.shape[2] != 3 and indexes.shape[1] == 3:
249-
# indexes = indexes.swapaxes(1, 2)
250-
# if indexes.shape[2] != 3 and indexes.shape[0] == 3:
251-
# indexes = indexes.swapaxes(0, 2)
252-
if indexes.shape[2] != 3:
253-
logger.error("Indexes shape {}".format(indexes.shape))
254-
raise ValueError("Cell indexes needs to be NxNx3")
255-
return (
256-
indexes[:, :, 0]
257-
+ nsteps[None, None, 0] * indexes[:, :, 1]
258-
+ nsteps[None, None, 0] * nsteps[None, None, 1] * indexes[:, :, 2]
259-
)
260-
else:
261-
raise ValueError("Cell indexes need to be a 2 or 3d numpy array")
236+
if indexes.shape[-1] != 3:
237+
raise ValueError("Last dimensions should be ijk indexing")
238+
original_shape = indexes.shape
239+
indexes = indexes.reshape(-1, 3)
240+
gi = (
241+
indexes[:, 0]
242+
+ nsteps[None, 0] * indexes[:, 1]
243+
+ nsteps[None, 0] * nsteps[None, 1] * indexes[:, 2]
244+
)
245+
return gi.reshape(original_shape[:-1])
246+
# if len(indexes.shape) == 2:
247+
# if indexes.shape[1] != 3 and indexes.shape[0] == 3:
248+
# indexes = indexes.swapaxes(0, 1)
249+
# if indexes.shape[1] != 3:
250+
# logger.error("Indexes shape {}".format(indexes.shape))
251+
# raise ValueError("Cell indexes needs to be Nx3")
252+
# return (
253+
# indexes[:, 0]
254+
# + nsteps[None, 0] * indexes[:, 1]
255+
# + nsteps[None, 0] * nsteps[None, 1] * indexes[:, 2]
256+
# )
257+
# if len(indexes.shape) == 3:
258+
# # if indexes.shape[2] != 3 and indexes.shape[1] == 3:
259+
# # indexes = indexes.swapaxes(1, 2)
260+
# # if indexes.shape[2] != 3 and indexes.shape[0] == 3:
261+
# # indexes = indexes.swapaxes(0, 2)
262+
# if indexes.shape[2] != 3:
263+
# logger.error("Indexes shape {}".format(indexes.shape))
264+
# raise ValueError("Cell indexes needs to be NxNx3")
265+
# return (
266+
# indexes[:, :, 0]
267+
# + nsteps[None, None, 0] * indexes[:, :, 1]
268+
# + nsteps[None, None, 0] * nsteps[None, None, 1] * indexes[:, :, 2]
269+
# )
270+
# else:
271+
# raise ValueError("Cell indexes need to be a 2 or 3d numpy array")
262272

263273
def cell_corner_indexes(self, cell_indexes):
264274
"""

LoopStructural/interpolators/supports/_3d_structured_grid.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,6 @@ def neighbour_global_indexes(self, mask=None, **kwargs):
178178
).reshape((3, -1))
179179
# indexes = np.array(indexes).T
180180
if indexes.ndim != 2:
181-
print(indexes.ndim)
182181
return
183182
# determine which neighbours to return default is diagonals included.
184183
if mask is None:

LoopStructural/interpolators/supports/_3d_structured_tetra.py

Lines changed: 52 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -143,27 +143,26 @@ def get_element_for_location(self, pos: np.ndarray):
143143
pos = np.array(pos)
144144
inside = self.inside(pos)
145145
# initialise array for tetrahedron vertices
146-
vertices = np.zeros((5, 4, pos.shape[0], 3))
146+
vertices = np.zeros((pos.shape[0], 5, 4, 3))
147147
vertices[:] = np.nan
148148
# get cell indexes
149-
c_xi, c_yi, c_zi = self.position_to_cell_index(pos)
150-
149+
cell_indexes = self.position_to_cell_index(pos)
151150
# determine if using +ve or -ve mask
152-
even_mask = (c_xi + c_yi + c_zi) % 2 == 0
151+
even_mask = np.sum(cell_indexes, axis=1) % 2 == 0
153152
# get cell corners
154-
xi, yi, zi = self.cell_corner_indexes(
155-
c_xi, c_yi, c_zi
153+
corner_indexes = self.cell_corner_indexes(
154+
cell_indexes
156155
) # global_index_to_node_index(gi)
157156
# convert to node locations
158-
nodes = self.node_indexes_to_position(xi, yi, zi).T
157+
nodes = self.node_indexes_to_position(corner_indexes)
159158

160-
vertices[:, :, even_mask, :] = nodes[:, even_mask, :][
161-
self.tetra_mask_even, :, :
159+
vertices[even_mask, :, :, :] = nodes[even_mask, :, :][
160+
:, self.tetra_mask_even, :
162161
]
163-
vertices[:, :, ~even_mask, :] = nodes[:, ~even_mask, :][self.tetra_mask, :, :]
162+
vertices[~even_mask, :, :, :] = nodes[~even_mask, :, :][:, self.tetra_mask, :]
164163
# changing order to points, tetra, nodes, coord
165-
vertices = vertices.swapaxes(0, 2)
166-
vertices = vertices.swapaxes(1, 2)
164+
# vertices = vertices.swapaxes(0, 2)
165+
# vertices = vertices.swapaxes(1, 2)
167166
# use scalar triple product to calculate barycentric coords
168167

169168
vap = pos[:, None, :] - vertices[:, :, 0, :]
@@ -191,14 +190,13 @@ def get_element_for_location(self, pos: np.ndarray):
191190

192191
inside = np.logical_and(inside, np.any(mask, axis=1))
193192
# get cell corners
194-
xi, yi, zi = self.cell_corner_indexes(c_xi, c_yi, c_zi)
195193
# create mask to see which cells are even
196-
even_mask = (c_xi + c_yi + c_zi) % 2 == 0
194+
even_mask = np.sum(cell_indexes, axis=1) % 2 == 0
197195
# create global node index list
198-
gi = xi + yi * self.nsteps[0] + zi * self.nsteps[0] * self.nsteps[1]
196+
gi = self.global_node_indices(corner_indexes)
197+
# gi = xi + yi * self.nsteps[0] + zi * self.nsteps[0] * self.nsteps[1]
199198
# container for tetras
200-
tetras = np.zeros((xi.shape[0], 5, 4)).astype(int)
201-
199+
tetras = np.zeros((corner_indexes.shape[0], 5, 4)).astype(int)
202200
tetras[even_mask, :, :] = gi[even_mask, :][:, self.tetra_mask_even]
203201
tetras[~even_mask, :, :] = gi[~even_mask, :][:, self.tetra_mask]
204202
inside = np.logical_and(inside, self.inside(pos))
@@ -229,15 +227,12 @@ def get_elements(self):
229227
y = np.arange(0, self.nsteps_cells[1])
230228
z = np.arange(0, self.nsteps_cells[2])
231229

232-
c_xi, c_yi, c_zi = np.meshgrid(x, y, z, indexing="ij")
233-
c_xi = c_xi.flatten(order="F")
234-
c_yi = c_yi.flatten(order="F")
235-
c_zi = c_zi.flatten(order="F")
230+
cell_indexes = np.array(np.meshgrid(x, y, z, indexing="ij")).reshape(3, -1).T
236231
# get cell corners
237-
xi, yi, zi = self.cell_corner_indexes(c_xi, c_yi, c_zi)
238-
even_mask = (c_xi + c_yi + c_zi) % 2 == 0
239-
gi = xi + yi * self.nsteps[0] + zi * self.nsteps[0] * self.nsteps[1]
240-
tetras = np.zeros((c_xi.shape[0], 5, 4)).astype("int64")
232+
cell_corners = self.cell_corner_indexes(cell_indexes)
233+
even_mask = np.sum(cell_indexes, axis=1) % 2 == 0
234+
gi = self.global_node_indices(cell_corners)
235+
tetras = np.zeros((cell_corners.shape[0], 5, 4)).astype("int64")
241236
tetras[even_mask, :, :] = gi[even_mask, :][:, self.tetra_mask_even]
242237
tetras[~even_mask, :, :] = gi[~even_mask, :][:, self.tetra_mask]
243238

@@ -261,25 +256,25 @@ def get_element_gradients(self, elements=None):
261256
y = np.arange(0, self.nsteps_cells[1])
262257
z = np.arange(0, self.nsteps_cells[2])
263258

264-
c_xi, c_yi, c_zi = np.meshgrid(x, y, z, indexing="ij")
265-
c_xi = c_xi.flatten(order="F")
266-
c_yi = c_yi.flatten(order="F")
267-
c_zi = c_zi.flatten(order="F")
268-
even_mask = (c_xi + c_yi + c_zi) % 2 == 0
259+
cell_indexes = np.array(np.meshgrid(x, y, z, indexing="ij")).reshape(3, -1).T
260+
# c_xi = c_xi.flatten(order="F")
261+
# c_yi = c_yi.flatten(order="F")
262+
# c_zi = c_zi.flatten(order="F")
263+
even_mask = np.sum(cell_indexes, axis=1) % 2 == 0
269264
# get cell corners
270-
xi, yi, zi = self.cell_corner_indexes(
271-
c_xi, c_yi, c_zi
265+
corner_indexes = self.cell_corner_indexes(
266+
cell_indexes
272267
) # global_index_to_node_index(gi)
273268
# convert to node locations
274-
nodes = self.node_indexes_to_position(xi, yi, zi).T
269+
nodes = self.node_indexes_to_position(corner_indexes)
275270

276-
points = np.zeros((5, 4, self.n_cells, 3))
277-
points[:, :, even_mask, :] = nodes[:, even_mask, :][self.tetra_mask_even, :, :]
278-
points[:, :, ~even_mask, :] = nodes[:, ~even_mask, :][self.tetra_mask, :, :]
271+
points = np.zeros((self.n_cells, 5, 4, 3))
272+
points[even_mask, :, :, :] = nodes[even_mask, :, :][:, self.tetra_mask_even, :]
273+
points[~even_mask, :, :, :] = nodes[~even_mask, :, :][:, self.tetra_mask, :]
279274

280275
# changing order to points, tetra, nodes, coord
281-
points = points.swapaxes(0, 2)
282-
points = points.swapaxes(1, 2)
276+
# points = points.swapaxes(0, 2)
277+
# points = points.swapaxes(1, 2)
283278

284279
ps = points.reshape(
285280
points.shape[0] * points.shape[1], points.shape[2], points.shape[3]
@@ -402,72 +397,25 @@ def global_cell_indicies(self, indexes: np.ndarray):
402397
* indexes[:, :, 2]
403398
)
404399

405-
def cell_corner_indexes(self, x_cell_index, y_cell_index, z_cell_index):
406-
"""
407-
Returns the indexes of the corners of a cell given its location xi,
408-
yi, zi
409-
410-
Parameters
411-
----------
412-
x_cell_index
413-
y_cell_index
414-
z_cell_index
415-
416-
Returns
417-
-------
418-
419-
"""
420-
x_cell_index = np.array(x_cell_index)
421-
y_cell_index = np.array(y_cell_index)
422-
z_cell_index = np.array(z_cell_index)
423-
424-
xcorner = np.array([0, 1, 0, 1, 0, 1, 0, 1])
425-
ycorner = np.array([0, 0, 1, 1, 0, 0, 1, 1])
426-
zcorner = np.array([0, 0, 0, 0, 1, 1, 1, 1])
427-
xcorners = x_cell_index[:, None] + xcorner[None, :]
428-
ycorners = y_cell_index[:, None] + ycorner[None, :]
429-
zcorners = z_cell_index[:, None] + zcorner[None, :]
430-
return xcorners, ycorners, zcorners
431-
432-
def position_to_cell_corners(self, pos: np.ndarray) -> np.ndarray:
433-
"""
434-
Find the nodes that belong to a cell which contains a point
435-
436-
Parameters
437-
----------
438-
pos
439-
440-
Returns
441-
-------
442-
443-
"""
444-
inside = self.inside(pos)
445-
ix, iy, iz = self.position_to_cell_index(pos)
446-
cornersx, cornersy, cornersz = self.cell_corner_indexes(ix, iy, iz)
447-
globalidx = self.global_cell_indicies(
448-
np.dstack([cornersx, cornersy, cornersz]).T
449-
)
450-
return globalidx, inside
451-
452-
def node_indexes_to_position(self, xindex, yindex, zindex):
453-
"""
454-
Get the xyz position from the node coordinates
455-
456-
Parameters
457-
----------
458-
xindex
459-
yindex
460-
zindex
461-
462-
Returns
463-
-------
464-
465-
"""
466-
x = self.origin[0] + self.step_vector[0] * xindex
467-
y = self.origin[1] + self.step_vector[1] * yindex
468-
z = self.origin[2] + self.step_vector[2] * zindex
469-
470-
return np.array([x, y, z])
400+
# def position_to_cell_corners(self, pos: np.ndarray) -> np.ndarray:
401+
# """
402+
# Find the nodes that belong to a cell which contains a point
403+
404+
# Parameters
405+
# ----------
406+
# pos
407+
408+
# Returns
409+
# -------
410+
411+
# """
412+
# inside = self.inside(pos)
413+
# ix, iy, iz = self.position_to_cell_index(pos)
414+
# cornersx, cornersy, cornersz = self.cell_corner_indexes(ix, iy, iz)
415+
# globalidx = self.global_cell_indicies(
416+
# np.dstack([cornersx, cornersy, cornersz]).T
417+
# )
418+
# return globalidx, inside
471419

472420
def global_index_to_node_index(self, global_index: np.ndarray):
473421
"""

tests/unit/interpolator/test_discrete_supports.py

Lines changed: 12 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -160,32 +160,24 @@ def test_global_index_to_cell_index(support):
160160

161161

162162
def test_global_index(support):
163-
indexes = (
164-
np.array(
165-
np.meshgrid(
166-
np.arange(0, support.nsteps[0]),
167-
np.arange(0, support.nsteps[1]),
168-
np.arange(0, support.nsteps[2]),
169-
)
163+
indexes = np.array(
164+
np.meshgrid(
165+
np.arange(0, support.nsteps[0]),
166+
np.arange(0, support.nsteps[1]),
167+
np.arange(0, support.nsteps[2]),
170168
)
171-
.reshape(-1, 3)
172-
.T
173-
)
169+
).reshape(-1, 3)
174170
global_node_index = support.global_node_indices(indexes)
175171
assert np.all(global_node_index >= 0)
176172
assert np.all(global_node_index < support.n_nodes)
177173

178-
indexes = (
179-
np.array(
180-
np.meshgrid(
181-
np.arange(0, 3),
182-
np.arange(0, 1),
183-
np.arange(0, 1),
184-
)
174+
indexes = np.array(
175+
np.meshgrid(
176+
np.arange(0, 3),
177+
np.arange(0, 1),
178+
np.arange(0, 1),
185179
)
186-
.reshape(-1, 3)
187-
.T
188-
)
180+
).reshape(-1, 3)
189181
global_node_index = support.global_node_indices(indexes)
190182
assert np.all(global_node_index >= 0)
191183
assert np.all(global_node_index < support.n_nodes)

0 commit comments

Comments
 (0)