Skip to content

fix(meshing): honest 2D-only guard for the MMPDE mover (BF-09)#309

Open
lmoresi wants to merge 1 commit into
developmentfrom
bugfix/track0-mmpde-3d
Open

fix(meshing): honest 2D-only guard for the MMPDE mover (BF-09)#309
lmoresi wants to merge 1 commit into
developmentfrom
bugfix/track0-mmpde-3d

Conversation

@lmoresi

@lmoresi lmoresi commented Jul 3, 2026

Copy link
Copy Markdown
Member

Finding

BF-09 / READ-01 from the 2026-07 quality audit
(docs/reviews/2026-07/REMEDIATION-WORKLIST.md,
docs/reviews/2026-07/READABILITY-REVIEW.md).

_winslow_mmpde (src/underworld3/meshing/smoothing.py) claimed
"Dimension-general (d = 2, 3)" in its docstring, but the cdim == 3 branch
assigned signed_vol = _signed_volumes — a function that is defined nowhere in
the package — so any 3D MMPDE invocation died with a NameError deep inside
the mover. Maintainer decision (D8): do NOT implement the 3D discretization;
make the mover honestly 2D-only.

Reproduction

On the unfixed build:

mesh = uw.meshing.UnstructuredSimplexBox(minCoords=(0,0,0), maxCoords=(1,1,1), cellSize=0.5)
smooth_mesh_interior(mesh, metric=sympy.sympify(1), method="mmpde")
# NameError: name '_signed_volumes' is not defined

The new regression test fails with exactly this NameError on the unfixed
build (confirmed in the pre-fix gate run).

Fix

  • Raise a clear NotImplementedError ("MMPDE mesh movement is currently
    2D-only ...") at the top of _winslow_mmpde, before any metric parsing or
    DM work, so both the public smooth_mesh_interior(method="mmpde") path and
    the bare dispatch hit an honest message immediately.
  • Remove the dead 3D branch that referenced the phantom _signed_volumes;
    the 2D path collapses to the identical _tri_cells / _signed_areas /
    fact = 2.0 assignments (no behaviour change in 2D).
  • Docstrings made honestly 2D-only: the _winslow_mmpde docstring, a new
    "mmpde" bullet in smooth_mesh_interior's method documentation, and the
    _tet_cells helper note (that helper stays — _ot_adapt.py uses it for 3D
    boundary-face extraction).

No solver or 2D mover numerics are touched.

Tests

New TestMMPDEDimensionGuard in tests/test_0850_mesh_smoothing.py
(level_1, tier_a):

  • test_mmpde_3d_raises_not_implemented — real small 3D simplex box through
    the public API raises NotImplementedError matching "MMPDE mesh movement is
    currently 2D-only" (fails with NameError pre-fix).
  • test_mmpde_3d_guard_fires_before_any_mesh_work — cdim stand-in locks the
    guard-runs-first contract (same pattern as test_0762's non2d tests).
  • test_mmpde_2d_smoke_still_works — small 2D mmpde invocation runs, moves
    nodes, leaves finite coordinates.

Gate results (serial, worktree env):

  • Pre-fix pytest tests/ -m "level_1 and tier_a" -x -q: 217 passed; the ONLY
    failure is the new 3D regression test hitting the pre-fix NameError
    (the intended failing-first reproduction).
  • Post-fix same gate: 298 passed, 7 skipped, 4 xfailed, 1 xpassed, 0
    failed
    (skips/xfails/xpass all pre-existing).
  • Existing mover tests (test_0850, test_0750, test_0760, test_0762,
    test_0855) + new tests: 50 passed.

MPI runs not required for this item: the change is a dimension guard plus
dead-branch removal; the executable 2D path is byte-for-byte semantically
identical, so no partition-sensitive behaviour changes.

Underworld development team with AI support from Claude Code

The MMPDE mover (_winslow_mmpde) advertised "Dimension-general (d = 2, 3)"
but its 3D code path assigned signed_vol = _signed_volumes, a function that
was never implemented anywhere in the package, so any 3D invocation died
with a NameError deep inside the mover. Maintainer decision (D8) is not to
implement the 3D discretization now.

The fix raises a clear NotImplementedError ("MMPDE mesh movement is
currently 2D-only ...") at the top of _winslow_mmpde, before any metric
parsing or DM work, removes the dead 3D branch that referenced the phantom
function, and makes the docstrings honestly 2D-only (the mover docstring,
a new mmpde bullet in smooth_mesh_interior's method list, and the
_tet_cells helper note). The 2D path is untouched: the cells/signed-area
selection collapses to the identical 2D assignments.

Regression tests (tests/test_0850_mesh_smoothing.py, level_1/tier_a):
a real 3D simplex box through smooth_mesh_interior(method="mmpde") raises
NotImplementedError with the clear message (this test fails with NameError
on the unfixed build); a cdim stand-in locks the guard-before-any-mesh-work
contract; and a small 2D mmpde smoke invocation still runs and moves nodes.

Audit reference: docs/reviews/2026-07 READ-01 / REMEDIATION-WORKLIST BF-09.

Underworld development team with AI support from Claude Code
Copilot AI review requested due to automatic review settings July 3, 2026 22:54

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR makes the Huang–Kamenski MMPDE mesh mover in underworld3.meshing.smoothing honestly 2D-only, replacing a broken (and never-implemented) 3D branch that previously failed at runtime with a NameError (_signed_volumes).

Changes:

  • Add an early NotImplementedError guard in _winslow_mmpde for cdim != 2 and remove the dead 3D branch that referenced _signed_volumes.
  • Update documentation strings to clearly state that the MMPDE mover is currently limited to 2D triangle meshes.
  • Add regression tests verifying: (1) 3D raises NotImplementedError via the public API, (2) the guard triggers before any DM/metric work (via a minimal cdim stand-in), and (3) a basic 2D MMPDE call still runs.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
src/underworld3/meshing/smoothing.py Adds an explicit 2D-only guard for _winslow_mmpde, removes the broken 3D code path, and updates docstrings/method docs accordingly.
tests/test_0850_mesh_smoothing.py Adds regression coverage ensuring 3D fails with a clear NotImplementedError and that 2D MMPDE still executes successfully.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants