Skip to content

KineticForces — replace ximag offset with principal-value + residue for nutype="zero" pole handling #227

@logan-nc

Description

@logan-nc

Motivation

The energy integrand in src/KineticForces/EnergyIntegration.jl has a real
pole wherever the resonance denominator vanishes:

denom = i*(l_eff*wb*sqrt(x) + n*(we + wd*x)) - nu

When nutype = "zero" (collisionless) there is no nu to regularize the
integral, so the current code relies on a contour offset ximag > 0:
integrate along (1e-15, x + i*ximag) instead of the real axis. This is
inherited from Fortran PENTRC and has two defects:

  1. Accuracy: the offset introduces an O(ximag²) error in the integrated
    torque. There is no principled way to pick ximag — users currently set
    it by hand, and the default 0.0 silently disables pole handling.
  2. Performance: when ximag > 0 the entire [0, xmax] range is
    integrated with a ComplexF64 kernel (_energy_integrand_complex),
    paying full complex sqrt/exp cost across the whole domain even
    though the pole is typically localized to a small x-window.

A proper principal-value + residue decomposition would be both more
accurate (exact in the ε → 0 limit) and faster (the PV pieces run in
the fast Float64 kernel landed in PR #224; only the small ε-semicircle
around each pole pays the complex kernel cost).

Performance context

PR #224 landed a Float64 real-axis energy kernel that's ~2× faster than
the old complex kernel on the ximag == 0 path. That makes the ximag == 0
fast path cheap, but users who currently need pole handling for
nutype=\"zero\" are stuck paying the slow complex kernel everywhere.
PV+residue would let them stay in the Float64 kernel for most of the
range, paying the complex kernel only on the ε-arc.

Proposed implementation

Replace the ximag-based contour offset with:

∫₀^xmax f(x) dx  =  PV ∫₀^xmax f(x) dx  +  i·π·Σ Res[f, xₚ]

where the principal value is computed as PV = lim_{ε→0} [∫₀^{xₚ-ε} + ∫_{xₚ+ε}^xmax]
plus a small-ε semicircular arc contribution of i·π·Res[f, xₚ] (upper
half-plane convention consistent with Landau causality).

Pole locations xₚ are the real roots of the denominator and can be
found analytically for the quadratic-in-sqrt(x) form. Residues follow
from f(xₚ) / denom'(xₚ).

TOML changes (follow-up PR)

Replace ximag = 0.0 with x_residue_radius = 0.1 in [PENT_CONTROL].
Semantics: residue-arc radius in x = E/T units. Default 0.1.

Regression risk (important)

A prior attempt at this rewrite broke the Solovev kinetic "calculated"
fullruns test: et[1] dropped from 34.176 → 20.475. Root cause was
never identified; the source edits were lost before bisection
completed. That test has since been disabled in PR #224 (the
kinetic_source = \"calculated\" path is out of scope for the current
perturbative FFS→PE→KF work and its baseline was never physics-validated).

Before shipping the PV+residue rewrite, the follow-up PR must:

  1. Re-enable the kinetic_source = \"calculated\" fullruns test.
  2. Establish a physics-based baseline for that test — either against
    Fortran PENTRC on the same Solovev input, or against an analytical
    NTV limit. Do not re-pin to a number captured from the code.
  3. Validate that the PV+residue result matches the ximag → 0 limit of
    the old code on a smooth-test-case regression harness case with
    nutype = \"zero\".

Cross-references

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions