From 2459113d866172b260a4c6ee348c5a3ad4398ffa Mon Sep 17 00:00:00 2001 From: logan-nc Date: Wed, 8 Jul 2026 13:43:36 -0400 Subject: [PATCH 01/10] ISLANDS - NEW FEATURE - Add Krylov.jl dependency for the M2 Newton-Krylov solver Matrix-free GMRES backend for the L0 solve (design docs/src/islands/design/04-numerics.md $5, $9). Co-Authored-By: Claude Opus 4.8 (1M context) --- Project.toml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Project.toml b/Project.toml index 31cd4deb..3d538155 100644 --- a/Project.toml +++ b/Project.toml @@ -18,6 +18,7 @@ ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" HDF5 = "f67ccb44-e63f-5c2f-98bd-6dc0ccc4ba2f" IMASdd = "c5a45a97-b3f9-491c-b9a7-aa88c3bc0067" JLD2 = "033835bb-8acc-5ee8-8aae-3f567f8a3819" +Krylov = "ba0b0d4f-ebba-5204-a429-3ac8c609bfb7" LaTeXStrings = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f" LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" OrdinaryDiffEq = "1dea7af3-3e70-54e6-95c3-0bf5283fa5ed" @@ -48,6 +49,7 @@ ForwardDiff = "1.4.1" HDF5 = "0.17.2" IMASdd = "8" JLD2 = "0.6.3" +Krylov = "0.10.8" LaTeXStrings = "1.4.0" LinearAlgebra = "1" OrdinaryDiffEq = "6.102.0" From f577356391188e3bf22a1cfac3892a42a51c14c8 Mon Sep 17 00:00:00 2001 From: logan-nc Date: Wed, 8 Jul 2026 14:50:28 -0400 Subject: [PATCH 02/10] ISLANDS - NEW FEATURE - M2 L0 solve machinery: solvers, species, frames, fields, moments MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Land the Level-0 solve structure (design 03 §1-3, 04 §3-5; M2 contract), every physics coefficient a supplied [VERIFY]-gated parameter — no literal in src/: - solvers/Solvers.jl: matrix-free Newton-Krylov (Krylov.jl GMRES on a preallocated ForwardDiff JVP operator; Eisenstat-Walker forcing; backtracking line search; convergence on both norm and max-norm per 04 §5), YBlockJacobi physics-block preconditioner skeleton with TSVD-regularized pencil solves (the explicit y_c treatment of 04 §3), dense tiny-grid debug Jacobian, and a pseudo-arclength continuation scaffold with fold detection from day one. - species/Species.jl: Species{AbstractBackground}, Maxwellian/SlowingDown, Bulk/Trace roles, validation + trace-criteria check (warn, never degrade) — the D3 first-class species plumbing (02 §1). - frames/Frames.jl: Level0Parameters input vector (01 §5) and the frame conversion FORMS with every sign/normalization a NaN-defaulted gated FrameConvention field — an un-cleared convention poisons results instead of guessing (QUESTIONS Q3). - fields/Fields.jl: Q(Ω)/h(Ω) flattened-electron closure structure (prefactor supplied), the coefficient-free A7 identity ⟨∂²h/∂x²⟩_Ω = 0, and the NaN-gated ElectronClosure constant set. - moments/Moments.jl: J̄_∥ assembly from charge-scaled weighted moments, Δ_cos/Δ_sin projections with REQUIRED gated prefactors (ψ̃ open [VERIFY], sin normalization unpinned — QUESTIONS Q4), Ω label + ⟨·⟩_Ω average + channel-split diagnostics (pinned half-width convention). - operators/: PitchAngleDiffusion in mimetic divergence form (exact discrete particle conservation + entropy sign, ladder A4), FarFieldConditions matching BCs (never bare Neumann, 01 §3), weighted_moment!, flat-index helpers; IslandGrid now records y_c for the A8 monitor. - verify/: solve-level MMS + zero-drive configurations (A5/A1-solve) and the yc_block_sigma_min conditioning monitor (A8, the L23 §4.2 silent-noise regression tripwire). All new kernels pass a --check-bounds=yes run (M1 lesson). Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_016pUwoFRo9a5AjF8HuwcZMr --- src/Islands/Islands.jl | 24 +- src/Islands/fields/Fields.jl | 143 ++++++++++++ src/Islands/frames/Frames.jl | 119 ++++++++++ src/Islands/moments/Moments.jl | 133 +++++++++++ src/Islands/operators/Operators.jl | 177 +++++++++++++- src/Islands/phasespace/PhaseSpace.jl | 15 +- src/Islands/solvers/Solvers.jl | 331 +++++++++++++++++++++++++++ src/Islands/species/Species.jl | 170 ++++++++++++++ src/Islands/verify/Verify.jl | 116 +++++++++- 9 files changed, 1209 insertions(+), 19 deletions(-) create mode 100644 src/Islands/fields/Fields.jl create mode 100644 src/Islands/frames/Frames.jl create mode 100644 src/Islands/moments/Moments.jl create mode 100644 src/Islands/solvers/Solvers.jl create mode 100644 src/Islands/species/Species.jl diff --git a/src/Islands/Islands.jl b/src/Islands/Islands.jl index f6693c97..9fec2f9e 100644 --- a/src/Islands/Islands.jl +++ b/src/Islands/Islands.jl @@ -19,20 +19,26 @@ milestone M1 proceeds. module Islands # Submodule layout follows docs/src/islands/design/03-architecture.md §1. -# M1 lands the discretization + operator-stack skeleton + verification harness; -# the remaining submodules (species, frames, fields, moments, solvers) land as -# later milestones proceed. +# M1 landed the discretization + operator stack + MMS/AD harness; M2 lands the +# L0 solve machinery (species, frames, solve, fields, moments) as gated +# structure. Remaining design dirs (geometry/, closures/, io/) arrive with the +# milestones that need them (L2/L4/M2-io). include("phasespace/PhaseSpace.jl") # grids (x, ξ, λ→y, E, σ), layer-clustered maps +include("species/Species.jl") # Species, backgrounds, roles (D3) +include("frames/Frames.jl") # THE frequency/frame conversion module (gated forms) include("operators/Operators.jl") # the AbstractTerm stack + residual assembly -include("verify/Verify.jl") # MMS + AD-vs-FD JVP harness (ladder A1, A2) -# include("species/Species.jl") # Species, backgrounds, roles (M2+) -# include("frames/Frames.jl") # THE frequency/frame conversion module (M2+) -# include("fields/Fields.jl") # Φ̃ quasineutrality (A_∥ Ampère at L3) (M2+/L3) -# include("moments/Moments.jl") # Δ_cos, Δ_sin, profiles, channel decomps (M2) -# include("solvers/Solvers.jl") # Newton–Krylov, continuation, trace pass (M2) +include("fields/Fields.jl") # quasineutrality closure structure, h(Ω)/Q(Ω) +include("moments/Moments.jl") # J̄_∥, Δ_cos/Δ_sin projections, ⟨·⟩_Ω diagnostics +include("solvers/Solvers.jl") # Newton–Krylov, preconditioner, continuation +include("verify/Verify.jl") # MMS + AD-vs-FD JVP harness, y_c monitor import .PhaseSpace +import .SpeciesLists +import .Frames import .Operators +import .Fields +import .Moments +import .Solvers import .Verify end # module Islands diff --git a/src/Islands/fields/Fields.jl b/src/Islands/fields/Fields.jl new file mode 100644 index 00000000..a050d988 --- /dev/null +++ b/src/Islands/fields/Fields.jl @@ -0,0 +1,143 @@ +""" + Fields + +The Level-0 field-equation layer (design `01 §3`, `03 §1`): quasineutrality is +the only field equation at Level 0 (Ampère arrives at Level 3). The residual +term itself lives in `Operators.Quasineutrality`; this module provides the +closure *structure* around it: + + - the island-geometry functions `Q(Ω)`, `h(Ω)` of the flattened-electron + (WCHH96-class) closure — implemented as **structure with a supplied + prefactor** (the physics prefactor `w_ψ/2√2` is `[CHECKED]`-uncleared, + QUESTIONS Q3); + - the coefficient-free consistency identity `⟨∂²h/∂x²⟩_Ω = 0` (ladder A7 — + kokuchou's unit set, which caught inherited DK-NTM bugs); + - [`ElectronClosure`](@ref) — the gated constant set of the closure, NaN- + poisoned until human-cleared. +""" +module Fields + +import QuadGK + +export Q_omega, dQ_domega, h_profile, dh_domega, d2h_domega2 +export flat_average_d2h_dx2, ElectronClosure, is_cleared + +""" + Q_omega(Ω; rtol=1e-10) + +`Q(Ω) = (1/2π) ∮ √(Ω + cos ξ) dξ` over the region where the radicand is +positive (`01 §2.4` structure). For `Ω > 1` the integral covers the full +period; for `|Ω| < 1` it runs between the turning points `cos ξ_b = −Ω`. +""" +function Q_omega(Ω; rtol::Real=1e-10) + if Ω > 1 + val, _ = QuadGK.quadgk(ξ -> sqrt(Ω + cos(ξ)), 0.0, 2π; rtol=rtol) + return val / (2π) + elseif -1 < Ω <= 1 + ξb = acos(-Ω) + val, _ = QuadGK.quadgk(ξ -> sqrt(max(Ω + cos(ξ), 0.0)), -ξb, ξb; rtol=rtol) + return val / (2π) + else + throw(DomainError(Ω, "Q_omega needs Ω > −1")) + end +end + +""" + dQ_domega(Ω; rtol=1e-10) + +`dQ/dΩ = (1/4π) ∮ (Ω + cos ξ)^{−1/2} dξ` (differentiating `Q_omega` under the +integral; the inside-separatrix endpoint singularity is integrable). +""" +function dQ_domega(Ω; rtol::Real=1e-10) + if Ω > 1 + val, _ = QuadGK.quadgk(ξ -> 1.0 / sqrt(Ω + cos(ξ)), 0.0, 2π; rtol=rtol) + return val / (4π) + elseif -1 < Ω < 1 + ξb = acos(-Ω) + val, _ = QuadGK.quadgk(ξ -> 1.0 / sqrt(Ω + cos(ξ)), -ξb, ξb; rtol=rtol) + return val / (4π) + else + throw(DomainError(Ω, "dQ_domega needs Ω ∈ (−1, 1) ∪ (1, ∞)")) + end +end + +""" + h_profile(Ω; prefactor, rtol=1e-10) + +The flattened-electron profile function *structure* `h(Ω) = Θ(Ω − 1) · prefactor · ∫₁^Ω dΩ′/Q(Ω′)` (`01 §2.4`): exactly flat inside the separatrix, +`→ x` far outside. The physics prefactor (`w_ψ/2√2` in the sources) is +`[CHECKED]`-uncleared (QUESTIONS Q3) and therefore **supplied**; the A7 +identity below is prefactor-independent. +""" +function h_profile(Ω; prefactor, rtol::Real=1e-10) + Ω <= 1 && return zero(float(Ω)) + val, _ = QuadGK.quadgk(Ωp -> 1.0 / Q_omega(Ωp; rtol=rtol), 1.0, Ω; rtol=rtol) + return prefactor * val +end + +""" + dh_domega(Ω; prefactor, rtol=1e-10) + +`h′(Ω) = prefactor / Q(Ω)` for `Ω > 1`, zero inside. +""" +dh_domega(Ω; prefactor, rtol::Real=1e-10) = Ω > 1 ? prefactor / Q_omega(Ω; rtol=rtol) : zero(float(Ω)) + +""" + d2h_domega2(Ω; prefactor, rtol=1e-10) + +`h″(Ω) = −prefactor · Q′(Ω)/Q(Ω)²` for `Ω > 1`, zero inside. +""" +function d2h_domega2(Ω; prefactor, rtol::Real=1e-10) + Ω <= 1 && return zero(float(Ω)) + Q = Q_omega(Ω; rtol=rtol) + return -prefactor * dQ_domega(Ω; rtol=rtol) / Q^2 +end + +""" + flat_average_d2h_dx2(Ω, w; prefactor=1.0, rtol=1e-10) + +The ladder-A7 identity integrand: `⟨∂²h/∂x²⟩_Ω` assembled from the chain rule +`∂²h/∂x² = h″(Ω)(∂Ω/∂x)² + h′(Ω) ∂²Ω/∂x²` with `∂Ω/∂x = 4x/w²` on the surface +(`(∂Ω/∂x)² = 8(Ω + cos ξ)/w²`), averaged with the `(Ω + cos ξ)^{−1/2}` weight. +Analytically **exactly zero** for any prefactor — a coefficient-free +consistency check of the `Q`, `h` quadratures and the `⟨·⟩_Ω` machinery +(L23 Eq. 4.1.1-class unit target). Valid for `Ω > 1`. +""" +function flat_average_d2h_dx2(Ω, w; prefactor::Real=1.0, rtol::Real=1e-10) + Ω > 1 || throw(DomainError(Ω, "the A7 identity applies outside the separatrix (Ω > 1)")) + hp = dh_domega(Ω; prefactor=prefactor, rtol=rtol) + hpp = d2h_domega2(Ω; prefactor=prefactor, rtol=rtol) + num, _ = QuadGK.quadgk(ξ -> (hpp * 8 * (Ω + cos(ξ)) / w^2 + hp * 4 / w^2) / sqrt(Ω + cos(ξ)), 0.0, 2π; rtol=rtol) + den, _ = QuadGK.quadgk(ξ -> 1.0 / sqrt(Ω + cos(ξ)), 0.0, 2π; rtol=rtol) + return num / den +end + +""" + ElectronClosure(; k_HS=NaN, f_p=NaN, h_prefactor=NaN, C_phi=NaN) + +The gated constant set of the Level-0 flattened-electron closure (`01 §2.4`, +`§3`), all `[CHECKED]`-uncleared (QUESTIONS Q3) and **NaN-defaulted** so an +un-cleared closure poisons results instead of committing to a guess: + +## Fields + + - `k_HS` — the Hirshman–Sigmar flow coefficient (sources: `≃ −1.173`). + - `f_p` — the passing fraction form (sources: `≃ 1 − 1.46√ε`). + - `h_prefactor` — the `h(Ω)` amplitude (sources: `w_ψ/2√2`). + - `C_phi` — the quasineutrality closure coefficient (sources: `1/2L̂_{n0}`). +""" +Base.@kwdef struct ElectronClosure + k_HS::Float64 = NaN + f_p::Float64 = NaN + h_prefactor::Float64 = NaN + C_phi::Float64 = NaN +end + +""" + is_cleared(ec::ElectronClosure) + +`true` only when every gated closure constant has been assigned (no NaN). +""" +is_cleared(ec::ElectronClosure) = !(isnan(ec.k_HS) || isnan(ec.f_p) || isnan(ec.h_prefactor) || isnan(ec.C_phi)) + +end # module Fields diff --git a/src/Islands/frames/Frames.jl b/src/Islands/frames/Frames.jl new file mode 100644 index 00000000..079167d9 --- /dev/null +++ b/src/Islands/frames/Frames.jl @@ -0,0 +1,119 @@ +""" + Frames + +THE frequency/frame conversion module (design `01 §5`, module CLAUDE.md): no +other part of Islands may contain an ω sign convention. The polarization-current +sign disputes in the literature are largely frame disputes; this module owns the +conversions so they cannot be reproduced inconsistently elsewhere. + +**Milestone-M2 status: forms only, signs gated.** The frame identities of +`01 §5` are `[CHECKED: Diss19 pp. 46–48]` but not human-cleared (QUESTIONS Q3), +so every sign/normalization here is a `FrameConvention` field with a **NaN +default**: using an un-cleared convention poisons every downstream number +instead of silently committing to a guess. Only the mechanical, sign-free +bookkeeping (`frame_shift`, round-trips, parameter validation) is active. +""" +module Frames + +export Level0Parameters, FrameConvention +export frame_shift, omega_dia_form, effective_dlnn_form, is_cleared + +""" + Level0Parameters(; w_hat, omega_E_hat, epsilon, inv_Lq_hat, q_s, tau, nu_star) + +The Level-0 input parameter vector `p` (`01 §5`). Species-resolved quantities +(gradients, `η_j`, backgrounds, roles) live on the species list; this struct +carries the scalars. + +## Fields + + - `w_hat` — island **half**-width `w/ρ_θi` (half-width convention pinned + in the module CLAUDE.md; thresholds are always reported as half-widths). + - `omega_E_hat` — `ω_E/ω_dia,e` (`≡ −ω₀/ω_dia,e`; a scanned input from day one, + ordering O4). + - `epsilon` — inverse aspect ratio `r_s/R₀`. + - `inv_Lq_hat` — `L̂_q⁻¹ = (ψ_s/q) dq/dψ` at `r_s`. + - `q_s` — safety factor at the rational surface. + - `tau` — `T_e/T_i`. + - `nu_star` — per-species banana collisionality `ν_★j`, keyed by species name. +""" +struct Level0Parameters + w_hat::Float64 + omega_E_hat::Float64 + epsilon::Float64 + inv_Lq_hat::Float64 + q_s::Float64 + tau::Float64 + nu_star::Dict{Symbol,Float64} + function Level0Parameters(w_hat, omega_E_hat, epsilon, inv_Lq_hat, q_s, tau, nu_star) + w_hat > 0 || throw(ArgumentError("w_hat must be positive (half-width)")) + epsilon > 0 || throw(ArgumentError("epsilon must be positive")) + q_s > 0 || throw(ArgumentError("q_s must be positive")) + tau > 0 || throw(ArgumentError("tau must be positive")) + all(v -> v >= 0, values(nu_star)) || throw(ArgumentError("nu_star entries must be nonnegative")) + return new(w_hat, omega_E_hat, epsilon, inv_Lq_hat, q_s, tau, Dict{Symbol,Float64}(nu_star)) + end +end + +function Level0Parameters(; w_hat, omega_E_hat, epsilon, inv_Lq_hat, q_s, tau=1.0, nu_star=Dict{Symbol,Float64}()) + return Level0Parameters(w_hat, omega_E_hat, epsilon, inv_Lq_hat, q_s, tau, nu_star) +end + +""" + FrameConvention(; C_dia=NaN, sign_omega0=NaN, C_gradient_shift=NaN) + +The gated sign/normalization set of the frame identities (`01 §5`, +`[CHECKED: Diss19 pp. 46–48]`, awaiting human clearance — QUESTIONS **Q3**). +All fields default to **NaN** so an un-cleared convention poisons results +rather than silently committing to a guess; `is_cleared` tests for this. + +## Fields + + - `C_dia` — prefactor (incl. sign) of the electron diamagnetic + frequency form `ω_dia,e = C_dia · m T̂_e L̂_n⁻¹ / q_s`. + - `sign_omega0` — the island-propagation relation `ω₀ = sign_omega0 · ω_E`. + - `C_gradient_shift` — prefactor of the frame shift of the effective density + gradient, `L_n⁻¹ = L_{n0}⁻¹ (1 + C_gradient_shift · Z_j ω_E/ω_dia,e)`. +""" +Base.@kwdef struct FrameConvention + C_dia::Float64 = NaN + sign_omega0::Float64 = NaN + C_gradient_shift::Float64 = NaN +end + +""" + is_cleared(conv::FrameConvention) + +`true` only when every gated field has been assigned (no NaN). Downstream code +must check this before producing physics numbers. +""" +is_cleared(conv::FrameConvention) = !(isnan(conv.C_dia) || isnan(conv.sign_omega0) || isnan(conv.C_gradient_shift)) + +""" + frame_shift(omega, omega_E) + +The frame-invariant combination `ω − ω_E` (`01 §5`): mechanical bookkeeping, +no sign convention (the invariance is what *defines* the shift). +""" +frame_shift(omega, omega_E) = omega - omega_E + +""" + omega_dia_form(m_mode, T_hat, inv_Ln_hat, q_s, conv) + +The electron diamagnetic frequency *form* `C_dia · m T̂ L̂_n⁻¹ / q_s` +(structure of `01 §5`; value gated on `conv.C_dia`, QUESTIONS Q3). Returns NaN +until the convention is cleared. +""" +omega_dia_form(m_mode, T_hat, inv_Ln_hat, q_s, conv::FrameConvention) = conv.C_dia * m_mode * T_hat * inv_Ln_hat / q_s + +""" + effective_dlnn_form(inv_Ln0_hat, Z, omega_E_hat, conv) + +The frame shift of the effective density gradient *form* +`L̂_n⁻¹ = L̂_{n0}⁻¹ (1 + C_gradient_shift · Z ω̂_E)` (structure of `01 §5`; value +gated on `conv.C_gradient_shift`, QUESTIONS Q3). `omega_E_hat` is already +normalized to `ω_dia,e`. Returns NaN until the convention is cleared. +""" +effective_dlnn_form(inv_Ln0_hat, Z, omega_E_hat, conv::FrameConvention) = inv_Ln0_hat * (1 + conv.C_gradient_shift * Z * omega_E_hat) + +end # module Frames diff --git a/src/Islands/moments/Moments.jl b/src/Islands/moments/Moments.jl new file mode 100644 index 00000000..a9c4d71d --- /dev/null +++ b/src/Islands/moments/Moments.jl @@ -0,0 +1,133 @@ +""" + Moments + +Output-moment assembly (design `01 §4`, `03 §1`): the parallel current +`J̄_∥(x, ξ)` from species-summed velocity moments, its `cos ξ`/`sin ξ` Ampère +projections `Δ_cos`/`Δ_sin`, and the island flux-surface-average diagnostics +(`Ω` label, `⟨·⟩_Ω`, bootstrap/polarization channel split). + +**Gating:** the projection and quadrature machinery here is pure numerics. The +physics enters through (i) the per-species velocity-space weights `W_j` (the +`v̂_∥`-structure — `[VERIFY]`-gated, QUESTIONS Q3), and (ii) the `Δ` moment +prefactors (`±μ₀R/2ψ̃` with `ψ̃` under an open `[VERIFY]`, and the sin-moment +normalization still `[DERIVED]`-unpinned — QUESTIONS Q4). Both are **required +caller-supplied arguments** with no defaults; nothing here assigns them. + +The island label convention is the module-CLAUDE.md pin: `Ω = 2x²/w² − cos ξ`, +O-point `Ω = −1`, separatrix `Ω = +1`, `w` = **half**-width. +""" +module Moments + +using LinearAlgebra +import QuadGK +import ..PhaseSpace: IslandGrid, nnodes +import ..Operators: weighted_moment! +import ..SpeciesLists: Species + +export parallel_current!, delta_moments, omega_label, omega_average, channel_split + +""" + parallel_current!(Jpar, gs, species, weights, grid) + +Assemble `J̄_∥(x, ξ) = Σ_j Z_j ∫ W_j g_j` into `Jpar[ix, iξ]` (`01 §4`): one +`weighted_moment!` per species, charge-scaled and accumulated. `gs`, `species` +and `weights` are aligned vectors; each `W_j` is the supplied `(ny, nE, nσ)` +parallel-flow velocity weight (gated physics, QUESTIONS Q3). +""" +function parallel_current!(Jpar, gs::AbstractVector, species::AbstractVector{<:Species}, weights::AbstractVector, grid::IslandGrid) + length(gs) == length(species) == length(weights) || + throw(ArgumentError("gs, species, weights must be aligned (got $(length(gs)), $(length(species)), $(length(weights)))")) + fill!(Jpar, zero(eltype(Jpar))) + for (g, sp, W) in zip(gs, species, weights) + weighted_moment!(Jpar, g, W, grid; scale=sp.Z, accumulate=true) + end + return Jpar +end + +""" + delta_moments(Jpar, grid; prefactor_cos, prefactor_sin) + +The two Ampère projections of `J̄_∥` through the island (`01 §4`): + + Δ_cos = prefactor_cos · ∫dx ∮dξ J̄_∥ cos ξ + Δ_sin = prefactor_sin · ∫dx ∮dξ J̄_∥ sin ξ + +`ξ`-integration is the uniform-grid trapezoid (spectrally exact on the periodic +grid); `x`-integration uses the grid's Simpson weights. The prefactors +(`∓μ₀R/2ψ̃`, `01 §4`) are **gated** — `ψ̃` carries an open `[VERIFY]` and the +sin normalization is `[DERIVED]`-unpinned (QUESTIONS Q4) — so both are required +arguments. Returns `(Δcos, Δsin)`. +""" +function delta_moments(Jpar, grid::IslandGrid; prefactor_cos, prefactor_sin) + nx, nξ = size(Jpar) + (nx, nξ) == (grid.x.n, grid.ξ.n) || throw(ArgumentError("Jpar must be (nx, nξ) = $((grid.x.n, grid.ξ.n))")) + wξ = grid.ξ.L / grid.ξ.n + pc = zero(eltype(Jpar)) + ps = zero(eltype(Jpar)) + @inbounds for iξ in 1:nξ + c = cos(grid.ξ.nodes[iξ]) + s = sin(grid.ξ.nodes[iξ]) + for ix in 1:nx + w = grid.x.wq[ix] * wξ * Jpar[ix, iξ] + pc += w * c + ps += w * s + end + end + return (Δcos=prefactor_cos * pc, Δsin=prefactor_sin * ps) +end + +""" + omega_label(x, ξ, w) + +The island flux-surface label `Ω = 2x²/w² − cos ξ` (pinned convention, module +CLAUDE.md; O-point `Ω = −1`, separatrix `Ω = +1`, `w` = half-width). A +diagnostic label only — never a solve coordinate (Decision D1). +""" +omega_label(x, ξ, w) = 2 * x^2 / w^2 - cos(ξ) + +# x on the Ω surface at helical angle ξ (branch = ±1 selects the x-sign). +_x_on_surface(Ω, ξ, w, branch) = branch * (w / sqrt(2)) * sqrt(max(Ω + cos(ξ), 0.0)) + +""" + omega_average(f, Ω, w; branch=+1, rtol=1e-10) + +Island flux-surface average `⟨f⟩_Ω = ∮ f (Ω + cos ξ)^{−1/2} dξ / ∮ (Ω + cos ξ)^{−1/2} dξ` +(`01 §4` decomposition weight) of a callable `f(x, ξ)`: + + - `Ω > 1` (outside the separatrix): the `±x` branches are distinct surfaces; + `branch` selects one, integrating over the full `ξ ∈ [0, 2π)`. + - `−1 < Ω < 1` (inside): the surface closes through both branches between the + turning points `cos ξ_b = −Ω`; the endpoint weight singularity is integrable + and handled by the adaptive quadrature. +""" +function omega_average(f, Ω, w; branch::Int=1, rtol::Real=1e-10) + if Ω > 1 + num, _ = QuadGK.quadgk(ξ -> f(_x_on_surface(Ω, ξ, w, branch), ξ) / sqrt(Ω + cos(ξ)), 0.0, 2π; rtol=rtol) + den, _ = QuadGK.quadgk(ξ -> 1.0 / sqrt(Ω + cos(ξ)), 0.0, 2π; rtol=rtol) + return num / den + elseif -1 < Ω < 1 + ξb = acos(-Ω) + integrand(ξ) = (f(_x_on_surface(Ω, ξ, w, +1), ξ) + f(_x_on_surface(Ω, ξ, w, -1), ξ)) / sqrt(Ω + cos(ξ)) + num, _ = QuadGK.quadgk(integrand, -ξb, ξb; rtol=rtol) + den, _ = QuadGK.quadgk(ξ -> 2.0 / sqrt(Ω + cos(ξ)), -ξb, ξb; rtol=rtol) + return num / den + else + throw(DomainError(Ω, "omega_average needs Ω ∈ (−1, 1) ∪ (1, ∞) (O-point/separatrix excluded)")) + end +end + +""" + channel_split(Jfun, Ω, w; branch=+1) + +The `01 §4` bootstrap/polarization bookkeeping at one `Ω` surface: returns +`(bs, pol)` where `bs = ⟨J⟩_Ω` (the flux-surface-constant "bootstrap+curvature" +part) and `pol(x, ξ) = Jfun(x, ξ) − bs` (the piece that `Ω`-averages to zero). +Diagnostic only — the solve never separates channels; the split is approximate +bookkeeping (L23 Eq. 2.5.3 caveat). +""" +function channel_split(Jfun, Ω, w; branch::Int=1) + bs = omega_average(Jfun, Ω, w; branch=branch) + return (bs=bs, pol=(x, ξ) -> Jfun(x, ξ) - bs) +end + +end # module Moments diff --git a/src/Islands/operators/Operators.jl b/src/Islands/operators/Operators.jl index 230dad73..3a7afba5 100644 --- a/src/Islands/operators/Operators.jl +++ b/src/Islands/operators/Operators.jl @@ -36,7 +36,10 @@ import ..PhaseSpace: IslandGrid, nnodes export IslandState, IslandCache, IslandStack, AbstractTerm export ParallelStreaming, MagneticDrift, ExBDrift, Collisions, GradientDrive, PerpTransport, RadiationSink, Quasineutrality -export apply!, residual!, velocity_moment!, statelength, flatten!, unflatten! +export PitchAngleDiffusion, conservative_pitch_operator +export FarFieldConditions, apply_farfield! +export apply!, residual!, velocity_moment!, weighted_moment!, statelength, + flatten!, unflatten!, g_flat_index, Φ_flat_index # --------------------------------------------------------------------------- # State, cache @@ -161,6 +164,53 @@ struct Collisions{A} <: AbstractTerm end Collisions(a_y, b_y; model::Symbol=:pitch_angle) = Collisions(a_y, b_y, model) +""" + PitchAngleDiffusion(K, c) + +Pitch-angle collision operator in **discretely conservative (mimetic) form** +(`01 §2.3` structure; ladder A4): adds `c ⋅ (K g)` along `y`, where `K` is the +divergence-form matrix built by [`conservative_pitch_operator`](@ref) and `c` is +a supplied coefficient array over `(x, ξ, E, σ)` — **`y`-independent by +construction**, so the exact discrete particle conservation and entropy-sign +properties of `K` are preserved (the physical `ν̂(v̂)` energy dependence lives in +`c`'s `E`-dependence and is `[VERIFY]`-gated). The momentum-restoring +field-particle piece of the Level-0 operator is gated physics (QUESTIONS Q3) +and is not part of this structure. +""" +struct PitchAngleDiffusion{M<:AbstractMatrix,A} <: AbstractTerm + K::M + c::A +end + +""" + conservative_pitch_operator(ygrid, P, wmeas) + +Build the mimetic divergence-form pitch operator on `ygrid` +(`C[g] = (1/w) d/dy(P w dg/dy)` discretized as `K = −Wq⁻¹ Gᵀ diag(P .* wq) G` +with `G = ygrid.D1` and `Wq = wmeas .* ygrid.wq`), returning `(K, Wq)`. + +Because `G` differentiates constants exactly and the quadrature weights are +positive, `K` satisfies **exactly** (to machine precision, ladder A4): + + - particle conservation: `Wqᵀ (K g) = 0` for any `g` (zero-flux built in); + - entropy sign: `gᵀ diag(Wq) K g = −(Gg)ᵀ diag(P .* wq)(Gg) ≤ 0` for `P ≥ 0`. + +`P` (the pitch-space diffusivity profile, physically the `λ√(1−λB)`-structure) +and `wmeas` (the velocity-space measure) are **supplied** profiles — their +Level-0 physics forms are `[VERIFY]`-gated (QUESTIONS Q3); any positive test +profiles exercise the conservation structure. +""" +function conservative_pitch_operator(ygrid, P::AbstractVector, wmeas::AbstractVector) + length(P) == ygrid.n || throw(ArgumentError("P must have length $(ygrid.n)")) + length(wmeas) == ygrid.n || throw(ArgumentError("wmeas must have length $(ygrid.n)")) + all(>=(0), P) || throw(ArgumentError("diffusivity profile P must be nonnegative")) + all(>(0), wmeas) || throw(ArgumentError("measure weights wmeas must be positive")) + G = ygrid.D1 + Wq = wmeas .* ygrid.wq + K = -Diagonal(1.0 ./ Wq) * (G' * Diagonal(P .* ygrid.wq) * G) + return Matrix(K), Wq +end + """ GradientDrive(drive) @@ -321,6 +371,24 @@ function apply!(R::IslandState, t::Collisions, U::IslandState, grid::IslandGrid, return R end +function apply!(R::IslandState, t::PitchAngleDiffusion, U::IslandState, grid::IslandGrid, ::IslandCache) + K = t.K + c = t.c + g = U.g + nx, nξ, ny, nE, nσ = size(g) + @inbounds for iσ in 1:nσ, iE in 1:nE, iξ in 1:nξ, ix in 1:nx + cv = c[ix, iξ, iE, iσ] + for a in 1:ny + acc = zero(eltype(R.g)) + for b in 1:ny + acc += K[a, b] * g[ix, iξ, b, iE, iσ] + end + R.g[ix, iξ, a, iE, iσ] += cv * acc + end + end + return R +end + function apply!(R::IslandState, t::GradientDrive, U::IslandState, ::IslandGrid, ::IslandCache) @inbounds @. R.g += t.drive return R @@ -388,6 +456,78 @@ function velocity_moment!(M, g, grid::IslandGrid; accumulate::Bool=false) return M end +""" + weighted_moment!(M, g, W, grid; scale=1, accumulate=false) + +Accumulate the weighted velocity moment `scale · ∫dy ∫dE Σ_σ W(y, E, σ) g` into +`M[ix, iξ]` (`03 §2`, moments). `W` is a supplied `(ny, nE, nσ)` velocity-space +weight — e.g. the `v̂_∥`-structure of the parallel-flow moment, whose Level-0 +physics form is `[VERIFY]`-gated (QUESTIONS Q3). `scale` carries a per-species +factor (e.g. the charge `Z_j`). `velocity_moment!` is the `W ≡ 1` special case. +""" +function weighted_moment!(M, g, W, grid::IslandGrid; scale=1, accumulate::Bool=false) + accumulate || fill!(M, zero(eltype(M))) + wy = grid.y.wq + wE = grid.E.weights + nx, nξ, ny, nE, nσ = size(g) + size(W) == (ny, nE, nσ) || throw(ArgumentError("weight W must have size (ny, nE, nσ) = $((ny, nE, nσ))")) + @inbounds for iσ in 1:nσ, iE in 1:nE, iy in 1:ny + w = scale * wy[iy] * wE[iE] * W[iy, iE, iσ] + for iξ in 1:nξ, ix in 1:nx + M[ix, iξ] += w * g[ix, iξ, iy, iE, iσ] + end + end + return M +end + +# --------------------------------------------------------------------------- +# Far-field boundary conditions (01 §3, 04 §1): match g and Φ to supplied +# far-field states at |x| = L_x. NEVER bare Neumann — L23 traced its spurious +# "winged" solution branch to Neumann non-uniqueness; the physical far field is +# the neoclassical (no-island) solution, which is [VERIFY]-gated physics and +# therefore *supplied* here, not computed. +# --------------------------------------------------------------------------- +""" + FarFieldConditions(g_left, g_right, Φ_left, Φ_right) + +Dirichlet-type far-field matching data at the two radial boundaries (`01 §3`): +`g → g_far` and `Φ̂ → Φ̂_far` as `|x| → L_x`. The residual rows at `ix = 1, nx` +are replaced by `(U − far)` so the Newton solve pins the far field. The +neoclassical no-island `g_far` is gated physics (QUESTIONS Q3) — callers supply +it (tests use manufactured far fields). + +## Fields + + - `g_left`, `g_right` — `(nξ, ny, nE, nσ)` far-field distributions at `ix = 1`, `ix = nx`. + - `Φ_left`, `Φ_right` — length-`nξ` far-field potentials at `ix = 1`, `ix = nx`. +""" +struct FarFieldConditions{T,A4<:AbstractArray{T,4},V<:AbstractVector{T}} + g_left::A4 + g_right::A4 + Φ_left::V + Φ_right::V +end + +""" + apply_farfield!(R, U, bc, grid) + +Replace the residual rows at the radial boundaries with the far-field matching +conditions `U − far` (`01 §3`). Called after the operator stack in +[`residual!`](@ref); allocation-free and AD-transparent. +""" +function apply_farfield!(R::IslandState, U::IslandState, bc::FarFieldConditions, grid::IslandGrid) + nx, nξ, ny, nE, nσ = size(U.g) + @inbounds for iσ in 1:nσ, iE in 1:nE, iy in 1:ny, iξ in 1:nξ + R.g[1, iξ, iy, iE, iσ] = U.g[1, iξ, iy, iE, iσ] - bc.g_left[iξ, iy, iE, iσ] + R.g[nx, iξ, iy, iE, iσ] = U.g[nx, iξ, iy, iE, iσ] - bc.g_right[iξ, iy, iE, iσ] + end + @inbounds for iξ in 1:nξ + R.Φ[1, iξ] = U.Φ[1, iξ] - bc.Φ_left[iξ] + R.Φ[nx, iξ] = U.Φ[nx, iξ] - bc.Φ_right[iξ] + end + return R +end + # --------------------------------------------------------------------------- # Stack + residual assembly # --------------------------------------------------------------------------- @@ -421,6 +561,19 @@ function residual!(R::IslandState, U::IslandState, stack::IslandStack, grid::Isl return R end +""" + residual!(R, U, stack, grid, cache, bc) + +Residual assembly with far-field boundary conditions: assemble the stack, then +replace the radial-boundary rows with the `FarFieldConditions` matching +residual (`01 §3`). +""" +function residual!(R::IslandState, U::IslandState, stack::IslandStack, grid::IslandGrid, cache::IslandCache, bc::FarFieldConditions) + residual!(R, U, stack, grid, cache) + apply_farfield!(R, U, bc, grid) + return R +end + # recursive tuple walk keeps the loop type-stable (no dynamic dispatch, no alloc) @inline _apply_kinetic!(R, ::Tuple{}, U, grid, cache) = R @inline function _apply_kinetic!(R, terms::Tuple, U, grid, cache) @@ -465,4 +618,26 @@ function unflatten!(U::IslandState, v) return U end +""" + g_flat_index(grid, ix, iξ, iy, iE, iσ) + +Flat-state-vector index of `g[ix, iξ, iy, iE, iσ]` under the `flatten!` layout +(`g` block column-major, then `Φ`). Used by the `y_c`-block conditioning +monitor (ladder A8) to address pitch-pencil sub-blocks of the dense Jacobian. +""" +function g_flat_index(grid::IslandGrid, ix::Int, iξ::Int, iy::Int, iE::Int, iσ::Int) + nx, nξ, ny, nE, = nnodes(grid) + return ix + nx * ((iξ - 1) + nξ * ((iy - 1) + ny * ((iE - 1) + nE * (iσ - 1)))) +end + +""" + Φ_flat_index(grid, ix, iξ) + +Flat-state-vector index of `Φ[ix, iξ]` under the `flatten!` layout. +""" +function Φ_flat_index(grid::IslandGrid, ix::Int, iξ::Int) + nx, nξ, ny, nE, nσ = nnodes(grid) + return nx * nξ * ny * nE * nσ + ix + nx * (iξ - 1) +end + end # module Operators diff --git a/src/Islands/phasespace/PhaseSpace.jl b/src/Islands/phasespace/PhaseSpace.jl index 9a9c241e..025132fa 100644 --- a/src/Islands/phasespace/PhaseSpace.jl +++ b/src/Islands/phasespace/PhaseSpace.jl @@ -302,11 +302,13 @@ internal layers (`x = 0`, `y = y_c`) per `04 §1`. ## Fields - - `x` — radial `MappedFDGrid` (clustered at `x = 0`). - - `ξ` — helical `FourierGrid`. - - `y` — pitch `MappedFDGrid` on `[0, y_max]` (clustered at `y_c`). - - `E` — energy `GaussGrid`. - - `σ` — `[+1.0, -1.0]`. + - `x` — radial `MappedFDGrid` (clustered at `x = 0`). + - `ξ` — helical `FourierGrid`. + - `y` — pitch `MappedFDGrid` on `[0, y_max]` (clustered at `y_c`). + - `E` — energy `GaussGrid`. + - `σ` — `[+1.0, -1.0]`. + - `y_c` — trapped–passing boundary location in `y` (the layer the pitch grid + packs toward; consumed by the `y_c`-block conditioning monitor, ladder A8). """ struct IslandGrid x::MappedFDGrid @@ -314,6 +316,7 @@ struct IslandGrid y::MappedFDGrid E::GaussGrid σ::Vector{Float64} + y_c::Float64 end function IslandGrid(; nx::Int, nxi::Int, ny::Int, nE::Int, @@ -326,7 +329,7 @@ function IslandGrid(; nx::Int, nxi::Int, ny::Int, nE::Int, y = MappedFDGrid(ny; halfwidth=y_max, clustering=clustering_y, center=y_c, domain=:half, order=order) E = GaussGrid(nE; kind=energy_kind) - return IslandGrid(x, ξ, y, E, [1.0, -1.0]) + return IslandGrid(x, ξ, y, E, [1.0, -1.0], Float64(y_c)) end """ diff --git a/src/Islands/solvers/Solvers.jl b/src/Islands/solvers/Solvers.jl new file mode 100644 index 00000000..2b4799cf --- /dev/null +++ b/src/Islands/solvers/Solvers.jl @@ -0,0 +1,331 @@ +""" + Solvers + +The Islands steady-state solve (design `03 §3`, `04 §5`, Decision D2): +matrix-free **Newton–Krylov** — never initial-value time-stepping, never nested +Picard loops (kokuchou's Picard criterion was *never met* in production; the +sources' Φ-outer/ū_∥i-inner iteration is the explicit anti-pattern). + +Pieces: + + - [`flat_residual`](@ref) — wrap an operator stack (+ optional far-field BCs) + as a flat-vector residual `f!(out, u)`, generic over `eltype` with + preallocated real and dual workspaces. + - [`JVPOperator`](@ref) — the exact Jacobian–vector product via ForwardDiff + duals through the stack (`04 §5`); no global sparse Jacobian is ever formed + except in [`dense_jacobian`](@ref) tiny-grid debug mode. + - [`YBlockJacobi`](@ref) — the physics-block preconditioner skeleton: per-pitch- + pencil blocks with **TSVD-regularized** solves, the explicit `y_c`-matching + treatment of `04 §3` (GMRES must never resolve the near-singular directions + itself). + - [`newton_krylov`](@ref) — inexact Newton with Eisenstat–Walker forcing and + a backtracking line search. + - [`pseudo_arclength`](@ref) — the continuation scaffold with fold detection + from day one (`03 §3`: the Level-3 penetration bifurcation is a fold; the + solver must step around folds, not fail at them). + +Pure numerics — no physics coefficients (the stack it solves carries the gated +parameters). +""" +module Solvers + +using LinearAlgebra +import Krylov +import ForwardDiff +import ..PhaseSpace: IslandGrid, nnodes +import ..Operators: IslandState, IslandCache, IslandStack, FarFieldConditions, + residual!, flatten!, unflatten!, statelength + +export flat_residual, JVPOperator, dense_jacobian +export YBlockJacobi, newton_krylov, pseudo_arclength + +# Tag for the solver's ForwardDiff duals (one directional derivative). +struct JVPTag end +const JVPDual = ForwardDiff.Dual{JVPTag,Float64,1} + +# --------------------------------------------------------------------------- +# Flat residual wrapper +# --------------------------------------------------------------------------- +""" + flat_residual(stack, grid; bc=nothing) + +Wrap `residual!` for `stack` on `grid` (with optional `FarFieldConditions`) as +a flat-vector function `f!(out, u)` usable by [`newton_krylov`](@ref) and +[`JVPOperator`](@ref). Real (`Float64`) and dual workspaces are preallocated so +repeated evaluations allocate nothing. +""" +function flat_residual(stack::IslandStack, grid::IslandGrid; bc::Union{Nothing,FarFieldConditions}=nothing) + U = IslandState(grid) + R = IslandState(grid) + cache = IslandCache(grid) + Ud = IslandState{JVPDual}(grid) + Rd = IslandState{JVPDual}(grid) + cached = IslandCache{JVPDual}(grid) + function f!(out, u) + if eltype(u) === Float64 + unflatten!(U, u) + bc === nothing ? residual!(R, U, stack, grid, cache) : residual!(R, U, stack, grid, cache, bc) + flatten!(out, R) + else + unflatten!(Ud, u) + bc === nothing ? residual!(Rd, Ud, stack, grid, cached) : residual!(Rd, Ud, stack, grid, cached, bc) + flatten!(out, Rd) + end + return out + end + return f! +end + +# --------------------------------------------------------------------------- +# Matrix-free Jacobian-vector product +# --------------------------------------------------------------------------- +""" + JVPOperator(f!, u) + +Matrix-free linear operator for the Jacobian of `f!` at the point `u` (which is +**aliased**, so updating `u` in place moves the linearization point): `mul!(y, J, v)` computes the exact directional derivative via one dual-mode evaluation +of `f!` (`04 §5`). Satisfies the `mul!`/`size`/`eltype` interface Krylov.jl +expects. +""" +struct JVPOperator{F} + f!::F + u::Vector{Float64} + udual::Vector{JVPDual} + rdual::Vector{JVPDual} +end + +function JVPOperator(f!, u::Vector{Float64}) + n = length(u) + return JVPOperator(f!, u, Vector{JVPDual}(undef, n), Vector{JVPDual}(undef, n)) +end + +Base.size(J::JVPOperator) = (length(J.u), length(J.u)) +Base.size(J::JVPOperator, d::Int) = d <= 2 ? length(J.u) : 1 +Base.eltype(::JVPOperator) = Float64 + +function LinearAlgebra.mul!(y::AbstractVector, J::JVPOperator, v::AbstractVector) + @inbounds for i in eachindex(J.u) + J.udual[i] = JVPDual(J.u[i], ForwardDiff.Partials((v[i],))) + end + J.f!(J.rdual, J.udual) + @inbounds for i in eachindex(y) + y[i] = ForwardDiff.partials(J.rdual[i])[1] + end + return y +end + +""" + dense_jacobian(f!, u) + +Dense Jacobian of `f!` at `u` by column-wise dual sweeps — **tiny-grid debug +mode only** (`04 §5`): used for eigenvalue/conditioning diagnostics (the +`y_c`-block singular-value monitor, ladder A8), never in the production solve. +""" +function dense_jacobian(f!, u::Vector{Float64}) + n = length(u) + J = zeros(n, n) + ud = Vector{JVPDual}(undef, n) + rd = Vector{JVPDual}(undef, n) + for j in 1:n + @inbounds for i in 1:n + ud[i] = JVPDual(u[i], ForwardDiff.Partials((i == j ? 1.0 : 0.0,))) + end + f!(rd, ud) + @inbounds for i in 1:n + J[i, j] = ForwardDiff.partials(rd[i])[1] + end + end + return J +end + +# --------------------------------------------------------------------------- +# Physics-block preconditioner skeleton (04 §3, §5) +# --------------------------------------------------------------------------- +""" + YBlockJacobi(grid, block; svd_cutoff=1e-10, phi_scale=1.0) + +Block-Jacobi preconditioner over pitch pencils — the skeleton of the `04 §5` +physics-block preconditioner. `block(ix, iξ, iE, iσ)` returns the `ny × ny` +stiff-direction block for that pencil (typically the identity-plus-collisions +operator); each block is factored by SVD and **truncated below +`svd_cutoff · σ_max`** — the explicit, regularized `y_c`-matching treatment of +`04 §3` (kokuchou's rcond ≈ 1e-16 block gave machine-dependent noise under +plain LU; TSVD is the documented fix). `phi_scale` is the diagonal applied to +the `Φ` rows. Apply via `ldiv!` (pass as `N=...` with `ldiv=true` to GMRES). +""" +struct YBlockJacobi + grid::IslandGrid + pinvs::Array{Matrix{Float64},4} + phi_scale::Float64 +end + +function YBlockJacobi(grid::IslandGrid, block; svd_cutoff::Real=1e-10, phi_scale::Real=1.0) + nx, nξ, ny, nE, nσ = nnodes(grid) + pinvs = Array{Matrix{Float64},4}(undef, nx, nξ, nE, nσ) + for iσ in 1:nσ, iE in 1:nE, iξ in 1:nξ, ix in 1:nx + B = Matrix{Float64}(block(ix, iξ, iE, iσ)) + size(B) == (ny, ny) || throw(ArgumentError("block must be ny×ny = ($ny, $ny)")) + F = svd(B) + smax = F.S[1] + sinv = [s > svd_cutoff * smax ? 1.0 / s : 0.0 for s in F.S] + pinvs[ix, iξ, iE, iσ] = F.V * Diagonal(sinv) * F.U' + end + return YBlockJacobi(grid, pinvs, Float64(phi_scale)) +end + +function LinearAlgebra.ldiv!(y::AbstractVector, P::YBlockJacobi, x::AbstractVector) + nx, nξ, ny, nE, nσ = nnodes(P.grid) + ng = nx * nξ * ny * nE * nσ + xg = reshape(view(x, 1:ng), nx, nξ, ny, nE, nσ) + yg = reshape(view(y, 1:ng), nx, nξ, ny, nE, nσ) + @inbounds for iσ in 1:nσ, iE in 1:nE, iξ in 1:nξ, ix in 1:nx + Pi = P.pinvs[ix, iξ, iE, iσ] + for a in 1:ny + acc = 0.0 + for b in 1:ny + acc += Pi[a, b] * xg[ix, iξ, b, iE, iσ] + end + yg[ix, iξ, a, iE, iσ] = acc + end + end + @inbounds for i in (ng+1):length(x) + y[i] = x[i] / P.phi_scale + end + return y +end + +# --------------------------------------------------------------------------- +# Inexact Newton-Krylov +# --------------------------------------------------------------------------- +""" + newton_krylov(f!, u0; rtol=1e-8, atol=1e-10, max_iter=25, precond=nothing, + eta0=0.5, eta_max=0.9, gamma=0.9, ls_max=10, memory=30, + verbose=false) + +Matrix-free inexact Newton–Krylov solve of `f!(out, u) = 0` (design `03 §3`, +`04 §5`, Decision D2): + + - GMRES (Krylov.jl) on the ForwardDiff [`JVPOperator`](@ref), with the + **Eisenstat–Walker** (choice-2) forcing term `η_k = γ(‖F_k‖/‖F_{k−1}‖)²` so + early Newton steps do not over-solve the linear system; + - a backtracking (Armijo-on-`‖F‖`) line search; + - optional right preconditioner `precond` applied via `ldiv!` (e.g. + [`YBlockJacobi`](@ref)). + +Convergence is declared on **both** the global residual norm and its max-norm +(`04 §5`: the array-averaged residual hid locally divergent regions in the +prior art). Returns a NamedTuple `(u, converged, iterations, residual_norms, residual_max, gmres_iters)` — the total Krylov iteration count is a tracked +preconditioner-quality metric (`04 §5`), not folklore. +""" +function newton_krylov(f!, u0::AbstractVector{Float64}; + rtol::Real=1e-8, atol::Real=1e-10, max_iter::Int=25, precond=nothing, + eta0::Real=0.5, eta_max::Real=0.9, gamma::Real=0.9, ls_max::Int=10, + memory::Int=30, verbose::Bool=false) + u = collect(u0) + n = length(u) + F = similar(u) + f!(F, u) + nF = norm(F) + nF0 = max(nF, eps()) + tol = max(atol, rtol * nF0) + hist = Float64[nF] + J = JVPOperator(f!, u) # aliases u: updates move the linearization point + Ftrial = similar(u) + utrial = similar(u) + eta = float(eta0) + nF_prev = nF + k = 0 + gmres_total = 0 + while nF > tol && k < max_iter + k += 1 + k > 1 && (eta = clamp(gamma * (nF / nF_prev)^2, 1e-4, eta_max)) + rhs = -F + du, stats = + precond === nothing ? + Krylov.gmres(J, rhs; rtol=eta, atol=0.1 * atol, memory=memory, itmax=10n) : + Krylov.gmres(J, rhs; rtol=eta, atol=0.1 * atol, memory=memory, itmax=10n, N=precond, ldiv=true) + gmres_total += stats.niter + verbose && @info "newton iter $k: ‖F‖=$nF, η=$eta, gmres iters=$(stats.niter)" + # backtracking line search on ‖F‖ + λ = 1.0 + nFtrial = Inf + for _ in 1:ls_max + @. utrial = u + λ * du + f!(Ftrial, utrial) + nFtrial = norm(Ftrial) + nFtrial <= (1 - 1e-4 * λ) * nF && break + λ /= 2 + end + nF_prev = nF + if nFtrial < nF + u .= utrial + F .= Ftrial + nF = nFtrial + else + verbose && @warn "newton line search stagnated at iter $k" + break + end + push!(hist, nF) + end + return (u=u, converged=(nF <= tol), iterations=k, residual_norms=hist, residual_max=maximum(abs, F), gmres_iters=gmres_total) +end + +# --------------------------------------------------------------------------- +# Pseudo-arclength continuation scaffold (03 §3) +# --------------------------------------------------------------------------- +""" + pseudo_arclength(f!, u0, p0; ds=0.1, nsteps=10, newton_kwargs...) + +Pseudo-arclength continuation scaffold for a parameterized residual +`f!(out, u, p)` (`03 §3`): predictor along the (secant) tangent, corrector = +[`newton_krylov`](@ref) on the extended system `[F(u, p); t·(z − z_pred)]`, and +**fold detection from day one** via sign changes of the tangent's `p`-component +(the Level-3 penetration bifurcation is a fold in this curve). Returns +`(us, ps, folds)` where `folds` lists the step indices at which `dp/ds` +reversed. +""" +function pseudo_arclength(f!, u0::AbstractVector{Float64}, p0::Real; + ds::Real=0.1, nsteps::Int=10, newton_kwargs...) + n = length(u0) + # converge onto the curve at fixed p0 + sol = newton_krylov((out, u) -> f!(out, u, p0), collect(u0); newton_kwargs...) + sol.converged || error("pseudo_arclength: initial solve at p0 did not converge") + us = [copy(sol.u)] + ps = [float(p0)] + folds = Int[] + # initial tangent from du/dp: J du = -dF/dp (finite difference in p) + Fp = zeros(n) + Fm = zeros(n) + hp = max(1e-7, 1e-7 * abs(p0)) + f!(Fp, sol.u, p0 + hp) + f!(Fm, sol.u, p0 - hp) + dFdp = (Fp .- Fm) ./ (2hp) + Jop = JVPOperator((out, u) -> f!(out, u, p0), copy(sol.u)) + dudp, _ = Krylov.gmres(Jop, -dFdp; rtol=1e-10) + t = vcat(dudp, 1.0) + t ./= norm(t) + tp_prev = t[end] + for step in 1:nsteps + zpred = vcat(us[end], ps[end]) .+ ds .* t + tloc = copy(t) # freeze tangent for this corrector + function ext!(out, z) + f!(view(out, 1:n), view(z, 1:n), z[n+1]) + out[n+1] = LinearAlgebra.dot(tloc, z) - LinearAlgebra.dot(tloc, zpred) + return out + end + sol = newton_krylov(ext!, zpred; newton_kwargs...) + sol.converged || break + push!(us, sol.u[1:n]) + push!(ps, sol.u[n+1]) + # secant tangent for the next step; fold when dp/ds changes sign + t = vcat(us[end] .- us[end-1], ps[end] - ps[end-1]) + t ./= norm(t) + if t[end] * tp_prev < 0 + push!(folds, step) + end + tp_prev = t[end] + end + return (us=us, ps=ps, folds=folds) +end + +end # module Solvers diff --git a/src/Islands/species/Species.jl b/src/Islands/species/Species.jl new file mode 100644 index 00000000..f1948150 --- /dev/null +++ b/src/Islands/species/Species.jl @@ -0,0 +1,170 @@ +""" + SpeciesLists + +Species as a first-class dimension of the Islands solve (design `02 §1`, +Decision D3): every kinetic object is indexed by species, and the species list +is an array from day one even though Level-0 *physics* is single-bulk-ion. + +Pure data structures and bookkeeping — no physics coefficients live here. +Quantities follow the Level-0 normalization (`01 §5`): densities to `n_e`, +temperatures to `T_i`, masses to the reference bulk ion, gradients as inverse +scale lengths at `r_s`. +""" +module SpeciesLists + +export AbstractBackground, Maxwellian, SlowingDown +export SpeciesRole, Bulk, Trace +export Species, is_bulk, is_trace, bulk_species, trace_species +export validate_species, check_trace_criteria + +# --------------------------------------------------------------------------- +# Backgrounds +# --------------------------------------------------------------------------- +""" + AbstractBackground + +Supertype of species background distributions (`02 §1.1`). `Maxwellian` is the +Level-0 background; `SlowingDown` enters at Level 2 (energetic particles) and +changes the energy-grid weight map, not the machinery. +""" +abstract type AbstractBackground end + +""" + Maxwellian(; n, T, dlnn_dr, dlnT_dr) + +Maxwellian background at the rational surface `r_s` (`02 §1.1`), carrying the +strictly-local constant gradients of ordering O2. + +## Fields + + - `n` — density normalized to `n_e`. + - `T` — temperature normalized to `T_i`. + - `dlnn_dr` — inverse density scale length `L̂_n⁻¹` at `r_s`. + - `dlnT_dr` — inverse temperature scale length `L̂_T⁻¹` at `r_s`. +""" +Base.@kwdef struct Maxwellian <: AbstractBackground + n::Float64 + T::Float64 + dlnn_dr::Float64 = 0.0 + dlnT_dr::Float64 = 0.0 +end + +""" + SlowingDown(; S0, v_birth, v_crit, dlnS_dr) + +Slowing-down background (isotropic at Level-2 entry, `02 §3`). Present now so +the background abstraction is exercised from day one; the Level-2 physics that +consumes it is out of Level-0 scope. + +## Fields + + - `S0` — source rate normalization. + - `v_birth` — birth speed (normalized to the reference thermal speed). + - `v_crit` — critical speed (from `T_e` and composition). + - `dlnS_dr` — inverse source scale length at `r_s`. +""" +Base.@kwdef struct SlowingDown <: AbstractBackground + S0::Float64 + v_birth::Float64 + v_crit::Float64 + dlnS_dr::Float64 = 0.0 +end + +# --------------------------------------------------------------------------- +# Roles and the species struct +# --------------------------------------------------------------------------- +""" + SpeciesRole + +`Bulk` = full nonlinear participant (its `g` enters the Newton state vector). +`Trace` = linear post-processing pass with frozen bulk fields (`02 §1.2`) — +one linear solve, an additive contribution to `Δ_cos`/`Δ_sin`. +""" +@enum SpeciesRole Bulk Trace + +""" + Species(; name, Z, m, background, role, collisional_coupling=false) + +One species of the Islands solve (`02 §1.1`). + +## Fields + + - `name` — identifying symbol (unique within a list). + - `Z` — charge number (`Float64` to allow mean-charge-state impurities). + - `m` — mass ratio to the reference bulk ion. + - `background` — an `AbstractBackground` (Maxwellian at Level 0). + - `role` — `Bulk` or `Trace` (`02 §1.2`). + - `collisional_coupling` — whether the bulk feels this species' field-particle + back-reaction (`02 §1.3`; L1+ physics, plumbing present from day one). +""" +Base.@kwdef struct Species{B<:AbstractBackground} + name::Symbol + Z::Float64 + m::Float64 + background::B + role::SpeciesRole = Bulk + collisional_coupling::Bool = false +end + +is_bulk(sp::Species) = sp.role == Bulk +is_trace(sp::Species) = sp.role == Trace + +""" + bulk_species(list) / trace_species(list) + +Filter a species list by role. +""" +bulk_species(list::AbstractVector{<:Species}) = filter(is_bulk, list) +trace_species(list::AbstractVector{<:Species}) = filter(is_trace, list) + +# --------------------------------------------------------------------------- +# Validation and the trace-criteria check +# --------------------------------------------------------------------------- +""" + validate_species(list) + +Structural validation of a species list: unique names, positive `Z`-magnitude, +`m`, density and temperature, and at least one `Bulk` species. Throws +`ArgumentError` on violation; returns the list for chaining. +""" +function validate_species(list::AbstractVector{<:Species}) + isempty(list) && throw(ArgumentError("species list is empty")) + names = [sp.name for sp in list] + length(unique(names)) == length(names) || throw(ArgumentError("duplicate species names: $names")) + any(is_bulk, list) || throw(ArgumentError("species list needs at least one Bulk species")) + for sp in list + sp.m > 0 || throw(ArgumentError("species $(sp.name): mass ratio must be positive")) + abs(sp.Z) > 0 || throw(ArgumentError("species $(sp.name): charge must be nonzero")) + if sp.background isa Maxwellian + sp.background.n > 0 || throw(ArgumentError("species $(sp.name): density must be positive")) + sp.background.T > 0 || throw(ArgumentError("species $(sp.name): temperature must be positive")) + end + end + return list +end + +""" + check_trace_criteria(list; threshold=0.05) + +Check every `Trace` species against both trace criteria (`02 §1.2`): charge +trace (`n_j Z_j ≪ n_e`) and current trace (`n_j ≪ n_e`), with densities already +normalized to `n_e`. A violating species gets an `@warn` recommending `Bulk` +promotion — **warn, never silently degrade** (`02 §1.2` promotion rule). +`threshold` is a diagnostic heuristic knob for "≪", not a physics coefficient. +Returns the vector of violating species names (empty when clean). +""" +function check_trace_criteria(list::AbstractVector{<:Species}; threshold::Real=0.05) + violators = Symbol[] + for sp in trace_species(list) + sp.background isa Maxwellian || continue + n = sp.background.n + charge_frac = n * abs(sp.Z) + if charge_frac > threshold || n > threshold + push!(violators, sp.name) + @warn "species $(sp.name) violates trace criteria (n Z = $(charge_frac), n = $(n) vs threshold $(threshold)); run it as Bulk" maxlog = 1 + end + end + return violators +end + +end # module SpeciesLists diff --git a/src/Islands/verify/Verify.jl b/src/Islands/verify/Verify.jl index 4c585b04..b41f3054 100644 --- a/src/Islands/verify/Verify.jl +++ b/src/Islands/verify/Verify.jl @@ -27,15 +27,17 @@ using LinearAlgebra import ForwardDiff import ..PhaseSpace: IslandGrid, MappedFDGrid, GaussGrid, nnodes import ..Operators: IslandState, IslandCache, IslandStack, residual!, velocity_moment!, - apply!, statelength, flatten!, unflatten!, + apply!, statelength, flatten!, unflatten!, g_flat_index, ParallelStreaming, MagneticDrift, ExBDrift, Collisions, GradientDrive, - PerpTransport, Quasineutrality + PerpTransport, RadiationSink, Quasineutrality, FarFieldConditions +import ..Solvers: flat_residual, newton_krylov export manufactured_state, test_coefficients, build_stack, mms_operator_error, mms_assembled_error, estimate_order, jvp_fd_maxerror, moment_selfconvergence, - term_allocations, residual_allocations + term_allocations, residual_allocations, + yc_block_sigma_min, solve_mms, zero_drive_setup # --------------------------------------------------------------------------- # Manufactured solution: smooth, separable, ξ-periodic and bandlimited. @@ -347,4 +349,112 @@ function residual_allocations(grid::IslandGrid; coeffs=test_coefficients(grid)) return @allocated residual!(R, U, stack, grid, cache) end +# --------------------------------------------------------------------------- +# Solve-level MMS configurations (ladder A1-solve, A5) — the manufactured +# configurations live here per 04 §4 so tests and benchmark scripts share them. +# --------------------------------------------------------------------------- +""" + zero_drive_setup(grid) + +The ladder-A5 configuration: the manufactured advective stack with **all drives +off** (no `GradientDrive`, no source), so `g ≡ 0, Φ ≡ 0` is the exact solution +and the residual there is machine zero (`01 §6`). Returns `(f, N)` — the flat +residual function and state length — for the null test and the trivial-Newton +check. The `RadiationSink(−1)` entry is a **unit relaxation shift** (a +manufactured test coefficient, not physics) making the zero state locally unique. +""" +function zero_drive_setup(grid::IslandGrid) + c = test_coefficients(grid) + shift = fill(-1.0, size(c.drive)) + kin = (ParallelStreaming(c.a_xi, c.a_x), MagneticDrift(c.c_D; variant=:original), + ExBDrift(c.c_E), Collisions(c.a_y, c.b_y; model=:pitch_angle), RadiationSink(shift)) + stack = IslandStack(kin, Quasineutrality(c.α)) + return (f=flat_residual(stack, grid), N=statelength(grid)) +end + +""" + solve_mms(nx; nxi=8, ny=9, nE=2, rtol=1e-10, memory=300) + +The assembled **solve-level** MMS (the ladder-A1 extension to a full converged +Newton–Krylov solve): the advective manufactured stack (streaming + drift + +E×B + unit relaxation shift + quasineutrality) with far-field matching BCs +taken from the manufactured state, forced by the *analytic* continuous source +so the discrete solution differs from `g*` by the discretization error. The +first-order-in-`x` stack needs only the `x` far-field conditions (the pitch +operator's degenerate zero-flux structure is exercised separately, ladder A4). +Returns `(err, converged, iterations, gmres_iters)` where `err` is the max-norm +solution error against the manufactured state — refining `nx` must show the +design order. +""" +function solve_mms(nx::Int; nxi::Int=8, ny::Int=9, nE::Int=2, rtol::Real=1e-10, memory::Int=300) + grid = IslandGrid(; nx=nx, nxi=nxi, ny=ny, nE=nE, halfwidth_x=6.0, clustering_x=1.0, + y_max=4.0, y_c=1.0, clustering_y=0.8, order=4) + c = test_coefficients(grid) + shift = fill(-1.0, size(c.drive)) + kin = (ParallelStreaming(c.a_xi, c.a_x), MagneticDrift(c.c_D; variant=:original), + ExBDrift(c.c_E), RadiationSink(shift)) + stack = IslandStack(kin, Quasineutrality(c.α)) + Ustar, deriv = manufactured_state(grid) + bc = FarFieldConditions(Ustar.g[1, :, :, :, :], Ustar.g[nx, :, :, :, :], Ustar.Φ[1, :], Ustar.Φ[nx, :]) + f0! = flat_residual(stack, grid; bc=bc) + N = statelength(grid) + # continuous source: the analytic values of every active term at (g*, Φ*) + Sg = c.a_xi .* deriv.dgdξ .+ c.a_x .* deriv.dgdx .+ c.c_D .* deriv.dgdξ .+ Ustar.g + dPx = reshape(deriv.dΦdx, nx, nxi, 1, 1, 1) + dPξ = reshape(deriv.dΦdξ, nx, nxi, 1, 1, 1) + Sg .+= c.c_E .* (dPξ .* deriv.dgdx .- dPx .* deriv.dgdξ) + Sg[1, :, :, :, :] .= 0.0 + Sg[nx, :, :, :, :] .= 0.0 # BC rows carry no source + MΦ = zeros(nx, nxi) + velocity_moment!(MΦ, Ustar.g, grid) + SΦ = MΦ .- c.α .* Ustar.Φ # field rows: discretely consistent source + SΦ[1, :] .= 0.0 + SΦ[nx, :] .= 0.0 + S = zeros(N) + flatten!(S, IslandState(Sg, SΦ)) + f!(out, u) = (f0!(out, u); out .-= S; out) + sol = newton_krylov(f!, zeros(N); rtol=rtol, atol=1e-13, max_iter=30, memory=memory) + ustar = zeros(N) + flatten!(ustar, Ustar) + return (err=maximum(abs, sol.u .- ustar), converged=sol.converged, + iterations=sol.iterations, gmres_iters=sol.gmres_iters) +end + +# --------------------------------------------------------------------------- +# y_c matching-block conditioning monitor (ladder A8, 04 §3). +# --------------------------------------------------------------------------- +""" + yc_block_sigma_min(J, grid; window=3) + +Ladder-A8 conditioning monitor: the smallest singular value of the pitch-pencil +sub-block of the (tiny-grid debug) Jacobian `J` nearest the trapped–passing +boundary `y_c`, minimized over all `(x, ξ, E, σ)` pencils. The prior art's +`y_c` matching system was intrinsically near-singular (rcond ≈ 1e-16, L23 §4.2) +and produced machine-dependent **noise, not crashes** — so this must be +*tested for*, not observed. Returns `(sigma_min, pencil)` where `pencil` is the +`(ix, iξ, iE, iσ)` of the minimizing block. +""" +function yc_block_sigma_min(J::AbstractMatrix, grid::IslandGrid; window::Int=3) + nx, nξ, ny, nE, nσ = nnodes(grid) + window <= ny || throw(ArgumentError("window ($window) exceeds ny ($ny)")) + # contiguous y-index window centered on the node nearest y_c + ic = argmin(abs.(grid.y.nodes .- grid.y_c)) + lo = clamp(ic - window ÷ 2, 1, ny - window + 1) + iys = lo:(lo+window-1) + σmin = Inf + pencil = (0, 0, 0, 0) + idx = Vector{Int}(undef, window) + for iσ in 1:nσ, iE in 1:nE, iξ in 1:nξ, ix in 1:nx + for (k, iy) in enumerate(iys) + idx[k] = g_flat_index(grid, ix, iξ, iy, iE, iσ) + end + s = svdvals(J[idx, idx])[end] + if s < σmin + σmin = s + pencil = (ix, iξ, iE, iσ) + end + end + return (sigma_min=σmin, pencil=pencil) +end + end # module Verify From a7fb714fda3150f40de683d76398fc42a3356b49 Mon Sep 17 00:00:00 2001 From: logan-nc Date: Wed, 8 Jul 2026 14:50:28 -0400 Subject: [PATCH 03/10] ISLANDS - NEW FEATURE - M2 structural verification tests (A3/A4/A5/A7/A8 + solve-MMS) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit test/runtests_islands_solve.jl (67 tests, wired into runtests.jl): - A5 zero-drive null: residual exactly machine zero at g ≡ 0; Newton falls back to the zero state from a perturbation. - A1-solve: assembled Newton-Krylov solve recovers the manufactured state at design order (observed 3.98 on the nx = 17→33 pair). - A4: exact discrete particle conservation (≲1e-11) + entropy sign of the mimetic pitch-angle operator; allocation-free apply!. - A3: Δ_cos even / Δ_sin odd under ξ-reflection, spectrally exact projections. - A7: ⟨∂²h/∂x²⟩_Ω = 0 to 1e-10 across Ω and prefactors (coefficient-free). - A8: y_c-block σ_min monitor is finite/positive and detects an artificially singularized pencil. - Preconditioner gate: YBlockJacobi cuts GMRES iterations >2× at identical solutions; far-field BC rows; pseudo-arclength fold detection; species + gated-frames plumbing. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_016pUwoFRo9a5AjF8HuwcZMr --- test/runtests.jl | 1 + test/runtests_islands_solve.jl | 227 +++++++++++++++++++++++++++++++++ 2 files changed, 228 insertions(+) create mode 100644 test/runtests_islands_solve.jl diff --git a/test/runtests.jl b/test/runtests.jl index 7679f942..98a7bfb5 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -38,4 +38,5 @@ else include("./runtests_rerun_from_h5.jl") include("./runtests_islands_grids.jl") include("./runtests_islands_operators.jl") + include("./runtests_islands_solve.jl") end diff --git a/test/runtests_islands_solve.jl b/test/runtests_islands_solve.jl new file mode 100644 index 00000000..2a56c7cf --- /dev/null +++ b/test/runtests_islands_solve.jl @@ -0,0 +1,227 @@ +# runtests_islands_solve.jl +# +# Islands M2 — Level-0 solve machinery, structural verification gates +# (docs/src/islands/design/05 §A; the M2 milestone contract): +# A5 zero-drive null: g ≡ 0 ⇒ residual = machine zero; Newton converges trivially. +# A1+ assembled solve-MMS: Newton–Krylov recovers the manufactured state at design order. +# A8 y_c matching-block smallest-singular-value conditioning monitor. +# A4 (L0) exact discrete particle conservation + entropy sign of the mimetic +# pitch-angle collision operator. +# A3 Δ_cos even / Δ_sin odd parity under ξ-reflection (manufactured J̄_∥). +# A7 the coefficient-free closure identity ⟨∂²h/∂x²⟩_Ω = 0. +# + preconditioner quality (GMRES iteration reduction), far-field BC rows, +# pseudo-arclength fold detection, species/frames plumbing. +# +# STRUCTURAL (pre-physics) checks: manufactured order-unity coefficients only. +# Every physics coefficient in src/ is a [VERIFY]-gated supplied parameter +# (QUESTIONS Q2–Q4); the York-gate physics benchmarks stay skipped in +# benchmarks/islands/ until human clearance. + +using LinearAlgebra + +const IslM2 = GeneralizedPerturbedEquilibrium.Islands +const PS2 = IslM2.PhaseSpace +const Op2 = IslM2.Operators +const So2 = IslM2.Solvers +const V2 = IslM2.Verify +const Mo2 = IslM2.Moments +const Fi2 = IslM2.Fields +const Sp2 = IslM2.SpeciesLists +const Fr2 = IslM2.Frames + +_sgrid(n; ny=n) = PS2.IslandGrid(; nx=n, nxi=8, ny=ny, nE=2, halfwidth_x=6.0, clustering_x=1.0, + y_max=4.0, y_c=1.0, clustering_y=0.8, order=4) + +@testset "Islands L0 solve machinery (M2)" begin + + @testset "species plumbing (02 §1, D3)" begin + bg = Sp2.Maxwellian(; n=1.0, T=1.0, dlnn_dr=-1.0) + ion = Sp2.Species(; name=:D, Z=1.0, m=1.0, background=bg, role=Sp2.Bulk) + trc = Sp2.Species(; name=:Dtrace, Z=1.0, m=1.0, background=Sp2.Maxwellian(; n=1e-4, T=1.0), role=Sp2.Trace) + @test Sp2.validate_species([ion, trc]) == [ion, trc] + @test Sp2.is_bulk(ion) && Sp2.is_trace(trc) + @test Sp2.bulk_species([ion, trc]) == [ion] + # the L0 test pair: trace deuterium copy of the bulk passes the criteria + @test isempty(Sp2.check_trace_criteria([ion, trc])) + # a heavy trace at bulk-like density violates and is flagged (warn, never degrade) + w = Sp2.Species(; name=:W, Z=40.0, m=92.0, background=Sp2.Maxwellian(; n=0.01, T=1.0), role=Sp2.Trace) + @test Sp2.check_trace_criteria([ion, w]) == [:W] + # structural validation + @test_throws ArgumentError Sp2.validate_species([trc]) # no Bulk + @test_throws ArgumentError Sp2.validate_species([ion, ion]) # duplicate names + end + + @testset "frames: gated conventions poison, mechanics work (01 §5)" begin + conv = Fr2.FrameConvention() # all NaN until human-cleared (Q3) + @test !Fr2.is_cleared(conv) + @test isnan(Fr2.omega_dia_form(2, 1.0, -1.0, 2.0, conv)) + @test isnan(Fr2.effective_dlnn_form(-1.0, 1.0, 0.5, conv)) + # the frame-invariant combination is pure bookkeeping + @test Fr2.frame_shift(1.7, 0.4) ≈ 1.3 + # parameter-vector validation + p = Fr2.Level0Parameters(; w_hat=1.0, omega_E_hat=0.0, epsilon=0.1, inv_Lq_hat=1.0, q_s=2.0) + @test p.tau == 1.0 + @test_throws ArgumentError Fr2.Level0Parameters(-1.0, 0.0, 0.1, 1.0, 2.0, 1.0, Dict{Symbol,Float64}()) + end + + @testset "A4 — mimetic pitch operator: exact conservation + entropy sign" begin + g = _sgrid(9) + P = @. g.y.nodes * (4.0 - g.y.nodes) + 0.1 # arbitrary positive test profile + wm = @. 1.0 + 0.1 * g.y.nodes + K, Wq = Op2.conservative_pitch_operator(g.y, P, wm) + for gv in (sin.(g.y.nodes) .+ 0.3 .* g.y.nodes .^ 2, exp.(-g.y.nodes), g.y.nodes) + @test abs(dot(Wq, K * gv)) < 1e-11 # particle conservation, machine level + @test dot(gv .* Wq, K * gv) <= 1e-13 # entropy sign (0 only for constants) + end + @test abs(dot(ones(g.y.n) .* Wq, K * ones(g.y.n))) < 1e-12 # constants in the null space + @test_throws ArgumentError Op2.conservative_pitch_operator(g.y, -P, wm) + # the term applies c ⋅ (K g) and is allocation-free + nx, nξ, ny, nE, nσ = PS2.nnodes(g) + c4 = fill(2.0, nx, nξ, nE, nσ) + term = Op2.PitchAngleDiffusion(K, c4) + U, = V2.manufactured_state(g) + R = Op2.IslandState(g) + cache = Op2.IslandCache(g) + Op2.apply!(R, term, U, g, cache) + @test R.g[3, 2, :, 1, 1] ≈ 2.0 .* (K * U.g[3, 2, :, 1, 1]) + @test (@allocated Op2.apply!(R, term, U, g, cache)) == 0 + end + + @testset "A5 — zero-drive null test" begin + g = _sgrid(7; ny=7) + setup = V2.zero_drive_setup(g) + r = ones(setup.N) + setup.f(r, zeros(setup.N)) + @test maximum(abs, r) == 0.0 # residual is EXACTLY machine zero + # Newton from a small perturbation falls back to the zero state + sol = So2.newton_krylov(setup.f, 1e-3 .* sin.(1:setup.N); rtol=1e-12, atol=1e-12) + @test sol.converged + @test norm(sol.u) < 1e-9 + end + + @testset "A1 — assembled solve-MMS at design order" begin + r17 = V2.solve_mms(17) + r33 = V2.solve_mms(33) + @test r17.converged && r33.converged + # solution error against the manufactured state converges at design order + @test log(r17.err / r33.err) / log(33 / 17) > 3.3 + @test r33.err < 5e-3 + end + + @testset "preconditioner: y-block Jacobi with TSVD cuts GMRES iterations (04 §5)" begin + g = _sgrid(9) + nx, nξ, ny, nE, nσ = PS2.nnodes(g) + P = @. g.y.nodes * (4.0 - g.y.nodes) # degenerate endpoints: zero-flux built in + K, = Op2.conservative_pitch_operator(g.y, P, ones(ny)) + cstiff = fill(30.0, nx, nξ, nE, nσ) # stiff collisional pencil + shift = fill(-1.0, nx, nξ, ny, nE, nσ) + stack = Op2.IslandStack((Op2.PitchAngleDiffusion(K, cstiff), Op2.RadiationSink(shift)), + Op2.Quasineutrality(1.3)) + f0! = So2.flat_residual(stack, g) + N = Op2.statelength(g) + b = sin.((1:N) ./ 7) + f!(out, u) = (f0!(out, u); out .-= b; out) + pc = So2.YBlockJacobi(g, (ix, iξ, iE, iσ) -> I(ny) + cstiff[ix, iξ, iE, iσ] .* K; phi_scale=-1.3) + s0 = So2.newton_krylov(f!, zeros(N); rtol=1e-10, memory=300) + s1 = So2.newton_krylov(f!, zeros(N); rtol=1e-10, memory=300, precond=pc) + @test s0.converged && s1.converged + @test maximum(abs, s0.u .- s1.u) < 1e-8 # same solution + @test s1.gmres_iters < s0.gmres_iters ÷ 2 # preconditioner earns its keep + end + + @testset "far-field BCs replace the boundary residual rows (01 §3)" begin + g = _sgrid(7; ny=7) + nx, nξ, ny, nE, nσ = PS2.nnodes(g) + U, = V2.manufactured_state(g) + bc = Op2.FarFieldConditions(0.1 .+ zeros(nξ, ny, nE, nσ), 0.2 .+ zeros(nξ, ny, nE, nσ), + fill(0.3, nξ), fill(0.4, nξ)) + stack = V2.build_stack(g) + R = Op2.IslandState(g) + cache = Op2.IslandCache(g) + Op2.residual!(R, U, stack, g, cache, bc) + @test R.g[1, 2, 3, 1, 1] ≈ U.g[1, 2, 3, 1, 1] - 0.1 + @test R.g[nx, 2, 3, 1, 2] ≈ U.g[nx, 2, 3, 1, 2] - 0.2 + @test R.Φ[1, 5] ≈ U.Φ[1, 5] - 0.3 + @test R.Φ[nx, 5] ≈ U.Φ[nx, 5] - 0.4 + # interior rows are untouched by the BC application + R2 = Op2.IslandState(g) + Op2.residual!(R2, U, stack, g, cache) + @test R.g[2:(nx-1), :, :, :, :] == R2.g[2:(nx-1), :, :, :, :] + end + + @testset "A8 — y_c matching-block conditioning monitor" begin + g = _sgrid(7; ny=7) + setup = V2.zero_drive_setup(g) + J = So2.dense_jacobian(setup.f, zeros(setup.N)) + mon = V2.yc_block_sigma_min(J, g) + @test isfinite(mon.sigma_min) && mon.sigma_min > 0 + @test all(mon.pencil .>= 1) + # the monitor detects an artificially singularized pencil block (the + # silent-noise regression of L23 §4.2 must be *tested for*) + idx = [Op2.g_flat_index(g, 1, 1, iy, 1, 1) for iy in 3:5] + Jsing = copy(J) + Jsing[idx, :] .= 0.0 + @test V2.yc_block_sigma_min(Jsing, g).sigma_min < 1e-14 + end + + @testset "A3 — Δ_cos even / Δ_sin odd under ξ-reflection" begin + g = _sgrid(9) + J = [exp(-x^2) * (2.0 + 1.5 * cos(ξ) + 0.7 * sin(ξ)) for x in g.x.nodes, ξ in g.ξ.nodes] + Jr = [exp(-x^2) * (2.0 + 1.5 * cos(-ξ) + 0.7 * sin(-ξ)) for x in g.x.nodes, ξ in g.ξ.nodes] + d = Mo2.delta_moments(J, g; prefactor_cos=1.0, prefactor_sin=1.0) + dr = Mo2.delta_moments(Jr, g; prefactor_cos=1.0, prefactor_sin=1.0) + @test d.Δcos ≈ dr.Δcos atol = 1e-12 # even + @test d.Δsin ≈ -dr.Δsin atol = 1e-12 # odd + @test abs(d.Δsin) > 0.1 # the projection actually sees the sin part + # ξ-projection is spectrally exact: a pure cos ξ current has zero sin moment + Jc = [cos(ξ) for x in g.x.nodes, ξ in g.ξ.nodes] + @test abs(Mo2.delta_moments(Jc, g; prefactor_cos=1.0, prefactor_sin=1.0).Δsin) < 1e-13 + end + + @testset "moments: J̄_∥ assembly and Ω-average diagnostics" begin + g = _sgrid(9) + nx, nξ, ny, nE, nσ = PS2.nnodes(g) + U, = V2.manufactured_state(g) + W = ones(ny, nE, nσ) + ion = Sp2.Species(; name=:D, Z=1.0, m=1.0, background=Sp2.Maxwellian(; n=1.0, T=1.0), role=Sp2.Bulk) + anti = Sp2.Species(; name=:A, Z=-1.0, m=1.0, background=Sp2.Maxwellian(; n=1.0, T=1.0), role=Sp2.Bulk) + Jp = zeros(nx, nξ) + # equal & opposite charges with identical g cancel exactly + Mo2.parallel_current!(Jp, [U.g, U.g], [ion, anti], [W, W], g) + @test maximum(abs, Jp) < 1e-14 + # single species with W ≡ 1 reduces to the plain velocity moment + Mo2.parallel_current!(Jp, [U.g], [ion], [W], g) + Mref = zeros(nx, nξ) + Op2.velocity_moment!(Mref, U.g, g) + @test Jp ≈ Mref + # ⟨1⟩_Ω = 1 outside and inside the separatrix; constant J has no polarization part + @test Mo2.omega_average((x, ξ) -> 1.0, 1.5, 1.0) ≈ 1.0 rtol = 1e-8 + @test Mo2.omega_average((x, ξ) -> 1.0, 0.2, 1.0) ≈ 1.0 rtol = 1e-6 + cs = Mo2.channel_split((x, ξ) -> 3.0, 2.0, 1.0) + @test cs.bs ≈ 3.0 rtol = 1e-8 + @test abs(cs.pol(0.5, 1.0)) < 1e-8 + @test Mo2.omega_label(0.0, 0.0, 1.0) ≈ -1.0 # O-point + @test Mo2.omega_label(1.0, float(π), 1.0) ≈ 3.0 + end + + @testset "A7 — flattened-electron identity ⟨∂²h/∂x²⟩_Ω = 0 (coefficient-free)" begin + for Ω in (1.2, 2.0, 5.0), pref in (1.0, 3.7) # prefactor-independent + @test abs(Fi2.flat_average_d2h_dx2(Ω, 1.0; prefactor=pref)) < 1e-10 + end + @test Fi2.h_profile(0.5; prefactor=1.0) == 0.0 # exactly flat inside the separatrix + @test Fi2.h_profile(2.0; prefactor=1.0) > 0.0 + @test Fi2.Q_omega(3.0) > Fi2.Q_omega(1.5) # Q grows with Ω + @test !Fi2.is_cleared(Fi2.ElectronClosure()) # closure constants stay NaN-gated (Q3) + @test isnan(Fi2.ElectronClosure().k_HS) + end + + @testset "pseudo-arclength continuation detects the toy fold (03 §3)" begin + ftoy!(out, u, p) = (out[1] = u[1]^2 + p; out) + pa = So2.pseudo_arclength(ftoy!, [1.0], -1.0; ds=0.3, nsteps=15, rtol=1e-12, atol=1e-12) + @test length(pa.ps) > 10 # stepped through, no stall at the fold + @test !isempty(pa.folds) # the fold at p = 0 is detected + @test maximum(pa.ps) < 0.05 # never steps past the fold parameter + # both branches visited: u > 0 before the fold, u < 0 after + @test any(z -> z[1] > 0.5, pa.us) && any(z -> z[1] < -0.5, pa.us) + end +end From b4000368bacb514cfc36694e174e342921af7478 Mon Sep 17 00:00:00 2001 From: logan-nc Date: Wed, 8 Jul 2026 14:57:41 -0400 Subject: [PATCH 04/10] ISLANDS - NEW FEATURE - Skipped B-ladder benchmarks + islands_l0_structural regression case MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - benchmarks/islands/ (+ figures/): the docs/05 B-ladder scripts B2 (large-w limits), B4 (polarization ω_E structure), B5a/b/c (York threshold triangle) — all SKIPPED, each naming the QUESTIONS.md entries (Q2-Q4) whose human clearance un-gates it. Un-skipping by filling in a coefficient is the forbidden action; the scripts say so. - regression-harness: new computed case islands_l0_structural tracking the structural numbers that silently move if the discretization/solver/quadratures drift — solve-MMS error + Newton/GMRES iteration counts (nx=17), the A7 closure identity, and the A8 y_c-block sigma_min. Verified locally: err=5.254e-2, 6 Newton / 1210 GMRES, A7=8.0e-17, sigma_min=0.1139. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_016pUwoFRo9a5AjF8HuwcZMr --- benchmarks/islands/README.md | 23 +++++++ .../islands/benchmark_B2_large_w_limits.jl | 14 +++++ .../benchmark_B4_polarization_omegaE.jl | 16 +++++ .../islands/benchmark_B5_york_thresholds.jl | 22 +++++++ benchmarks/islands/figures/README.md | 9 +++ .../cases/islands_l0_structural.toml | 60 +++++++++++++++++++ regression-harness/src/runner.jl | 34 +++++++++++ 7 files changed, 178 insertions(+) create mode 100644 benchmarks/islands/README.md create mode 100644 benchmarks/islands/benchmark_B2_large_w_limits.jl create mode 100644 benchmarks/islands/benchmark_B4_polarization_omegaE.jl create mode 100644 benchmarks/islands/benchmark_B5_york_thresholds.jl create mode 100644 benchmarks/islands/figures/README.md create mode 100644 regression-harness/cases/islands_l0_structural.toml diff --git a/benchmarks/islands/README.md b/benchmarks/islands/README.md new file mode 100644 index 00000000..fe273953 --- /dev/null +++ b/benchmarks/islands/README.md @@ -0,0 +1,23 @@ +# Islands benchmark ladder (docs/05) + +Benchmark scripts for the Islands verification ladder +(`docs/src/islands/design/05-verification.md`). Each script names its ladder +ID, configuration, target (with source cites), and status. + +**Status policy (the `[VERIFY]` discipline, `src/Islands/CLAUDE.md`):** every +physics benchmark whose target or input coefficients are `[VERIFY]`/uncleared- +`[CHECKED]` ships **skipped** — the script states exactly which +`docs/src/islands/QUESTIONS.md` entries gate it and exits without running. +Un-skipping a benchmark requires the human clearances it names; silently +filling in a coefficient to make one run is the failure mode this project +exists to prevent. The structural A-ladder (A1–A8) runs in CI via +`test/runtests_islands_*.jl`, not here. + +Figure scripts (docs/07 pipeline) live in `figures/` and read archived +benchmark data only. + +| Script | Ladder ID | Status | +|---|---|---| +| `benchmark_B2_large_w_limits.jl` | B2 | SKIPPED — gated on Q2/Q3/Q4 | +| `benchmark_B4_polarization_omegaE.jl` | B4 | SKIPPED — gated on Q2/Q3 | +| `benchmark_B5_york_thresholds.jl` | B5a/B5b/B5c | SKIPPED — gated on Q2/Q3/Q4 | diff --git a/benchmarks/islands/benchmark_B2_large_w_limits.jl b/benchmarks/islands/benchmark_B2_large_w_limits.jl new file mode 100644 index 00000000..f9123e84 --- /dev/null +++ b/benchmarks/islands/benchmark_B2_large_w_limits.jl @@ -0,0 +1,14 @@ +# benchmark_B2_large_w_limits.jl — ladder B2 (docs/05 §B) +# +# Target: large-w analytic limits — Δ_bs + Δ_cur ∝ 1/w with coefficient against +# WCHH96 Eq. (85) mapped to the island frame (Diss19 p. 86 frame caveat), and the +# Δ_pol ∝ 1/w³ tail [CHECKED: Diss19 pp. 84–86; D21 Fig. 8-class curves]. +# +# STATUS: SKIPPED — gated per docs/src/islands/QUESTIONS.md: +# Q3 the Δ moment prefactors and electron-closure constants are uncleared +# Q4 WCHH96 is not yet in the docs/08 reference library (cited only via +# transcriptions) and the ψ̃ amplitude carries an open [VERIFY] +# Q2 D7 (re-derived equation set) unratified. + +println("SKIPPED: B2 large-w limits — gated on QUESTIONS Q2, Q3, Q4") +println(" (WCHH96 not in the reference library; ψ̃ [VERIFY] open; closure constants uncleared).") diff --git a/benchmarks/islands/benchmark_B4_polarization_omegaE.jl b/benchmarks/islands/benchmark_B4_polarization_omegaE.jl new file mode 100644 index 00000000..d16f9b08 --- /dev/null +++ b/benchmarks/islands/benchmark_B4_polarization_omegaE.jl @@ -0,0 +1,16 @@ +# benchmark_B4_polarization_omegaE.jl — ladder B4 (docs/05 §B) +# +# Target: polarization structure — (i) Wilson–Connor collisionless and Smolyakov +# collisional scalings; (ii) Δ_pol ∝ ω_E² away from zero with the sign reversal +# at ω_E ≈ −0.89 ω_dia,e, reversal point insensitive to w/ρ_θi; (iii) +# torque-balance roots at discrete ω̂_E (Diss19 benchmark root ω₀ = −0.93 +# ω_dia,e) [CHECKED: D23b Fig. 8; Diss19 Fig. 4.18]. +# +# STATUS: SKIPPED — gated per docs/src/islands/QUESTIONS.md: +# Q3 the frame-convention signs (src/Islands/frames/) are NaN-gated until +# cleared — the ω_E-dependence of Δ_pol is exactly the physics the frames +# module must own before any sign-bearing benchmark runs +# Q2 D7 unratified (L0 equation set). + +println("SKIPPED: B4 polarization ω_E structure — gated on QUESTIONS Q2, Q3") +println(" (frame-convention signs NaN-gated; L0 equation set unratified).") diff --git a/benchmarks/islands/benchmark_B5_york_thresholds.jl b/benchmarks/islands/benchmark_B5_york_thresholds.jl new file mode 100644 index 00000000..1766b183 --- /dev/null +++ b/benchmarks/islands/benchmark_B5_york_thresholds.jl @@ -0,0 +1,22 @@ +# benchmark_B5_york_thresholds.jl — ladder B5a/B5b/B5c (docs/05 §B) +# +# Targets (transcribed, awaiting human sign-off — see docs/src/islands/design/05): +# B5a DK-NTM threshold w_c ≃ 2.76 ρ_θi (half-width) ≡ 8.73 ρ_bi at ε = 0.1, +# :original drift model [CHECKED: I19 Fig. 9; PRL p. 4] +# + open [VERIFY]: run collisionality (I19 §4.2 ν_★ = 0.01 vs L23 p. 82 ν_★ = 1e-3). +# B5b RDK-NTM improved-model threshold w_c ≈ 0.45 ρ_θi ≡ 1.46 ρ_bi half-width +# [CHECKED: D21 abstract + Fig. 8; D23a abstract] +# B5c kokuchou finite-ν_★ surface w_c ≈ 0.440 ρ̂_θi + 0.0178 ν_★ − 7.54e-5 +# [CHECKED: L23 Eqs. 6.3.1–6.3.2], L23-amended equation set. +# +# STATUS: SKIPPED — running this requires assigning Level-0 physics +# coefficients that are at most [CHECKED] and not human-cleared: +# Q2 ratify D7 (re-derived L0 equation set) and D8 (the B5a/b/c triangle) +# Q3 clear the L0 coefficient set (ω̂_D/L̂_B toggle, collision kernel, +# electron closure, quasineutrality closure) +# Q4 resolve the ψ̃ amplitude [VERIFY] and the B5a collisionality [VERIFY] +# per docs/src/islands/QUESTIONS.md. Do not fill in a number to make this run. + +println("SKIPPED: B5a/B5b/B5c York thresholds — gated on QUESTIONS Q2, Q3, Q4") +println(" (uncleared [CHECKED] L0 coefficients; D7/D8 unratified).") +println(" See docs/src/islands/QUESTIONS.md and docs/src/islands/design/05-verification.md.") diff --git a/benchmarks/islands/figures/README.md b/benchmarks/islands/figures/README.md new file mode 100644 index 00000000..f0b2ad83 --- /dev/null +++ b/benchmarks/islands/figures/README.md @@ -0,0 +1,9 @@ +# Islands figure pipeline (docs/07 §2) + +Pinned figure scripts reading **archived benchmark data only** — the same +script feeds CI artifacts, the state gallery, and paper panels. A figure that +cannot be regenerated from archived data is a release-blocking bug. + +Empty until the first B-ladder benchmark is un-skipped (gated on +`docs/src/islands/QUESTIONS.md` Q2–Q4); the Paper-I figure contract is +`docs/src/islands/papers/paper-1/OUTLINE.md`. diff --git a/regression-harness/cases/islands_l0_structural.toml b/regression-harness/cases/islands_l0_structural.toml new file mode 100644 index 00000000..091b4949 --- /dev/null +++ b/regression-harness/cases/islands_l0_structural.toml @@ -0,0 +1,60 @@ +# Regression case: Islands L0 solve machinery, structural (pre-physics) quantities. +# A "computed" case (kind = "computed", no example_dir) tracking the M2 structural +# gates: the solve-level MMS error and solver iteration counts (Newton-Krylov on the +# manufactured advective stack at nx = 17), the coefficient-free flattened-electron +# closure identity |_Omega| at Omega = 2, and the y_c-block smallest singular +# value (the L23 SS4.2 silent-noise tripwire). The physics B-ladder stays skipped until +# [VERIFY] clearance (docs/src/islands/QUESTIONS.md Q2-Q4); these are the numbers that +# silently move if the discretization, solver, or quadratures drift. +[case] +name = "islands_l0_structural" +description = "Islands L0 structural: solve-MMS error, solver iterations, A7 identity, y_c sigma_min" +kind = "computed" + +[quantities.solve_mms_err] +h5path = "islands/solve_mms_err" +type = "real_scalar" +extract = "value" +label = "solve-MMS max error (nx=17)" +noise_threshold = 1e-8 +order = 10 + +[quantities.newton_iters] +h5path = "islands/newton_iters" +type = "real_scalar" +extract = "value" +label = "Newton iterations" +noise_threshold = 0.0 +order = 11 + +[quantities.gmres_iters] +h5path = "islands/gmres_iters" +type = "real_scalar" +extract = "value" +label = "GMRES iterations (total)" +noise_threshold = 0.0 +order = 12 + +[quantities.a7_identity] +h5path = "islands/a7_identity" +type = "real_scalar" +extract = "value" +label = "|_Omega| (A7)" +noise_threshold = 1e-12 +order = 13 + +[quantities.yc_sigma_min] +h5path = "islands/yc_sigma_min" +type = "real_scalar" +extract = "value" +label = "y_c block sigma_min (A8)" +noise_threshold = 1e-10 +order = 14 + +[quantities.runtime] +h5path = "" +type = "runtime" +extract = "value" +label = "Runtime (s)" +noise_threshold = 0.0 +order = 90 diff --git a/regression-harness/src/runner.jl b/regression-harness/src/runner.jl index 8705cb4d..5bcbd20c 100644 --- a/regression-harness/src/runner.jl +++ b/regression-harness/src/runner.jl @@ -109,6 +109,38 @@ open(ARGS[2], "w") do f end """ +# Islands L0 structural regression: the solve-level MMS (Newton-Krylov recovers +# the manufactured state), the coefficient-free A7 closure identity, and the A8 +# y_c-block conditioning monitor. Tracks the structural (pre-physics) numbers +# that would silently move if the discretization, solver, or quadratures drift; +# the physics B-ladder stays skipped until [VERIFY] clearance (QUESTIONS Q2-Q4). +const COMPUTED_ISLANDS_SCRIPT_TEMPLATE = """ +using Pkg +%INSTANTIATE% +using GeneralizedPerturbedEquilibrium +using HDF5 +const Isl = GeneralizedPerturbedEquilibrium.Islands +t_start = time() +r = Isl.Verify.solve_mms(17) +a7 = Isl.Fields.flat_average_d2h_dx2(2.0, 1.0) +grid = Isl.PhaseSpace.IslandGrid(nx=7, nxi=8, ny=7, nE=2, halfwidth_x=6.0, clustering_x=1.0, + y_max=4.0, y_c=1.0, clustering_y=0.8, order=4) +setup = Isl.Verify.zero_drive_setup(grid) +J = Isl.Solvers.dense_jacobian(setup.f, zeros(setup.N)) +mon = Isl.Verify.yc_block_sigma_min(J, grid) +elapsed = time() - t_start +h5open(ARGS[1], "w") do fid + fid["islands/solve_mms_err"] = r.err + fid["islands/newton_iters"] = Float64(r.iterations) + fid["islands/gmres_iters"] = Float64(r.gmres_iters) + fid["islands/a7_identity"] = abs(a7) + fid["islands/yc_sigma_min"] = mon.sigma_min +end +open(ARGS[2], "w") do f + println(f, elapsed) +end +""" + """ Run GPEC for a single commit/ref and case. Dispatches to run_local for the working tree or run_at_commit for a git ref. @@ -141,6 +173,8 @@ function _computed_script_template(case_spec::CaseSpec) return COMPUTED_GGJ_SCRIPT_TEMPLATE elseif case_spec.name == "efit_fixedbdy_separatrix" return COMPUTED_SEPARATRIX_SCRIPT_TEMPLATE + elseif case_spec.name == "islands_l0_structural" + return COMPUTED_ISLANDS_SCRIPT_TEMPLATE end error("No computed-script template registered for case '$(case_spec.name)'") end From 1342e6cae10124969d02efc4f32e1530a039c071 Mon Sep 17 00:00:00 2001 From: logan-nc Date: Wed, 8 Jul 2026 14:57:41 -0400 Subject: [PATCH 05/10] ISLANDS - MINOR - Paper-I OUTLINE (figure contract) + M2 docs/LOG MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - docs/src/islands/papers/paper-1/OUTLINE.md: the Level-0 figure contract (docs/07 §3), claims → figures → ladder IDs. C1-C3 (discretization order, solver conditioning, conservation structure) are green as CI artifacts; C4-C8 (neoclassics, large-w limits, the York triangle, the Δ_pol(ω_E) reversal, the L23 electron-Δ_pol question) are gated on QUESTIONS Q2-Q4. - docs/src/islands.md: M2 status (all seven submodules, gating summary). - LOG.md: M2 session entry, including the solve-well-posedness lesson (generic y-diffusion without BCs is unstable; the mimetic degenerate form + far-field x-BCs are the correct structure). Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_016pUwoFRo9a5AjF8HuwcZMr --- docs/src/islands.md | 44 ++++++++++++++++------ docs/src/islands/LOG.md | 41 ++++++++++++++++++++ docs/src/islands/papers/paper-1/OUTLINE.md | 44 ++++++++++++++++++++++ 3 files changed, 117 insertions(+), 12 deletions(-) create mode 100644 docs/src/islands/papers/paper-1/OUTLINE.md diff --git a/docs/src/islands.md b/docs/src/islands.md index 52d78479..c56f20fc 100644 --- a/docs/src/islands.md +++ b/docs/src/islands.md @@ -6,26 +6,46 @@ SLAYER, generalizing the Modified Rutherford Equation. It is under active development. The design documents live under `islands/design/` in the documentation source tree, and the module conventions in `src/Islands/CLAUDE.md`. -## Status — milestone M1 (skeleton) +## Status — M1 skeleton + M2 Level-0 solve machinery (structure, gated physics) -M1 lands the numerical skeleton, not the physics numbers (module `CLAUDE.md`, the -`[VERIFY]` policy): +M1 landed the numerical skeleton and M2 the Level-0 solve machinery — structure +only, no physics numbers (module `CLAUDE.md`, the `[VERIFY]` policy): - `Islands.PhaseSpace` — the `(x, ξ, λ→y, E, σ)` phase-space grids with layer-clustered mappings (design `04 §1`): Fourier spectral `∂ξ`, high-order finite-difference `∂x`/`∂y` on stretched grids, and Gauss energy quadrature. Pure numerics; no physics coefficients. - `Islands.Operators` — the `AbstractTerm` operator stack and residual assembly - (design `03 §2`) as allocation-free, AD-compatible *structural stubs*. Every - physics coefficient is a supplied data field, never a literal — literature - numbers stay `[VERIFY]`/`[CHECKED]`-gated until human-cleared. - - `Islands.Verify` — the manufactured-solution (MMS) and AD-vs-finite-difference - JVP harness backing verification ladder **A1/A2** (design `05 §A`), exercised - by `test/runtests_islands_{grids,operators}.jl`. + (design `03 §2`) as allocation-free, AD-compatible structure, including the + mimetic (exactly conservative) pitch-angle diffusion and the neoclassical- + matching far-field boundary conditions (`01 §3` — never bare Neumann). Every + physics coefficient is a supplied data field, never a literal. + - `Islands.SpeciesLists` — first-class species arrays (`02 §1`, Decision D3): + backgrounds, `Bulk`/`Trace` roles, trace-criteria checks that warn and never + silently degrade. + - `Islands.Frames` — THE frequency/frame conversion module (`01 §5`): the + conversion *forms* with every sign/normalization a NaN-gated + `FrameConvention` field until human-cleared (QUESTIONS Q3). + - `Islands.Fields` — the Level-0 quasineutrality closure structure: `Q(Ω)`, + `h(Ω)` (supplied prefactor), the coefficient-free identity + `⟨∂²h/∂x²⟩_Ω = 0` (ladder A7), and the NaN-gated `ElectronClosure` constants. + - `Islands.Moments` — `J̄_∥` assembly and the `Δ_cos`/`Δ_sin` Ampère + projections (`01 §4`) with **required, gated** prefactors; `Ω`-average and + channel-split diagnostics. + - `Islands.Solvers` — matrix-free Newton–Krylov (ForwardDiff JVP + GMRES, + Eisenstat–Walker forcing), the TSVD-regularized physics-block preconditioner + skeleton (`04 §3, §5`), tiny-grid dense debug Jacobian, and pseudo-arclength + continuation with fold detection. + - `Islands.Verify` — MMS/JVP harness (ladder A1/A2), solve-level MMS and + zero-drive configurations (A5), and the `y_c`-block conditioning monitor + (A8), exercised by `test/runtests_islands_{grids,operators,solve}.jl`. -The physics operators (drift-frequency coefficients, collision kernels, the -Δ moments and York thresholds) land in later milestones and remain gated until -their `[VERIFY]` tags are cleared. +Structural gates **A1–A5, A7 (coefficient-free part), A8** run in CI. The +physics numbers (drift-frequency coefficients, collision kernels, closure +constants, the Δ prefactors, York thresholds) remain `[VERIFY]`-gated: the +B-ladder benchmarks in `benchmarks/islands/` ship skipped, each naming the +`QUESTIONS.md` entries (Q2–Q4) whose human clearance un-gates it. The Paper-I +figure contract is `docs/src/islands/papers/paper-1/OUTLINE.md`. ## API Reference diff --git a/docs/src/islands/LOG.md b/docs/src/islands/LOG.md index 3c7dfba9..1022300a 100644 --- a/docs/src/islands/LOG.md +++ b/docs/src/islands/LOG.md @@ -8,6 +8,47 @@ relevant. --- +## 2026-07-08 — M2 L0 solve machinery: Newton–Krylov + moments + species/frames/fields (structure, gated physics) + +- **Contract**: `docs/src/islands/design/M2-launch-prompt.md` (interactive /goal + run). Branch `feature/islands-m2` (stacked on `feature/islands-m1`/PR #320). +- **Moved**: the full L0 solve *structure*, every physics coefficient a supplied + `[VERIFY]`-gated parameter (physics-verifier: **PASS**): + - `solvers/` — matrix-free Newton–Krylov (Krylov.jl GMRES on a preallocated + ForwardDiff JVP; Eisenstat–Walker; line search; convergence on norm AND + max-norm per `04 §5`), `YBlockJacobi` physics-block preconditioner with + TSVD-regularized pencil solves (the `04 §3` y_c treatment), dense tiny-grid + debug Jacobian, pseudo-arclength continuation with fold detection (toy fold + found at step 6 of the test problem). + - `species/` (D3 plumbing), `frames/` (conversion forms, NaN-gated + `FrameConvention`), `fields/` (Q(Ω)/h(Ω) structure + NaN-gated + `ElectronClosure`), `moments/` (J̄_∥, Δ projections with required gated + prefactors, ⟨·⟩_Ω diagnostics), operators additions (mimetic + `PitchAngleDiffusion`, `FarFieldConditions` — never bare Neumann, + `weighted_moment!`). + - **Structural gates green** (67 new tests in `runtests_islands_solve.jl`): + A5 (residual exactly 0 at g≡0), solve-MMS at design order (3.98 observed, + nx 17→33), A4 (conservation ≲1e-11, entropy sign exact), A3 parity, A7 + ⟨∂²h/∂x²⟩_Ω ≈ 1e-16, A8 σ_min monitor + singular detection. Preconditioner + cuts a stiff collisional solve from 79.5 s/28 Newton to 0.6 s/7 (GMRES + 1700→200-class); all new kernels pass `--check-bounds=yes`. + - `benchmarks/islands/` created: B2/B4/B5 scripts **skipped**, each naming its + gating QUESTIONS IDs; `regression-harness` case `islands_l0_structural` + (solve-MMS err 5.254e-2, 6 Newton/1210 GMRES, A7 8.0e-17, σ_min 0.1139). + - Paper-I figure contract: `docs/src/islands/papers/paper-1/OUTLINE.md` + (claims C1–C3 green as CI artifacts; C4–C8 gated on Q2–Q4). +- **Physics debugging note**: the first solve-MMS attempt failed to converge — + the generic `Collisions` (a_y ∂²y) term has no y-BCs, so its BVP + discretization is unstable under refinement; the *mimetic* divergence form + (degenerate P → 0 endpoints, zero-flux built in) is the correct structure and + the far-field x-BCs are what make the advective solve well-posed. Exactly the + design's point (`01 §3`, `04 §1`). +- **Blocked**: the York gates (B5a/b/c, B2, B4) and Paper-I claims C4–C8 — all + on the human clearance queue **Q2/Q3/Q4** (unchanged). +- **Next**: human clears Q2–Q4 → thin run fills the L0 coefficients from the + D7 re-derivation and un-skips the B-ladder; independent M2+ work: kinetic- + electron toggle (E4), io/ TOML section, trace-species linear pass. + ## 2026-07-08 — M1 skeleton: phase-space grids + operator stack + MMS/AD harness - **PR**: #320 (`feature/islands-m1` → `feature/islands`); full suite green. diff --git a/docs/src/islands/papers/paper-1/OUTLINE.md b/docs/src/islands/papers/paper-1/OUTLINE.md new file mode 100644 index 00000000..bfc3704d --- /dev/null +++ b/docs/src/islands/papers/paper-1/OUTLINE.md @@ -0,0 +1,44 @@ +# Paper I — OUTLINE (the Level-0 figure contract) + +> Created at level *start* per design doc `07 §3`: claims → figures → ladder +> IDs. This outline is the figure contract — agents implementing benchmarks +> know which figures are paper figures from day one. Every claim must be backed +> by a ladder ID; claims lacking one are flagged. Status reflects the +> `[VERIFY]` gating of `docs/src/islands/QUESTIONS.md` (Q2–Q4) — **no +> submission until every tag in the paper's equation set is cleared**. + +**Working title:** Formulation and verification of a generalized drift-kinetic +solver for magnetic-island stability (Islands, Level 0). + +**Indicative venue:** Phys. Plasmas (methods paper). **Gate:** Level 0 +(design `00`), i.e. ladder A + B1/B2/B4/B5a–c green with convergence artifacts. + +## Claims and figures + +| # | Claim | Figure(s) | Ladder ID(s) | Status | +|---|---|---|---|---| +| C1 | The `(x, ξ; y, E, σ)` discretization converges at design order: spectral in `ξ`, 4th-order FD on layer-clustered `x`/`y` grids, per operator and for the assembled solve | F1: MMS convergence panels (per-operator + assembled residual + assembled solve error vs. resolution) | A1, A2 | **green** (M1/M2; CI artifacts) | +| C2 | The steady-state Newton–Krylov solve is exact-Jacobian (AD), globally convergent from zero states, and its conditioning is monitored at the trapped–passing boundary (no silent-noise regime, contra L23 §4.2) | F2: Newton/GMRES convergence histories with and without the physics-block preconditioner; `σ_min(y_c)` track | A5, A8 (+ solver gates) | **green** (M2) | +| C3 | The discretized collision operator conserves particles exactly and has definite entropy sign — bootstrap-relevant structure holds discretely, not just asymptotically | F3: conservation/entropy residuals vs. resolution and profile | A4 | **green** (L0 parts, M2) | +| C4 | In the no-island limit the solver reproduces standard local neoclassics (bootstrap current vs. Sauter/NEO) — the strongest global check of the velocity-space discretization | F4: `J_bs` vs. `ν_★` against NEO/Sauter | B1 | **gated** — needs cleared L0 coefficient set (Q2, Q3) + external NEO runs | +| C5 | At large `w` the solver recovers the analytic MRE limits: `Δ_bs + Δ_cur ∝ 1/w` (WCHH96 Eq. 85, frame-mapped) and `Δ_pol ∝ 1/w³` | F5: `Δ` channels vs. `w` with analytic asymptotes | B2 | **gated** — Q2, Q3, Q4 (WCHH96 acquisition; `ψ̃` [VERIFY]) | +| C6 | The three-code threshold triangle is reproduced in its exact configurations: DK-NTM `w_c ≃ 2.76 ρ_θi ≡ 8.73 ρ_bi` (`:original` drift model), RDK-NTM `w_c ≈ 0.45 ρ_θi ≡ 1.46 ρ_bi` (`:improved`), kokuchou's finite-`ν_★` surface `w_c(ρ̂_θi, ν_★)` — and the 8.73 → 1.46 shift is a single drift-model toggle (E1) | F6: threshold `w_c` vs. configuration (the triangle); F7: the E1 toggle scan | B5a, B5b, B5c (E1) | **gated** — Q2 (D7/D8), Q3, Q4 (B5a collisionality) | +| C7 | The polarization contribution is frame-pinned: `Δ_pol ∝ ω_E²` away from zero with sign reversal at `ω_E ≈ −0.89 ω_dia,e`, insensitive to `w/ρ_θi`; single-`ω_E` `Δ` values are misleading (surfaces over `(w, ω_E)` are the deliverable) | F8: `Δ_pol(ω_E)` reversal curve vs. D23b Fig. 8; F9: `Δ(w, ω_E)` surface | B4 | **gated** — Q2, Q3 (frame-convention signs) | +| C8 (candidate headline) | Resolution of L23's open question: the stabilizing *electron* `Δ_pol` at `ω_E = 0` — reproduced or refuted by the `ω_E` scan with kinetic vs. flattened electrons (E4) | F10: electron-channel `Δ_pol(ω_E)` decomposition | B4 + E4 | **gated** — Q2, Q3; kinetic-electron toggle is M2+/E4 work | + +## Verification-artifact rules (docs/05 reporting) + +- Every figure names its configuration (docs/03 §2) and git SHA; no benchmark + "passes" on a single grid — convergence + tolerance archived with the result. +- Threshold numbers are reported as **half-widths** with both `ρ_θi` and + `ρ_bi = ε^{1/2} ρ_θi` stated at the run's `ε` (docs/05 rule 5). +- Disagreements with published targets are triaged per the standing rule + (docs/05: our bug / their approximation / their published-equation error / + transcription error) with `[VERIFY]` resolution logged first. + +## Dependencies for un-gating (the human clearance queue) + +`QUESTIONS.md` **Q2** (ratify D7/D8), **Q3** (clear the L0 `[CHECKED]` +coefficient set), **Q4** (resolve the `ψ̃` and B5a-collisionality `[VERIFY]`s; +acquire WCHH96 + Park 2022). C1–C3 are already green as CI artifacts; C4–C8 +un-gate in that order of effort once the queue clears. From 99f5c3e1d6ff9701d1764fbc452191dd5377c792 Mon Sep 17 00:00:00 2001 From: logan-nc Date: Wed, 8 Jul 2026 15:06:16 -0400 Subject: [PATCH 06/10] ISLANDS - CLEANUP - Format runner.jl (JuliaFormatter) Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_016pUwoFRo9a5AjF8HuwcZMr --- regression-harness/src/runner.jl | 96 ++++++++++++++++---------------- 1 file changed, 49 insertions(+), 47 deletions(-) diff --git a/regression-harness/src/runner.jl b/regression-harness/src/runner.jl index 5bcbd20c..d6aa9b21 100644 --- a/regression-harness/src/runner.jl +++ b/regression-harness/src/runner.jl @@ -2,7 +2,9 @@ Runner: orchestrates checking out commits, running GPEC, and extracting results. """ -"""Read the GPEC-only runtime from the timing file written by the subprocess.""" +""" +Read the GPEC-only runtime from the timing file written by the subprocess. +""" function _read_timing_file(path::String)::Float64 if isfile(path) return parse(Float64, strip(read(path, String))) @@ -29,7 +31,7 @@ function _materialize_rundir(example_path::String, overrides::Dict{String,Any}) for (dotted, val) in overrides ks = split(dotted, ".") d = cfg - for k in ks[1:(end - 1)] + for k in ks[1:(end-1)] d = get!(d, k, Dict{String,Any}()) end d[ks[end]] = val @@ -146,23 +148,23 @@ Run GPEC for a single commit/ref and case. Dispatches to run_local for the working tree or run_at_commit for a git ref. """ function run_commit(db::SQLite.DB, commit_hash::String, ref_name::String, - case_spec::CaseSpec, repo_root::String; - force::Bool=false, verbose::Bool=false, - no_instantiate::Bool=false) + case_spec::CaseSpec, repo_root::String; + force::Bool=false, verbose::Bool=false, + no_instantiate::Bool=false) if case_spec.kind == "computed" if commit_hash == LOCAL_REF return run_computed_local(db, case_spec, repo_root; - verbose=verbose, no_instantiate=no_instantiate) + verbose=verbose, no_instantiate=no_instantiate) end return run_computed_at_commit(db, commit_hash, ref_name, case_spec, repo_root; - force=force, verbose=verbose, no_instantiate=no_instantiate) + force=force, verbose=verbose, no_instantiate=no_instantiate) end if commit_hash == LOCAL_REF return run_local(db, case_spec, repo_root; - force=force, verbose=verbose, no_instantiate=no_instantiate) + force=force, verbose=verbose, no_instantiate=no_instantiate) end return run_at_commit(db, commit_hash, ref_name, case_spec, repo_root; - force=force, verbose=verbose, no_instantiate=no_instantiate) + force=force, verbose=verbose, no_instantiate=no_instantiate) end """ @@ -187,11 +189,11 @@ import GeneralizedPerturbedEquilibrium), reads the resulting tempfile h5 with so callers can handle store_failed_run uniformly. """ function _execute_computed(case_spec::CaseSpec, project_root::String; - verbose::Bool, no_instantiate::Bool, - stderr_buf::IO) + verbose::Bool, no_instantiate::Bool, + stderr_buf::IO) instantiate_line = no_instantiate ? "" : "Pkg.instantiate()" script_content = replace(_computed_script_template(case_spec), - "%INSTANTIATE%" => instantiate_line) + "%INSTANTIATE%" => instantiate_line) tmpscript = tempname() * ".jl" h5path = tempname() * ".h5" timingfile = tempname() * ".timing" @@ -200,8 +202,8 @@ function _execute_computed(case_spec::CaseSpec, project_root::String; if verbose run(pipeline(`julia --project=$project_root $tmpscript $h5path $timingfile`)) else - run(pipeline(`julia --project=$project_root $tmpscript $h5path $timingfile`, - stdout=devnull, stderr=stderr_buf)) + run(pipeline(`julia --project=$project_root $tmpscript $h5path $timingfile`; + stdout=devnull, stderr=stderr_buf)) end runtime_s = _read_timing_file(timingfile) if !isfile(h5path) @@ -220,18 +222,18 @@ end Run a kind="computed" case against the working tree. """ function run_computed_local(db::SQLite.DB, case_spec::CaseSpec, repo_root::String; - verbose::Bool=false, no_instantiate::Bool=false) + verbose::Bool=false, no_instantiate::Bool=false) delete_cached(db, LOCAL_REF, case_spec.name) date = Dates.format(Dates.now(), "yyyy-mm-ddTHH:MM:SS") @info "Running: $(case_spec.name) @ local (working tree, computed)" stderr_buf = IOBuffer() try extracted, runtime_s = _execute_computed(case_spec, repo_root; - verbose=verbose, - no_instantiate=no_instantiate, - stderr_buf=stderr_buf) + verbose=verbose, + no_instantiate=no_instantiate, + stderr_buf=stderr_buf) store_run(db, LOCAL_REF, "local", date, "working tree", case_spec.name, - runtime_s, extracted) + runtime_s, extracted) @info " Completed in $(round(runtime_s, digits=3))s — $(length(extracted)) quantities extracted" catch e err_msg = if e isa ProcessFailedException @@ -246,7 +248,7 @@ function run_computed_local(db::SQLite.DB, case_spec::CaseSpec, repo_root::Strin err_msg_short = length(err_msg) > 2000 ? "..." * last(err_msg, 2000) : err_msg @warn "Run failed (local computed): $(first(err_msg_short, 200))" store_failed_run(db, LOCAL_REF, "local", date, "working tree", case_spec.name, - err_msg_short) + err_msg_short) end end @@ -254,9 +256,9 @@ end Run a kind="computed" case at a specific git commit via worktree. """ function run_computed_at_commit(db::SQLite.DB, commit_hash::String, ref_name::String, - case_spec::CaseSpec, repo_root::String; - force::Bool=false, verbose::Bool=false, - no_instantiate::Bool=false) + case_spec::CaseSpec, repo_root::String; + force::Bool=false, verbose::Bool=false, + no_instantiate::Bool=false) if !force && is_cached(db, commit_hash, case_spec.name) info = get_run_info(db, commit_hash, case_spec.name) if info !== nothing @@ -277,11 +279,11 @@ function run_computed_at_commit(db::SQLite.DB, commit_hash::String, ref_name::St try worktree_path = create_worktree(commit_hash, repo_root) extracted, runtime_s = _execute_computed(case_spec, worktree_path; - verbose=verbose, - no_instantiate=no_instantiate, - stderr_buf=stderr_buf) + verbose=verbose, + no_instantiate=no_instantiate, + stderr_buf=stderr_buf) store_run(db, commit_hash, commit_info.short, commit_info.date, - commit_info.msg, case_spec.name, runtime_s, extracted) + commit_info.msg, case_spec.name, runtime_s, extracted) @info " Completed in $(round(runtime_s, digits=3))s — $(length(extracted)) quantities extracted" catch e err_msg = if e isa ProcessFailedException @@ -296,7 +298,7 @@ function run_computed_at_commit(db::SQLite.DB, commit_hash::String, ref_name::St err_msg_short = length(err_msg) > 2000 ? "..." * last(err_msg, 2000) : err_msg @warn "Run failed (computed) for $(commit_info.short): $(first(err_msg_short, 200))" store_failed_run(db, commit_hash, commit_info.short, commit_info.date, - commit_info.msg, case_spec.name, err_msg_short) + commit_info.msg, case_spec.name, err_msg_short) finally if worktree_path !== nothing remove_worktree(worktree_path, repo_root) @@ -309,8 +311,8 @@ Run GPEC in the current working tree (uncommitted changes included). Always re-runs (local results are never cached since the working tree is mutable). """ function run_local(db::SQLite.DB, case_spec::CaseSpec, repo_root::String; - force::Bool=false, verbose::Bool=false, - no_instantiate::Bool=false) + force::Bool=false, verbose::Bool=false, + no_instantiate::Bool=false) # Always delete previous local results and re-run delete_cached(db, LOCAL_REF, case_spec.name) @@ -321,7 +323,7 @@ function run_local(db::SQLite.DB, case_spec::CaseSpec, repo_root::String; if !isdir(example_path) @warn "Example directory not found: $(case_spec.example_dir)" store_failed_run(db, LOCAL_REF, "local", date, "working tree", case_spec.name, - "Example directory not found: $(case_spec.example_dir)") + "Example directory not found: $(case_spec.example_dir)") return end @@ -343,8 +345,8 @@ function run_local(db::SQLite.DB, case_spec::CaseSpec, repo_root::String; if verbose run(pipeline(`julia --project=$repo_root $tmpscript $rundir $timingfile`)) else - run(pipeline(`julia --project=$repo_root $tmpscript $rundir $timingfile`, - stdout=devnull, stderr=stderr_buf)) + run(pipeline(`julia --project=$repo_root $tmpscript $rundir $timingfile`; + stdout=devnull, stderr=stderr_buf)) end runtime_s = _read_timing_file(timingfile) @@ -352,13 +354,13 @@ function run_local(db::SQLite.DB, case_spec::CaseSpec, repo_root::String; if !isfile(h5path) @warn "gpec.h5 not produced" store_failed_run(db, LOCAL_REF, "local", date, "working tree", case_spec.name, - "gpec.h5 not produced after successful run") + "gpec.h5 not produced after successful run") return end extracted = extract_quantities(h5path, case_spec.quantities, runtime_s) store_run(db, LOCAL_REF, "local", date, "working tree", case_spec.name, - runtime_s, extracted) + runtime_s, extracted) @info " Completed in $(round(runtime_s, digits=1))s — $(length(extracted)) quantities extracted" @@ -375,7 +377,7 @@ function run_local(db::SQLite.DB, case_spec::CaseSpec, repo_root::String; err_msg_short = length(err_msg) > 2000 ? "..." * last(err_msg, 2000) : err_msg @warn "Run failed (local): $(first(err_msg_short, 200))" store_failed_run(db, LOCAL_REF, "local", date, "working tree", case_spec.name, - err_msg_short) + err_msg_short) finally if tmpscript !== nothing rm(tmpscript; force=true) @@ -394,9 +396,9 @@ Run GPEC for a specific git commit via worktree. Stores results in the database. Skips if already cached (unless force=true). """ function run_at_commit(db::SQLite.DB, commit_hash::String, ref_name::String, - case_spec::CaseSpec, repo_root::String; - force::Bool=false, verbose::Bool=false, - no_instantiate::Bool=false) + case_spec::CaseSpec, repo_root::String; + force::Bool=false, verbose::Bool=false, + no_instantiate::Bool=false) # Check cache if !force && is_cached(db, commit_hash, case_spec.name) info = get_run_info(db, commit_hash, case_spec.name) @@ -432,8 +434,8 @@ function run_at_commit(db::SQLite.DB, commit_hash::String, ref_name::String, if !isdir(example_path) @warn "Example directory not found at commit $(commit_info.short): $(case_spec.example_dir)" store_failed_run(db, commit_hash, commit_info.short, commit_info.date, - commit_info.msg, case_spec.name, - "Example directory not found: $(case_spec.example_dir)") + commit_info.msg, case_spec.name, + "Example directory not found: $(case_spec.example_dir)") return end @@ -452,8 +454,8 @@ function run_at_commit(db::SQLite.DB, commit_hash::String, ref_name::String, if verbose run(pipeline(`julia --project=$project_root $tmpscript $rundir $timingfile`)) else - run(pipeline(`julia --project=$project_root $tmpscript $rundir $timingfile`, - stdout=devnull, stderr=stderr_buf)) + run(pipeline(`julia --project=$project_root $tmpscript $rundir $timingfile`; + stdout=devnull, stderr=stderr_buf)) end runtime_s = _read_timing_file(timingfile) @@ -462,8 +464,8 @@ function run_at_commit(db::SQLite.DB, commit_hash::String, ref_name::String, if !isfile(h5path) @warn "gpec.h5 not produced at $(commit_info.short)" store_failed_run(db, commit_hash, commit_info.short, commit_info.date, - commit_info.msg, case_spec.name, - "gpec.h5 not produced after successful run") + commit_info.msg, case_spec.name, + "gpec.h5 not produced after successful run") return end @@ -472,7 +474,7 @@ function run_at_commit(db::SQLite.DB, commit_hash::String, ref_name::String, # Store in database store_run(db, commit_hash, commit_info.short, commit_info.date, - commit_info.msg, case_spec.name, runtime_s, extracted) + commit_info.msg, case_spec.name, runtime_s, extracted) @info " Completed in $(round(runtime_s, digits=1))s — $(length(extracted)) quantities extracted" @@ -490,7 +492,7 @@ function run_at_commit(db::SQLite.DB, commit_hash::String, ref_name::String, err_msg_short = length(err_msg) > 2000 ? "..." * last(err_msg, 2000) : err_msg @warn "Run failed for $(commit_info.short): $(first(err_msg_short, 200))" store_failed_run(db, commit_hash, commit_info.short, commit_info.date, - commit_info.msg, case_spec.name, err_msg_short) + commit_info.msg, case_spec.name, err_msg_short) finally # Clean up if tmpscript !== nothing From fb979b283d348c170de86cee58626e66a4c81c28 Mon Sep 17 00:00:00 2001 From: logan-nc Date: Wed, 8 Jul 2026 15:07:33 -0400 Subject: [PATCH 07/10] ISLANDS - MINOR - LOG: reference M2 PR #324 Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_016pUwoFRo9a5AjF8HuwcZMr --- docs/src/islands/LOG.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/src/islands/LOG.md b/docs/src/islands/LOG.md index 1022300a..7e4c6ec9 100644 --- a/docs/src/islands/LOG.md +++ b/docs/src/islands/LOG.md @@ -11,7 +11,9 @@ relevant. ## 2026-07-08 — M2 L0 solve machinery: Newton–Krylov + moments + species/frames/fields (structure, gated physics) - **Contract**: `docs/src/islands/design/M2-launch-prompt.md` (interactive /goal - run). Branch `feature/islands-m2` (stacked on `feature/islands-m1`/PR #320). + run). Branch `feature/islands-m2`, **PR #324** (stacked on + `feature/islands-m1`/PR #320; retargets to `feature/islands` when #320 merges). + Full suite green locally. - **Moved**: the full L0 solve *structure*, every physics coefficient a supplied `[VERIFY]`-gated parameter (physics-verifier: **PASS**): - `solvers/` — matrix-free Newton–Krylov (Krylov.jl GMRES on a preallocated From 2a5635f2841a57bf28214e64a62de985fb60082a Mon Sep 17 00:00:00 2001 From: logan-nc Date: Wed, 8 Jul 2026 15:38:19 -0400 Subject: [PATCH 08/10] ISLANDS - BUG FIX - Cover the M2 submodule docstrings in docs (checkdocs missing_docs) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Extend the islands.md API reference with @autodocs sections for the five M2 submodules (SpeciesLists, Frames, Fields, Moments, Solvers) on top of the M1 fix — checkdocs=:exports requires every exported docstring covered. Local docs build passes clean. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_016pUwoFRo9a5AjF8HuwcZMr --- docs/src/islands.md | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/docs/src/islands.md b/docs/src/islands.md index 0a0a4035..c858f48f 100644 --- a/docs/src/islands.md +++ b/docs/src/islands.md @@ -59,12 +59,42 @@ Modules = [GeneralizedPerturbedEquilibrium.Islands] Modules = [GeneralizedPerturbedEquilibrium.Islands.PhaseSpace] ``` +### Species (`Islands.SpeciesLists`) + +```@autodocs +Modules = [GeneralizedPerturbedEquilibrium.Islands.SpeciesLists] +``` + +### Frames and parameters (`Islands.Frames`) + +```@autodocs +Modules = [GeneralizedPerturbedEquilibrium.Islands.Frames] +``` + ### Operator stack (`Islands.Operators`) ```@autodocs Modules = [GeneralizedPerturbedEquilibrium.Islands.Operators] ``` +### Field-equation closure structure (`Islands.Fields`) + +```@autodocs +Modules = [GeneralizedPerturbedEquilibrium.Islands.Fields] +``` + +### Output moments (`Islands.Moments`) + +```@autodocs +Modules = [GeneralizedPerturbedEquilibrium.Islands.Moments] +``` + +### Newton–Krylov solve (`Islands.Solvers`) + +```@autodocs +Modules = [GeneralizedPerturbedEquilibrium.Islands.Solvers] +``` + ### Verification harness (`Islands.Verify`) ```@autodocs From b28e61b7f172fac93a422df1c0fe1f8ab0301436 Mon Sep 17 00:00:00 2001 From: logan-nc Date: Wed, 8 Jul 2026 17:45:37 -0400 Subject: [PATCH 09/10] ISLANDS - NEW FEATURE - Rendered docs story: numerics chapter with equations + figures, Islands site section MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Address the missing narrative documentation: the design docs existed in-repo but were never wired into the rendered site, and no figures existed because the figure pipeline was contracted to the (gated) B-ladder. - docs/src/islands/numerics.md: "numerics as implemented (M1-M2)" — the equations of everything actually built (sinh layer maps, spectral/Fornberg operators, the operator-stack residual, the mimetic collision form with its exact discrete conservation/entropy identities, Newton-Krylov + EW forcing + TSVD preconditioning, pseudo-arclength fold detection, Ω/⟨·⟩_Ω/h(Ω) geometry and the A7 identity, the Δ projections with gated prefactors), each anchored to its implementing symbols, with the A-ladder evidence table. - benchmarks/islands/figures/make_structural_figures.jl: pinned script (docs/07 §2) generating the five structural figures from the verification machinery (grid clustering, MMS+solve convergence, Q/h profiles + A7, preconditioner GMRES comparison, continuation fold); PNGs committed under docs/src/islands/figures/ (gitignore exception) as docs assets. - docs/make.jl: new "Islands" nav section — overview, numerics chapter, Paper-I figure contract, and the full design-document set (00-08). - docs/src/islands.md: now links the narrative pages from the API reference. Local docs build passes clean. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_016pUwoFRo9a5AjF8HuwcZMr --- .gitignore | 1 + .../figures/make_structural_figures.jl | 151 +++++++++ docs/make.jl | 16 + docs/src/islands.md | 10 +- .../src/islands/figures/continuation_fold.png | Bin 0 -> 37645 bytes docs/src/islands/figures/grids_clustering.png | Bin 0 -> 45476 bytes docs/src/islands/figures/hQ_profiles.png | Bin 0 -> 46309 bytes docs/src/islands/figures/mms_convergence.png | Bin 0 -> 65917 bytes .../islands/figures/preconditioner_gmres.png | Bin 0 -> 20346 bytes docs/src/islands/numerics.md | 302 ++++++++++++++++++ 10 files changed, 478 insertions(+), 2 deletions(-) create mode 100644 benchmarks/islands/figures/make_structural_figures.jl create mode 100644 docs/src/islands/figures/continuation_fold.png create mode 100644 docs/src/islands/figures/grids_clustering.png create mode 100644 docs/src/islands/figures/hQ_profiles.png create mode 100644 docs/src/islands/figures/mms_convergence.png create mode 100644 docs/src/islands/figures/preconditioner_gmres.png create mode 100644 docs/src/islands/numerics.md diff --git a/.gitignore b/.gitignore index 8ecc70e4..d7121fb4 100644 --- a/.gitignore +++ b/.gitignore @@ -17,6 +17,7 @@ !docs/resources/**/*.pdf *.png !docs/src/assets/**/*.png +!docs/src/islands/figures/*.png *.jld2 .gitattributes Manifest.toml diff --git a/benchmarks/islands/figures/make_structural_figures.jl b/benchmarks/islands/figures/make_structural_figures.jl new file mode 100644 index 00000000..448dfbbe --- /dev/null +++ b/benchmarks/islands/figures/make_structural_figures.jl @@ -0,0 +1,151 @@ +# make_structural_figures.jl — pinned figure script (design docs/07 §2) +# +# Regenerates the structural (A-ladder) figures embedded in +# docs/src/islands/numerics.md from the verification machinery itself — no +# archived data needed yet because everything here is deterministic M1/M2 +# structure (manufactured coefficients, no physics). Physics (B-ladder) figures +# will read archived benchmark data once QUESTIONS Q2–Q4 clear. +# +# Usage (repo root): +# env -u LD_LIBRARY_PATH julia --project=. benchmarks/islands/figures/make_structural_figures.jl +# +# Writes PNGs into docs/src/islands/figures/ (committed as docs assets so the +# Documenter CI build does not need to run this script). + +ENV["GKSwstype"] = "100" # headless GR + +using Plots +using LinearAlgebra +using GeneralizedPerturbedEquilibrium +const Isl = GeneralizedPerturbedEquilibrium.Islands +const PS = Isl.PhaseSpace +const Op = Isl.Operators +const So = Isl.Solvers +const V = Isl.Verify +const Fi = Isl.Fields + +outdir = normpath(joinpath(@__DIR__, "..", "..", "..", "docs", "src", "islands", "figures")) +mkpath(outdir) +saved = String[] +function save!(p, name) + path = joinpath(outdir, name) + savefig(p, path) + push!(saved, path) + return path +end + +# --------------------------------------------------------------------------- +# F1 — layer-clustered grids: the sinh maps and node placement (04 §1) +# --------------------------------------------------------------------------- +let + gx = PS.MappedFDGrid(33; halfwidth=6.0, clustering=2.0, order=4) + gy = PS.MappedFDGrid(25; halfwidth=4.0, clustering=2.0, center=1.0, domain=:half, order=4) + s = range(-1, 1; length=33) + p1 = plot(s, gx.nodes; lw=2, xlabel="computational coordinate s", ylabel="x", + label="x(s), β=2", legend=:topleft, title="radial map (packs x = 0)") + scatter!(p1, s, gx.nodes; ms=3, label="nodes") + p2 = plot(; xlabel="node index", ylabel="y", title="pitch grid (packs y_c = 1)", legend=:topleft) + scatter!(p2, 1:gy.n, gy.nodes; ms=4, label="y nodes, β=2") + hline!(p2, [1.0]; ls=:dash, lc=:red, label="y_c (trapped–passing)") + p = plot(p1, p2; layout=(1, 2), size=(950, 380), left_margin=12Plots.mm, bottom_margin=6Plots.mm) + save!(p, "grids_clustering.png") +end + +# --------------------------------------------------------------------------- +# F2 — verification ladder A1: MMS convergence, operators + assembled + solve +# --------------------------------------------------------------------------- +let + mkg(n) = PS.IslandGrid(; nx=n, nxi=8, ny=n, nE=3, halfwidth_x=6.0, clustering_x=1.0, + y_max=4.0, y_c=1.0, clustering_y=0.8, order=4) + ns = [9, 17, 33] + p = plot(; xscale=:log10, yscale=:log10, xlabel="radial/pitch resolution n", + ylabel="max error", legend=:bottomleft, title="MMS convergence (ladder A1)", + size=(700, 480), left_margin=12Plots.mm, bottom_margin=6Plots.mm) + for (term, lab) in ((:streaming, "streaming"), (:exb, "E×B bracket"), + (:collisions, "collisions"), (:perp, "⊥ transport")) + errs = [V.mms_operator_error(mkg(n), term) for n in ns] + plot!(p, ns, errs; marker=:circle, lw=2, label=lab) + end + errs = [V.mms_assembled_error(mkg(n)) for n in ns] + plot!(p, ns, errs; marker=:square, lw=3, lc=:black, label="assembled residual") + solve_errs = [V.solve_mms(n).err for n in (9, 17, 33)] + plot!(p, [9, 17, 33], solve_errs; marker=:diamond, lw=3, ls=:dash, label="converged solve (A1-solve)") + guide = errs[1] .* (ns[1] ./ ns) .^ 4 + plot!(p, ns, guide; ls=:dot, lc=:gray, label="4th order") + save!(p, "mms_convergence.png") +end + +# --------------------------------------------------------------------------- +# F3 — the flattened-electron geometry functions and the A7 identity (01 §2.4) +# --------------------------------------------------------------------------- +let + Ωout = 1.02:0.02:5.0 + Ωin = -0.98:0.02:0.98 + Q = [Fi.Q_omega(Ω) for Ω in Ωout] + Qin = [Fi.Q_omega(Ω) for Ω in Ωin] + h = [Fi.h_profile(Ω; prefactor=1.0) for Ω in Ωout] + p1 = plot(Ωin, Qin; lw=2, label="Q(Ω), inside", xlabel="Ω", ylabel="Q", + title="Q(Ω) = (1/2π)∮√(Ω+cos ξ) dξ", legend=:topleft) + plot!(p1, Ωout, Q; lw=2, label="Q(Ω), outside") + vline!(p1, [1.0]; ls=:dash, lc=:red, label="separatrix") + a7 = [abs(Fi.flat_average_d2h_dx2(Ω, 1.0)) for Ω in (1.2, 2.0, 3.0, 5.0)] + p2 = plot(Ωout, h; lw=2, label="h(Ω) (unit prefactor)", xlabel="Ω", ylabel="h", + title="electron profile h(Ω)", legend=:topleft) + vline!(p2, [1.0]; ls=:dash, lc=:red, label="separatrix (h ≡ 0 inside)") + annotate!(p2, 1.6, 0.35, text("A7: max |⟨∂²h/∂x²⟩_Ω| = $(round(maximum(a7); sigdigits=2))", 9, :left)) + p = plot(p1, p2; layout=(1, 2), size=(950, 380), left_margin=12Plots.mm, bottom_margin=6Plots.mm, right_margin=6Plots.mm) + save!(p, "hQ_profiles.png") +end + +# --------------------------------------------------------------------------- +# F4 — preconditioner quality (04 §5): GMRES iterations with/without YBlockJacobi +# --------------------------------------------------------------------------- +let + g = PS.IslandGrid(; nx=9, nxi=8, ny=9, nE=2, halfwidth_x=6.0, clustering_x=1.0, + y_max=4.0, y_c=1.0, clustering_y=0.8, order=4) + nx, nξ, ny, nE, nσ = PS.nnodes(g) + P = @. g.y.nodes * (4.0 - g.y.nodes) + K, = Op.conservative_pitch_operator(g.y, P, ones(ny)) + cstiff = fill(30.0, nx, nξ, nE, nσ) + shift = fill(-1.0, nx, nξ, ny, nE, nσ) + stack = Op.IslandStack((Op.PitchAngleDiffusion(K, cstiff), Op.RadiationSink(shift)), + Op.Quasineutrality(1.3)) + f0! = So.flat_residual(stack, g) + N = Op.statelength(g) + b = sin.((1:N) ./ 7) + f!(out, u) = (f0!(out, u); out .-= b; out) + pc = So.YBlockJacobi(g, (ix, iξ, iE, iσ) -> I(ny) + cstiff[ix, iξ, iE, iσ] .* K; phi_scale=-1.3) + s0 = So.newton_krylov(f!, zeros(N); rtol=1e-10, memory=300) + s1 = So.newton_krylov(f!, zeros(N); rtol=1e-10, memory=300, precond=pc) + p = bar(["unpreconditioned", "y-block Jacobi (TSVD)"], [s0.gmres_iters, s1.gmres_iters]; + ylabel="total GMRES iterations", legend=false, + title="preconditioner: stiff collisional solve", + ylims=(0, 1.25 * s0.gmres_iters), + size=(600, 430), left_margin=12Plots.mm, bottom_margin=6Plots.mm, top_margin=4Plots.mm) + annotate!(p, [(1, s0.gmres_iters + 0.06 * s0.gmres_iters, text("$(s0.gmres_iters)", 10)), + (2, s1.gmres_iters + 0.06 * s0.gmres_iters, text("$(s1.gmres_iters)", 10))]) + save!(p, "preconditioner_gmres.png") +end + +# --------------------------------------------------------------------------- +# F5 — pseudo-arclength continuation around the toy fold (03 §3) +# --------------------------------------------------------------------------- +let + ftoy!(out, u, p) = (out[1] = u[1]^2 + p; out) + pa = So.pseudo_arclength(ftoy!, [1.0], -1.0; ds=0.15, nsteps=30, rtol=1e-12, atol=1e-12) + us = [z[1] for z in pa.us] + p = plot(pa.ps, us; marker=:circle, lw=2, xlabel="parameter p", ylabel="u", + label="continuation path", legend=:topleft, + title="pseudo-arclength steps around the fold (u² + p = 0)", + size=(650, 430), left_margin=12Plots.mm, bottom_margin=6Plots.mm) + plot!(p, -1.2:0.01:0.0, sqrt.(-(-1.2:0.01:0.0)); ls=:dash, lc=:gray, label="analytic ±√(−p)") + plot!(p, -1.2:0.01:0.0, -sqrt.(-(-1.2:0.01:0.0)); ls=:dash, lc=:gray, label="") + if !isempty(pa.folds) + k = pa.folds[1] + 1 + scatter!(p, [pa.ps[k]], [us[k]]; ms=8, mc=:red, label="fold detected") + end + save!(p, "continuation_fold.png") +end + +println("Saved figures:") +foreach(f -> println(" ", f), saved) diff --git a/docs/make.jl b/docs/make.jl index 8f701374..5fddf45d 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -41,6 +41,22 @@ makedocs(; "Analysis" => "analysis.md", "Utilities" => "utilities.md" ], + "Islands" => [ + "Overview" => "islands/index.md", + "Numerics (as implemented)" => "islands/numerics.md", + "Paper I — figure contract" => "islands/papers/paper-1/OUTLINE.md", + "Design documents" => [ + "00 — Roadmap" => "islands/design/00-roadmap.md", + "01 — Level-0 physics" => "islands/design/01-physics-level0.md", + "02 — Species and EPs" => "islands/design/02-species-and-eps.md", + "03 — Architecture" => "islands/design/03-architecture.md", + "04 — Numerics" => "islands/design/04-numerics.md", + "05 — Verification ladder" => "islands/design/05-verification.md", + "06 — Autonomy and tooling" => "islands/design/06-autonomy-and-tooling.md", + "07 — Documentation and papers" => "islands/design/07-documentation-and-papers.md", + "08 — Reference library" => "islands/design/08-reference-library.md" + ] + ], "Citations" => "citations.md", "Developer Notes" => "developer_notes.md", ], diff --git a/docs/src/islands.md b/docs/src/islands.md index c858f48f..0a616786 100644 --- a/docs/src/islands.md +++ b/docs/src/islands.md @@ -3,8 +3,14 @@ The Islands module is a steady-state, multi-species drift-kinetic solver for the resonant magnetic island/layer region in tokamaks — the nonlinear analog of SLAYER, generalizing the Modified Rutherford Equation. It is under active -development. The design documents live under `islands/design/` in the -documentation source tree, and the module conventions in `src/Islands/CLAUDE.md`. +development; the module conventions live in `src/Islands/CLAUDE.md`. + +This page is the **API reference**. The narrative documentation lives in the +**Islands** section of this site: the [project overview](islands/index.md), +the equations-and-figures chapter of what is +[implemented and verified so far](islands/numerics.md), the +[Paper I figure contract](islands/papers/paper-1/OUTLINE.md), and the full +[design document set](islands/design/00-roadmap.md). ## Status — M1 skeleton + M2 Level-0 solve machinery (structure, gated physics) diff --git a/docs/src/islands/figures/continuation_fold.png b/docs/src/islands/figures/continuation_fold.png new file mode 100644 index 0000000000000000000000000000000000000000..6431920b146f7b254bd66237f135a0e6ce4301ae GIT binary patch literal 37645 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

mccFl^l`&K+r}2yw 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 literal 0 HcmV?d00001 diff --git a/docs/src/islands/figures/mms_convergence.png b/docs/src/islands/figures/mms_convergence.png new file mode 100644 index 0000000000000000000000000000000000000000..5b2a4dd6750ab263fcc85a4830f6130862b71b95 GIT binary patch literal 65917 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 literal 0 HcmV?d00001 diff --git a/docs/src/islands/figures/preconditioner_gmres.png b/docs/src/islands/figures/preconditioner_gmres.png new file mode 100644 index 0000000000000000000000000000000000000000..d885a9b62a9fa65f80792d30a9767411eeeac855 GIT binary patch literal 20346 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≀|yo6;5k!81a zadj<%FV8JnWo{arPj`2>k@|Z?G%$5T5L5{WYk2lWif*LCemqa37b4{iOUui|1A-P8weH}U+J2g8*vsWTf)GA*}4RgRm_!b*}4@D{O#Ul0H)cin$cno zmYC56-3oB42kR$gN^H)3b!jI?8{F+F6tA5fN&yfqDnqgRDlou%AD;@!2<%B@wY$3K zu3V|tUQ>-Nrod$=kq8&BU^L74BG~)a^x*0tVR-J8MW+z?p}#-HBZnzR_QD5H2GF1? z;w;L^-GqA%I#T@6pP(x!%o`$($c9VDq@(Q!#)N1NpEt*QV6u95)!4#<2~Goa+Taur z$Y&_eYp@0%hJ~!JV1@#Na}SDwo|zdPu{HT2@(ZR&BRn|J6jAm%ow+kosoV z_p?cZ6oC62p0GD>7{WB}V}y?!I0Qh#OoHJ8(f84#=7xsY(!3l4EH*F*5_Dc}?qxZ-=o2aD=#lC zC51AVGdT6y($Mfpbo9lx)*p%Yc%WG00SfT+E=QlX!9;jLf%CRqokg8)U*6Duu$MHpkTqNTDe{#7|9oo&KNK>UM#z^w^sse{+g*P2LfsL?%mE* z&q#kTVup7tV2Bea`S;wM<(&}NiCE4!-UjfPWfvD9vv4S1C6ZqVh={;}vOZP#>-?kr z8Gu0abz4F?=%_K)T!7~jA#4F#MM{~R5EaEmMNk|7TMaN}gNHrf^z1}?05xnEH8o`# z7>|{}qYLo3qZuq1oPEwvEHEU7jO&2;kd~CT>Rd)VeFx+1r{FrxIYOG&r|aL4R=j)NrIrIHPVioUV9P>WBOq@p8z zS-IG}%02|&RNx6P4`sHme7dW@^xPFA6{?2V;FbGM56g}ukCJ0~J6_t|aGI|BsBndU zw83wXIN}sDuLB;t+~B5}Sgbm0sNsfJ@1ZC>>sWTE1YpC~qQ!lR^r2x3*=0WRxG!H!V)pgnciSN|L zkwxr8bucEd5}=1|ZfIx#HMF+k6jQfv&mI*#Q{WfH*`1^1_GeHoygEl^H>4jZU$l&j zV*LF5(~g7pu7l_VUjWXi#$=|f%u_c_5>yvZJ|6f3G&X}%h3r0AZUE8*jN*|eW016g zzW!Lf?-PisWe&oo2#QUfkdWZ5n}uRqS6h4fVBn;%SxzT1F92hwx$vTurm;i}9zJxT z|MmjTI(8fn61s|6>!PZGX*@P*V$xKgqH}WY2Fs>6)+0y0mZR0m5py<3V~Q{A7MK2} zR2eni5PHmxzWDyf;LuPz^jxU3@IZBRXhzj0Ugd)Ki(O7jS67%JK=e5;2IjF-6b_P+ z@q9c#i3kbtmJmaH!|Rq?R8&-w?khL)x-gT0U(wSGLV2pI3*Wr}AOsL0pO9HpbPW?) z&o5(((5-1{Jp<_+9-gF}jOPv&WM@-mj!;=w1=7!EAEonypp1tVIVJz*E9*~>jt13@ zIQ~07U%h7`_R1&}>aF+L#Kl+9Hi92}^5h9%8M5?a_Q}4|zFRpZpoVR2o5%mcX~3}K z!CBT|%w8bN!ranw3y)IKyK*I6e0yeo{>?l*Yp67}Z5)C)niw%W0}DD6p4KurI2av$ zFh`5WqZxui31}#cDn~?UsHtHh31jDj^UE$SE<@#AxEc_v5;0cSue0JTrlgp`!T*?j zadiz-Eur#%XSSgx;iC&b5-ysqNOLQzJgs*grwOYuKWNMrvH&mdfBaohP5WUAa(Z=5 z%|T}7z#ocFWZ7}D077v0_UlU>P!|!66xz{a^*rt-SA!e$zx$0nF^s7_xV74hCYP zqb~2&{rphpJR~6UzyoK(-FhM$;p`1B5`k5SOeByP*ftZ00hm Date: Wed, 8 Jul 2026 17:46:32 -0400 Subject: [PATCH 10/10] ISLANDS - MINOR - LOG: record the rendered-docs-story addition Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_016pUwoFRo9a5AjF8HuwcZMr --- docs/src/islands/LOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docs/src/islands/LOG.md b/docs/src/islands/LOG.md index 7e4c6ec9..2119e8e9 100644 --- a/docs/src/islands/LOG.md +++ b/docs/src/islands/LOG.md @@ -39,6 +39,14 @@ relevant. (solve-MMS err 5.254e-2, 6 Newton/1210 GMRES, A7 8.0e-17, σ_min 0.1139). - Paper-I figure contract: `docs/src/islands/papers/paper-1/OUTLINE.md` (claims C1–C3 green as CI artifacts; C4–C8 gated on Q2–Q4). + - **Rendered docs story** (user-flagged gap vs docs/07's M0–M1 intent): new + `docs/src/islands/numerics.md` — the equations + figures of everything as + implemented — plus the pinned figure script + (`benchmarks/islands/figures/make_structural_figures.jl`, five structural + figures committed as docs assets) and a full "Islands" site-nav section + (overview, numerics chapter, Paper-I contract, design docs 00–08). + Remaining docs/07 infra for later milestones: anchor-sync CI check, + STATE.md dashboard. - **Physics debugging note**: the first solve-MMS attempt failed to converge — the generic `Collisions` (a_y ∂²y) term has no y-BCs, so its BVP discretization is unstable under refinement; the *mimetic* divergence form