Resolution and convergence
An algebraically converged linear solve is not necessarily a converged drift-kinetic discretization. NTX treats three checks separately:
the residual of the block equations;
Fourier sampling of the retained geometry harmonics;
convergence of transport coefficients under angular and Legendre refinement.
Residual semantics
The production solve eliminates the high Legendre tail by Schur complements
and returns the three modes needed by the transport moments.
TransportResult.schur_residual_l2 is the root-mean-square residual of that
complete tail-eliminated system, evaluated from its pivoted LU factors. It
includes the high-mode Schur contribution to row 2 without reconstructing
another mode. TransportResult.residual_l2 remains as a compatibility alias;
neither name denotes the full original DKE residual.
The test suite also factors and reconstructs every Legendre mode on a small
system, applies every original block row independently, and requires both
residuals to reach roundoff. Full-mode reconstruction scales as
O(N_xi N_fs^2) storage, so it is an audit path rather than the default
production diagnostic.
Run that audit explicitly on a prepared system:
from ntx import audit_prepared_residuals
residuals = audit_prepared_residuals(prepared, case)
print(residuals.schur_residual_l2)
print(residuals.full_system_residual_l2)
print(residuals.retained_mode_max_abs_error)
The CI oracle checks both diagnostics at N_xi=2,16,32,63. A separate small
problem materializes the complete block-tridiagonal operator, solves it with a
dense solver, and applies every original block row. This keeps the Schur solve,
the residual action, and the dense reference as distinct numerical paths.
Geometry sampling
NTX evaluates each retained harmonic as
on one toroidal field period. Consequently, alias-free collocation requires
The odd floor avoids treating the real Nyquist mode of an even grid as a resolved derivative mode. Inspect a proposed grid before a solve:
from ntx import geometry_resolution_report
report = geometry_resolution_report(surface, grid)
report.require_resolved()
print(report.theta_oversampling, report.zeta_oversampling)
The adaptive convergence API enforces this gate. For a one-off solve, request strict pre-solve validation explicitly:
result = solve_monoenergetic(
surface, grid, case, require_resolved_geometry=True
)
The default remains permissive so deliberately underresolved smoke diagnostics
and historical reference reproductions remain runnable, but they are not
research-grade convergence claims. If a surface is passed as a dynamic argument
to jax.jit, call the report host-side first because traced integer harmonic
arrays cannot be converted into a host report.
Nyquist adequacy is necessary, not sufficient. Products, reciprocals, and
derivatives of the magnetic field can demand angular oversampling beyond the
retained input bandwidth. The exact 3/2 product rule for two band-limited
Fourier fields does not directly prove adequacy for this operator because its
geometry coefficients include reciprocals and other non-band-limited derived
fields. NTX therefore uses measured coefficient convergence rather than
silently filtering the assembled operator.
The committed finite-beta QA, NCSX, and HSX audit found a worst
D11/D31/D33 error of 6.889e-3 at 2.25 times the retained-mode Nyquist
floor relative to the 2.5-times reference. NTX now warns below 2.25; this is
a recommended starting grid, not a hard rejection or a substitute for the
two-successive-refinement gate. The recommendation is exported as
RECOMMENDED_ANGULAR_OVERSAMPLING.
python examples/angular_oversampling_audit.py --preset production

Adaptive coefficient gate
Use independent angular and pitch-angle ladders:
from ntx import solve_monoenergetic_converged
audit = solve_monoenergetic_converged(
surface,
case,
angular_resolutions=((13, 15), (17, 21), (21, 25), (25, 31)),
legendre_orders=(16, 24, 32, 48, 63),
rtol=1e-2,
atol=(1e-10, 1e-10, 1e-10), # D11, D31, D33
)
if audit.status != "converged":
raise RuntimeError(audit.message)
For each coefficient c, a refinement is accepted when
The absolute term is essential for symmetry-conditioned D31 values near
zero. The default research policy requires two consecutive accepted angular
changes and two consecutive accepted Legendre changes. Exhausting a ladder
returns unresolved; the last result is retained for diagnosis but is not
silently promoted. Non-finite coefficients return model-out-of-scope.
These numerical gates follow Fourier collocation sampling theory and the angular/Legendre convergence practice used for monoenergetic neoclassical transport calculations. They do not replace independent-code validation or a separate model-discrepancy tolerance.