Skip to content

feat(QL-Balance): add KIM as alternative wave code backend#120

Merged
marjohma merged 20 commits intomainfrom
feature/kim-ql-balance-interface
Mar 25, 2026
Merged

feat(QL-Balance): add KIM as alternative wave code backend#120
marjohma merged 20 commits intomainfrom
feature/kim-ql-balance-interface

Conversation

@marjohma
Copy link
Copy Markdown
Member

Summary

  • Add KIM wave code adapter (kim_wave_code_adapter.f90) that wraps KIM library calls behind the same data contract QL-Balance expects from KiLCA, enabling KIM as a drop-in alternative wave code backend
  • Namelist-driven backend selection via wave_code = 'KiLCA' or 'KIM' in balance_conf.nml — existing KiLCA path is unchanged and remains the default
  • Expose KIM internal APIs for library mode: species, equilibrium, fields, and grid modules now provide public accessors for QL-Balance to extract Es, Br, kp, ks, collision frequencies, and background quantities
  • Build integration: link KIM_lib into QL-Balance, fix ddeabm duplicate symbols, add unit test for the KIM adapter module
  • Python interface: add balance_mode='KIM' support in KiLCA_interface and balance_interface, modernize file operations
  • Add curl(B) Jpar method for antenna factor computation (restricted to KiLCA wave code)

Key changes

  • 18 commits, 40 files changed (+2153, -218 lines)
  • New kim_wave_code_adapter_m module (~940 lines) implements kim_initialize, kim_run_for_all_modes, and field/auxiliary extraction
  • Transport coefficient wiring in diff_coeffs.f90, get_dql.f90, and integrate_parallel_current.f90 extended for KIM data
  • KIM modules (species_mod, fields_mod, grid_mod, config_mod) gain public getters and reallocation guards

Test plan

  • make test passes (CTest suite including new test_kim_adapter)
  • Build succeeds with make all (Release and Debug)
  • Run QL-Balance with wave_code = 'KiLCA' — verify unchanged behavior
  • Run QL-Balance with wave_code = 'KIM' — verify KIM fields populate correctly

🤖 Generated with Claude Code

marjohma and others added 20 commits March 25, 2026 12:48
Add KIM_lib as a dependency and link target for ql-balance_lib to enable
the upcoming KIM wave code adapter integration. To resolve duplicate
sparse_mod symbols between KIM's bundled copy and the shared sparse
target, KIM now links against the shared sparse target instead of
bundling its own copy.

Changes:
- QL-Balance/CMakeLists.txt: add KIM_lib to add_dependencies and
  target_link_libraries
- KIM/src/CMakeSources.in: remove bundled sparse_mod.f90
- KIM/src/CMakeLists.txt: link KIM_lib against shared sparse target

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds 'wave_code' namelist variable to BALANCENML with default 'KiLCA'.
Supports future selection between KiLCA and KIM wave code backends.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Skeleton module with public API stubs for KIM-QL-Balance interface:
kim_initialize, kim_run_for_all_modes, kim_update_profiles,
kim_get_wave_fields, kim_get_wave_vectors,
kim_get_background_magnetic_fields, kim_get_collision_frequencies.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Initializes KIM backend, runs electrostatic solver for first mode,
and extracts background quantities (B0, kp, ks, nue, nui, dPhi0,
profiles) from KIM modules onto the QL-Balance radial grid.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Runs KIM electrostatic solver for each (m,n) mode and stores Es/Br
results in per-mode arrays. Adds kim_update_profiles for transferring
QL-Balance time-evolved parameters back to wave_code_data arrays.

Key additions:
- kim_run_for_all_modes: loops over modes, sets m/n, creates fresh KIM
  solver via factory, runs Poisson solve, interpolates fields onto the
  QL-Balance grid, and stores results in kim_*_modes arrays
- kim_update_profiles: mirrors update_background_files for KIM path,
  converting params_b (erg) to wave_code_data units (eV, cm/s)
- deallocate_EBdat helper: cleans up global EBdat between mode solves
- interp_complex_profile helper: interpolates complex profiles by
  splitting into real/imaginary parts

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Implement kim_get_wave_fields (copies per-mode stored Es/Br/Er/Ep/Et/Ez
into wave_code_data scalars), kim_get_wave_vectors (per-mode kp/ks with
new kim_kp_modes/kim_ks_modes storage arrays), and no-op stubs for
kim_get_background_magnetic_fields and kim_get_collision_frequencies
(already populated during initialization).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds select case(wave_code) dispatch in:
- initialize_wave_code_interface: KiLCA vs KIM init
- get_dql timestep calls: profile update + solve
- Mode loop: field/vector retrieval per mode
- Misalignment diffusion: wave field refresh
- Vacuum Br for form factor
- FLRE Br for form factor
- Current density approximation (zeroed for KIM)

Also makes kim_Br_modes public in the adapter module so
get_dql can access per-mode Br arrays directly.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Avoids duplicate symbol collision with QL-Balance's resonances_mod
when both libraries are linked into ql-balance.x. Also moves cerf
and ddeabm link dependencies from KIM_exe to KIM_lib so they are
available when KIM_lib is consumed by other targets.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Allow users to configure the KIM namelist file path via balance_conf.nml
instead of relying on the hardcoded default "./KIM_config.nml".

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Tests wave_code default value, interp_complex_profile with constant
and linear functions. Verifies adapter module compilation and linkage
against KIM_lib. Full integration tests require KIM config data and
are deferred to end-to-end validation.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
ddeabm's i1mach had all DATA statements commented out, shadowing the
correct slatec version at link time and breaking DGAMLN/Bessel functions.
Explicitly list only the ODE-solver sources instead of globbing.

Move KiLCA linkage from KIM_lib (PUBLIC) to KIM_exe only — KIM does not
use KiLCA symbols directly, and the duplicate linkage corrupted symbol
resolution when QL-Balance linked both KIM_lib and kilca_lib.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Rename read_config → kim_read_config to avoid symbol clash when KIM is
linked as a library into QL-Balance (which has its own read_config).

Add deallocate-before-allocate guards in grid_m, equilibrium_m, and
species_m so that KIM can be re-initialized on repeated calls without
crashing on double allocation.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add profiles_in_memory flag and set_profiles_from_arrays subroutine so
QL-Balance can inject profiles directly without file I/O. Add no-write
variant of postprocess_electric_field and store jpar in EBdat for
extraction by the adapter.

Replace SuiteSparse sparse solver with LAPACK ZGESV in the EM solver
(dense direct solve, appropriate for the 2N ~ 400 system size) and
fix Poisson solver method to use SuiteSparse (method=3).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ring

Add KIM mode list configuration (kim_m_list, kim_n_list, kim_n_modes,
kim_profiles_from_balance) to balance namelist. Extend the KIM adapter
with profile injection, vacuum field loading, domain consistency checks,
current density extraction, and antenna factor computation.

Wire KIM adapter into the transport workflow: get_dql dispatches to KIM
when wave_code='KIM', gengrid supports KIM grid setup, diff_coeffs and
transp_coeffs_mod compute antenna factors from parallel current,
integrate_parallel_current handles KIM jpar data, and writeData outputs
KIM-specific diagnostics.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace os.system calls with os.makedirs, os.remove, and os.symlink in
KiLCA_interface for safer file handling. Extract vacuum KiLCA run into
prepare_vacuum_kilca method and add prepare_balance_kim for KIM-mode
workflow (profiles + vacuum fields without full KiLCA plasma response).

Fix balance_input_h5 ubounds calculation (len(data) instead of
len(data[0])). Set vgalsys=-1e8 in background data for consistency.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Recompute equilibrium (kp, ks, om_E) before each mode 2+ solve
  so multi-mode runs use correct mode-dependent wave vectors
- Make vacuum Br per-mode: kim_vac_Br is now (dim_r, dim_mn),
  loaded from KiLCA vacuum solution for each (m,n) independently
- Compute per-species parallel current via electron/ion kernels:
  add jpar_e, jpar_i to EBdat_t, fill from Kllp_e/Kllp_i in EM
  solver, assign correctly to Jpe/Jpi in the adapter
- Initialize kim_vac_Br with IEEE NaN instead of (1,0) to catch
  uninitialized usage via NaN propagation
- Add case default error stop to all wave_code select blocks
- Fix KIM test linking: add KiLCA library to test executables
  after KiLCA was removed from KIM_lib PUBLIC linkage
- Delete unused kim_wave_code_adapter_stub.f90

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add compute_jpar_curlB subroutine that computes parallel current density
from Ampere's law (J = curl(B)/(4*pi)) matching the Matlab KiLCA
postprocessor convention. Both conductivity-based (sigma*E) and curl(B)
Jpar are computed and logged; jpar_method namelist option ('conductivity'
or 'curlB') selects which feeds the antenna factor calculation.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add error stop when jpar_method='curlB' is used with wave_code other
than KiLCA, since KIM does not output Bt/Bz components needed for
the curl(B) computation.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
ddeabm depends on xermsg_ from slatec, so ddeabm must precede slatec
in the static library link order for the linker to resolve the symbol.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The golden record test builds main's ql-balance.x but was using the
current branch's balance_conf.nml template, which may contain namelist
variables unknown to the main binary (e.g. wave_code, kim_*).

Pass main_ref's own template to setup_runfolder so the generated config
only includes variables the main-branch binary recognises.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@marjohma marjohma force-pushed the feature/kim-ql-balance-interface branch from ace752a to 4c9eac2 Compare March 25, 2026 11:55
@marjohma marjohma merged commit 02bf47a into main Mar 25, 2026
1 check passed
@marjohma marjohma deleted the feature/kim-ql-balance-interface branch March 25, 2026 12:11
@marjohma marjohma restored the feature/kim-ql-balance-interface branch March 30, 2026 12:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant