Stratified-ABL Neutral-Limit Regression¶
Status: VALIDATED (neutral-limit regression PASSES on GPU)
Run on GPU (RTX 3060, single precision, all six simulations). The regression
passes on both the single block and the 2:1-refined (multiblock)
configuration: the feature-inert neutral_limit run reproduces the feature-off
baseline to the solver noise floor in both cases. Because the multiblock run
matches its baseline to the same floor that the single-block run does, the inert
feature composes across the refinement interface (F2C/C2F/border reconstruction)
without introducing any discontinuity. See Results. This case
makes no physics claim against any external reference - it is a
self-regression: the feature-off path IS the reference.
Why this case matters¶
This is the mandatory neutral-limit regression for the stratified-ABL feature - the single most important case in the validation ladder and the one that protects every other developer’s work. A new physical capability (here the Monin-Obukhov stratified IBM ground wall model and the Boussinesq buoyancy coupling) must, with the feature off or at its inert parameter, recover the solver’s pre-feature behaviour exactly. If the feature-off path has moved, the feature has silently changed unrelated physics, and nothing else in the ladder can be trusted until that is fixed.
The stratified-ABL feature’s own development case
(examples/mo_stability_validation/mo_stability.nassu.yaml) checks the
differential sign of the stability correction (unstable fuller than stable),
but there was no committed case asserting that the inert setting is a true
no-op. This case fills that gap, on both a single block and, crucially, across a
2:1 refinement interface.
Physical description¶
A minimal half-channel ABL-like box: a flat IBM ground floor (EqLog wall model)
at \(z = 1\) in a \(64 \times 32 \times 64\) domain, periodic in \(x\) (streamwise)
and \(y\) (spanwise), no-slip at the bottom, free-slip at the top. A streamwise
body force \(F_x\) drives the flow against the wall drag, LES Smagorinsky is on,
and one coupling scalar temperature rides the shared DDF scalar path
(advected and diffused, with a mild vertical gradient from a warm floor). All
quantities are in lattice units; the setup is modelled directly on the
stratified-ABL development case so the regression exercises the identical code
path.
The regression pair¶
Two simulations that must produce statistically identical results:
Simulation |
|
Buoyancy |
Meaning |
|---|---|---|---|
|
absent |
|
pre-feature neutral path (feature OFF) |
|
|
|
feature code path ACTIVE but inert |
In
baselinethe feature is entirely off: nomo_stabilityblock, and the buoyancy is inert - \(f_\mathrm{buoy} = -\rho_0\,\beta\,(\phi - \phi_\mathrm{ref})\,g\) is exactly zero because \(\beta = 0\). The wall model is the plain EqLog log law;temperatureis a passive tracer.In
neutral_limitthe feature is present but at its inert parameter:mo_stabilitywithsurface_heat_flux = 0drives the Obukhov length \(L \to \infty\), so \(\zeta = z/L \to 0\) and the momentum stability function \(\psi_m = 0\) - the neutral log law (the schema documentssurface_heat_flux = 0as “recovers the neutral log law”). Buoyancy stays inert (\(\beta = 0\)). Themo_stabilitycode path executes but must reproducebaseline.
Multiblock variant¶
The same pair (baseline_mb, neutral_limit_mb) is run across a 2:1
refinement slab: a full \(x\)-\(y\) band at \(z \in [16, 32]\). This puts two
\(z\)-normal coarse-fine interfaces directly in the path of the vertical
temperature gradient, so the regression exercises F2C (fine->coarse),
C2F (coarse->fine spatial + temporal interpolation) and the same-level
border population reconstruction / init-borders path. This is the
highest-value composition rung: it is exactly where Nassu’s most damaging bugs
have lived (a term correct in bulk collision but omitted from border
reconstruction or the level-transfer rescale - e.g. the porous Darcy-force
sawtooth, the forked-scalar C2F bug). The inert buoyancy force and the
temperature field must stay continuous across the interface, with no per-block
sawtooth.
Validation ladder and composition matrix¶
This case fills the entire neutral-limit-regression row of the
stratified-ABL feature’s composition matrix. LES, the temperature scalar and
the IBM ground wall model are all present simultaneously in both the
single-block and the multiblock cells, so every applicable cell of the row is
covered by this one case:
| single-block | multiblock | +LES | +scalar | +IBM
neutral limit (07) | reg | reg | reg | reg | reg
reg = neutral-limit regression, covered here (feature-off / inert recovers the
pre-feature path to the solver noise floor). The X benchmark rungs of the
ladder (canonical stratified references + acceptance criteria) live in the
sibling cases 05 (vc_stratified_street_canyon) and 06
(vc_stratified_building); this case is the regression foundation they rest on.
Numerical acceptance criterion¶
The GPU solver is not bit-reproducible run-to-run (atomicAdd ordering, ~\(10^{-6}\) relative in float32), so the regression validates statistics, not instantaneous fields, and proves parity the robust way - by comparing against the solver’s own noise floor. Concretely, using the time-averaged (mean) profiles over \([10000, 20000]\) steps, \(x\)-\(y\)-averaged into \(z\)-profiles of \(u(z)\), \(\rho(z)\) and \(\mathrm{temperature}(z)\):
for each profiled quantity \(q \in \{u, \rho, \mathrm{temperature}\}\). That is:
the neutral_limit-vs-baseline difference must be the same order as a
baseline-vs-baseline rerun difference (pure solver noise). The baseline_rerun
/ baseline_mb_rerun simulations exist solely to establish that noise floor
within a single nassu run invocation.
For the multiblock variant, additionally require the temperature (and hence the inert buoyancy) field to be continuous across the \(z = 16\) and \(z = 32\) refinement interfaces to the same noise floor - no per-block sawtooth or jump in the mean field straddling the interface.
The regression fails if \(\Delta_\mathrm{feature} \gg \Delta_\mathrm{noise}\) for any profiled quantity, or if a sawtooth appears at the multiblock interface: either means the (supposedly inert) feature code path has perturbed the pre-feature physics and must be fixed before any benchmark rung is trusted.
Simulation setup¶
All values are in lattice units (modelled on the stratified-ABL development case). Single-block level-0 grid; the multiblock variants add one refinement level over the mid slab.
Parameter |
Value (lattice) |
|---|---|
Domain \((x, y, z)\) |
\(64 \times 32 \times 64\), |
Periodicity |
\(x\), \(y\) periodic; \(z\) walls (B / F) |
Bottom / top BC |
RegularizedHWBB (no-slip) / RegularizedNeumannSlip (free-slip) |
Driving force \(F_x\) |
\(1.7\times10^{-6}\) |
Relaxation time \(\tau\) |
0.51 (\(\nu = 3.33\times10^{-3}\), \(\mathrm{Ma}\) well below 0.1) |
Fluid velocity set / operator |
D3Q19 / RRBGK |
LES model |
Smagorinsky \(C_S = 0.17\) |
Ground wall model |
IBM EqLog (\(z_0 = 0.1\), |
Coupling scalar |
|
Buoyancy |
INERT (\(\beta = 0 \Rightarrow f_\mathrm{buoy} = 0\)) |
MO stability (neutral_limit) |
|
Multiblock refinement |
full \(x\)-\(y\) slab at \(z \in [16, 32]\), level 1 (2:1) |
Steps / stats window |
20000 / \([10000, 20000]\) (P5-tunable) |
There is no external reference dataset; the baseline run is the reference
(see reference/README.md).
Results¶
The comparison notebook (07_stratified_neutral_limit.ipynb) is executed
against the GPU run and presents results as PLOTS (overlaid
neutral_limit-vs-baseline profiles and a parity bar chart against the solver
noise floor), never a bare table. Measured relative-L2 profile differences:
Quantity |
Single block \(\Delta_\mathrm{noise}\) / \(\Delta_\mathrm{feature}\) |
Multiblock \(\Delta_\mathrm{noise}\) / \(\Delta_\mathrm{feature}\) |
|---|---|---|
\(u\) |
\(5.5\times10^{-7}\) / \(3.4\times10^{-7}\) |
\(1.1\times10^{-6}\) / \(8.5\times10^{-7}\) |
\(\rho\) |
\(3.0\times10^{-8}\) / \(1.5\times10^{-8}\) |
\(2.6\times10^{-8}\) / \(1.5\times10^{-8}\) |
temperature |
\(6.0\times10^{-7}\) / \(3.0\times10^{-7}\) |
\(1.8\times10^{-7}\) / \(1.8\times10^{-7}\) |
For every quantity, in both topologies, \(\Delta_\mathrm{feature} \leq \Delta_\mathrm{noise}\) - the feature-inert path differs from baseline by no more than a baseline-vs-baseline rerun does, i.e. by pure solver noise. The multiblock pair sits at the same floor as the single-block pair, so the refinement interface (F2C/C2F/border reconstruction) introduces no feature-induced discontinuity. The neutral-limit gate is met. (Table shown beneath its plots in the notebook, per the plots-not-tables convention.)