Normalization
This section documents the normalization conventions used in SPECTRAX-GK and the calibration parameters that scale drift/drive terms for benchmark comparisons.
Canonical normalization contract
SPECTRAX-GK now centralizes benchmark-family normalization values in
spectraxgk.normalization via spectraxgk.normalization.NormalizationContract.
This is the single source of truth for case defaults:
Case key |
|
|
|
|
|---|---|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
These contracts are consumed by benchmark constants for backward compatibility
(CYCLONE_OMEGA_D_SCALE, etc.), so existing scripts keep working while all
new calibration updates flow through one module.
Dimensionless units
We evolve a dimensionless gyrokinetic system normalized to ion thermal quantities. The parallel streaming term uses the normalized thermal velocity \(v_{th}\) and the flux-tube coordinate \(z\) (theta-like). The perpendicular wave numbers are normalized by the ion gyro-radius \(\rho_i\), while the distribution function and potential use the standard gyrokinetic scaling:
For the Cyclone base case we take the reference length \(L_{ref}=a\) so that the input gradients are expressed as \(a/L_T\) and \(a/L_n\). With \(R_0 = R/a\), this means \(R/L_T = (R_0)\,(a/L_T)\) and similarly for \(R/L_n\).
Kinetic species conventions
SPECTRAX-GK supports multi-species kinetic systems. Species-dependent arrays carry the charge, mass, density, temperature, and gradient inputs:
charge_sign: \(Z_s\) (e.g., \(+1\) for ions, \(-1\) for electrons).temp/mass/density: normalized to the reference species.tz: \(Z_s / T_s\) coupling used in the field terms.R_over_LTi/R_over_Ln: normalized gradients for each species.
For adiabatic closures, tau_e provides the ratio between the kinetic
species temperature and the Boltzmann species temperature.
Field-aligned grid parameters
For the Cyclone base case we use a field-aligned grid with:
In SPECTRAX-GK these map to GridConfig(y0=20, ntheta=32, nperiod=2), which
sets:
The reduced scan tables and regression tests use Nx=1, Ny=24, Nz=96 on this
grid to match the discrete ky set used in the reference CSV.
Spectral grids
SPECTRAX-GK’s explicit benchmark integrator uses the compressed Fourier conventions required by the tracked reference data. The perpendicular wave numbers are defined as
with x0 = Lx / (2π) and y0 = Ly / (2π). The parallel wave number is
where \(Z_p\) sets the field-line length
(\(z \in [-\pi Z_p, \pi Z_p)\)), and \(k_z\) is defined without the
gradpar factor. These definitions are implemented by
spectraxgk.grids.build_spectral_grid and are consistent with GX’s
kInit kernel.
The midplane index used by the reference growth-rate diagnostic corresponds to
z_index = Nz//2 + 1, matching the audited benchmark kernel logic when Nz > 1.
Perpendicular normalization
The reference diagnostic contract defines the perpendicular metric as \(k_\perp^2/B^2\) before applying the Laguerre gyroaverage. To match that convention in SPECTRAX-GK:
kperp2_bmag = True(include the \(B^{-2}\) factor in \(k_\perp^2\))bessel_bmag_power = 0(no extra \(B\) scaling inside the Bessel argument)
The Cyclone base case defaults follow this benchmark setting, and the
compare_gx_rhs_terms.py comparison tool assumes the same normalization.
Sign conventions
The growth-rate fitting in spectraxgk.analysis.fit_growth_rate() assumes
so:
gamma > 0indicates instability.omegais obtained from the negative phase slope.
This is consistent across time-integration and Krylov post-processing paths. For scan tables and figures, values are reported in the same sign convention as the solver output unless an explicit diagnostic normalization is requested.
Normalization parameters
The linear operator exposes three normalization parameters that influence the drift/drive terms:
rho_star: scales \(k_x\) and \(k_y\) in the drift and drive terms.omega_d_scale: scales curvature/grad-\(B\)/mirror couplings.omega_star_scale: scales the diamagnetic drive.
In code, rho_star multiplies the Fourier grids inside
spectraxgk.linear.build_linear_cache(), while omega_d_scale and
omega_star_scale enter directly in spectraxgk.linear.linear_rhs_cached().
Diagnostic normalization mode
Benchmark runners expose diagnostic_norm and route it through
spectraxgk.normalization.apply_diagnostic_normalization:
none: return raw solver(gamma, omega).gx/rho_star: multiply reported(gamma, omega)byrho_star.
This affects reporting only; it does not alter the RHS/operator.
The unified runtime schema defaults to diagnostic_norm = "gx" so that
out-of-the-box reports match the tracked benchmark normalization. Set
diagnostic_norm = "none" in the TOML or runtime config to recover raw
solver outputs.
Diagnostic scaling
The reference diagnostics apply fixed factors in a few places that depend on the storage convention (e.g. real-FFT nyquist handling or per-unit-time damping). The runtime schema therefore exposes light-weight diagnostic scale factors:
flux_scale: multiplicative factor applied to the reported heat/particle fluxes (default1.0for GX-reference).wphi_scale: multiplicative factor applied toWphi(default1.0; Cyclone GX-reference uses1.155in the nonlinear benchmark config).
These are reporting-only knobs; they do not alter the RHS/operator. They are intended to document the exact GX-reference settings used for benchmark plots.
The reference end-damping defaults are damp_ends_amp = 0.1 and
damp_ends_widthfrac = 0.125. The damping kernel interprets
damp_ends_amp directly as a rate; the runtime no longer rescales it by the
timestep.
Defaults (model parameters):
rho_star = 1.0(model default)omega_d_scale = 1.0(model default)omega_star_scale = 1.0(model default)
These parameters are surfaced in the regression tables so that future normalization refinements can be tracked in a reproducible way.
Programmatic usage
from spectraxgk.normalization import get_normalization_contract
contract = get_normalization_contract("etg")
# contract.omega_d_scale == 0.4
# contract.omega_star_scale == 0.8