Skip to content

Moving mesh (mesh.deform / free surface / r-adapt) crashes at np>1: _build_kd_tree_index nav_coords[points - pStart] out of bounds #360

Description

@lmoresi

Summary

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-points
cell_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.

Relationship to other issues

Fix direction

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions