Skip to content

InnerLayer (GGJ) - NEW - rotated-ray collocation backend (:ray), robust to |Q| ~ 500#323

Open
matt-pharr wants to merge 1 commit into
developfrom
GGJ_colocation_backend
Open

InnerLayer (GGJ) - NEW - rotated-ray collocation backend (:ray), robust to |Q| ~ 500#323
matt-pharr wants to merge 1 commit into
developfrom
GGJ_colocation_backend

Conversation

@matt-pharr

Copy link
Copy Markdown
Collaborator

Summary

Adds a third interchangeable solver to the GGJ inner-layer model — GGJModel{:ray} — and makes it the default. It returns the same parity-projected matching data (Δ₁, Δ₂) in the same deltac convention as :galerkin and :shooting, but remains accurate far into the regime where both existing backends fail: validated to Q = 500i, the territory resistivity scans (|Q| ∝ η^(−1/3)) and rotation physics actually visit.

Method (one paragraph)

The layer equations are continued analytically onto the complex ray x = e^{iθ}s with θ = arg(Q)/4, which makes the parabolic-cylinder WKB exponent exactly real (no oscillation along the contour) and moves the coefficient pseudo-resonance x² ≈ −Q²(G+KF) — which sits on the real axis for imaginary Q — off the path. Δ is an analytic invariant of the contour angle within the Stokes sector, which doubles as a built-in error diagnostic (outward θ-consistency check). On [0, s_m] a global Chebyshev spectral-element collocation BVP is solved in plain variables with parity conditions at the origin and (Δ, c₁, c₂) as bordered unknowns of one sparse LU per parity (rank-3 Woodbury correction for the second parity). The far-field condition reuses the existing, validated inps Wasow kernel (InnerAsymptotics.jl) — evaluated at complex x via new methods in RayAsymptotics.jl, construction untouched — applied at the series radius S and transported inward by an L-stable 2-stage Radau IIA march in the quotient modulo the decaying exponential pair. The damped-zone march arithmetic runs in Complex{Double64}: at large S the near-parallel power-pair geometry amplifies the structured backward error of the ill-conditioned implicit solves into Δ-mixing ~1e-4 at |Q| = 500 in Float64 (a floor generic to any inps-based method handed to double-precision linear algebra at large S).

Validation

Developed and validated in a standalone package before porting; highlights:

  • Manufactured bordered problem with prescribed Δ*: agreement 3e-14.
  • Fortran rmatch pins and :galerkin cross-check at moderate Q: 1e-5–1e-9.
  • Physical q=4 benchmark surface pinned at Q = 100i and 500i.
  • Campaign scale (Slurm, 102 equilibria × 65-point Q-grids incl. DIII-D and ITER PFPO cases, ~14k solves): zero θ-consistency flags above 1e-3 at any |Q|; worst Δ₁ drift 5.8e-4, worst Δ₂ 3.7e-6. The legacy Galerkin self-disagrees at O(1) for |Q| ≳ 1 on the same points.
  • In-repo: test/runtests_innerlayer.jl gains a :ray testset (agreement with :galerkin at the GW2020 Eq. 55 paper point; q4 pins at 500i; θ-invariance). 19/19 pass.

Default backend change

GGJModel() now defaults to :ray. Blast radius checked: there are no bare GGJModel() call sites in the repo — all 17 benchmark uses and the regression harness pass solver=:galerkin explicitly. The backends take different numerical-knob keywords, so any stale galerkin-knob call fails loudly rather than returning a silently wrong Δ.

Dependencies

  • Random (stdlib, zero footprint) promoted from test-extras to [deps] — seeds the decaying-pair extraction (provably Δ-neutral; kept fixed for bit-reproducibility).
  • DoubleFloats was already a project dependency; only the using line is new.

Files

  • src/InnerLayer/GGJ/RayAsymptotics.jl (new) — complex-x evaluation methods for the existing inps kernel.
  • src/InnerLayer/GGJ/Ray.jl (new) — ODE system, WKB-graded mesh, decaying-pair extraction, Radau march, bordered collocation solve, refinement, delta_convergence error-bar battery, profile reconstruction, and the solve_inner(::GGJModel{:ray}, …) interface method.
  • GGJ.jl / InnerLayer.jl — backend registration, exports, docs.

A complete replication-grade methods write-up (strong form, cell-by-cell matrix assembly, march schedule derivation, finite-precision floor analysis) exists and will accompany the paper in preparation.

🤖 Generated with Claude Code

…location method implementation of GGJ that avoids Delta poles on the imaginary Q axis and can solve for Delta_even adn Delta_odd up to very high (at least ~500) |Q|
@matt-pharr matt-pharr requested review from d-burg and logan-nc July 8, 2026 16:39
@matt-pharr

Copy link
Copy Markdown
Collaborator Author

@logan-nc @d-burg this is something I have been working on with claude for a few weeks. It has a number of advantages over the galerkin GGJ solver. It uses collocation which is also a finite element method, but I learned that the reason that the galerkin solver sometimes freaks out is because there are poles to the GGJ solutions in Q space, and when you get near those poles the solutions become super oscillatory on the real axis. However, since we are solving this in a complex domain, you can show that the GGJ solutions should be entire in the complex plane, so the mercier terms in the large |X| limit are the same polynomial + coefficient even off of the real-axis (which is where the physically-relevant part of the solution lies). So you can get a much cleaner/quicker exponential decay of the non-limiting terms if you integrate on a ray that is rotated off of the real axis. This also gives way to an entirely different numerical stability check, which is to re-integrate for multiple rotation angles and see that you get the same Delta_even and Delta_odd. Overall this method is far superior to the galerkin one in all of my testing so far, and can safely go up to Q ~ 500i with a maximum error in the final Delta of ~1e-4 which is pretty good for this problem. Error stays ~1e-7 for more reasonable Q. This enables scanning to lower resistivities (Q ~ 1/eta^1/3) and higher rotation rates (or to absurd growth rates). It also makes the solve more robust for lower |Q|. I will do some more testing on this branch before I merge but I am opening it for review now.

@logan-nc logan-nc added the enhancement New feature or request label Jul 8, 2026
@logan-nc logan-nc added this to the GPEC v2.0.0 milestone Jul 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants