test: apply shear-wave review corrections
Modal magnitude R=hypot(a,b) with amplitude error and separate phase; free-intercept ln R rate fit with per-interval rates, log-fit residual, t* units and finite-positive check; spurious-pressure naming with raw rms; INVALID_CONTROL vs CONTROL_SCREEN_FAIL (refined results kept), mixed-source check, raw ratios to both controls; docs narrow the cubic-term scope, startup and placement limitations. oracle.py still byte-identical. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
ffff742b69
commit
10069feadb
3 files changed
+197
-101
No files matched your search
@@ -164,82 +164,98 @@ The four Python harness files remain together under tests/validation/taylor_gree
|
||||
|
||||
`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.
|
||||
eec4677 SHA-256. `run_case.py --flow shear_wave` selects the shear wave;
|
||||
the default flow and its receipt are the unchanged Taylor–Green path.
|
||||
|
||||
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:
|
||||
### Convention
|
||||
|
||||
Integer mode (2,1) on the L=N periodic root domain:
|
||||
- the wavevector `k = (2*pi/L)*(2,1)` points 26.565° from +x;
|
||||
- mode (1,2) would point 63.435°, and a wrong-mode test catches a swap.
|
||||
|
||||
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.
|
||||
`nu = U*N/100`, the Taylor–Green Re100 viscosity at the same N. This is an
|
||||
exact incompressible Navier–Stokes solution. 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.
|
||||
### Physical caveats
|
||||
|
||||
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.
|
||||
1. *Scope of the cubic-term argument.* The second-order D2Q9 equilibrium
|
||||
lacks the cubic third moment `rho*u_a*u_b*u_g` of the Maxwellian (Dellar,
|
||||
https://people.maths.ox.ac.uk/dellar/papers/Galilean.pdf, eq. 3). At
|
||||
Navier–Stokes order this produces a stress error proportional to
|
||||
`d_g(rho u_a u_b u_g)`.
|
||||
|
||||
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.
|
||||
For the ideal constant-density, zero-background transverse wave, k.E = 0
|
||||
makes that contracted derivative vanish. That is the only claim made.
|
||||
It does not remove other discrete or finite-Mach errors. It is not
|
||||
guaranteed once AMR introduces density, longitudinal or higher-mode
|
||||
contamination. The analytic NS field itself is exact.
|
||||
2. *Startup.* Equilibrium initialization is not the discrete shear
|
||||
eigenmode (Mei et al., https://doi.org/10.1016/j.compfluid.2005.08.008).
|
||||
- The decay rate is a free-intercept least-squares fit of ln R over the
|
||||
samples with t* >= 0.12, where `R = hypot(a_hat, b_hat)`.
|
||||
- The intercept cancels only a constant amplitude prefactor, and only
|
||||
once a single exponential dominates.
|
||||
- Per-interval rates and the maximum log-fit residual are kept, so a
|
||||
lingering transient stays visible.
|
||||
- Late sampling alone does not show that transients have gone.
|
||||
|
||||
- `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.
|
||||
### Metrics
|
||||
|
||||
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.
|
||||
Computed on ACTIVE leaf cells, each weighted by its area `4**-level` in
|
||||
root-cell units. The partition must cover the domain exactly once, and one
|
||||
global pressure gauge is used.
|
||||
|
||||
Scope: one flow, one rectangle, SRT only. Two resolutions show a trend,
|
||||
not an order. This does not establish placement robustness.
|
||||
- `a_hat`, `b_hat`: weighted least-squares fit of `u.E` onto sin/cos, using
|
||||
the 2x2 Gram matrix of the actual composite quadrature. A wrong Fourier
|
||||
mode need not project to exactly zero on this quadrature.
|
||||
- `amplitude_error = R/A_exact - 1`.
|
||||
- `phase_drift = atan2(b_hat, a_hat)`, in radians, reported separately.
|
||||
- Rates are positive (minus the fitted slope).
|
||||
- Per root step they are compared with `nu*|k|^2`. Uniform 2N uses its
|
||||
own `nu = 0.0768` at N=256 and doubled step counts.
|
||||
- In t* they are compared with `5*(2*pi)^2/Re = 1.97392088`.
|
||||
- `rate_error = |rate/exact - 1|`.
|
||||
- `velocity_l2`, `residual_l2` (velocity left after removing the fitted
|
||||
mode) and `longitudinal_l2` (the `u.k_hat` part), all relative to the
|
||||
exact-field norm. A longitudinal perturbation also raises the
|
||||
full-vector residual and the velocity L2.
|
||||
- `spurious_pressure_rms`: the raw gauged rms of `p = (rho-1)/3`.
|
||||
- `spurious_pressure_scaled`: that rms divided by `A_exact(t)^2/4`, a
|
||||
continuum reference scale. It is *not* the discrete, globally gauged
|
||||
Taylor–Green norm on the composite grid. Exact pressure is constant, so
|
||||
no relative-to-exact claim is made. Max and per-level values are kept.
|
||||
|
||||
### Preregistered screens (`shear_wave.assess`)
|
||||
|
||||
Run set: uniform N, uniform 2N, and refined depth-2 runs at root N.
|
||||
|
||||
- `eps(N) = (|k| h_root)^2 = 5*(2*pi/N)^2`: dimensionless, coefficient
|
||||
one, 0.01205 at N=128. This is a chosen screen, not a proven error bound.
|
||||
- Absolute screens:
|
||||
- rate_error, max |phase_drift| (radians) and max residual_l2 must each
|
||||
be <= eps;
|
||||
- velocity_l2 <= 0.05, mass <= 1e-5, spurious_pressure_scaled <= 0.02.
|
||||
- Budgets keep the `assess.py` form, `refined <= max(2*control_N, floor)`:
|
||||
- floors are 0.002 for rate and residual, 0.02 for pressure;
|
||||
- because the pressure ceiling and floor are both 0.02, the comparative
|
||||
pressure budget adds no constraint unless the root control exceeds 0.01;
|
||||
- raw ratios to both the root and finest controls, including raw
|
||||
pressure rms, are always reported.
|
||||
- Outcomes are kept distinct:
|
||||
- INVALID_CONTROL: a control is missing, incomplete or nonfinite, or the
|
||||
records come from mixed sources;
|
||||
- CONTROL_SCREEN_FAIL: complete, finite controls that fail a screen.
|
||||
Refined results are still computed and retained.
|
||||
- Screens are never retuned.
|
||||
|
||||
### Limitations
|
||||
|
||||
One flow, one phase and one rectangle, SRT only. The rectangle's vertical
|
||||
faces span 0.625 tangential periods and its horizontal faces 1.5, so this
|
||||
is not placement robustness. Two resolutions show a trend, not an order.
|
||||
Reference in new issue
Block a user