A conserved scalar carried on a wind while it spreads.
The ForgeGIS™ twin engine’s transport operator has something most simulation code never gets: a closed-form external truth. Act I holds it against the analytic Gaussian solutions and reports the errors to the decimal. Act II takes it to the coast — one hypothetical release, paused mid-event, forked five ways off a single anchor — with the divergence read off the conservation ledger. Every claim on this page is checked against the recordings.
What the units mean, and where the model stops being literal. Worth two minutes before the charts.
windSpeed·Δt/substeps ≤ 1 enforced by refusal rather than
clamping. So read shapes, ratios and conservation bookkeeping — never
“concentration at 3 PM.”
Three runs on a synthetic flat world — no terrain, because the operator is deliberately terrain-free in v1 — registered directly against the twin API and read back through the same endpoints the Studio panel uses: exact cell values and mass-weighted moments, never pixel luminance. The operator under test is corner-transport upwind advection plus explicit five-point diffusion, operator-split, substepped, behind closed walls.
One bump, no wind, closed walls, five sampled ticks of the same run. The core dims and the halo widens — and the total never changes. Both of those are laws with closed forms, and the run is held to both.
slopeX 0.999995, slopeY 0.999995expected2D = 1 ± 2%|slopeX − slopeY| = 4.08e-8expected< 1e-3 · 2Dworst per-epoch relative deviation 2.103e-8expected< 1e-5 (float32 rounding)e0 4a3658fd · e20 eee871ba · e40 9d4ec274 · e59 c365c06d — all equalexpectedsame sha256 per epochA continuous source in a steady wind, run to steady state. The Gaussian plume has three signatures, and each is read off the final frame’s raw cells rather than fitted to them: column mass exactly equal to the injection (conservation), width growing linearly downwind (the width law), and the centerline falling as 1/σy — the 1/√x law.
At CFL = 1 the advection pass is an exact one-cell shift, which is what lets the steady plume be held against the pure-diffusion Gaussian with no numerical-diffusion correction applied anywhere.
col d=40: 2.0000 · col d=70: 1.9998expected2 ± 2%Δσy² = 7.4721expected7.5 ± 10%C(40)/C(70) = 1.3245expectedσy(70)/σy(40) = 1.3201 ± 10%NRMS 0.20% @ d=40, 0.10% @ d=70expected≤ 5% of peakA hypothetical release at a point on the coast — no real facility; the coordinates are a stage, not a scenario — carried inland on a 20° wind at 3 cells per tick. At epoch 20 the run pauses, and the operator’s question is the one that actually gets asked in a room: which way does the sky go, and how big is the source really? So the run forks five sibling branches off that one anchor: a wind-shift through the panel’s fork form, a three-branch wind-direction fan, and a 10× source fork through the API.
The what-if form opens on the paused branch and exposes exactly what is forkable: the twin was
registered with windSpeed, windDirDeg and sourceRate as
declared constants, and that is precisely what makes them fork knobs. Here the wind direction is
backed 30°, from 20° to −10°. Nothing else is touched.
The note under the fields states the contract the whole capability rests on:
branches differ by parameters only; the fork anchors where this branch paused. The status
line reads main: PAUSED @ epoch 20, and that is the anchor every one of the five
siblings inherits.
windDirDeg is being taken from 20° to −10° for the
branch.
Both frames are epoch 39 in two worlds that share every byte of history to epoch 20 and nothing after it.
Left, the baseline track runs inland to the north-northeast. Right, the branch after the wind backs 30°: the same source, the same history, a plume that leans almost due north and misses everything the baseline crossed. The only difference between these two frames is one number, changed once, 19 epochs earlier.
windDirDeg + sourceRate + windSpeed fields presentexpected3 fields5 forks created — wind −10°, 320°, 50°, 80°, source 10×expectedwind-shift + 3-fan + 10×-rate, all siblings of timeline 0t1←0@20 t2←0@20 t3←0@20 t4←0@20 t5←0@20expectedall ←0@20measured 1367.998 vs closed form 1368.000 @ shared epoch 39expectedequal to 1%baseline 1.713e-1 vs backed-wind 5.694e-6 at epoch 39expectedshifted < 25% of baseline
windDirDeg=−10 @20 and the note diverged from main at epoch 20. The thumbnail
row underneath is the n-up replay: every branch rendered at the one cursor epoch, so worlds are compared
at the same moment rather than from memory.
The limits are part of the result. A validation that hides its regime is not a validation.
Operational plume work belongs to HPAC, HYSPLIT and AERMOD — models with turbulence closures, stability classes, source physics and decades of field calibration. This page is none of that. It demonstrates that the twin engine’s transport is exactly the equation it claims to solve — the property those models assume of their own solvers — and that the twin contract holds around it.
No met data, no sea-breeze cycle, no boundary layer. That is exactly what makes the wind-shift fork honest: it is a parameter study over an idealized field, not a forecast for anywhere.
v1 transport ignores topography entirely, and the domain edge is a closed wall — mass that reaches it piles up rather than leaving. Validation runs are sized so nothing reaches a wall, and the conservation check depends on the walls being closed.
Corner-transport upwind is first-order: off the CFL = 1 axis it adds numerical diffusion with a known closed form. The validation runs sit where that term is exactly zero; the Act II worlds run where the extra spreading is real but small — and disclosed, not hidden.
Display settings on the screenshots are disclosed and display-only: a shallow boost, because the 10× fork’s source otherwise dominates the shared colour ramp, and a display floor at 0.1% of the ramp, because a diffusing scalar stays float32-nonzero far past anything meaningful and that underflow halo would paint as an opaque disc that reads like a footprint. The floor is a fraction of the ramp, not a threshold of concern — the ledger is untouched by either.
The full technical showcase carries the blocks this page condenses — definition hashes, run identifiers, every recorded API exchange, and the Java probes that pin the same cards cell-by-cell. Seaglass Foundry™ is happy to walk an evaluator through it.
rich@seaglassfoundry.com