Skip to content

Restore Fourier-space KIM kernels with behavioral tests#177

Closed
krystophny wants to merge 3 commits into
mainfrom
feat/flux-pumping/wp5-kernel-restore
Closed

Restore Fourier-space KIM kernels with behavioral tests#177
krystophny wants to merge 3 commits into
mainfrom
feat/flux-pumping/wp5-kernel-restore

Conversation

@krystophny

@krystophny krystophny commented Jul 12, 2026

Copy link
Copy Markdown
Member

First split item of #175: restore the continuous-Fourier kernels
kernel_rho_phi_of_kr_krp_rg and kernel_rho_B_of_kr_krp_rg as kernels_m
(KIM/src/kernels/kernel_mod.f90), rewired from the removed
plasma_parameter/back_quants globals to the current species_m plasma_t
state, and reactivate the kernel tests as ctest-registered behavioral checks.

Stack: parent branch main, pinned parent commit 2341697e.

Invariant preserved

  • Both kernel expressions are restored term-for-term from
    kernel_mod.f90 at 1ae0aeeb~1: Debye branch, large-argument Bessel
    asymptotics, exp(i (k_r - k_r') r_g) phase, 1/(8 pi^2) (rho-phi) and
    i/(8 pi^2 c) (rho-B) normalizations, CGS-Gaussian units.
  • The background quantities the kernels consume are computed by species_m
    with the same defining formulas the deleted calculate_backs used
    (A1, A2, lambda_D, z0, ks, kp verified line-by-line);
    Lagrange interpolation keeps the historical binsrc/plag_coeff
    4-point scheme on plasma%r_grid.
  • Provider changes only: gsl_sf_bessel_In -> fortnum_special::bessel_in
    (same modified Bessel I_n), and the retired kernel_debye_case config key
    becomes a module switch with unchanged default .false..
  • Nothing else links against the new module yet; the existing solver paths,
    golden records, and all 25 pre-existing ctests are untouched.

Test changes

The orphaned KIM/src/tests/ programs pinned values of the deleted
NRL-rounded background (vTe = 4.19e7 sqrt(Te), constant btor); the
current pipeline computes sqrt(T ev/m) and omega_c from B0(r), so
those pins differ at the 1e-3 level while the tightest tolerance was 1e-5:
they cannot pass against either code state. They are replaced by analytic
and property checks at 1e-12 relative tolerance:

The dead KIM/src/tests/ directory (empty CMakeLists, broken
kim_init_for_test) and the commented-out KIM_kernels source group are
removed; the new tests live in KIM/tests/ with the other ctest programs.

Verification

Test fails on defective kernel (normalization mutated)

$ sed -i 's|/(2.0d0\*\*3\*pi\*\*2)|/(2.0d0**3*pi)|' KIM/src/kernels/kernel_mod.f90
$ cmake --build build --target test_kernel_rho_phi && ctest --test-dir build -R test_kernel_rho_phi
1/1 Test #23: test_kernel_rho_phi ..............***Failed    0.07 sec
 FAIL adiabatic Debye screening -1/(8 pi^2 lambda_D^2)
   got  =               (-2879.8814430158527,0.0000000000000000)
   want =               (-916.69473434918780,0.0000000000000000)
   rel  =    2.1415926535897900
ERROR STOP

(On main the module and tests do not build at all; the historical test
programs reference modules deleted in 7c1345dc.)

Test passes after restore

$ ctest --test-dir build -R "test_kernel_rho"
1/2 Test #23: test_kernel_rho_phi ..............   Passed    0.06 sec
2/2 Test #24: test_kernel_rho_B ................   Passed    0.06 sec
100% tests passed, 0 tests failed out of 2

Full suite

$ ctest --test-dir build
100% tests passed, 0 tests failed out of 27

Relation to Markus's Fokker-Planck periodic branch

This PR restores the historical continuous Krook kernels. It is useful for Fourier-phase, Debye-limit, and interpolation comparisons, but it is not the off-diagonal Fokker-Planck kernel implemented on feature/kim-forced-periodicity. Hold integration until #191 decides whether any generic tests are retained. The independent FP derivation and oracle are #187, #194, and #196.

@krystophny

Copy link
Copy Markdown
Member Author

Follow-up commit: the Debye switch now only zeroes the thermodynamic-force terms and keeps the sign, gyroaverage Gaussian, and Fourier phase of the full expression. The historical branch flipped the sign relative to the adiabatic limit and dropped the phase factor, which would anti-screen and break diagonality once the switch feeds a matrix assembly; the modern hat-basis path (artificial_debye_case with the G0 prefactor) uses the retained convention. The switch test now checks that enabling it removes the force response while reproducing the force-free kernel.

@marjohma

Copy link
Copy Markdown
Member

Closing: the wp5 flux-pumping stack is retired. This work is superseded by the forced-periodicity lineage on feature/kim-forced-periodicity (issue #175): the oracle-verified Fokker-Planck Fourier kernel (#187/#216/#217), vendored background/geometry periodization, the periodic deviation solver with gauge policy (#219), and the numerical trust gates (#215). The Krook Fourier kernel deliberately remains reference-only in git history per the FP-not-Krook design decision.

@marjohma marjohma closed this Jul 15, 2026
marjohma added a commit that referenced this pull request Jul 15, 2026
)

## Summary

Extracts the two salvageable pieces of the retired wp5 flux-pumping
stack onto the forced-periodicity lineage. The rest of that stack
(#177#181, #184) is closed as superseded.

## Krook argument `z0` (was #183)

`interpolate_plasma_backs` interpolated the **derived** `z0` alongside
the primitives. `z0` carries a `1/|k_parallel|` singularity at the
resonance, so a four-point Lagrange stencil spanning `k_parallel = 0`
returns values that violate its own defining formula. The fix
interpolates primitives only and recomputes

    z0 = -(omega_E - omega - i nu) / (|k_parallel| sqrt(2) v_T)

on the target grid — the same invariant the periodized-background path
already follows.

**Scope:** `z0` is consumed only by `Krook_kernel_plasma_prefacs.f90`.
The Fokker-Planck path recomputes `x1/x2/A1/A2/I^{kl}` after
interpolation and never reads `z0`, so **FP results are bit-unchanged**.
This repairs the Krook hat path, whose nml still marks it `(unstable)` —
plausibly part of why.

## Collision-frequency scale (was #182)

New positive `&KIM_CONFIG` key `collision_frequency_scale` multiplying
the calculated electron and ion collision frequencies before `z0` and
the FP susceptibility inputs are assembled. Default `1.0` leaves every
collision formula, profile, unit, and output unchanged. Non-positive
values are rejected at startup; the value is displayed when it differs
from 1.0 and stored in HDF5 provenance. Same shape as the existing
`ion_flr_scale_factor` knob. No benchmark-acceptance claim — it is a
sensitivity parameter.

## Tests

`test_collision_scale_z0` (new) asserts the `z0` invariant on a stencil
straddling `k_parallel = 0` and away from it, and that the scale reaches
both `nu` and `z0` (including the imaginary part of `z0` tracking it).

Developed red-first: against the pre-fix code the test fails with a
**36% relative `z0` error at k_par = 2e-4** (`got (-0.0983, 0.0129)` vs
`want (-0.4543, 0.0599)`), growing without bound toward the resonance.

## Validation

- `make` — clean build
- `ctest -E
'test_rhs_balance|test_periodic_convergence|test_periodic_vs_global'` —
**32/32 passed**

Known red gates excluded as usual: the pre-existing `test_rhs_balance`
baseline failure, the periodization-deformation gate, and the
periodic-vs-global 5% gate — none touched by this change.

Supersedes #182, #183.
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.

2 participants