Skip to content

Commit 1ee5dd6

Browse files
author
Lachlan Grose
committed
perf: ⚡ reducing memory for unstructured tetra
memory use high when evaluating value for large pointset. Dividing problem into smaller points to reduce memory
1 parent 63d61a4 commit 1ee5dd6

File tree

1 file changed

+52
-46
lines changed

1 file changed

+52
-46
lines changed

LoopStructural/interpolators/supports/_3d_unstructured_tetra.py

Lines changed: 52 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -373,57 +373,63 @@ def get_element_for_location(self, points):
373373
-------
374374
375375
"""
376-
377-
cell_index = np.array(self.aabb_grid.position_to_cell_index(points)).swapaxes(
378-
0, 1
379-
)
380-
inside = self.aabb_grid.inside(points)
381-
global_index = (
382-
cell_index[:, 0]
383-
+ self.aabb_grid.nsteps_cells[None, 0] * cell_index[:, 1]
384-
+ self.aabb_grid.nsteps_cells[None, 0]
385-
* self.aabb_grid.nsteps_cells[None, 1]
386-
* cell_index[:, 2]
387-
)
388-
389-
tetra_indices = self.aabb_table[global_index[inside], :].tocoo()
390-
# tetra_indices[:] = -1
391-
row = tetra_indices.row
392-
col = tetra_indices.col
393-
# using returned indexes calculate barycentric coords to determine which tetra the points are in
394-
vertices = self.nodes[self.elements[col, :4]]
395-
pos = points[row, :]
396-
vap = pos[:, :] - vertices[:, 0, :]
397-
vbp = pos[:, :] - vertices[:, 1, :]
398-
# # vcp = p - points[:, 2, :]
399-
# # vdp = p - points[:, 3, :]
400-
vab = vertices[:, 1, :] - vertices[:, 0, :]
401-
vac = vertices[:, 2, :] - vertices[:, 0, :]
402-
vad = vertices[:, 3, :] - vertices[:, 0, :]
403-
vbc = vertices[:, 2, :] - vertices[:, 1, :]
404-
vbd = vertices[:, 3, :] - vertices[:, 1, :]
405-
406-
va = np.einsum("ij, ij->i", vbp, np.cross(vbd, vbc, axisa=1, axisb=1)) / 6.0
407-
vb = np.einsum("ij, ij->i", vap, np.cross(vac, vad, axisa=1, axisb=1)) / 6.0
408-
vc = np.einsum("ij, ij->i", vap, np.cross(vad, vab, axisa=1, axisb=1)) / 6.0
409-
vd = np.einsum("ij, ij->i", vap, np.cross(vab, vac, axisa=1, axisb=1)) / 6.0
410-
v = np.einsum("ij, ij->i", vab, np.cross(vac, vad, axisa=1, axisb=1)) / 6.0
411-
c = np.zeros((va.shape[0], 4))
412-
c[:, 0] = va / v
413-
c[:, 1] = vb / v
414-
c[:, 2] = vc / v
415-
c[:, 3] = vd / v
416-
# inside = np.ones(c.shape[0],dtype=bool)
417-
mask = np.all(c >= 0, axis=1)
418376
verts = np.zeros((points.shape[0], 4, 3))
419377
bc = np.zeros((points.shape[0], 4))
420378
tetras = np.zeros(points.shape[0], dtype="int64")
421379
inside = np.zeros(points.shape[0], dtype=bool)
380+
npts = 0
381+
npts_step = int(1e4)
382+
# break into blocks of 10k points
383+
while npts<points.shape[0]:
384+
385+
cell_index = np.array(self.aabb_grid.position_to_cell_index(points[:npts+npts_step,:])).swapaxes(
386+
0, 1
387+
)
388+
inside = self.aabb_grid.inside(points[:npts+npts_step,:])
389+
global_index = (
390+
cell_index[:, 0]
391+
+ self.aabb_grid.nsteps_cells[None, 0] * cell_index[:, 1]
392+
+ self.aabb_grid.nsteps_cells[None, 0]
393+
* self.aabb_grid.nsteps_cells[None, 1]
394+
* cell_index[:, 2]
395+
)
422396

423-
verts[row[mask], :, :] = vertices[mask, :, :]
424-
bc[row[mask], :] = c[mask, :]
425-
tetras[row[mask]] = col[mask]
426-
inside[row[mask]] = True
397+
tetra_indices = self.aabb_table[global_index[inside], :].tocoo()
398+
# tetra_indices[:] = -1
399+
row = tetra_indices.row
400+
col = tetra_indices.col
401+
# using returned indexes calculate barycentric coords to determine which tetra the points are in
402+
vertices = self.nodes[self.elements[col, :4]]
403+
pos = points[row, :]
404+
vap = pos[:, :] - vertices[:, 0, :]
405+
vbp = pos[:, :] - vertices[:, 1, :]
406+
# # vcp = p - points[:, 2, :]
407+
# # vdp = p - points[:, 3, :]
408+
vab = vertices[:, 1, :] - vertices[:, 0, :]
409+
vac = vertices[:, 2, :] - vertices[:, 0, :]
410+
vad = vertices[:, 3, :] - vertices[:, 0, :]
411+
vbc = vertices[:, 2, :] - vertices[:, 1, :]
412+
vbd = vertices[:, 3, :] - vertices[:, 1, :]
413+
414+
va = np.einsum("ij, ij->i", vbp, np.cross(vbd, vbc, axisa=1, axisb=1)) / 6.0
415+
vb = np.einsum("ij, ij->i", vap, np.cross(vac, vad, axisa=1, axisb=1)) / 6.0
416+
vc = np.einsum("ij, ij->i", vap, np.cross(vad, vab, axisa=1, axisb=1)) / 6.0
417+
vd = np.einsum("ij, ij->i", vap, np.cross(vab, vac, axisa=1, axisb=1)) / 6.0
418+
v = np.einsum("ij, ij->i", vab, np.cross(vac, vad, axisa=1, axisb=1)) / 6.0
419+
c = np.zeros((va.shape[0], 4))
420+
c[:, 0] = va / v
421+
c[:, 1] = vb / v
422+
c[:, 2] = vc / v
423+
c[:, 3] = vd / v
424+
# inside = np.ones(c.shape[0],dtype=bool)
425+
mask = np.all(c >= 0, axis=1)
426+
427+
428+
verts[:npts+npts_step,:,:][row[mask], :, :] = vertices[mask, :, :]
429+
bc[:npts+npts_step,:][row[mask], :] = c[mask, :]
430+
tetras[:npts+npts_step][row[mask]] = col[mask]
431+
inside[:npts+npts_step][row[mask]] = True
432+
npts+=npts_step
427433
return verts, bc, tetras, inside
428434

429435
def get_element_gradients(self, elements=None):

0 commit comments

Comments
 (0)