Rotated free-slip: prescribed-normal datum through the SNES path; one unified Newton loop (#438, #403) - #458
Rotated free-slip: prescribed-normal datum through the SNES path; one unified Newton loop (#438, #403)#458lmoresi wants to merge 9 commits into
Conversation
…rotated path (#438) - v_n = u_n now carried through the manual Newton/Picard loop: accepted iterates are kept feasible (affine snap in _impose_normal_constraint), so increments stay homogeneous (n.delta = 0) and the datum never touches the tangent, the increment RHS, the custom-FMG prolongation or the nullspace handling. - A COLD start imposes the datum through the FIRST increment's affine lift (zeroRowsColumns x/b at the rest-state tangent, exactly the linear one-shot's treatment): snapping the zero state onto the datum manufactures a boundary-strip strain state whose shear-thinning tangent cannot descend (measured: first Newton step 4 orders too large, no line-searched alpha improves). Warm starts take the exact affine snap directly. - Collective datum-activity flag in BOTH solve paths: branching on the rank-local datum_map desyncs the ranks' collective sequences at np>1 (the two zeroRowsColumns variants scatter differently; the lift skips the line-search collectives). The linear path carried the same latent pattern, tolerated only because annulus partitions happen to give every rank a piece of the outer arc. - Regression: nonlinear power-law annulus with a u.n = cos(theta) datum imposed to machine precision through genuine Newton iteration (test_1018). Tests: test_1018 serial 18/18; test_1066 np2; test_1070 serial + np2 (7); test_1071 serial. Underworld development team with AI support from Claude Code
…t bare MPI The rank-consistent datum-activity flag now rides the x-hat lift vector's collective norm (PETSc-before-MPI house rule): x-hat carries the prescribed rotated-frame datum for the zeroRowsColumns lift anyway, so one object does both jobs and the hand-rolled ownership loop collapses into _set_rows_local. Removes the mpi4py allreduce introduced in the previous commit. The deeper cure is a surface submesh (the 1D-manifold gap, #202 lineage): a boundary-field datum would make this flag a field norm and retire the hand-rolled surface bookkeeping in this layer - workstream C. Underworld development team with AI support from Claude Code
…d solves; datum via conds (#438, #403) One constraint, one path: the linear one-shot is deleted and every rotated solve runs the manual Newton/Picard loop. A linear model converges after its first increment (the cold-start affine lift IS the linear solve), so the up-front _residual_is_nonlinear probe leaves the dispatch entirely - two Jacobian assemblies saved per linear solve (test_1018: 60s -> 55s). The probe survives only as a lazy guard in the picard + pure-Newton corner, where a linear model now ignores the meaningless warmup instead of raising. - solver._rotated_use_lu becomes an increment-solver choice (direct LU per Newton increment, serial PC-free diagnostic; naive pressure pin extracted to _naive_pressure_pin with its TODO(BUG)). Verified against the iterative path to 6e-10. - One result-dict shape: reaction = F(u) always (equals A.u - b exactly for linear residuals); the linear-only A/b keys and their consumer fallback in boundary_normal_traction retire. ksp_its is always the per-increment list (test_1018 3D assertion moved to max-per-increment). - add_rotated_freeslip_bc(conds, ...) accepts the non-zero wall-normal datum (number or scalar expression, value-first; #403 item 2) and stores it in _rotated_freeslip_datum; vector values rejected. Tests and FreeSurface now use the public argument instead of poking the attribute. - FreeSurface: the penalty-fallback NotImplementedError catch in _solve_consistent is gone - consistent_constraint="strong" now runs through the SNES rotated path for nonlinear rheologies. Linear solutions change at solver-tolerance level only (agreed relaxation of bit-preservation); an occasional cheap polish increment can follow the lift when the first residual check sits at the tolerance boundary (free-surface plume wall-time unchanged). Tests: test_1018 serial 18/18; test_1066 np2; test_1070 serial + np2 (7); test_1071 serial; LU-vs-iterative and lazy-probe smokes. Underworld development team with AI support from Claude Code
…ll modes Two defects surfaced by the TI fault smoke (#438 acceptance): 1. The step-norm exit reported converged=True on tiny increments while the residual was still O(1) (a stiff power-law tangent at the regularisation floor produces tiny steps far from the solution). The exit is now VERIFIED against the problem's intrinsic scale ||F(0)||: a warm start at the solution passes; a stagnating crawl goes back through the line search and either progresses (bounded by max_it) or ends on the stall exit honestly. 2. _mode_satisfies_constraints admitted rigid-rotation modes that are PINNED by an essential BC on another boundary (it only checked the rotated constraint rows). The admitted mode was projected out of every increment RHS, leaving an irreducible residual component: Newton converged superlinearly to rel ~2e-5 and floored there (measured on the essential-inner + rotated-outer power-law annulus). Modes are now also verified as null vectors of the ASSEMBLED operator (||J.m|| against the velocity diagonal scale), which catches any pinning without enumerating BC types; the null space is built after the first Jacobian assembly to make that possible. Same fix protects the post-solve rotation-gauge removal. With the fix the same solve converges to rel 2e-13 in 11 iterations and correctly leaves the gauge in place. TI fault-bearing smoke (power-law background, weak-plane band, cos(theta) datum) now passes: 24 its to rel 6e-8, datum at the quadrature floor, sigma_nn recovery clean. Tests: test_1018 serial 18/18 (incl. gauge-removal cases), test_1066 np2 (reference unchanged - the linear-case imprint of the spurious projection is below the 1e-6 test tolerance), test_1070 serial (7) + test_1071. Underworld development team with AI support from Claude Code
…scale convergence for warm starts - FreeSurface._solve_consistent now warm-starts from the free solve's fields: the consistent solution is the free solution with a small material-boundary datum correction, and the free solve has already converged this step. Starting there keeps a power-law tangent at physical strain rates - a cold start puts it at the regularisation floor, where the Newton line search stalls at O(0.1) relative residual (measured, acceptance attempt 2). With the warm start the first acceptance step converges in 3 iterations. - The rotated loop's convergence reference is now max(r0, ||F(0)||): rtol relative to a warm start's own (small) initial residual demands ever-more absolute accuracy the better the guess (the warm-start rtol trap). The rest-state residual is the intrinsic forcing scale; cold starts unchanged (their r0 IS that scale). The step-norm verification and the non-convergence warning read the same reference. Acceptance (#438) evidence in ~/+Simulations/FreeSurface/annulus_fs_convection/b_snes_datum_acceptance/: power-law annulus FS convection with consistent_constraint="strong" through the SNES rotated path holds the material boundary at the strong-datum level (err 5.3e-3 vs penalty 3.7e-2; net flux 1.4e-4 vs 2.0e-3) at matched steps; TI fault-bearing smoke passes (24 its to rel 6e-8). Open finding recorded there: deformed-ring datum compatibility floors the interior residual at rel ~2e-3 (honestly reported unconverged; suspected arc-length-vs-FE-quadrature demean gap - the principled fix is a trace-mass-weighted demean). Tests: test_1018 18/18 serial; test_1070 serial+np2 (7); test_1071; test_1066 np2. Underworld development team with AI support from Claude Code
…ith the PETSc Jacobian checker Regroup note (#438 B-session): TI power-law under consistent_jacobian=True shows an early trajectory identical to the frozen tangent and Picard-paced convergence (24 its vs ~11 isotropic) - consistent with the dC/d(eps_II) director-orientation terms being dropped or mis-oriented in the JIT-lowered tangent, while the isotropic terms survive (isotropic Newton is superlinear through the same rotated machinery, which also argues the rotation algebra itself is transparent). Discriminating harness (native -snes_test_jacobian vs rotated directional-derivative probe, with an isotropic control) is staged in the #438 acceptance run directory; not yet run - joint item. Underworld development team with AI support from Claude Code
#457 The PETSc Jacobian checker (bounded-curvature protocol; at 1e-12 regularisation the FD reference is invalid for power-law and every model reads the same large mismatch) convicts the TI anisotropy tangent on the NATIVE path: ||J-Jfd||/||J|| ~ 2e-3-5e-3 in developed flow vs an FD-limited 4e-6 isotropic control. The rotated machinery is exonerated. Evidence and harness recorded in #457. Underworld development team with AI support from Claude Code
…inear datum test - docs/developer/subsystems/rotated-freeslip.md: the unified rotated path - constraint semantics, datum-through-Newton design (feasible iterates, cold-start lift), convergence reference scale, operator-verified null modes, parallel rules, reaction/sigma_nn hand-off. Linked from the developer index. - Changelog entry for the #438/#403 work at the conceptual level. - tests/parallel/test_1066: nonlinear (power-law) rotated datum at np>=2 - guards the collective-sequence class through the Newton loop (lift, line-search residuals, mode verification). Passes np2 and np4. Underworld development team with AI support from Claude Code
Adversarial review (pre-ready, per house practice)Ordered by how much each item should worry a reviewer. 1. The unconditional lift-step acceptance has no safety net. On a cold start with a datum, iteration 0 is accepted without any line search. For the tested rheologies the lift lands on a smooth state, but a rheology whose rest-state tangent is a bad global model (e.g. strongly pressure-dependent viscosity, or yield already active at rest) could get a first iterate far uphill, and the loop would then need the line search to walk back from a worse place than zero. Mitigations: bounded by 2. 3. Linear rotated solves are no longer bit-identical to 4. The occasional polish increment is a real cost on linear solves. When the first residual check sits at the tolerance boundary the loop pays a second (cheap, but nonzero) KSP solve. Measured: FS plume wall-time unchanged, test_1018 faster overall (probe removal wins). But a user with many marginal linear solves could see it; the mitigation (inner KSP slightly tighter than outer) was considered and deferred. 5. The nullspace mode verification depends on an assembled J. The build was moved inside the loop to guarantee that, but 6. The FreeSurface warm-start copies fields via 7. Parallel coverage is honest but not exhaustive. np2/np4 pass for both datum tests; np4 on an annulus still gives every rank a boundary segment, so the true empty-datum-rank path (a 3D cap datum at high rank counts) is exercised only by construction (collective flags), not by test. The 8. Deleted code / behaviour surface. The linear one-shot's removal takes with it: the 9. What we could not test. The 3D spherical datum (no 3D FreeSurface yet — the guard stands); TI Newton-rate claims (blocked by #457, found during this work); behaviour under Net: the riskiest items are (1) and (2), both semantic rather than correctness regressions, both documented in the subsystem page. The three fixed bugs each have a regression guard (deadlock class → np2/np4 tests; nullspace floor → the 1018 nonlinear datum test converges to tolerance, which the floor made impossible; false convergence → the TI smoke asserts the honest verdict). Underworld development team with AI support from Claude Code |
… refusal Conflict in the rotated free-slip dispatch only: development added the armed wall-clock-guard refusal (#442) around the old two-path dispatch; this branch had unified the dispatch into one Newton loop. Resolution keeps BOTH: the guard re-check (an armed guard would be silently inert on the rotated path, which runs its own Krylov loop outside self.snes) followed by the single unified call. Development's _record_convergence_status hook after the rotated report (#441 warm-start flag) auto-merged and stands. Underworld development team with AI support from Claude Code
What this is
Workstream B of the free-surface roadmap (joint session with @lmoresi): the prescribed wall-normal datum
u·n̂ = ũ_nnow runs through the full nonlinear rotated machinery, and the separate linear/nonlinear rotated solve paths are unified into one Newton/Picard loop. Closes #438's acceptance checklist and #403 items 2 & 4.Design
v_n = ũ_nexactly (an affine snap in the rotated frame) and every increment satisfies the homogeneous constraintn̂·δ = 0— the datum never touches the tangent, the increment RHS, the FMG prolongation, or the null-space handling.zeroRowsColumns(x̂, b̂)at the rest-state tangent — which is exactly the old linear path's operation sequence, and is what makes unification natural:_residual_is_nonlinearprobe leaves the dispatch (two Jacobian assemblies saved per linear rotated solve; the probe survives as a lazy guard in thepicard+pure-Newton corner). Direct LU becomes a per-increment diagnostic option. One result-dict shape (reaction = F(u); the linear-onlyA/bkeys retire). Linear solutions change at solver-tolerance level only (bit-preservation deliberately relaxed — maintainer decision in-session).add_rotated_freeslip_bc(conds, boundary, normal=)accepts the non-zero scalar datum (value-first, per the Charter); the FreeSurface manager uses it and its penalty-fallback catch is gone —consistent_constraint="strong"works for nonlinear rheologies.Three latent bugs found and fixed (each was masking the next)
datum_map; a rank owning no datum boundary nodes desyncs the collective sequences (np>1 deadlock class; latent in the linear path since the datum landed). The activity flag now rides a collective PETSc Vec norm of the lift vector._mode_satisfies_constraintschecked only the rotated constraint rows, so a rigid-rotation mode pinned by an essential BC on another boundary was projected out of every increment RHS: Newton converged superlinearly to rel ~2e-5 and floored there, irreducibly. Modes are now also verified as null vectors of the assembled operator (‖J·m‖against the velocity diagonal scale); after the fix the same solve reaches rel 2e-13 in 11 iterations and correctly leaves the gauge in place.max(r0, ‖F̂(0)‖), which also fixes the warm-start rtol trap (rtol relative to a good warm start's own small r0 demands ever-more absolute accuracy).Plus: FreeSurface's consistent solve warm-starts from the free solve's converged fields (a cold start at the power-law regularisation floor stalls at rel 0.13 while the free solve converges beside it).
Evidence
Acceptance runs in
~/+Simulations/FreeSurface/annulus_fs_convection/b_snes_datum_acceptance/(README carries the full table and attempt history):consistent_constraint="strong", matched steps: material-boundary error 5.3e-3 (strong-linear reference 7.8e-3; penalty 3.7e-2), net surface flux 1.4e-4 (penalty 2.0e-3).Tests:
test_101818/18 serial ·test_1066np2 + np4 ·test_1070serial + np2 (7) ·test_1071serial.Known limitations / follow-ups (all recorded)
TODO(BUG)retained);_eval_datuminherits the uw.function.evaluate returns wrong values for P1 fields at points exactly on cell edges (3D) #432 3D point-evaluation exposure; np4 is suggestive rather than a guaranteed empty-rank exercise (annulus partitions give every rank boundary).New subsystem documentation:
docs/developer/subsystems/rotated-freeslip.md; changelog entry included.An adversarial review follows as the first comment, per house practice. Draft until @lmoresi signs off.
🤖 Generated with Claude Code
Underworld development team with AI support from Claude Code