M6d: axisymmetric relief, and reconciling the docs with the gates - #2
Merged
Conversation
M6c's G7 is ungated, and the spec justifies that with one omission: "a planar 1-D code has no radial relief ... it is the one effect the geometry has removed by assumption". This puts the effect back. src/euler2d.rs is planar/axisymmetric Euler on annular cells, reusing euler1d's HLLC rather than carrying a second copy: a sweep packs (rho, rho*u_par, E - rho*v_t^2/2) into the 1-D state, and the transverse flux comes back as F_rho*v_t with the upwind side read off sign(F_rho). Both identities are exact. The area-weighted form means the 1/r never appears in the code at all -- the axis interface has zero area, and the geometric source is written as the same floating-point expression as the pressure part of the flux difference, so a radially uniform state is a bit-exact fixed point. That is what lets G9 assert equality rather than a tolerance: the planar 2-D solver reproduces Euler1d BIT FOR BIT over 240 cells and 40 steps. The M6c lsd artifacts are byte-identical to a baseline taken before the first line of code. Sedov-Taylor lands as the repo's first multidimensional anchor. xi_0 is DERIVED here from the energy integral rather than quoted -- 1.03278 against the published ~1.033 -- so the literature value is a cross-check instead of an input. Its profile is put back into the Euler PDEs, where the residual is 6.9e-5 and falls as the finite-difference step squared; that verifies the hand derivation, not just the arithmetic. Gates: G9 bit-identical; G10 exponent 0.38628 vs 2/5 with level and peak compression gated as trends under refinement (a spherical blast's spike is one or two cells wide at any affordable mesh); G11 1.861/1.964 against a split-source contrast at 1.030/1.155; G12 <1e-13 with radial momentum deliberately NOT conserved and an escape-flux leg; G13 2.99e-7 -> 3.12e-8 against 3.02e-6 for an even-parity axis; G14 3.1e-13 in the smooth window; G16 S^0.34666 against the parameter-free 1/3. THE RESULT (G15, pinned). Radial relief costs delta = 0.230 of the front speed at R_b*alpha = 3.2 and 0.305 at 1.6, monotone in beam radius, with the wide-beam limit itself within 1% of Raizer. It is pinned as a BAND of +-13%, and that width is measured rather than chosen: grid +6% on halving dx, seed -7% at a 1x rather than 2x CJ-pressure seed, ignition threshold +-8% over a 4x sweep. Pinning a third digit would assert a precision three separate knobs say is not there. Shown not to be a boundary effect: 21.1/21.3/21.3% at domain radii of 3/5/8 beam radii. So relief is real and it is NOT the whole ~2x gap to measurement. G7 stays ungated -- but now for one reason only, the missing dataset, rather than because the geometry removed the physics. THE UNLOOKED-FOR RESULT. The modelled front is transversely unstable. A radially uniform run diverges exponentially from the 1-D column out of round-off, reaching 3% by M6c's settle. Three measurements say it is physical rather than a defect: it is bit-identical in planar and axisymmetric geometry, so it is not the geometric source; it is amplitude-proportional, a 1e6x larger seed giving a 1e6x larger early response; and it saturates at |u_r| ~ 200-400 m/s whatever the seed. Linear growth to nonlinear saturation is the mechanism behind the cellular structure real detonations have. A planar solver structurally cannot show it. That forced a change the spec did not anticipate: delta is measured against the wide-beam 2-D run, not the 1-D column. The instability is present at every beam radius including infinite, so a 1-D reference would report it as relief. Three defects the gates caught, each recorded with its before-number. Ghost cells borrowing a neighbour's face areas leaked 3.3e-4 of the mass -- a reflective wall is only exact when the ghost's metric mirrors too. The Hancock predictor built its geometric source from face rather than cell pressures, which is well-balanced and wrong: expanded against the flux difference the pressure terms cancel identically, deleting the gradient from the predictor, and it cost an order (0.86/1.12 against planar's 1.71/1.89). And G13's first entropy measure was reading the shock rather than the axis -- the broken-parity run scored LOWER than the correct one, which is what exposed it. Also: the lsd2d CLI case and scripts/render_lsd2d.py (the field mirrored about r = 0, so an axis artifact would show as a seam down the centre), MODELS.md ledger rows and census, and the M6C_SPEC amendments retiring the two NOT-in-scope bullets this milestone closes. Suite 219 -> 243, 0 ignored. Added CI time is ~45 s, above the ~25 s aimed for; G14 and G15 are genuine coupled runs and further trimming would mean dropping a leg rather than shrinking a grid. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
MODELS.md has been written append-only: each investigation added a section and left the paragraphs above it describing a model that no longer ships. The claims ledger was kept current, so the drift hid underneath a table that looked right. Section M6a said the seed was one electron in the focal volume and the multiphoton source off by default -- both retired on 2026-07-31, the seed is q/nu_att and PPT is on. It quoted n = 0.095 from the retired mean-trajectory closure, called the I_thr(p) slope gate RED five weeks after it went green, carried Chylek local exponents of 1.951/1.047/0.170 against a current 0.501/0.857/0.386, and still summarised M6a as "falsified against air on both axes" when the low-pressure branch is now 1.17x. That prose is rewritten to the current model. The superseded narrative was already in M6A_SPEC.md under its own Superseded headings, so it is pointed at rather than retold, and the section loses 89 lines. The same drift had reached the source. breakdown0d.rs documented with_ppt_mpi as off by default (it is on), with_seed_density's default as 1/V_focal (it is the ambient background), and the analytic-limits gate said T&T's measured 0.33 sits "outside this interval entirely" -- the gap that closed on 2026-07-30. validation.rs's own doc comment quoted an envelope of [0.183, 0.407] and a centre of 0.279 while its assertions twelve lines below pin [0.174, 0.382] and 0.264. Comment changes only; no behaviour moved. The suite goes 243 -> 245, both additions being the doc gates below. AUDIT. All 122 ledger rows were then checked against the assert! in the gate each one names. Three carried stale numbers -- Chylek's low-pressure branch, the wavelength ratio, the cascade bracket -- and row 134 quoted the two closure values from before the closure change. Four rows that looked wrong turned out to be right: several gates deliberately run seeding_suppressed to isolate one change, so a number that disagrees with the shipped default can be a correct isolated measurement rather than a stale one. M1-M4, M6a.2, M6c and M6d rows all match their gates. THE CENSUS WAS WRONG, and nothing could catch it. The line claimed 118 rows (80 verified, 10 validated, 16 pinned, 12 ungated) against an actual 122 (83/10/17/12). CONTRIBUTING requires it to move with the row it describes; prose cannot fail, so it did not. tests/docs.rs now parses the ledger, counts by status, and fails printing the corrected line; a second gate asserts every row carries one of the four statuses, since a typo would silently skew the count. Both were made to fail before being trusted -- reintroducing the 118/80/16 census reproduces the exact drift. M6c prose carried the same thing outward. Its G7 entry still justified being ungated by "a planar 1-D solver has no radial relief", the excuse M6d retired by modelling relief and pinning it at delta = 0.230. The lsd demonstration run quoted a threshold of 1.14e16 that "does not fall with pulse length" when it is 8.815e15 at 6 ns converging to 6.745e15 -- a bounded 1.31x fall, asymptotic rather than flat. M6a's ungated level appeared as 4.8-7.0x in five places against a pinned 3.90-4.69x. And "the threshold moves by 4% over a 500x range of spot radius" was ungated prose in two files; measured, it is 6%. The demonstration-run figures were checked by running the case rather than by trusting the text: D = 5400.7 vs Raizer 5390.7 (+0.185%), budget 1.26e-16, tau = 374.2, alpha = 6.753 1/m at 1.06 um and 1.084e3 at 10.6 um. All matched. M6C_SPEC's copy of the threshold paragraph is amended in place with a dated note rather than rewritten, because the shape of the claim changed and the spec records what the milestone landed believing. The two-stage argument it supports is untouched: a bounded fall to a floor is still an intensity criterion, not a fluence one. README's milestone table is compressed from 30 KB to 17 KB. One cell held 10,305 characters of M6a narrative, which renders as an unreadable column on GitHub and duplicated material that MODELS.md and M6A_SPEC.md both carry. Every measured gate number and every ungated/pinned flag stays, per CONTRIBUTING; the chronological narrative goes. WHAT IS STILL NOT GATED. The census gate catches structural drift only. A row whose prose quotes a stale slope is checked by nobody -- the ground truth for any such number is the assert! in the gate it names, which CONTRIBUTING now says in as many words. Mechanising that would mean the ledger emitting numbers rather than quoting them. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Two commits: the M6d milestone, and a docs reconciliation that came out of reviewing it.
M6d — axisymmetric gas dynamics and radial relief (
8c6732e)M6c's G7 is ungated, and its spec justified that with one omission: "a planar 1-D code has no radial relief … it is the one effect the geometry has removed by assumption." This puts the effect back and measures it.
src/euler2d.rsis planar/axisymmetric Euler on annular cells, reusingeuler1d's HLLC rather than carrying a second copy: a sweep packs(ρ, ρu_∥, E − ½ρv_t²)into the 1-D state and the transverse flux comes back asF_ρ·v_twith the upwind side read offsign(F_ρ). Both identities are exact. The area-weighted form means the1/rnever appears in the code — the axis interface has zero area, and the geometric source is written as the same floating-point expression as the pressure part of the flux difference, so a radially uniform state is a bit-exact fixed point. That is what lets G9 assert equality rather than a tolerance.Verification: G9 planar limit reproduces
Euler1dbit for bit over 240 cells × 40 steps; G10 Sedov–Taylor exponent 0.38628 vs the exact 2/5, level and peak compression gated as trends under refinement; G11 1.861/1.964 against a split-source contrast at 1.030/1.155; G12 conservation to <1e-13 with radial momentum deliberately not conserved plus an escape-flux leg; G13 axis entropy defect 2.99e-7 → 3.12e-8 under refinement against 3.02e-6 for an even-parity contrast; G14 wide-beam limit reproduces the 1-D column to 3.1e-13.Sedov–Taylor is the repo's first multidimensional anchor, and
ξ₀is derived from the energy integral rather than quoted — 1.03278 against the published ≈1.033, so the literature value is a cross-check instead of an input.The result (G15, pinned): radial relief costs
δ = 1 − D/D_wide= 0.230 of the front speed atR_b·α= 3.2 and 0.305 at 1.6, monotone in beam radius. Pinned as a band of ±13 %, and that width is measured rather than chosen: grid +6 %, seed −7 %, ignition threshold ±8 %. Shown not to be a boundary effect (21.1/21.3/21.3 % at 3/5/8 beam radii). So relief is real and is not the whole ~2× gap to measurement — G7 stays ungated, but now for one reason only, the missing dataset.The unlooked-for result: the modelled front is transversely unstable, growing cellular structure out of round-off, amplitude-proportionally, saturating at |u_r| ≈ 200–400 m/s, identically in planar and axisymmetric geometry. A 1-D solver structurally cannot show it, and it had to be separated from relief before the relief number meant anything — which is why
δis measured against the wide-beam 2-D run and not against the 1-D column.Docs reconciliation (
36f15de)Reviewing the above turned up that
MODELS.mdhas been written append-only: each investigation added a section and left the paragraphs above it describing a model that no longer ships. The claims ledger was kept current, so the drift hid underneath a table that looked right.§ M6a prose said the seed was one electron in the focal volume and the multiphoton source off by default (both retired 2026-07-31 — the seed is
q/ν_attand PPT is on), quotedn = 0.095from the retired mean-trajectory closure, called theI_thr(p)slope gate RED five weeks after it went green, and carried Chylek local exponents of 1.951/1.047/0.170 against a current 0.501/0.857/0.386. Rewritten to the current model; the superseded narrative was already inM6A_SPEC.mdunder its ownSupersededheadings, so it is pointed at rather than retold (−89 lines).The same drift had reached the source.
breakdown0d.rsdocumentedwith_ppt_mpias off by default (it is on) andwith_seed_density's default as1/V_focal(it is the ambient background);validation.rs's doc comment quoted an envelope of[0.183, 0.407]while its assertions twelve lines below pin[0.174, 0.382]. Comment changes only — no behaviour moved.Audit. All 122 ledger rows were checked against the
assert!in the gate each names. Three carried stale numbers; four that looked wrong turned out right, because several gates deliberately runseeding_suppressedto isolate one change. M1–M4, M6a.2, M6c and M6d rows all match their gates.The census was wrong and nothing could catch it — the line claimed 118 rows (80/10/16/12) against an actual 122 (83/10/17/12).
tests/docs.rsnow parses the ledger, counts by status, and fails printing the corrected line; a second gate asserts every row carries one of the four statuses. Both were made to fail before being trusted.M6c prose carried the same outward: G7 still justified by the excuse M6d retired; the
lsddemo quoting a threshold of 1.14e16 that "does not fall with pulse length" when it is 8.815e15 at 6 ns converging to 6.745e15; M6a's ungated level as 4.8–7.0× in five places against a pinned 3.90–4.69×. The demo figures were re-checked by running the case:D= 5400.7 vs Raizer 5390.7 (+0.185 %), budget 1.26e-16,τ= 374.2 — all matched.M6C_SPEC's copy of the threshold paragraph is amended in place with a dated note rather than rewritten, because the shape of the claim changed and the spec records what the milestone landed believing.README's milestone table is compressed 30 KB → 17 KB; one cell held 10,305 characters. Every measured gate number and every ungated/pinned flag stays, perCONTRIBUTING.Gates
All four pass locally, in order:
cargo fmt --all -- --check,cargo clippy --all-targets --all-featuresunderRUSTFLAGS="-D warnings",cargo build --all-targets,cargo test— 245 passed, 0 failed, 0 ignored.Known limitation
The census gate catches structural drift only. A row whose prose quotes a stale slope is checked by nobody — the ground truth for any such number is the
assert!in the gate it names, whichCONTRIBUTINGnow says explicitly. Mechanising that would mean the ledger emitting numbers rather than quoting them.🤖 Generated with Claude Code