From 02c2eda21aa804410b1a465f18068cf1afadc36b Mon Sep 17 00:00:00 2001 From: Christopher Albert Date: Mon, 15 Jun 2026 16:42:09 +0200 Subject: [PATCH 1/6] Drop the GSL dependency and finalize fortnum wiring --- AGENTS.md | 2 +- KIM/README.md | 2 +- KIM/src/CMakeLists.txt | 9 +----- KIM/src/math/ddeabm/CMakeLists.txt | 7 +++-- KIM/tests/CMakeLists.txt | 7 ++--- KiLCA/CMakeLists.txt | 5 +--- KiLCA/interface/make_it | 2 +- KiLCA/math/fourier/mk_fourier | 2 +- KiLCA/math/hyper/Makefile | 4 +-- KiLCA/math/hyper/hyper1F1.cpp | 20 +++++++------ QL-Balance/CMakeLists.txt | 2 -- README.md | 4 +-- cmake/Dependencies.cmake | 1 - cmake/FetchGSL.cmake | 42 ---------------------------- python/susc_functions/f2py_Ifuncs.sh | 3 +- utility_scripts/setup_arch.sh | 1 - utility_scripts/setup_debian.sh | 2 +- 17 files changed, 30 insertions(+), 85 deletions(-) delete mode 100644 cmake/FetchGSL.cmake diff --git a/AGENTS.md b/AGENTS.md index e743c3c3..e9f84b47 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -58,7 +58,7 @@ make clean - **LAPACK/BLAS** - Linear algebra - **SuiteSparse** - Sparse matrix operations - **HDF5** - Data storage -- **GSL** - GNU Scientific Library +- **fortnum** - Numerical core (special functions, quadrature, ODE, root finding) - **SUNDIALS** - Numerical solvers ### Python Dependencies diff --git a/KIM/README.md b/KIM/README.md index 160d1668..58abcc2f 100644 --- a/KIM/README.md +++ b/KIM/README.md @@ -5,7 +5,7 @@ This is the integral plasma response model based on the code and model Kinetic L ### Required Libraries - **LAPACK/BLAS** - Linear algebra -- **GSL** - GNU Scientific Library +- **fortnum** - Special functions (Bessel) and error function - **HDF5** - Data storage (with Fortran bindings) - **SuiteSparse** - Sparse matrix operations (UMFPACK) - **SuperLU** - Sparse direct solver diff --git a/KIM/src/CMakeLists.txt b/KIM/src/CMakeLists.txt index 04cdad21..6340c89e 100644 --- a/KIM/src/CMakeLists.txt +++ b/KIM/src/CMakeLists.txt @@ -31,11 +31,6 @@ target_include_directories(KIM_lib PUBLIC "${CMAKE_BINARY_DIR}/OBJS/sparse/") # fortnum provides the special functions (bessel_in) used by FLR2_asymptotics. target_link_libraries(KIM_lib PUBLIC fortnum) -# TODO: unify this: either use the system library everywhere, or use the cloned version -# KiLCA uses the cloned libraries for now, QL-Balance the system libraries -find_package(GSL REQUIRED) -target_include_directories(KIM_lib PUBLIC "${GSL_INCLUDE_DIRS}") - find_package(LAPACK REQUIRED) if("${LAPACK_FOUND}") message(" ====== LAPACK was found! ======") @@ -111,13 +106,11 @@ if("${SUPERLU_FOUND}") endif() set(KILCA_PATH ${CMAKE_SOURCE_DIR}/KiLCA) -set(KiLCA_lib_path ${CMAKE_SOURCE_DIR}/build/install/lib/libKiLCA_Lib_V_2.4.2_MDNO_FPGEN_POLYNOMIAL_Release_64bit.a) # KiLCA is NOT linked to KIM_lib: KIM does not use any KiLCA symbols. # Previously PUBLIC, this caused duplicate library linking when QL-Balance # linked both KIM_lib and kilca_lib, corrupting symbol resolution order # and breaking KiLCA's wave solver (besselj failures, vacuum stitching errors). # KIM_exe links KiLCA directly via slatec (which provides the math routines). -target_link_libraries(KIM_lib PUBLIC GSL::gsl GSL::gslcblas) target_include_directories(KIM_lib PUBLIC ${KILCA_PATH}/math/) find_package(HDF5 COMPONENTS C Fortran HL REQUIRED) @@ -141,7 +134,7 @@ set_target_properties(KIM_exe PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/install/bin/") target_link_libraries(KIM_exe KIM_lib - "${KiLCA_lib_path}" + kilca_lib lapack slatec ) diff --git a/KIM/src/math/ddeabm/CMakeLists.txt b/KIM/src/math/ddeabm/CMakeLists.txt index adc9cbaa..f3a4c231 100644 --- a/KIM/src/math/ddeabm/CMakeLists.txt +++ b/KIM/src/math/ddeabm/CMakeLists.txt @@ -13,7 +13,8 @@ set(ddeabm_files dsteps.f ) add_library(ddeabm "${ddeabm_files}") -# ddeabm.f/ddes.f reference xermsg (and i1mach/d1mach via that path); those -# live in libslatec. Declare the dependency so the linker orders libslatec -# after libddeabm and resolves xermsg_ instead of dropping it. + +# ddeabm calls the slatec error machinery (xermsg and friends); declare the +# dependency explicitly so the static-archive link order resolves xermsg_ +# regardless of how the consuming executable orders its libraries. target_link_libraries(ddeabm PUBLIC slatec) diff --git a/KIM/tests/CMakeLists.txt b/KIM/tests/CMakeLists.txt index 1f5c039e..067c17b8 100644 --- a/KIM/tests/CMakeLists.txt +++ b/KIM/tests/CMakeLists.txt @@ -1,12 +1,9 @@ -# KiLCA library path (needed for tests that use KIM_lib symbols depending on KiLCA math) -set(KiLCA_lib_path ${CMAKE_SOURCE_DIR}/build/install/lib/libKiLCA_Lib_V_2.4.2_MDNO_FPGEN_POLYNOMIAL_Release_64bit.a) - # Optional: build QUADPACK/RKF45 integration comparison test add_executable(test_integration_methods ${CMAKE_SOURCE_DIR}/KIM/tests/test_integration_methods.f90) set_target_properties(test_integration_methods PROPERTIES OUTPUT_NAME test_integration_methods.x RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/tests/") -target_link_libraries(test_integration_methods KIM_lib "${KiLCA_lib_path}" lapack cerf ddeabm slatec) +target_link_libraries(test_integration_methods KIM_lib kilca_lib lapack cerf ddeabm slatec) add_test(NAME test_integration_methods COMMAND ${CMAKE_BINARY_DIR}/tests/test_integration_methods.x) @@ -58,7 +55,7 @@ add_executable(test_ampere_matrices ${CMAKE_SOURCE_DIR}/KIM/tests/test_ampere_ma set_target_properties(test_ampere_matrices PROPERTIES OUTPUT_NAME test_ampere_matrices.x RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/tests/") -target_link_libraries(test_ampere_matrices KIM_lib "${KiLCA_lib_path}" lapack cerf ddeabm slatec) +target_link_libraries(test_ampere_matrices KIM_lib kilca_lib lapack cerf ddeabm slatec) add_test(NAME test_ampere_matrices COMMAND ${CMAKE_BINARY_DIR}/tests/test_ampere_matrices.x) diff --git a/KiLCA/CMakeLists.txt b/KiLCA/CMakeLists.txt index d8e63fa8..5f3d128e 100644 --- a/KiLCA/CMakeLists.txt +++ b/KiLCA/CMakeLists.txt @@ -109,9 +109,8 @@ set (kilca_eigparam_main progs/main_eig_param.cpp) # include paths: set (libs_root_path ${CMAKE_BINARY_DIR}/external-install) -set (gsl_include_path ${libs_root_path}/gsl/include) -set(EXTERNAL_LIBS slatec lapack blas SUNDIALS::cvode SUNDIALS::nvecserial fortnum gsl gslcblas) +set(EXTERNAL_LIBS slatec lapack blas SUNDIALS::cvode SUNDIALS::nvecserial fortnum) # configure a header file to pass some of the CMake settings to the source code configure_file( @@ -121,7 +120,6 @@ configure_file( # Make generated header available include_directories("${CMAKE_CURRENT_BINARY_DIR}") -include_directories ("${gsl_include_path}") # fortnum C ABI header (fortnum.h); the Fortran fortnum target is linked above. include_directories ("${fortnum_SOURCE_DIR}/include") include_directories ("${PROJECT_BINARY_DIR}") @@ -284,7 +282,6 @@ target_include_directories(kilca_lib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/spline # External dependencies ${sundials_include_path} - ${gsl_include_path} ${fortnum_SOURCE_DIR}/include ) diff --git a/KiLCA/interface/make_it b/KiLCA/interface/make_it index 889f947f..a12f39c8 100755 --- a/KiLCA/interface/make_it +++ b/KiLCA/interface/make_it @@ -18,4 +18,4 @@ kilca_64bit="KiLCA_Lib_V_2.4_MDNO_FPGEN_USUAL_Debug_64bit" #kilca_64bit="KiLCA_Lib_V_2.4_MDYES_FPGEN_POLYNOMIAL_Debug_64bit" #kilca_64bit="libkilca_64bit" -gfortran ql-balance_mod.f90 wave_code_data_64bit.f90 bessel.f90 amn_of_r.f90 test_interface.f90 -L$kilca_lib_path -l$kilca_64bit -L$cvode_lib_path -lsundials_cvode -lsundials_nvecserial -L$slatec_lib_path -lslatec -lgsl -lgslcblas -lblas -llapack -lm -lc -lgfortran -lstdc++ +gfortran ql-balance_mod.f90 wave_code_data_64bit.f90 bessel.f90 amn_of_r.f90 test_interface.f90 -L$kilca_lib_path -l$kilca_64bit -L$cvode_lib_path -lsundials_cvode -lsundials_nvecserial -L$slatec_lib_path -lslatec -lfortnum -lblas -llapack -lm -lc -lgfortran -lstdc++ diff --git a/KiLCA/math/fourier/mk_fourier b/KiLCA/math/fourier/mk_fourier index 9a5c51cb..db421871 100644 --- a/KiLCA/math/fourier/mk_fourier +++ b/KiLCA/math/fourier/mk_fourier @@ -64,7 +64,7 @@ cvode_lib_path = /usr/local/lib libs = -L$(LINKER_PATH) \ -L$(math_lib_path) -lslatec_gf_430 -llapack_gf_430 -lblas_gf_430 \ -L$(cvode_lib_path) -lsundials_cvode -lsundials_nvecserial \ --lgsl -lgslcblas \ +-lfortnum \ -lgfortran \ -lstdc++ diff --git a/KiLCA/math/hyper/Makefile b/KiLCA/math/hyper/Makefile index 4f0cb870..c46515c8 100644 --- a/KiLCA/math/hyper/Makefile +++ b/KiLCA/math/hyper/Makefile @@ -47,13 +47,13 @@ LINKER_PATH = /usr/local/gcc$(COMPILER_PREFIX)/lib math_lib_path = /usr/local/lib/math_lib cvode_lib_path = /usr/local/lib -libs = -lgsl -lstdc++ +libs = -lfortnum -lstdc++ # libs = -L$(LINKER_PATH) \ # -L$(math_lib_path) -lslatec_gf_430 -llapack_gf_430 -lblas_gf_430 \ # -L$(cvode_lib_path) -lsundials_cvode -lsundials_nvecserial \ -# -lgsl -lgslcblas \ +# -lfortnum \ # -lgfortran \ # -lstdc++ diff --git a/KiLCA/math/hyper/hyper1F1.cpp b/KiLCA/math/hyper/hyper1F1.cpp index f0a9d968..eb5a211e 100644 --- a/KiLCA/math/hyper/hyper1F1.cpp +++ b/KiLCA/math/hyper/hyper1F1.cpp @@ -260,15 +260,19 @@ int hypergeometric1f1_cont_fract_1_modified_0_ada_ (double *b_re, double *b_im, //computes modified function 1F1m(a,b,z) for a = 1 and complex b & z by continued fraction //1F1 = 1 + z/b + z^2/b/(b+1)*(1 + 1F1m) -complex b(*b_re, *b_im), z(*z_re, *z_im); - -// fortnum computes F11m = 1F1(1;b+2;z) - 1 directly, avoiding the -// cancellation of the |z/b|-dispatch reconstruction at small z. -fortnum_complex result; -fortnum_hyperg_1f1m_a1 (b, z, &result); +complex b(*b_re, *b_im), z(*z_re, *z_im), F11m(0.0, 0.0); -*f_re = result.real(); -*f_im = result.imag(); +if (abs(z/b) < 0.1e0) +{ + hypergeometric1f1_kummer_modified_0_ada_ (b_re, b_im, z_re, z_im, f_re, f_im); +} +else //big numbers substraction - better to implement direct continued fraction! +{ + hypergeometric1f1_cont_fract_1_inv_ada_ (b_re, b_im, z_re, z_im, f_re, f_im); + F11m = ((*f_re) + (*f_im)*I - 1.0 - z/b)*(b/z)*((b + 1.0)/z) - 1.0; + *f_re = real(F11m); + *f_im = imag(F11m); +} return 0; } diff --git a/QL-Balance/CMakeLists.txt b/QL-Balance/CMakeLists.txt index 70a5d3d1..5f88161a 100644 --- a/QL-Balance/CMakeLists.txt +++ b/QL-Balance/CMakeLists.txt @@ -154,8 +154,6 @@ target_link_libraries(ql-balance_lib PUBLIC SUNDIALS::nvecserial blas fortnum - gsl - gslcblas hdf5::hdf5 hdf5::hdf5_fortran hdf5::hdf5_hl diff --git a/README.md b/README.md index b9ad348a..10f1b3a8 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ The framework consists of three main codes: ### Auto-Fetched Libraries The following are automatically downloaded and built if not found on the system: -- **GSL** - GNU Scientific Library +- **fortnum** - Numerical core (special functions, quadrature, ODE, root finding) - **SuiteSparse** - Sparse matrix operations (UMFPACK) - **SUNDIALS** - Numerical differential equation solvers - **NetCDF** - Network Common Data Form (with Fortran bindings) @@ -60,7 +60,7 @@ make QL-Balance make clean ``` -**Note:** External dependencies (LAPACK, SuiteSparse, GSL, SUNDIALS) are automatically downloaded and built during the first compilation if not found on the system. +**Note:** External dependencies (LAPACK, SuiteSparse, fortnum, SUNDIALS) are automatically downloaded and built during the first compilation if not found on the system. To pin libneo to a specific branch, tag, or commit, pass `-DLIBNEO_REF=` to cmake or `LIBNEO_REF=` to make. To use a local checkout instead of fetching, pass `-DLIBNEO_PATH=` / `LIBNEO_PATH=`. diff --git a/cmake/Dependencies.cmake b/cmake/Dependencies.cmake index c886cede..b7c410a4 100644 --- a/cmake/Dependencies.cmake +++ b/cmake/Dependencies.cmake @@ -5,7 +5,6 @@ list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake") # Core dependencies -include(FetchGSL) include(FetchLapack) include(FetchNetcdf) include(FetchSuiteSparse) diff --git a/cmake/FetchGSL.cmake b/cmake/FetchGSL.cmake deleted file mode 100644 index 51838ea8..00000000 --- a/cmake/FetchGSL.cmake +++ /dev/null @@ -1,42 +0,0 @@ -include(ExternalProject) - -if(NOT DEFINED GSL_INSTALL_DIR) - set(GSL_INSTALL_DIR - ${CMAKE_BINARY_DIR}/external-install/gsl - CACHE PATH "Where to install GSL headers & libs") -endif() - -ExternalProject_Add(EXTERNAL_gsl - PREFIX ${CMAKE_BINARY_DIR}/download - URL https://mirror.easyname.at/gnu/gsl/gsl-2.4.tar.gz - DOWNLOAD_NAME gsl-2.4.tar.gz - DOWNLOAD_EXTRACT_TIMESTAMP TRUE - BUILD_IN_SOURCE TRUE - - CONFIGURE_COMMAND - /configure --prefix=${GSL_INSTALL_DIR} - - BUILD_COMMAND - make -C -j - - INSTALL_COMMAND - make -C install - - BUILD_BYPRODUCTS - ${GSL_INSTALL_DIR}/lib/libgsl.a - ${GSL_INSTALL_DIR}/lib/libgslcblas.a -) - -add_library(gsl STATIC IMPORTED GLOBAL) -set_target_properties(gsl PROPERTIES - IMPORTED_LOCATION - "${GSL_INSTALL_DIR}/lib/libgsl.a" -) -add_dependencies(gsl EXTERNAL_gsl) - -add_library(gslcblas STATIC IMPORTED GLOBAL) -set_target_properties(gslcblas PROPERTIES - IMPORTED_LOCATION - "${GSL_INSTALL_DIR}/lib/libgslcblas.a" -) -add_dependencies(gslcblas EXTERNAL_gsl) diff --git a/python/susc_functions/f2py_Ifuncs.sh b/python/susc_functions/f2py_Ifuncs.sh index 1e88f8f9..9cf42a97 100755 --- a/python/susc_functions/f2py_Ifuncs.sh +++ b/python/susc_functions/f2py_Ifuncs.sh @@ -9,8 +9,7 @@ f2py -c src/getIfunc.f90 src/W2_arr.f90 $curr_loc/../../KiLCA/flre/conductivity/ -L$libs_path/sundials/build/src/nvector/serial/ -lsundials_nvecserial \ -L$libs_path/slatec/ -lslatec \ -L$libs_path/bessel/lib/ -lbessel \ - -lgsl \ - -lgslcblas \ + -L$libs_path -lfortnum \ -lm \ -lc \ --verbose diff --git a/utility_scripts/setup_arch.sh b/utility_scripts/setup_arch.sh index 5a4615b8..819b545c 100755 --- a/utility_scripts/setup_arch.sh +++ b/utility_scripts/setup_arch.sh @@ -8,7 +8,6 @@ sudo pacman -Sy \ gcc \ gcc-fortran \ git \ - gsl \ make \ netcdf \ netcdf-cxx \ diff --git a/utility_scripts/setup_debian.sh b/utility_scripts/setup_debian.sh index 966f9f88..e9d530b2 100755 --- a/utility_scripts/setup_debian.sh +++ b/utility_scripts/setup_debian.sh @@ -2,5 +2,5 @@ sudo apt update && apt install -y wget git cmake make gcc g++ gfortran \ libnetcdf-dev libnetcdff-dev openmpi-bin libopenmpi-dev libfftw3-dev \ - python3 python3-pip python3-numpy python3-scipy ninja-build libgsl-dev \ + python3 python3-pip python3-numpy python3-scipy ninja-build \ libopenblas-dev From 3c4945b383db987674ec2411b5f0025de7c8096d Mon Sep 17 00:00:00 2001 From: Christopher Albert Date: Tue, 30 Jun 2026 20:51:54 +0200 Subject: [PATCH 2/6] KIM/tests: link OpenMP into test_profile_input(_integration) These targets link kilca_lib, which pulls in libneo's field_divB0.f90 (OMP critical sections). CI link error: undefined reference to GOMP_critical_start/end. test_kim_diagnostics/solver/solver_em already link OpenMP::OpenMP_Fortran for the same reason; these two were missed. --- KIM/tests/CMakeLists.txt | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/KIM/tests/CMakeLists.txt b/KIM/tests/CMakeLists.txt index 067c17b8..e54c8d4c 100644 --- a/KIM/tests/CMakeLists.txt +++ b/KIM/tests/CMakeLists.txt @@ -1,3 +1,7 @@ +# OpenMP runtime: KIM/libneo objects use OMP critical sections, so test +# executables that pull them need libgomp (GOMP_critical_*) at link time. +find_package(OpenMP REQUIRED COMPONENTS C Fortran) + # Optional: build QUADPACK/RKF45 integration comparison test add_executable(test_integration_methods ${CMAKE_SOURCE_DIR}/KIM/tests/test_integration_methods.f90) set_target_properties(test_integration_methods PROPERTIES @@ -31,7 +35,7 @@ set_target_properties(test_profile_input PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/tests/") # Links the full math set: using profile_input_m pulls KIM objects whose # transitive deps (W2_arr) need the hypergeometric routines from KiLCA/slatec. -target_link_libraries(test_profile_input KIM_lib "${KiLCA_lib_path}" lapack cerf ddeabm slatec) +target_link_libraries(test_profile_input KIM_lib kilca_lib lapack cerf ddeabm slatec OpenMP::OpenMP_Fortran) add_test(NAME test_profile_input COMMAND ${CMAKE_BINARY_DIR}/tests/test_profile_input.x) @@ -39,7 +43,7 @@ add_executable(test_profile_input_integration ${CMAKE_SOURCE_DIR}/KIM/tests/test set_target_properties(test_profile_input_integration PROPERTIES OUTPUT_NAME test_profile_input_integration.x RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/tests/") -target_link_libraries(test_profile_input_integration KIM_lib "${KiLCA_lib_path}" lapack cerf ddeabm slatec) +target_link_libraries(test_profile_input_integration KIM_lib kilca_lib lapack cerf ddeabm slatec OpenMP::OpenMP_Fortran) add_test(NAME test_profile_input_integration COMMAND ${CMAKE_BINARY_DIR}/tests/test_profile_input_integration.x) From 728e595a2bf7dfb5be103bf390d28fb72eaa7fe4 Mon Sep 17 00:00:00 2001 From: Christopher Albert Date: Fri, 3 Jul 2026 07:35:17 +0200 Subject: [PATCH 3/6] fix(k8): link remaining KIM tests to kilca_lib --- KIM/tests/CMakeLists.txt | 12 ++++++------ KiLCA/math/hyper/hyper1F1.cpp | 20 ++++++++------------ 2 files changed, 14 insertions(+), 18 deletions(-) diff --git a/KIM/tests/CMakeLists.txt b/KIM/tests/CMakeLists.txt index e54c8d4c..cc196d39 100644 --- a/KIM/tests/CMakeLists.txt +++ b/KIM/tests/CMakeLists.txt @@ -51,7 +51,7 @@ add_executable(test_kim_diagnostics ${CMAKE_SOURCE_DIR}/KIM/tests/test_kim_diagn set_target_properties(test_kim_diagnostics PROPERTIES OUTPUT_NAME test_kim_diagnostics.x RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/tests/") -target_link_libraries(test_kim_diagnostics KIM_lib "${KiLCA_lib_path}" lapack cerf ddeabm slatec) +target_link_libraries(test_kim_diagnostics KIM_lib kilca_lib lapack cerf ddeabm slatec OpenMP::OpenMP_Fortran) add_test(NAME test_kim_diagnostics COMMAND ${CMAKE_BINARY_DIR}/tests/test_kim_diagnostics.x) @@ -70,7 +70,7 @@ add_executable(test_plag_coeff ${CMAKE_SOURCE_DIR}/KIM/tests/test_plag_coeff.f90 set_target_properties(test_plag_coeff PROPERTIES OUTPUT_NAME test_plag_coeff.x RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/tests/") -target_link_libraries(test_plag_coeff KIM_lib "${KiLCA_lib_path}" lapack cerf ddeabm slatec) +target_link_libraries(test_plag_coeff KIM_lib kilca_lib lapack cerf ddeabm slatec) add_test(NAME test_plag_coeff COMMAND ${CMAKE_BINARY_DIR}/tests/test_plag_coeff.x) @@ -78,7 +78,7 @@ add_executable(test_findIndex ${CMAKE_SOURCE_DIR}/KIM/tests/test_findIndex.f90) set_target_properties(test_findIndex PROPERTIES OUTPUT_NAME test_findIndex.x RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/tests/") -target_link_libraries(test_findIndex KIM_lib "${KiLCA_lib_path}" lapack cerf ddeabm slatec) +target_link_libraries(test_findIndex KIM_lib kilca_lib lapack cerf ddeabm slatec) add_test(NAME test_findIndex COMMAND ${CMAKE_BINARY_DIR}/tests/test_findIndex.x) @@ -86,7 +86,7 @@ add_executable(test_grid_equidistant ${CMAKE_SOURCE_DIR}/KIM/tests/test_grid_equ set_target_properties(test_grid_equidistant PROPERTIES OUTPUT_NAME test_grid_equidistant.x RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/tests/") -target_link_libraries(test_grid_equidistant KIM_lib "${KiLCA_lib_path}" lapack cerf ddeabm slatec) +target_link_libraries(test_grid_equidistant KIM_lib kilca_lib lapack cerf ddeabm slatec) add_test(NAME test_grid_equidistant COMMAND ${CMAKE_BINARY_DIR}/tests/test_grid_equidistant.x) @@ -95,7 +95,7 @@ add_executable(test_kim_solver ${CMAKE_SOURCE_DIR}/KIM/tests/test_kim_solver.f90 set_target_properties(test_kim_solver PROPERTIES OUTPUT_NAME test_kim_solver.x RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/tests/") -target_link_libraries(test_kim_solver KIM_lib "${KiLCA_lib_path}" lapack cerf ddeabm slatec) +target_link_libraries(test_kim_solver KIM_lib kilca_lib lapack cerf ddeabm slatec OpenMP::OpenMP_Fortran) add_test(NAME test_kim_solver COMMAND ${CMAKE_BINARY_DIR}/tests/test_kim_solver.x) @@ -104,7 +104,7 @@ add_executable(test_kim_solver_em ${CMAKE_SOURCE_DIR}/KIM/tests/test_kim_solver_ set_target_properties(test_kim_solver_em PROPERTIES OUTPUT_NAME test_kim_solver_em.x RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/tests/") -target_link_libraries(test_kim_solver_em KIM_lib "${KiLCA_lib_path}" lapack cerf ddeabm slatec) +target_link_libraries(test_kim_solver_em KIM_lib kilca_lib lapack cerf ddeabm slatec OpenMP::OpenMP_Fortran) configure_file(${CMAKE_SOURCE_DIR}/KIM/tests/test_data/KIM_config_em_small.nml ${CMAKE_BINARY_DIR}/tests/KIM_config_em_small.nml COPYONLY) add_test(NAME test_kim_solver_em diff --git a/KiLCA/math/hyper/hyper1F1.cpp b/KiLCA/math/hyper/hyper1F1.cpp index eb5a211e..f0a9d968 100644 --- a/KiLCA/math/hyper/hyper1F1.cpp +++ b/KiLCA/math/hyper/hyper1F1.cpp @@ -260,19 +260,15 @@ int hypergeometric1f1_cont_fract_1_modified_0_ada_ (double *b_re, double *b_im, //computes modified function 1F1m(a,b,z) for a = 1 and complex b & z by continued fraction //1F1 = 1 + z/b + z^2/b/(b+1)*(1 + 1F1m) -complex b(*b_re, *b_im), z(*z_re, *z_im), F11m(0.0, 0.0); +complex b(*b_re, *b_im), z(*z_re, *z_im); -if (abs(z/b) < 0.1e0) -{ - hypergeometric1f1_kummer_modified_0_ada_ (b_re, b_im, z_re, z_im, f_re, f_im); -} -else //big numbers substraction - better to implement direct continued fraction! -{ - hypergeometric1f1_cont_fract_1_inv_ada_ (b_re, b_im, z_re, z_im, f_re, f_im); - F11m = ((*f_re) + (*f_im)*I - 1.0 - z/b)*(b/z)*((b + 1.0)/z) - 1.0; - *f_re = real(F11m); - *f_im = imag(F11m); -} +// fortnum computes F11m = 1F1(1;b+2;z) - 1 directly, avoiding the +// cancellation of the |z/b|-dispatch reconstruction at small z. +fortnum_complex result; +fortnum_hyperg_1f1m_a1 (b, z, &result); + +*f_re = result.real(); +*f_im = result.imag(); return 0; } From 853260c0f2a4af84ffcd71f79aed9ff5b5d48029 Mon Sep 17 00:00:00 2001 From: Markus Markl Date: Fri, 3 Jul 2026 18:05:19 +0200 Subject: [PATCH 4/6] Carry OpenMP transitively via kilca_lib instead of per test target The GOMP_critical_* symbols come from libneo's field_divB0.f90, which is pulled into any executable that links kilca_lib. Until now each consumer that happened to drag in that object had to link OpenMP::OpenMP_Fortran itself; the KIM test targets were fixed in two separate passes as the missing ones surfaced, and five other kilca_lib consumers still omit it (they only build because they don't currently reference that object). Make OpenMP part of kilca_lib's PUBLIC link interface so every consumer (KIM_exe, ql-balance_lib, all KIM tests) inherits it automatically, which removes the per-target annotations and the latent breakage if one of the un-annotated targets later pulls the OMP object. To reference the imported target from kilca_lib's interface it must exist on all platforms, so hoist find_package(OpenMP) out of the APPLE-only branch to top scope (it was previously never resolved on Linux, where the top level only appends -fopenmp to the compile flags). The macOS libomp discovery and per-platform flag logic are unchanged. --- CMakeLists.txt | 10 ++++++---- KIM/tests/CMakeLists.txt | 16 ++++++++-------- KiLCA/CMakeLists.txt | 6 +++++- 3 files changed, 19 insertions(+), 13 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7d1daed0..9bc4961d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -53,12 +53,14 @@ project(KAMEL LANGUAGES C CXX Fortran) set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD_REQUIRED ON) +# OpenMP is a project-wide dependency: -fopenmp is on the global compile flags +# below, and libneo objects in the KiLCA link closure use OMP critical sections +# (GOMP_critical_*). Resolve the imported target once at top scope so it is +# visible to every subdirectory and can ride on targets' PUBLIC link interfaces. +find_package(OpenMP REQUIRED COMPONENTS C Fortran) + # Set architecture flags based on platform if(APPLE) - # On macOS, use libomp from Homebrew for OpenMP support - # find_package(OpenMP REQUIRED) - find_package(OpenMP REQUIRED C Fortran) - # Locate libomp from Homebrew find_program(BREW_EXECUTABLE brew HINTS /opt/homebrew/bin /usr/local/bin) if(BREW_EXECUTABLE) diff --git a/KIM/tests/CMakeLists.txt b/KIM/tests/CMakeLists.txt index cc196d39..c98cd1dd 100644 --- a/KIM/tests/CMakeLists.txt +++ b/KIM/tests/CMakeLists.txt @@ -1,6 +1,6 @@ -# OpenMP runtime: KIM/libneo objects use OMP critical sections, so test -# executables that pull them need libgomp (GOMP_critical_*) at link time. -find_package(OpenMP REQUIRED COMPONENTS C Fortran) +# OpenMP runtime (GOMP_critical_* from libneo's OMP critical sections) is +# carried transitively by kilca_lib's PUBLIC link interface, so no per-target +# OpenMP linkage is needed here. # Optional: build QUADPACK/RKF45 integration comparison test add_executable(test_integration_methods ${CMAKE_SOURCE_DIR}/KIM/tests/test_integration_methods.f90) @@ -35,7 +35,7 @@ set_target_properties(test_profile_input PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/tests/") # Links the full math set: using profile_input_m pulls KIM objects whose # transitive deps (W2_arr) need the hypergeometric routines from KiLCA/slatec. -target_link_libraries(test_profile_input KIM_lib kilca_lib lapack cerf ddeabm slatec OpenMP::OpenMP_Fortran) +target_link_libraries(test_profile_input KIM_lib kilca_lib lapack cerf ddeabm slatec) add_test(NAME test_profile_input COMMAND ${CMAKE_BINARY_DIR}/tests/test_profile_input.x) @@ -43,7 +43,7 @@ add_executable(test_profile_input_integration ${CMAKE_SOURCE_DIR}/KIM/tests/test set_target_properties(test_profile_input_integration PROPERTIES OUTPUT_NAME test_profile_input_integration.x RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/tests/") -target_link_libraries(test_profile_input_integration KIM_lib kilca_lib lapack cerf ddeabm slatec OpenMP::OpenMP_Fortran) +target_link_libraries(test_profile_input_integration KIM_lib kilca_lib lapack cerf ddeabm slatec) add_test(NAME test_profile_input_integration COMMAND ${CMAKE_BINARY_DIR}/tests/test_profile_input_integration.x) @@ -51,7 +51,7 @@ add_executable(test_kim_diagnostics ${CMAKE_SOURCE_DIR}/KIM/tests/test_kim_diagn set_target_properties(test_kim_diagnostics PROPERTIES OUTPUT_NAME test_kim_diagnostics.x RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/tests/") -target_link_libraries(test_kim_diagnostics KIM_lib kilca_lib lapack cerf ddeabm slatec OpenMP::OpenMP_Fortran) +target_link_libraries(test_kim_diagnostics KIM_lib kilca_lib lapack cerf ddeabm slatec) add_test(NAME test_kim_diagnostics COMMAND ${CMAKE_BINARY_DIR}/tests/test_kim_diagnostics.x) @@ -95,7 +95,7 @@ add_executable(test_kim_solver ${CMAKE_SOURCE_DIR}/KIM/tests/test_kim_solver.f90 set_target_properties(test_kim_solver PROPERTIES OUTPUT_NAME test_kim_solver.x RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/tests/") -target_link_libraries(test_kim_solver KIM_lib kilca_lib lapack cerf ddeabm slatec OpenMP::OpenMP_Fortran) +target_link_libraries(test_kim_solver KIM_lib kilca_lib lapack cerf ddeabm slatec) add_test(NAME test_kim_solver COMMAND ${CMAKE_BINARY_DIR}/tests/test_kim_solver.x) @@ -104,7 +104,7 @@ add_executable(test_kim_solver_em ${CMAKE_SOURCE_DIR}/KIM/tests/test_kim_solver_ set_target_properties(test_kim_solver_em PROPERTIES OUTPUT_NAME test_kim_solver_em.x RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/tests/") -target_link_libraries(test_kim_solver_em KIM_lib kilca_lib lapack cerf ddeabm slatec OpenMP::OpenMP_Fortran) +target_link_libraries(test_kim_solver_em KIM_lib kilca_lib lapack cerf ddeabm slatec) configure_file(${CMAKE_SOURCE_DIR}/KIM/tests/test_data/KIM_config_em_small.nml ${CMAKE_BINARY_DIR}/tests/KIM_config_em_small.nml COPYONLY) add_test(NAME test_kim_solver_em diff --git a/KiLCA/CMakeLists.txt b/KiLCA/CMakeLists.txt index 5f3d128e..51a34442 100644 --- a/KiLCA/CMakeLists.txt +++ b/KiLCA/CMakeLists.txt @@ -249,7 +249,11 @@ set_target_properties(kilca_lib PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/install/lib/ Fortran_MODULE_DIRECTORY ${PROJECT_BINARY_DIR}/OBJS/kilca/) add_dependencies(kilca_lib ${EXTERNAL_LIBS}) -target_link_libraries(kilca_lib PUBLIC ${EXTERNAL_LIBS}) +# libneo objects pulled into the KiLCA link closure use OMP critical sections +# (GOMP_critical_*). Carry the OpenMP runtime on kilca_lib's PUBLIC interface so +# every consumer (KIM_exe, ql-balance_lib, and all KIM tests) inherits it and no +# downstream target has to re-declare OpenMP to link. +target_link_libraries(kilca_lib PUBLIC ${EXTERNAL_LIBS} OpenMP::OpenMP_Fortran) # Add include directories on `kilca_lib` target for all source and module paths target_include_directories(kilca_lib PUBLIC From d1c9b5d108971dce30bdd6c67d1f49afc3eb29a1 Mon Sep 17 00:00:00 2001 From: Christopher Albert Date: Sun, 5 Jul 2026 22:15:42 +0200 Subject: [PATCH 5/6] Drop libgsl-dev from CI and golden workflows The build no longer links GSL after the fortnum migration, so the apt install of libgsl-dev in ci.yml and golden.yml is dead weight. --- .github/workflows/ci.yml | 1 - .github/workflows/golden.yml | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 891bbf3a..aa440f61 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -37,7 +37,6 @@ jobs: libopenblas-dev \ liblapack-dev \ doxygen \ - libgsl-dev \ libsuitesparse-dev \ libsuperlu-dev \ python3-dev \ diff --git a/.github/workflows/golden.yml b/.github/workflows/golden.yml index ddb68d04..83098a86 100644 --- a/.github/workflows/golden.yml +++ b/.github/workflows/golden.yml @@ -29,7 +29,7 @@ jobs: sudo apt-get install -y cmake ninja-build gfortran \ libopenmpi-dev openmpi-bin libhdf5-openmpi-dev libnetcdf-dev \ libnetcdff-dev libomp-dev libopenblas-dev liblapack-dev doxygen \ - libgsl-dev libsuitesparse-dev libsuperlu-dev python3-dev python3-pip \ + libsuitesparse-dev libsuperlu-dev python3-dev python3-pip \ libmpfr-dev libgmp-dev # matplotlib: KAMELpy's KiLCA_interface imports it, so the QL-Balance # prepare hook needs it. doxygen: required by KiLCA's CMake build. @@ -64,7 +64,7 @@ jobs: sudo apt-get install -y cmake ninja-build gfortran \ libopenmpi-dev openmpi-bin libhdf5-openmpi-dev libnetcdf-dev \ libnetcdff-dev libomp-dev libopenblas-dev liblapack-dev doxygen \ - libgsl-dev libsuitesparse-dev libsuperlu-dev python3-dev python3-pip \ + libsuitesparse-dev libsuperlu-dev python3-dev python3-pip \ libmpfr-dev libgmp-dev pip install numpy scipy matplotlib h5py f90nml From 7bef9994911b9979240647eea261c065eae9883f Mon Sep 17 00:00:00 2001 From: Markus Markl Date: Fri, 10 Jul 2026 08:05:18 +0200 Subject: [PATCH 6/6] ci(golden): restore libgsl-dev for historical reference build The golden-record job rebuilds the golden-baseline (and pre-fortnum) reference trees, which predate the GSL removal and still call find_package(GSL REQUIRED) in KIM/src/CMakeLists.txt. Dropping libgsl-dev in d1c9b5d1 broke the reference build's CMake configure: Could NOT find GSL (missing: GSL_INCLUDE_DIR ...) at KIM/src/CMakeLists.txt HEAD no longer needs GSL, so ci.yml correctly drops it, but golden.yml must keep it to compile the frozen references it diffs against. --- .github/workflows/golden.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/golden.yml b/.github/workflows/golden.yml index 83098a86..ddb68d04 100644 --- a/.github/workflows/golden.yml +++ b/.github/workflows/golden.yml @@ -29,7 +29,7 @@ jobs: sudo apt-get install -y cmake ninja-build gfortran \ libopenmpi-dev openmpi-bin libhdf5-openmpi-dev libnetcdf-dev \ libnetcdff-dev libomp-dev libopenblas-dev liblapack-dev doxygen \ - libsuitesparse-dev libsuperlu-dev python3-dev python3-pip \ + libgsl-dev libsuitesparse-dev libsuperlu-dev python3-dev python3-pip \ libmpfr-dev libgmp-dev # matplotlib: KAMELpy's KiLCA_interface imports it, so the QL-Balance # prepare hook needs it. doxygen: required by KiLCA's CMake build. @@ -64,7 +64,7 @@ jobs: sudo apt-get install -y cmake ninja-build gfortran \ libopenmpi-dev openmpi-bin libhdf5-openmpi-dev libnetcdf-dev \ libnetcdff-dev libomp-dev libopenblas-dev liblapack-dev doxygen \ - libsuitesparse-dev libsuperlu-dev python3-dev python3-pip \ + libgsl-dev libsuitesparse-dev libsuperlu-dev python3-dev python3-pip \ libmpfr-dev libgmp-dev pip install numpy scipy matplotlib h5py f90nml