Skip to content

Commit

Permalink
Invalidate spatial index when coordinates updated (#3956)
Browse files Browse the repository at this point in the history
  • Loading branch information
connorjward authored Jan 8, 2025
1 parent 767f5e1 commit e11e833
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 7 deletions.
21 changes: 14 additions & 7 deletions firedrake/mesh.py
Original file line number Diff line number Diff line change
Expand Up @@ -2269,6 +2269,9 @@ def __init__(self, coordinates):
# submesh
self.submesh_parent = None

self._spatial_index = None
self._saved_coordinate_dat_version = coordinates.dat.dat_version

def _ufl_signature_data_(self, *args, **kwargs):
return (type(self), self.extruded, self.variable_layers,
super()._ufl_signature_data_(*args, **kwargs))
Expand Down Expand Up @@ -2448,12 +2451,9 @@ def clear_spatial_index(self):
Use this if you move the mesh (for example by reassigning to
the coordinate field)."""
try:
del self.spatial_index
except AttributeError:
pass
self._spatial_index = None

@utils.cached_property
@property
def spatial_index(self):
"""Spatial index to quickly find which cell contains a given point.
Expand All @@ -2466,10 +2466,15 @@ def spatial_index(self):
can be found.
"""

from firedrake import function, functionspace
from firedrake.parloops import par_loop, READ, MIN, MAX

if (
self._spatial_index
and self.coordinates.dat.dat_version == self._saved_coordinate_dat_version
):
return self._spatial_index

gdim = self.geometric_dimension()
if gdim <= 1:
info_red("libspatialindex does not support 1-dimension, falling back on brute force.")
Expand Down Expand Up @@ -2531,7 +2536,9 @@ def spatial_index(self):
coords_max = coords_mid + (tolerance + 0.5)*d

# Build spatial index
return spatialindex.from_regions(coords_min, coords_max)
self._spatial_index = spatialindex.from_regions(coords_min, coords_max)
self._saved_coordinate_dat_version = self.coordinates.dat.dat_version
return self._spatial_index

@PETSc.Log.EventDecorator()
def locate_cell(self, x, tolerance=None, cell_ignore=None):
Expand Down
9 changes: 9 additions & 0 deletions tests/firedrake/regression/test_point_eval_fs.py
Original file line number Diff line number Diff line change
Expand Up @@ -213,3 +213,12 @@ def test_point_reset_works():
f.assign(1)
m.clear_spatial_index()
assert np.allclose([1.0], f.at((0.3, 0.3)))


def test_changing_coordinates_invalidates_spatial_index():
mesh = UnitSquareMesh(2, 2)
mesh.init()

saved_spatial_index = mesh.spatial_index
mesh.coordinates.assign(mesh.coordinates * 2)
assert mesh.spatial_index != saved_spatial_index

0 comments on commit e11e833

Please sign in to comment.