Skip to content

Commit e11e833

Browse files
authored
Invalidate spatial index when coordinates updated (#3956)
1 parent 767f5e1 commit e11e833

File tree

2 files changed

+23
-7
lines changed

2 files changed

+23
-7
lines changed

firedrake/mesh.py

+14-7
Original file line numberDiff line numberDiff line change
@@ -2269,6 +2269,9 @@ def __init__(self, coordinates):
22692269
# submesh
22702270
self.submesh_parent = None
22712271

2272+
self._spatial_index = None
2273+
self._saved_coordinate_dat_version = coordinates.dat.dat_version
2274+
22722275
def _ufl_signature_data_(self, *args, **kwargs):
22732276
return (type(self), self.extruded, self.variable_layers,
22742277
super()._ufl_signature_data_(*args, **kwargs))
@@ -2448,12 +2451,9 @@ def clear_spatial_index(self):
24482451
24492452
Use this if you move the mesh (for example by reassigning to
24502453
the coordinate field)."""
2451-
try:
2452-
del self.spatial_index
2453-
except AttributeError:
2454-
pass
2454+
self._spatial_index = None
24552455

2456-
@utils.cached_property
2456+
@property
24572457
def spatial_index(self):
24582458
"""Spatial index to quickly find which cell contains a given point.
24592459
@@ -2466,10 +2466,15 @@ def spatial_index(self):
24662466
can be found.
24672467
24682468
"""
2469-
24702469
from firedrake import function, functionspace
24712470
from firedrake.parloops import par_loop, READ, MIN, MAX
24722471

2472+
if (
2473+
self._spatial_index
2474+
and self.coordinates.dat.dat_version == self._saved_coordinate_dat_version
2475+
):
2476+
return self._spatial_index
2477+
24732478
gdim = self.geometric_dimension()
24742479
if gdim <= 1:
24752480
info_red("libspatialindex does not support 1-dimension, falling back on brute force.")
@@ -2531,7 +2536,9 @@ def spatial_index(self):
25312536
coords_max = coords_mid + (tolerance + 0.5)*d
25322537

25332538
# Build spatial index
2534-
return spatialindex.from_regions(coords_min, coords_max)
2539+
self._spatial_index = spatialindex.from_regions(coords_min, coords_max)
2540+
self._saved_coordinate_dat_version = self.coordinates.dat.dat_version
2541+
return self._spatial_index
25352542

25362543
@PETSc.Log.EventDecorator()
25372544
def locate_cell(self, x, tolerance=None, cell_ignore=None):

tests/firedrake/regression/test_point_eval_fs.py

+9
Original file line numberDiff line numberDiff line change
@@ -213,3 +213,12 @@ def test_point_reset_works():
213213
f.assign(1)
214214
m.clear_spatial_index()
215215
assert np.allclose([1.0], f.at((0.3, 0.3)))
216+
217+
218+
def test_changing_coordinates_invalidates_spatial_index():
219+
mesh = UnitSquareMesh(2, 2)
220+
mesh.init()
221+
222+
saved_spatial_index = mesh.spatial_index
223+
mesh.coordinates.assign(mesh.coordinates * 2)
224+
assert mesh.spatial_index != saved_spatial_index

0 commit comments

Comments
 (0)