From 8f78187702c34aa3bae5a05da9c044d3de8b8408 Mon Sep 17 00:00:00 2001 From: lmoresi Date: Tue, 21 Apr 2026 17:09:04 +1000 Subject: [PATCH] Fix mesh.X.coords returning stale coordinates after _deform_mesh (#122) _deform_mesh updates the DM coordinate vector and calls nuke_coords_and_rebuild, which may replace the internal coordinate buffer (via createCoordinateSpace). The self._coords NDArray view still pointed to the old buffer, so mesh.X.coords returned pre-deformation values. Fix: rebuild self._coords from the current DM coordinate vector after nuke_coords_and_rebuild, preserving the update callback. Closes #122 Underworld development team with AI support from Claude Code (https://claude.com/claude-code) --- .../discretisation/discretisation_mesh.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/underworld3/discretisation/discretisation_mesh.py b/src/underworld3/discretisation/discretisation_mesh.py index c3a37b00f..a5eb07e29 100644 --- a/src/underworld3/discretisation/discretisation_mesh.py +++ b/src/underworld3/discretisation/discretisation_mesh.py @@ -1283,6 +1283,20 @@ def _deform_mesh(self, new_coords: numpy.ndarray, verbose=False): self.dm.setCoordinatesLocal(coord_vec) self.nuke_coords_and_rebuild() + # Rebuild the _coords array view. nuke_coords_and_rebuild may + # replace the coordinate vector internally (createCoordinateSpace), + # leaving self._coords as a stale numpy view of the old buffer. + import underworld3.utilities + old_callbacks = getattr(self._coords, "_callbacks", []) + self._coords = underworld3.utilities.NDArray_With_Callback( + numpy.ndarray.view( + self.dm.getCoordinatesLocal().array.reshape(-1, self.cdim) + ), + owner=self, + ) + for cb in old_callbacks: + self._coords.add_callback(cb) + return def _legacy_access(self, *writeable_vars: "MeshVariable"):