Charge Exchange
Charge Exchange
Charge exchange in GUERNICA is an optional operator enabled by including charge_exchange under operators in [components]. In practice, charge exchange also requires the ion background species i to be included under [components] species, because the operator is built from prescribed ion density, drift velocity, and temperature fields. The available charge-exchange models are currently FFT, Full, LB, Avg, and Meier.
At the input-file level, a minimal charge-exchange setup looks like:
[components]
species = n, i
operators = charge_exchange
[charge_exchange]
model = FFT
sigma = Krstic
plasma_species = i
neutral_species = n
The [charge_exchange] entries currently mean:
modelselects the charge-exchange model. Supported values areFFT,Full,LB,Avg, andMeier.sigmaselects the cross-section model, but only forFFTandFull. The currently supported choices areKrsticandJanev-Smith.plasma_speciesis the ion background species and is currentlyi.neutral_speciesis the evolved neutral species and is currentlyn.
The ion background used by charge exchange comes from the ion initialization and profile sections, not from a time-evolved ion kinetic solve. In the main driver, the code reads the ion density, temperature, and drift profiles, projects them into MFEM grid functions, and passes those fields into the selected charge-exchange operator. So, in addition to [charge_exchange], a real case also needs an [i:init] section and the corresponding [profile:<name>] sections for ion density, temperature, and drift.
A more complete example therefore looks like:
[components]
species = n, i
operators = charge_exchange
[charge_exchange]
model = Full
sigma = Janev-Smith
plasma_species = i
neutral_species = n
[i:init]
type = maxwellian
density = ion_density
temperature = ion_temperature
ux = ion_ux
uy = ion_uy
uz = ion_uz
[profile:ion_density]
type = constant
value = 1.0
[profile:ion_temperature]
type = constant
value = 1.0
[profile:ion_ux]
type = constant
value = 0.0
[profile:ion_uy]
type = constant
value = 0.0
[profile:ion_uz]
type = constant
value = 0.0
All of the charge-exchange models first build an ion distribution \(f_i\) on the discrete velocity grid from the prescribed ion background. In the code, this is a Maxwellian of the form
evaluated at every velocity point and every spatial degree of freedom. This precomputed ion distribution is then combined with the current neutral distribution \(f_n\) in the selected charge-exchange model.
For the two most detailed models, Full and FFT, the operator has the same underlying structure. The code computes two velocity-space integrals,
and then applies the charge-exchange source term
So the loss term removes neutrals at velocity \(v\) based on collisions with ions, and the gain term repopulates neutrals at \(v\) from the ion distribution.
The Full model evaluates that operator directly by looping over all source velocities \(v'\) for each target velocity \(v\). In the implementation, it precomputes one-dimensional squared-difference tables, uses a lookup table for \(\sigma(|v-v'|)\), and performs the full discrete sum over velocity space. This is the most direct discrete realization of the charge-exchange operator among the currently available models.
The FFT model computes the same basic convolutional structure as Full, but accelerates the velocity-space sums with padded FFT-based convolutions. The code pads the velocity grid to about twice its size in each dimension, builds the kernel spectrum once, packs weighted neutral and ion sources, applies forward FFTs, multiplies by the kernel spectrum in Fourier space, performs inverse FFTs, and then assembles the same residual form
In the current driver, FFT is only available in a CUDA build; otherwise the code aborts and instructs the user to rebuild with CUDA support.
For FFT and Full, the cross section is chosen through sigma in [charge_exchange]. The code supports Krstic and Janev-Smith, and validation only allows sigma to be specified for these two models.
The Avg model is a reduced approximation. Instead of keeping the full target-velocity dependence in the loss and gain integrals, it first computes two scalar rates at each spatial degree of freedom,
where \(\alpha\) is built from a tabulated \(\langle \sigma v \rangle\) fit. It then applies
So Avg keeps the same loss-plus-gain structure as the full operator, but compresses the integral information into spatially local scalar coefficients rather than full velocity-dependent convolutions.
The LB model is another reduced approximation. It first computes only a neutral-side scalar integral
again using a tabulated \(\langle \sigma v \rangle\) fit, and then applies a mixed pointwise/scalar form
So compared with Avg, the loss term remains explicitly velocity dependent through \(\alpha(v)\), while the gain term is driven by a scalar neutral integral multiplied by the ion Maxwellian.
Both Avg and LB use a Janev–Smith-style \(\langle \sigma v \rangle\) fit internally rather than the explicit \(\sigma(|v-v'|)\) models used in Full and FFT. In the code, this quantity is tabulated in advance in \((\log T,\log E)\) space for smoother interpolation on the device.
The Meier model is the most reduced of the currently implemented options. Unlike the other charge-exchange models, it depends not only on the ion background but also on the current neutral moments. In the time loop, the code explicitly recomputes the neutral density, momentum, and energy before applying the Meier operator, and passes those moments into the operator with SetNeutralMoments(...).
Inside Meier, the neutral bulk velocity and neutral temperature are reconstructed from the neutral moments, and the relative bulk speed between ions and neutrals is formed. The model then defines
uses the coded approximation
and applies
So Meier is effectively a local moment-based closure for charge exchange rather than a full velocity-space integral operator.
In summary, the different charge-exchange models mainly differ in how much of the velocity-space coupling they retain:
Full: direct discrete evaluation of the full velocity-space operator.FFT: same basic full operator, but accelerated with FFT-based convolution on CUDA.Avg: replaces the full operator with spatially local scalar gain/loss rates \(K_i\) and \(K_n\).LB: keeps a velocity-dependent loss term but uses a scalar neutral integral for the gain term.Meier: uses local ion and neutral moments to build a fully local approximate charge-exchange rate.
From a user perspective, the only thing that changes in the input file is the value of model in [charge_exchange], plus the optional sigma choice for FFT and Full. The ion background specification through [i:init] and its associated profiles is required regardless of which charge-exchange model is selected.