You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This issue is the single entry point for the coordinator driving the
fortnum extraction. The coordinator dispatches each leaf issue per its Model field, enforces the review ladder, updates tracker checklists, and
implements nothing directly. Coordinator model: fable (opus acceptable for
pure dispatch turns).
haiku: label/milestone housekeeping, checklist updates, re-export boilerplate. No algorithms.
sonnet: fully specified ports (source path + SHA given), wrappers, CI fixes with a clear failing log.
opus: build-system and CI scaffolding, multi-file refactors, ports that change APIs.
fable: API design issues, clean-room algorithm work, review of opus-implemented PRs.
Review ladder: sonnet PRs reviewed by opus; opus PRs reviewed by fable; haiku changes gated by CI only.
PR rules:
One leaf issue = one PR. Branch from the base named in the issue.
PR title = issue title. Body: Closes #N plus a ## Verification section with real failing-before and passing-after output.
Squash merge. Stacked PRs only where the issue names a non-main base.
Executor rule: if any issue under "Blocked by" is open, stop and report instead of starting.
Standing instructions for the coordinator
If a leaf's Blocked-by is open, skip it.
Create downstream leaf issues from the tracker tables only when the named
fortnum milestone closes. Use the leaf template below.
Never link private fortnum content into public-repo issue bodies beyond
bare issue references.
Keep the Fan-out table's "Unblocked today?" column current as milestones
close.
Leaf issue template
Model: <haiku|sonnet|opus|fable>
Review: <per ladder>
Blocked by: <#N, ... or "none">
Branch from: <base>
Files: <exact paths>
## Spec
...
## Port from / Context
...
## Do not
...
## Verify
<exact commands and expected outcomes>
## Done when
<checklist>
Goal
Create lazy-fortran/fortnum: a small MIT-licensed numerical-computing library for generic algorithms that are currently duplicated, vendored, or supplied through avoidable upstream numerical dependencies in libneo and downstream plasma codes.
This is not a plan to replace the whole scientific software stack. We explicitly keep the heavy infrastructure dependencies upstream:
replace / absorb into fortnum:
GSL / FGSL wrappers
direct gsl_* C bindings
FFTW usage where local clean-room FFT is good enough
old LGPL/Burkardt/IQPACK-style quadrature generators
old QUADPACK/SLATEC/AMOS/libcerf vendoring where it is uncontrolled or unnecessary
duplicated RKF45 / Cash-Karp / odeint code
root-finding wrappers
generic integration/quadrature helpers
generic interpolation/polynomial/search helpers
generic RNG/sampling wrappers
libneo should remain the plasma/domain library: VMEC/Boozer/GEQDSK, magnetic coordinates, magfie, species/collisions/transport domain interfaces, Python domain I/O, and compatibility wrappers. fortnum should contain generic numerical kernels reusable by SIMPLE, NEO-2, KAMEL, GORILLA, and lazy-fortran packages.
Proposed tagline:
fortnum: MIT-licensed numerical computing for modern Fortran.
Why
Recent cleanup work already points in this direction:
The same pattern exists across downstream codes: generic ODE, quadrature, special-function, root-finding, interpolation, and RNG code is duplicated, vendored, or tied to GSL/FFTW/FGSL interfaces.
The point is supply-chain control for the avoidable numerical layer, not replacing foundational ecosystem libraries like HDF5, NetCDF, BLAS, or LAPACK.
External design references
These are the design points worth copying, not necessarily their exact APIs:
SciPy API structure: public submodules are explicitly defined, stable, and deprecations are used before incompatible changes. Submodules should be as self-contained as possible with minimal inter-submodule dependencies. https://docs.scipy.org/doc/scipy/reference/index.html
SciPy thread-safety guidance: thread workers should preferably own their own arrays/objects; functions should not mutate user arrays unless explicitly documented; stateful objects require clearer concurrency semantics. https://docs.scipy.org/doc/scipy/tutorial/thread_safety.html
SUNDIALS design direction: solver objects, vector abstractions, pluggable linear/nonlinear solvers, modern Fortran interfaces, and hidden implementation changes without breaking user APIs. https://arxiv.org/abs/2011.10073
SUNDIALS performance direction: fused vector operations, local/global reduction separation, and backend-flexible data structures for parallel/heterogeneous systems. https://arxiv.org/abs/1909.12966
GSL scope reference: special functions, integration, FFT, roots, minimization, ODEs, interpolation, RNG, statistics, splines, sparse matrices, etc. GSL itself is GPL and therefore should be an optional oracle only, not a shipped dependency. https://www.gnu.org/software/gsl/
FFTW license reference: GPL by default, with non-free alternative licensing; therefore also oracle-only or replaced by clean-room/permissive code in shipped artifacts. https://www.fftw.org/doc/License-and-Copyright.html
QUADPACK reference: public-domain Fortran quadrature family and useful semantic/API model for adaptive integration. https://www.netlib.org/quadpack/
PocketFFT reference: permissively licensed FFT implementation used in the Python ecosystem; useful as an algorithm/design comparison, but do not copy unless license/provenance is explicitly checked. https://github.com/mreineck/pocketfft
Naming decision
Use fortnum, not fortmath, fortcalc, fortalg, or fortsl.
Rationale:
fortnum means numerical computing, which matches the scope.
fortmath is broader and vaguer: symbolic math, algebra, elementary math, discrete math.
fortcalc sounds like a calculator/calculus package and is too narrow.
fortalg is ambiguous between algorithms and algebra.
fortsl is too close to GSL and not descriptive enough.
Public module convention:
use fortnum_special
use fortnum_integrate
use fortnum_quadrature
use fortnum_fft
use fortnum_ode
use fortnum_roots
use fortnum_interp
use fortnum_rng
use fortnum_linalg_lite
Private implementation modules should use a clear private prefix, for example:
use fortnum_ode_cash_karp_impl
use fortnum_fft_bluestein_impl
Keep temporary libneo wrappers so existing code can still import old module names while downstream migration happens.
B. ODE integrators
Move generic ODE machinery:
src/odeint/odeint_allroutines.f90
test/odeint/*
doc/UserDoc/ODE_Integration.tex material that is generic rather than libneo-specific
Current code is generic adaptive Cash-Karp RK5(4) and event detection. This belongs in fortnum_ode, but not as a raw copy. Refactor to a clean API first:
module odeint_allroutines_sub
use fortnum_ode
! old argument order and old procedure names
end module
C. RNG utilities
Candidate:
src/MC/rng.f90
Do not merely move the existing wrapper around random_number. Design fortnum_rng around explicit RNG state so parallel runs are reproducible and thread-safe:
Initial compatibility wrapper can preserve getran(irand, ur).
D. Interpolation / polynomial / search helpers
Candidate generic pieces:
src/plag_coeff.f90
src/binsrc.f90
selected generic interpolation kernels under src/interpolate/ if not VMEC/magfie/domain-specific
Do not move domain-specific spline construction that knows about VMEC/Boozer/magnetic coordinates. Move only generic interpolation, search, and Lagrange/polynomial kernels.
E. Root finding / optimization placeholders
libneo itself currently does not seem to own the main root-finding wrappers, but downstream codes do. fortnum_roots should be created early enough to absorb NEO-2 and KAMEL GSL wrappers.
Minimum public API:
call root_bisection(f, a, b, xtol, rtol, root, status)
call root_newton(fdf, x0, xtol, rtol, root, status)
call root_brent(f, a, b, xtol, rtol, root, status) ! later
No global procedure pointers; pass callbacks through explicit interfaces and optional context objects.
Inventory: replace or absorb from downstream codes
SIMPLE
Search hits indicate current/local use of:
src/samplers.f90
src/collis_alphas.f90 random-number use
orbit/canonical-coordinate RK-related code paths and tests
Action: after fortnum_rng and fortnum_ode exist, audit SIMPLE samplers and any generic ODE/RK helpers for migration. Keep symplectic/orbit integrators in SIMPLE if they are physics-specific.
MEPHIT: trivial FFTW interface copy and diverged/orphaned field-line integration copies
NEO-RT: historical copies/symlinks of binsrc, plag_coeff, spline helpers
benchmark_orbit: pre-built archives
sparse_draft: broken raw download of hdf5_tools
Action: after fortnum_interp and fortnum_ode exist, audit these for use of binsrc, plag_coeff, spline helpers, and old ODE code. Do not move hdf5/domain I/O into fortnum.
Coordination
This issue is the single entry point for the coordinator driving the
fortnum extraction. The coordinator dispatches each leaf issue per its
Modelfield, enforces the review ladder, updates tracker checklists, andimplements nothing directly. Coordinator model: fable (opus acceptable for
pure dispatch turns).
Fan-out
fortnum is private during incubation. Reference its issues by bare number
only; quote no private content into public-repo bodies.
Execution order
Execution conventions
Model ladder (implementation):
Review ladder: sonnet PRs reviewed by opus; opus PRs reviewed by fable; haiku changes gated by CI only.
PR rules:
Closes #Nplus a## Verificationsection with real failing-before and passing-after output.Executor rule: if any issue under "Blocked by" is open, stop and report instead of starting.
Standing instructions for the coordinator
fortnum milestone closes. Use the leaf template below.
bare issue references.
close.
Leaf issue template
Goal
Create
lazy-fortran/fortnum: a small MIT-licensed numerical-computing library for generic algorithms that are currently duplicated, vendored, or supplied through avoidable upstream numerical dependencies inlibneoand downstream plasma codes.This is not a plan to replace the whole scientific software stack. We explicitly keep the heavy infrastructure dependencies upstream:
The target is narrower and realistic:
libneoshould remain the plasma/domain library: VMEC/Boozer/GEQDSK, magnetic coordinates,magfie, species/collisions/transport domain interfaces, Python domain I/O, and compatibility wrappers.fortnumshould contain generic numerical kernels reusable by SIMPLE, NEO-2, KAMEL, GORILLA, and lazy-fortran packages.Proposed tagline:
Why
Recent cleanup work already points in this direction:
collision_freqs.magfie.src/math/kit and removes FFTW/LGPL quadrature from shipped code.neotarget into smaller sub-targets.The same pattern exists across downstream codes: generic ODE, quadrature, special-function, root-finding, interpolation, and RNG code is duplicated, vendored, or tied to GSL/FFTW/FGSL interfaces.
The point is supply-chain control for the avoidable numerical layer, not replacing foundational ecosystem libraries like HDF5, NetCDF, BLAS, or LAPACK.
External design references
These are the design points worth copying, not necessarily their exact APIs:
https://docs.scipy.org/doc/scipy/reference/index.html
https://docs.scipy.org/doc/scipy/tutorial/thread_safety.html
https://arxiv.org/abs/2011.10073
https://arxiv.org/abs/1909.12966
https://www.gnu.org/software/gsl/
https://www.fftw.org/doc/License-and-Copyright.html
https://www.netlib.org/quadpack/
https://github.com/mreineck/pocketfft
Naming decision
Use
fortnum, notfortmath,fortcalc,fortalg, orfortsl.Rationale:
fortnummeans numerical computing, which matches the scope.fortmathis broader and vaguer: symbolic math, algebra, elementary math, discrete math.fortcalcsounds like a calculator/calculus package and is too narrow.fortalgis ambiguous between algorithms and algebra.fortslis too close to GSL and not descriptive enough.Public module convention:
Private implementation modules should use a clear private prefix, for example:
Only documented top-level modules are public API.
What stays upstream and is not part of this issue
Do not replace these in this effort:
Do not move these to
fortnum:Optional oracle/test-only dependencies are allowed:
but they must not be linked into shipped MIT artifacts.
Inventory: replace or absorb from
libneoA. Clean-room math kit from #290
Move after #286/#289/#290 settle, preserving oracle tests and benchmarks:
Keep temporary
libneowrappers so existing code can still import old module names while downstream migration happens.B. ODE integrators
Move generic ODE machinery:
Current code is generic adaptive Cash-Karp RK5(4) and event detection. This belongs in
fortnum_ode, but not as a raw copy. Refactor to a clean API first:Also provide a procedural wrapper:
call odeint_cash_karp(y, x1, x2, rtol, derivs, status)Keep in
libneo:C. RNG utilities
Candidate:
Do not merely move the existing wrapper around
random_number. Designfortnum_rngaround explicit RNG state so parallel runs are reproducible and thread-safe:Initial compatibility wrapper can preserve
getran(irand, ur).D. Interpolation / polynomial / search helpers
Candidate generic pieces:
Do not move domain-specific spline construction that knows about VMEC/Boozer/magnetic coordinates. Move only generic interpolation, search, and Lagrange/polynomial kernels.
E. Root finding / optimization placeholders
libneoitself currently does not seem to own the main root-finding wrappers, but downstream codes do.fortnum_rootsshould be created early enough to absorb NEO-2 and KAMEL GSL wrappers.Minimum public API:
No global procedure pointers; pass callbacks through explicit interfaces and optional context objects.
Inventory: replace or absorb from downstream codes
SIMPLE
Search hits indicate current/local use of:
Action: after
fortnum_rngandfortnum_odeexist, audit SIMPLE samplers and any generic ODE/RK helpers for migration. Keep symplectic/orbit integrators in SIMPLE if they are physics-specific.NEO-2
Replace avoidable GSL/FGSL dependencies:
Also audit:
for generic ODE/integration pieces versus domain-specific kinetic-field logic.
Target: replace FGSL/GSL dependency where possible with
fortnum_special,fortnum_integrate,fortnum_roots, andfortnum_interp.KAMEL
Replace avoidable GSL/direct C bindings:
Audit/replace quadrature and ODE code:
Audit special-function vendoring/provenance:
These should become either:
Prefer A for the long-term supply-chain-control goal.
Audit duplicate interpolation helpers:
Target: domain integrands stay in KAMEL; generic quadrature/ODE/special-function kernels move to
fortnum.GORILLA
Candidates:
Target: use
fortnum_odefor RKF45/Cash-Karp-like utilities where practical; keep orbit/tetrahedron physics in GORILLA.MEPHIT / NEO-RT / benchmark_orbit / sparse_draft
From #258:
Action: after
fortnum_interpandfortnum_odeexist, audit these for use ofbinsrc,plag_coeff, spline helpers, and old ODE code. Do not move hdf5/domain I/O intofortnum.fortnumpackage structureInitial repository layout:
Interface rules
Public API
fortnum_*modules.ode_cash_karp_tis public, butrk_stage_buffer_tshould not be.Thread safety
savestate for solver status, callbacks, work arrays, RNG seeds, FFT plans, or error flags.Performance
do concurrent/!$omp simdwhere justified by tests.Error handling
error stopin reusable numerical kernels except for impossible internal invariants.statusobjects or integer status codes:Licensing/provenance
src/must be MIT-compatible only.Migration plan
Phase 1: stabilize libneo-side cleanup
Phase 2: create
fortnumand move clean-room mathlazy-fortran/fortnumunder MIT.neo_*compatibility wrappers inlibneo.fortnum.libneoconsumefortnumthrough CMake FetchContent or another controlled dependency mechanism.Phase 3: move ODE machinery
fortnum_odeobject/workspace API.libneoodeint_allroutineswrapper.Phase 4: roots/integration/interpolation/RNG
fortnum_rootsbisection/Newton/Brent-style APIs.fortnum_integratetoward QAG/QAGS/QAGP/QAGIU-compatible semantics.fortnum_interp/fortnum_polynomial; migrateplag_coeff,binsrc, and duplicate polynomial helpers.fortnum_rng; migrate trivial RNG wrappers and establish reproducibility policy.Phase 5: special functions beyond current libneo needs
bessel_In,erf,erfc,dawson.fortnum_specialshould own Faddeeva/plasma-dispersion-function functionality.Phase 6: downstream gates and deprecation
Acceptance criteria
libneocan build without installed GSL and FFTW.fortnumhas no GPL/LGPL code in shipped source or linked artifacts.fortnumAPIs are documented, stable, and separated into public/private modules.fortnum.