Fix 3D boundary reaction flux recovery - #404
Conversation
Recover pointwise traction from 3D rotated free-slip reactions by assembling a lumped triangular boundary mass and dividing nodal reactions by that mass. Support P1 traces directly and P2 traces through four-triangle facet subdivision, with global coordinate-based assembly for partition independence and a surface-mass-weighted mean gauge. Add serial and MPI regressions using the Zhong et al. l=2 internal-load shell. The corrected surface and CMB topography coefficients reproduce the reference response and remain invariant across MPI partitions. Retain focused 2D traction and flux coverage.
Adversarial review (public record) — strong core, but the P2 recovery has a structural defectThanks @gthyagi — the approach is right and most of it verifies beautifully. Full skeptic pass with live probes at np1/np2/np4 (PR branch merged onto current development, dedicated build): What HELD (verified live)
The blocker: P2 pointwise recovery is structurally wrong, and the Zhong test cannot see itOn a straight P2 triangle,
Asks before merge: (a) a consistent surface-mass solve on the P2 trace (M_boundary σ = R), or an explicit P1-only restriction with a clear raise; (b) a pointwise exact-flux box regression — P1 passes it today, P2 fails it today, and it's the test the harmonic fit can't substitute for; (c) docstring updates — Filed separately (pre-existing, exposed by the probes — not blockers here)
The core of this PR — P1 de-smear, global assembly, gauge — is exactly the missing 3D piece and worth landing promptly once the P2 story is honest. Underworld development team with AI support from Claude Code |
Replace the invalid four-subtriangle P2 lumping with the exact six-node triangular surface mass matrix and a sparse consistent solve. Add mass=auto so existing 2D and 3D P1 traces retain lumped recovery while 3D P2 selects the mathematically required consistent operator; reject explicit P2 lumping and unsupported 3D traces. Add pointwise constant-flux P1/P2 tetrahedral-box regressions in serial and MPI, including two- and four-rank partitions. Extend the Zhong l=2 validation to compare all nodes, vertices, and edge midpoints independently, removing the prior all-node cancellation blind spot. Document trace-order behavior, non-triangular limitations, analytic-normal partition guarantees, and the corrected 3D CBF behavior.
|
@lmoresi Thank you for the adversarial review. I reproduced the P2 vertex/midpoint defect and pushed Changes
Pointwise box regressionUnit-cube conduction, exact outward Bottom flux
The P2 assertion covers every vertex and edge midpoint. A separate regression verifies that explicit P2 lumping raises. Zhong degree-2 validation
The regression now checks all-node, vertex-only, and midpoint-only coefficients independently, so the previous node-count cancellation cannot pass. Serial, np=2, and np=4 results agree within Focused local validation:
Issues #407 and #408 remain separate as requested: the Zhong rotated-constraint reaction is not affected by #407, and this correctness patch retains the existing global topology reconciliation tracked by #408. |
Allow the serial and MPI Zhong l=2 rotated free-slip diagnostics to accept an optional shell cell size while retaining 0.25 as the regression-test default. Extend the standalone MPI diagnostic output with the selected cell size so manual convergence results are self-describing. This supports serial/MPI comparisons at 1/4, 1/8, and 1/16 resolution without adding costly high-resolution cases to routine CI.
|
@lmoresi Follow-up resolution sweep for the exact P2 surface-mass recovery in This is the no-self-gravity Zhong
Observations:
Validation after parameterization:
|
Adversarial re-review — round 2 (public record): the P2 fix is verified. Approving.@gthyagi — the consistent trace-mass rework is exactly right. Full round-2 findings: The round-1 defect is genuinely fixed
One genuine subtlety found — filed as #414, not a blockerOn CURVED boundaries the P2 vertex values converge only slowly: the vertex basis has zero surface mean, so vertex reactions carry only the O(h) facet-geometry error, and the (correct) consistent solve faithfully reconstructs that error. Measured on a spherical conduction probe: vertex error 93%→55% under one refinement while midpoints go 2.8%→0.7% (superconvergent). Your Zhong vertex-only fit drifts away from the reference with refinement (0.395→0.371) while the midpoint fit converges onto 0.419 — the wide test tolerances absorb this, which is fine, but consumers of pointwise σ_nn on curved boundaries should read midpoints or fitted quantities. A docstring caveat is the ask (#414). Housekeeping from the round
Merging. Thanks for the fast, correct turnaround — the four-subtriangle → consistent-mass pivot was exactly the right call. Underworld development team with AI support from Claude Code |
Delegate rotated free-slip traction recovery to the boundary-flux auto mass policy introduced by PR underworldcode#404. This selects the exact consistent surface-mass solve for 3D P2 traces while retaining lumped recovery where valid. Document the slower convergence of raw P2 vertex values on faceted curved boundaries and recommend fitted harmonic coefficients or midpoint samples for convergence studies.
…datum fixed (#421) Closes the #421 defect chain, localised by three successive np2 probes: 1. u_n was multi-valued at seam nodes: _surface_normal_velocity point-evaluated the P1 velocity at its OWN nodes, and on-vertex point location mis-locates at process seams (the documented ddt band-aid class). Fixed by direct nodal data reads (the projection has already ghost-synced) — also faster. 2. With that fixed, h_inf remained ~50% multi-valued at seams: the gathered ring holds a seam vertex ONCE PER ADJACENT RANK, and the Taubin filter's roll-stencil treats the copies as two distinct neighbouring nodes (a phantom zero-length segment), smoothing each against a DIFFERENT stencil; each rank then scattered back its own diverged copy. Fix: deduplicate the ring at construction — gather averages seam copies (identical to round-off), all ring operations (filter, tangential transport, arc-length weights, datum gauge) act on unique physical nodes, scatter expands the unique value back to every copy. Ring fields are single-valued across ranks by construction. Measured: prescribed-datum net flux at np2 1.142e-3 vs serial 1.140e-3 (was 5.75e-2, 50x worse than serial). Seam probe shows zero multi-valued ring quantities. The two datum tests are un-skipped and pass at np2 (8 passed with --with-mpi). Also: NotImplementedError guard for dim != 2 (previously a 3D run would proceed with meaningless ring ordering and a stub de-smear — silently wrong; 3D is follow-on work via PR #404's boundary mass), and the background_buoyancy docstring entry. Underworld development team with AI support from Claude Code
Plain-language plan for the post-#435 work: A (land 2D, teaching rebuild, stationarity run), B (nonlinear datum + rotated-path unification, joint session, #438/#403), C (3D, structural, builds on #404 — suggested for Thyagi), plus the deferred/tracked list. 3D is assembly work, not new mathematics: the integrator, datum, carrier and full-density h_inf are dimension-free; the 2D-only pieces and their 3D replacements are tabulated with the #421 seam-dedup lesson carried over. Underworld development team with AI support from Claude Code
…t fix, parallel datum, full-density (Boussinesq) formulation (#435) The free-surface toolkit taken from stiff-surface/small-deformation only to a validated 2D capability. Highlights (measurements in the PR thread): - Arc-length datum gauge + strong rotated material-boundary constraint: net surface flux 4.4e-2 -> 7.0e-5, rate error 6.4x better than the penalty. - Old-frame SL reach-back retired from the manager (#423): the serial T blow-up was an exponential per-cycle loop instability requiring per-step mesh motion; envelope 2.6% -> 17% deformation. Guard test on a no-free-surface reproducer. - Parallel datum fixed (#421): ring seam deduplication + direct nodal velocity reads; np2 flux matches serial to three digits; datum tests live at np2. - Full-density (Boussinesq) formulation: background_buoyancy="analytic" cancels the self-load in the recovered reaction (one sign was the defect; the CBF recovery is exact); topography relaxes at the Cathles rate and equilibria have closed streamlines. Two-reaction reference mode retained. - estimate_dt(advect_scale), deform-aware velocity CFL, 3D NotImplementedError guard, skill + roadmap docs (docs/developer/design/FREE_SURFACE_ROADMAP_2026-07.md). Nonlinear rheology runs with consistent_constraint="penalty" (strong datum through the SNES path is workstream B, #438). 3D is workstream C (#404-based). Underworld development team with AI support from Claude Code
Summary
Root cause
The previous 3D branch in
_desmear()returned the raw nodal reaction after subtracting its arithmetic mean. A finite-element nodal reaction is an integrated force, not a pointwise traction. The recovery must solveM_boundary * sigma_nn = Ror, for lumped mass,
sigma_nn[i] = R[i] / m_boundary[i].Without the surface-mass division, recovered 3D topography was mesh-dependent and nearly zero. The arithmetic mean also did not represent the surface integral gauge.
Implementation
For 3D triangular boundaries, the recovery now:
Unsupported 3D mass choices and element traces fail explicitly. The existing 2D implementation is unchanged.
Validation
Zhong et al. degree-2 isoviscous internal-load response,
ri=0.55,rint=0.775,ro=1.0, P2/P1:Focused checks:
This PR intentionally excludes the higher-level spherical-shell geoid and response postprocessing work. It contains only the boundary-flux correction and focused tests.
Context: #248