test: add oblique (2,1) shear-wave diagnostic with composite modal fit

Test-only. New shear_wave.py (exact field, equilibrium initializer reusing
frozen oracle constants/geometry, area-weighted composite metrics with a
2x2 Gram-matrix modal fit, late-time rate fit, preregistered assess with
max(2*control, floor) budgets). run_case.py gains --flow (default
taylor_green, unchanged receipt). oracle.py byte-identical (pinned by test).
CPU manufactured checks in test_shear_wave.py; docs record caveats.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
ClaudeandClaude Opus 5.5 committed 2026-10-19 00:16:21 +00:00
1 parent eec4677db1
commit ffff742b69
4 files changed
+550 -3

No files matched your search

+84
View File
@@ -159,3 +159,87 @@ theoretical stress-consistency certification or production-kernel change.
## Repository integration
The four Python harness files remain together under tests/validation/taylor_green, so runtime provenance hashes precisely this harness directory. Formatting changes produce a new harness identity; preparation and integrated receipts must not be mixed. All analytic definitions, numerical floors, assessment gates, sample times, and source-import assertions are unchanged. Production source is unchanged from the cd3 snapshot; these periodic tests do not waive the separate channel GPU gate.
## Oblique shear wave (test-only diagnostic, not GPU-qualified)
`shear_wave.py` reuses the frozen oracle's constants, cell centers and
geometry. `oracle.py` is byte-identical, and `test_shear_wave.py` pins its
eec4677 SHA-256. `run_case.py --flow shear_wave` selects it. The default flow
is still the frozen Taylor–Green oracle, and the default receipt is unchanged.
Convention: integer mode (2,1) on the L=N periodic root domain, so
`k = (2*pi/L)*(2,1)` points 26.565° from +x. Mode (1,2) would point 63.435°.
A wrong-mode test catches a swap between the two. Polarization is
`E = (-1,2)/sqrt(5)`, perpendicular to k:
u = U*E*sin(k.x + phi)*exp(-nu*|k|^2*t), phi = 0, p = const, rho0 = 1
Here `nu = U*N/100`, the Taylor–Green Re100 viscosity at the same N. The
initial condition is FP64 second-order equilibrium at the actual leaf
centers, with no non-equilibrium part.
Physical caveats:
1. *Finite-Mach error.* The second-order D2Q9 equilibrium has third moment
`sum_i f_eq c_a c_b c_g = rho*cs^2*(u_a d_bg + u_b d_ag + u_g d_ab)`. The
`(c.u)^2` term contributes only even moments. The continuum target also
has `rho*u_a*u_b*u_g`. At Navier–Stokes (first Chapman–Enskog) order,
the resulting stress error is proportional to `d_g(rho u_a u_b u_g)`.
For this field with uniform density, `u.grad = 0` and `div u = 0`, so
that particular term vanishes.
This does *not* show that all finite-Mach or cubic error vanishes. It
does not cover:
- higher Chapman–Enskog orders;
- lattice truncation for the oblique wavevector;
- FP32 storage;
- any density nonuniformity, which interfaces or anisotropy can create.
2. *Startup.* Equilibrium initialization omits the non-equilibrium stress.
The resulting kinetic transient lasts O(tau) steps and may shift the
in-phase amplitude. The decay rate is fitted from `ln(a_hat)` using
only samples with t* >= 0.12, which is about 1.9N root steps and much
longer than tau. This is intended to reduce startup sensitivity. It
has not been shown to cancel the bias, and that remains unverified
until measured.
Metrics are computed on ACTIVE leaf cells only, each weighted by its area
`4**-level` in root-cell units. The partition must cover the domain exactly
once. One global pressure gauge is used, never one per level.
- `a_hat`, `b_hat`: weighted least-squares fit of `u.E` onto the sin and cos
modes, solved with the 2x2 Gram matrix of the actual composite quadrature.
- `phase_drift = atan2(b_hat, a_hat)`, in radians.
- `rate_error = |rate_fit/(nu|k|^2) - 1|`, dimensionless. Rates are per root
step.
- `velocity_l2`: error relative to the exact field.
- `residual_l2`: the velocity left after subtracting the fitted mode,
relative to the exact-field norm.
- `longitudinal_l2`: the `u.k_hat` part of the velocity, relative to the
exact-field norm.
- `pressure_rel = p_rms/(A(t)^2/4)`: the gauged composite rms of
`p = (rho-1)/3`, divided by a *fixed analytic scale*.
- A²/4 is the continuum rms of the Taylor–Green exact pressure at the
same amplitude. That makes the number comparable in magnitude with TG
`pressure_l2`, but it is not that norm. TG normalizes by the discrete,
globally gauged exact-pressure norm on the composite grid.
- Exact pressure here is constant, so no relative-to-exact claim is made.
- Max and per-level values are reported for localization.
Preregistered screens (`shear_wave.assess`):
- Run set: uniform N, uniform 2N, and refined depth-2 runs at root N, with
constant and/or projected_linear explosion.
- `eps(N) = (|k| h_root)^2 = 5*(2*pi/N)^2`, dimensionless, coefficient one.
It is 0.01205 at N=128.
- Absolute screens: rate_error, max |phase_drift| (radians) and max
residual_l2 must each be <= eps. This is a preregistered diagnostic
choice of the second-order truncation scale, *not* a proven error bound.
- Existing ceilings also apply: velocity_l2 <= 0.05, mass <= 1e-5 and
pressure_rel <= 0.02.
- Budget form, as in `assess.py`:
`refined <= max(2*control_N, floor)`, with floors 0.002 for rate and
residual and 0.02 for pressure.
- The ratio to the 2N control is reported, not gated.
- A control failing an absolute screen makes the set INVALID_CONTROL. The
screens are never retuned.
Scope: one flow, one rectangle, SRT only. Two resolutions show a trend,
not an order. This does not establish placement robustness.