Route collision_freqs incomplete gamma through fortnum#316
Merged
Conversation
collision_freqs linked GPLv3 GSL for one routine: the unnormalized lower incomplete gamma in the Chandrasekhar function. The GPL obligation reached every MIT-licensed downstream consumer (SIMPLE, NEO-2, NEO-RT, MEPHIT, KAMEL, rabe), including SIMPLE's published binary wheels. lower_incomplete_gamma returned gsl_sf_gamma_inc_P(a, x) * gsl_sf_gamma(a), the unnormalized lower incomplete gamma. That is fortnum gamma_lower(a, x), a pure function with the same domain (error stop on a <= 0 or x < 0). The public interface of lower_incomplete_gamma is unchanged, so callers compile without edits. - Replace the two bind(c) GSL interfaces and the line-160 product with a single use of fortnum gamma_lower. The now-dead iso_c_binding import goes. - Drop find_package(GSL REQUIRED) and the GSL::gsl link from src/collisions/CMakeLists.txt; link the fortnum Fortran target instead. - Fetch fortnum via FetchContent from lazy-fortran/fortnum at main, guarded by if(NOT TARGET fortnum) so a repo that also pulls fortnum transitively via libneo does not double-declare the target. This was libneo's only GSL site; GSL is now fully dropped.
This was referenced Jun 14, 2026
This was referenced Jun 14, 2026
krystophny
added a commit
that referenced
this pull request
Jun 15, 2026
## Merge order Merge sequence: #316 -> #317 -> #318. Each PR is based on `main` individually, so each diff is cumulative against `main` and the three share code. Merge them in order. Once a predecessor merges, the next PR's diff shrinks to its own increment. ## Scope src/magfie/coil_tools.f90 used FFTW3 for the one-dimensional real-to-complex transforms in `biot_savart_fourier` and `vector_potential_biot_savart_fourier`. This re-homes the field of the math-kit PR #290 / FFTW-drop PR #287 by routing those transforms through fortnum instead of an in-tree math kit. fortnum `fft_r2c` shares FFTW's unnormalized forward convention and `n/2+1` complex packing, so the transform output is identical and both public subroutine interfaces are unchanged. The FFTW `find_package` / `ExternalProject` paths and the bundled `cmake/Modules/findFFTW` module are removed; fortnum is fetched via `FetchContent` at tag `a7faa3c`, guarded by `if(NOT TARGET fortnum)`. ## Dependency removed FFTW3 (`src/fftw3.F90` binding wrapper, `FFTW::Double` / `FFTW::DoubleThreads` link, FFTW detection and from-source ExternalProject). ## Verification Configure (no FFTW detection runs; fortnum fetched at a7faa3c): ``` -- === Detecting External Dependencies === -- Found system HDF5: 2.1.1 -- -> ABI compatible, using system HDF5 -- -> ABI compatible, using system NetCDF -- === Dependency Detection Complete === -- Configuring done (9.8s) -- Build files have been written to: /tmp/libneo-l1 ``` Build: `[570/570] Linking Fortran shared module _efit_to_boozer.cpython-314-x86_64-linux-gnu.so` No FFTW symbols remain in the magfie archive: ``` $ nm /tmp/libneo-l1/src/magfie/libmagfie.a | grep -i fftw $ echo $? # (no matches) ``` FFT-path tests (Biot-Savart Fourier modes and field validation) pass: ``` 1/6 Test #50: test_biotsavart .................. Passed 0.45 sec 2/6 Test #52: test_biotsavart_field ............ Passed 0.07 sec 3/6 Test #59: test_coil_tools_biot_savart ...... Passed 29.23 sec 4/6 Test #60: tilted_coil_generate_geometry .... Passed 0.13 sec 5/6 Test #61: tilted_coil_fourier_modes ........ Passed 199.77 sec 6/6 Test #62: tilted_coil_field_validation ..... Passed 12.36 sec 100% tests passed, 0 tests failed out of 6 ``` Note: fortnum pin updated to current main (92de6e9) after a fortnum history rewrite; old shas no longer resolve.
krystophny
added a commit
that referenced
this pull request
Jun 15, 2026
…le (#318) ## Merge order Merge sequence: #316 -> #317 -> #318. Each PR is based on `main` individually, so each diff is cumulative against `main` and the three share code. Merge them in order. Once a predecessor merges, the next PR's diff shrinks to its own increment. ## Scope src/transport/gen_laguerre_rule.f90 was an LGPL generalized Gauss-Laguerre quadrature generator (`cgqf` / `r8_huge` / `rule_write`). This re-homes the field of the math-kit PR #290 / LGPL-quadrature-removal PR #288 by routing the rule through fortnum instead of an in-tree math kit. `init_gauss_laguerre_integration` called the LGPL code only to build the order-32 rule for the weight `x^alpha exp(-x)` on `[0, inf)` with `alpha = 5/2` (D11) and `7/2` (D12); the `a=0, b=1` scaling is the identity. fortnum `gauss_gen_laguerre(n, alpha, x, w)` returns exactly that rule (Golub-Welsch), so the public interfaces of `init_gauss_laguerre_integration` and `calc_D_one_over_nu` are unchanged and the D11/D12 reference values reproduce within tolerance. Stacked on #317 (FFTW drop); review and merge that first. ## Dependency removed The LGPL `src/transport/gen_laguerre_rule.f90` quadrature generator (and the dead `calculate_gauss_laguerre_rule` / `write_to_file` / `debugging` state that only fed it). ## Verification Build (stack tip, both aspects applied): ``` [568/568] ... ninja: no work to do. ``` No LGPL quadrature symbols remain in the transport archive (only the fortnum reference): ``` $ nm /tmp/libneo-l2/src/transport/libtransport.a | grep -iE 'cgqf|r8_huge|rule_write|gen_laguerre' U __fortnum_quadrature_MOD_gauss_gen_laguerre ``` Transport test (D11e/D11i/D12e/D12i within 5% of references) passes: ``` Start 20: test_transport 1/1 Test #20: test_transport ................... Passed 0.11 sec 100% tests passed, 0 tests failed out of 1 ``` Note: fortnum pin updated to current main (92de6e9) after a fortnum history rewrite; old shas no longer resolve.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Merge order
Merge sequence: #316 -> #317 -> #318.
Each PR is based on
mainindividually, so each diff is cumulative againstmainand the three share code. Merge them in order. Once a predecessor merges, the next PR's diff shrinks to its own increment.collision_freqslinked GPLv3 GSL for one routine: the unnormalized lowerincomplete gamma in the Chandrasekhar function. The GPL obligation reached
every MIT-licensed downstream consumer (SIMPLE, NEO-2, NEO-RT, MEPHIT, KAMEL,
rabe), including SIMPLE's published binary wheels.
This routes that single math call to the fortnum numerical core instead of a
libneo-internal replacement. Consumers depend on fortnum directly.
lower_incomplete_gammareturnedgsl_sf_gamma_inc_P(a, x) * gsl_sf_gamma(a),the unnormalized lower incomplete gamma. That product is fortnum
gamma_lower(a, x), a pure function with the same domain (error stopona <= 0orx < 0, per fortnumdocs/migration_libneo.md). The publicinterface of
lower_incomplete_gammais unchanged, so callers compile withoutedits.
Changes:
bind(c)GSL interfaces and the line-160 product with asingle
use fortnum_special, only: gamma_lower. The now-deadiso_c_bindingimport is removed.find_package(GSL REQUIRED)and theGSL::gsllink fromsrc/collisions/CMakeLists.txt; link the fortnum Fortran target instead.FetchContentfromgit@github.com:lazy-fortran/fortnum.gitat
main, guarded byif(NOT TARGET fortnum)so a repo that also pullsfortnum transitively via libneo does not double-declare the target. This
mirrors how NEO-2 PR add stellarator symmetric bc file block writer #90 wires fortnum.
This was libneo's only GSL site (no FGSL/SLATEC/AMOS/C-GSL elsewhere), so GSL
is fully dropped.
Supersedes #286: that PR dropped GSL with a libneo-internal reimplementation;
this one routes the same call to the shared fortnum core.
Verification
Environment: gfortran, system HDF5 2.1.1, NetCDF, FFTW, OpenBLAS, fortnum
fetched fresh from
lazy-fortran/fortnummain(8f4c71c).Configure (fortnum fetched and built):
Full build:
GSL appears on no link line in the generated build:
The migrated routine is exercised by
test_collision_freqs(
calc_perp_coll_freq->psi_of_x->lower_incomplete_gamma->gamma_lower), whose expected values were produced by the prior GSL-backedimplementation. They pass unchanged:
Full suite: 57/69 pass. The 12 failures (chartmap / map2disc / vector
conversion / refcoords) come from a missing optional
map2discPython module(
ModuleNotFoundError: No module named 'map2disc') and the chartmap fixturesthat depend on it. They fail identically on unmodified
origin/mainbuilt inthe same environment:
None of the 12 touch
collision_freqs,species,transport, orfortnum.Note: fortnum pin updated to current main (92de6e9) after a fortnum history rewrite; old shas no longer resolve.