You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Every moving-mesh workflow (free surface, mesh.deform, r-adaptation) crashes at np > 1. The Stokes solve completes correctly on all ranks, then mesh.deform() crashes at the end of the step inside _build_kd_tree_index.
This is parallel-only — the identical script runs fine serially. It is not particle/swarm related: reproduced with both a compositional swarm AND a pure mesh-level-set / field configuration (no particles). Both call mesh.deform() every step and hit the same line.
Reproduce
Any free-surface / mesh.deform driver under mpirun -np 4 (verified with the Crameri Case-2 driver, both swarm and mesh-LS plume). Step 1 solves on all ranks, then:
File ".../discretisation/discretisation_mesh.py", line 3129, in deform
File ".../discretisation/discretisation_mesh.py", line 3188, in _deform_mesh
File ".../discretisation/discretisation_mesh.py", line 2349, in nuke_coords_and_rebuild
File ".../discretisation/discretisation_mesh.py", line 4547, in _build_kd_tree_index
cell_point_coords = nav_coords[points - pStart]
IndexError: index -11 is out of bounds for axis 0 with size 10
IndexError: index 14 is out of bounds for axis 0 with size 14
Indices go both negative and past the end of the local array (different value per rank).
Root cause
_build_kd_tree_index (discretisation_mesh.py:4547, and the identical _build_kd_tree_index_PIC at :4723) maps vertex plex-point numbers to coordinate rows with an affine shift:
points=nav_dm.getTransitiveClosure(cell_id)[0][-cell_num_points:] # vertex plex-pointscell_point_coords=nav_coords[points-pStart] # <-- wrong in parallel
points - pStart is only a valid row index when vertex numbering is serial-contiguous. After nuke_coords_and_rebuild re-points _nav_coords at self.dm.getCoordinatesLocal() (:2404), the local overlapped coordinate array is ordered by the coordinate PetscSection, not by plex_point − pStart. In parallel, ghost/halo vertices make points − pStart run negative or overflow → IndexError.
Undeformed meshes never hit this: the kd-tree is built once at construction (before any rebuild). Moving-mesh workflows call mesh.deform() every step, so they hit it immediately.
Regression trace
The nav_coords[points - pStart] navigation indexing was introduced in fd6070d (2026-06-04, "feat(manifold): parallel point-evaluation + scalar PDE solver on cd-1 meshes").
It became reachable on every deform when fix(mesh): boundary normals and domain membership must track a deformed mesh #264 / 51ecd29 (2026-06-22, "fix(mesh): boundary normals and domain membership must track a deformed mesh") added the post-deform _nav_coords refresh in nuke_coords_and_rebuild (:2400–2414). That refresh is correct in serial; it exposes the parallel indexing bug.
Map vertex plex-points → coordinate rows via the coordinate PetscSection offsets (getCoordinateSection + getOffset / closure), not the affine points − pStart. This touches core navigation used by serial point-location, evaluate, and RBF, so it needs its own bugfix branch with the full serial + parallel (np2/np4) test suite. A regression test that deforms a distributed box mesh one step at np≥2 would guard it.
Summary
Every moving-mesh workflow (free surface,
mesh.deform, r-adaptation) crashes atnp > 1. The Stokes solve completes correctly on all ranks, thenmesh.deform()crashes at the end of the step inside_build_kd_tree_index.This is parallel-only — the identical script runs fine serially. It is not particle/swarm related: reproduced with both a compositional swarm AND a pure mesh-level-set / field configuration (no particles). Both call
mesh.deform()every step and hit the same line.Reproduce
Any free-surface /
mesh.deformdriver undermpirun -np 4(verified with the Crameri Case-2 driver, both swarm and mesh-LS plume). Step 1 solves on all ranks, then:Indices go both negative and past the end of the local array (different value per rank).
Root cause
_build_kd_tree_index(discretisation_mesh.py:4547, and the identical_build_kd_tree_index_PICat :4723) maps vertex plex-point numbers to coordinate rows with an affine shift:points - pStartis only a valid row index when vertex numbering is serial-contiguous. Afternuke_coords_and_rebuildre-points_nav_coordsatself.dm.getCoordinatesLocal()(:2404), the local overlapped coordinate array is ordered by the coordinate PetscSection, not byplex_point − pStart. In parallel, ghost/halo vertices makepoints − pStartrun negative or overflow →IndexError.Undeformed meshes never hit this: the kd-tree is built once at construction (before any rebuild). Moving-mesh workflows call
mesh.deform()every step, so they hit it immediately.Regression trace
nav_coords[points - pStart]navigation indexing was introduced in fd6070d (2026-06-04, "feat(manifold): parallel point-evaluation + scalar PDE solver on cd-1 meshes")._nav_coordsrefresh innuke_coords_and_rebuild(:2400–2414). That refresh is correct in serial; it exposes the parallel indexing bug.Relationship to other issues
IndexErrorclass but a distinct serial cause: kd-tree rebuilt against a stale, wrong-sizenav_coordsafteradapt()grew the mesh. That ordering fix is in place; this is a separate, parallel-only indexing error with an unchanged mesh size._deform_meshrejected by the coordinate-mutation guard; different symptom, same subsystem.Fix direction
Map vertex plex-points → coordinate rows via the coordinate
PetscSectionoffsets (getCoordinateSection+getOffset/ closure), not the affinepoints − pStart. This touches core navigation used by serial point-location,evaluate, and RBF, so it needs its own bugfix branch with the full serial + parallel (np2/np4) test suite. A regression test that deforms a distributed box mesh one step at np≥2 would guard it.