@@ -6,6 +6,110 @@ This log tracks significant development work at a conceptual level, suitable for
66
77## 2026 Q3 (July – September)
88
9+ ### The Multiplier Was Not the Whole Traction (August 2026)
10+
11+ ** ` Stokes_Constrained.topography() ` now returns the traction the boundary is
12+ actually held with** , and a new ` traction() ` exposes it directly. The momentum
13+ row carries ` λ + r(n·u − g) ` , so the bare multiplier is short by the
14+ augmented-Lagrangian share — ` r ` times the discrete constraint residual. With the
15+ viscosity-weighted default ` r = 1e4·μ(x) ` that share is a few per cent of the
16+ surface traction on a uniform-viscosity annulus and most of it across a ` 1e6 `
17+ viscosity step, where ` λ ` alone reads a tenth of the exact SolCx topography and
18+ is anti-correlated with it. ` multiplier() ` still returns ` λ ` and now says what it
19+ is not.
20+
21+ The defect survived because the validation scored a ** correlation** (0.9999)
22+ between the multiplier and the recovered normal stress. A correlation is
23+ scale-free and cannot see a systematic amplitude deficit, which is precisely what
24+ a missing share of the load is. The new guard,
25+ ` tests/test_1063_constrained_traction.py ` , scores a relative ` l2 ` against the
26+ exact SolCx surface topography and carries the bare multiplier as its negative
27+ control.
28+
29+ The corrected quantity is the consistent boundary flux: at convergence
30+ ` M_Γ(λ + r(n·u − g)) ` balances the volume residual restricted to the boundary,
31+ which is the CBF nodal load (Zhong, Gurnis & Hulbert 1993). So the multiplier
32+ route and the rotated constraint's ` boundary_normal_traction ` are the same
33+ computation, and they agree to 3–5% — inside each route's own error against the
34+ exact answer.
35+
36+ Documentation: ` docs/advanced/curved-boundary-conditions.md ` now writes the
37+ penalty free-slip recipe against ` mesh.boundary_normal ` rather than ` mesh.Gamma ` .
38+ A penalty against the per-facet normal over-constrains the shared nodes and does
39+ not converge — measured on an annulus at coefficient ` 1e6 ` , the velocity error
40+ stays at 0.60 and the surface-stress error grows from 0.21 to 0.26 as the mesh is
41+ refined, while the leak reads 1e-5 throughout. (underworld3 #607 , #608 , #614 )
42+
43+ ### A Singular Recovery Mass, Mistaken for a Penalty Defect (August 2026)
44+
45+ ** The grad-div penalty default stays off** , but the reason it was held off turned out to
46+ be a defect somewhere else entirely (#633 ) — so the objection that had blocked it is gone,
47+ and a different one took its place.
48+
49+ With the penalty at 10, the spherical dynamic topography recovered from the rotated
50+ free-slip reaction dropped 28% at * vertices* while the facet-integrated value stayed
51+ correct. The natural reading — that grad-div augmentation corrupts the de-smearing from
52+ reaction loads to pointwise stress — was wrong.
53+
54+ The de-smearing mass for a 3-D ** P2 triangular** trace has vertex rows that sum to
55+ ** exactly zero** . Those rows annihilate a constant, so solving ` M σ = R ` amplifies any
56+ perturbation of the nodal load at vertices by O(1) — and, being an instability rather
57+ than a discretisation error, does so independently of mesh resolution. The recovery was
58+ already 7.6% low with no penalty at all; the penalty only made it large enough to fail a
59+ test whose 12% tolerance had been hiding it.
60+
61+ The discrimination needed a case that was curved but not 3-D. A 2-D annulus reproduces
62+ the signature exactly and then parts company under refinement: its error falls ~ O(h²)
63+ while the shell's stays flat at ~ 0.28 over a 3.2× node-count range. The 2-D P2 ** line**
64+ mass has positive vertex row sums, which is why 2-D never showed the defect and why
65+ dimension, curvature and the rotated constraint were all red herrings.
66+
67+ - The zero-mean P2 vertex basis was ** already known and documented in #414 ** , which
68+ recorded the same drift-away-under-refinement we re-measured here. Its mechanism is
69+ the sharper one and is adopted: because the vertex basis has zero surface mean, the
70+ vertex reaction carries essentially only the O(h) facet-normal/geometry error, and the
71+ consistent solve * faithfully reconstructs that error* — it is not amplifying noise.
72+ What #633 adds is the separation from the grad-div penalty (which was blamed for it)
73+ and the fix below, which is #414 's own unactioned recommendation (2).
74+ - So ` mass="auto" ` stops asking. On a 3-D P2 trace it now takes the ** consistent** solve,
75+ keeps its superconvergent midpoints, and ** reconstructs the vertices from them** : the
76+ three midpoints of a facet determine a unique linear function, so a vertex reads its
77+ two adjacent midpoints and subtracts the opposite one, averaged over incident facets.
78+ Worst-node error against the analytic coefficient, over cellSize 0.25 → 0.11:
79+
80+ | | 0.25 | 0.20 | 0.16 | 0.13 | 0.11 |
81+ | ---| ---| ---| ---| ---| ---|
82+ | surface, P1-projected | 0.041 | 0.026 | 0.018 | 0.013 | 0.008 |
83+ | surface, reconstructed | 0.016 | 0.012 | 0.012 | 0.003 | 0.004 |
84+ | CMB, P1-projected | 0.116 | 0.067 | 0.047 | 0.030 | 0.025 |
85+ | CMB, reconstructed | 0.094 | 0.058 | 0.043 | 0.024 | 0.015 |
86+
87+ Better at every resolution on both boundaries, by 1.8x to 4.9x, and converging. The
88+ simpler P1-projected recovery stays available as ` mass="p1" ` — it is sound, it just
89+ discards the good data along with the bad.
90+ - ` FreeSurface ` already used the P1-projected recovery in 3-D, so production dynamic
91+ topography was never affected. The exposure was ` mass="auto" ` .
92+ - The spherical topography test is refined (cellSize 0.25 → 0.13) and its tolerances
93+ tightened from 0.10/0.12 to 0.01/0.05, set from measured discretisation error with
94+ ~ 2× headroom, and now assert every node class rather than the aggregate — the failure
95+ was confined to one class and an aggregate assertion passed straight through it.
96+ - Filed #637 : 3-D recovery accepts only P1/P2 triangular traces, so dynamic topography
97+ has exactly one supported discretisation there and cannot be cross-validated. That
98+ blocked the P3/hex arm of this investigation.
99+ - ` Stokes.DEFAULT_PENALTY ` was flipped to 10 on the #625 evidence and then ** reverted** .
100+ Three tier-A/B tests fail at 10 and pass at 0, and the same three run ** 8.3x slower**
101+ (9.27 s to 76.92 s, warm cache both ways). The #625 win needs an FMG hierarchy; without
102+ ` refinement>=1 ` the velocity block falls back to GAMG, which is where grad-div
103+ augmentation drives the solve into its iteration cap. The default path is the one
104+ without a hierarchy, so the default serves it; set ` penalty=10 ` explicitly where FMG
105+ is available.
106+ - Two of those three failures are not penalty defects. The Nitsche free-slip leak
107+ (1.234e-4 against a 1e-4 bound) is augmentation perturbing a * weakly* imposed
108+ constraint — a strong rotated constraint is untouched. The swarm one exposed #641 :
109+ ` evaluate ` returns −0.4976 for ` sqrt((E**2).trace()/2) ` at in-domain points near the
110+ lid-corner singularity, at ` penalty=0 ` as well; the penalty merely moved an accumulated
111+ total across zero.
112+
9113### The Free Surface Reaches the Spherical Shell (July 2026)
10114
11115** ` uw.systems.FreeSurface ` now runs in 3D on a spherical shell** — the same
0 commit comments