Skip to main content

GKX

Release PyPI CI Coverage License: MIT Python Docs

GKX is a JAX gyrokinetic solver for tokamak and stellarator flux tubes. It reads a VMEC or VMEX equilibrium, or builds an analytic Miller or s-alpha geometry, and computes linear stability and nonlinear turbulence in a Hermite-Laguerre velocity basis. The whole path, equilibrium included, is differentiable on CPUs and GPUs.

  • Run what you have: a VMEC/VMEX wout, a Miller or s-alpha tokamak, or one TOML deck. The executable sizes the grid and says why.
  • Trust the eigenvalue: every returned eigenpair is checked against the full operator; an under-resolved run warns instead of reporting a number.
  • Differentiate it: implicit eigenvalue derivatives, and a checkpointed adjoint of the nonlinear heat flux over a saturated window.
  • Optimize with it: the heat flux, growth rate or quasilinear flux is an objective in VMEX stellarator shape optimization.
Saturated ITG turbulence on a Cyclone flux tube, shown as a perpendicular cut and as the field-aligned tube

Saturated ITG turbulence on a Cyclone flux tube (full-rate movie).

Install and first run

pip install gkx
gkx

Python 3.11+. The wheel installs CPU JAX; for GPUs add an accelerator JAX wheel (JAX install guide). gkx with no arguments runs a linear Cyclone case in under a minute on a laptop CPU and prints gamma and omega; a CI gate holds its growth rate within 1% of the certified eigenvalue. The tutorial walks through twelve runs, from this one to a stellarator optimization; each is a directory in examples/.

Run a case

gkx wout_circular_tokamak.nc --estimate   # size the grid, explain it, exit
gkx wout_circular_tokamak.nc              # nonlinear ITG run to saturation
gkx plot wout_circular_tokamak/gkx.out.nc # replot a saved bundle
gkx examples/01_linear_tokamak/case.toml  # any TOML deck

--estimate derives each grid entry from the geometry and prints the reason. A run stops when heat flux, field energy and free energy are stationary, or reports that it did not. It writes figures, a restartable NetCDF bundle and the resolved deck that reproduces it (inputs, outputs).

From Python:

import gkx

case = gkx.load("examples/01_linear_tokamak/case.toml")
result = gkx.solve(
    case, ky_target=0.3, Nl=case.run.Nl, Nm=case.run.Nm, show_progress=True
)
print(result.gamma, result.omega)

Linear stability

Linear growth rates, frequencies and an eigenfunction against GX

Growth rate and frequency scans for Cyclone ITG (a), W7-X ITG (b) and KBM (d), and the W7-X eigenfunction at ky rho_i = 0.3 (c), whose overlap with GX's is 0.9999999994.

  • The default eigensolver (auto) is a banded direct shift-invert where it fits, else Arnoldi on the time-advance map. It returns an eigenpair only after checking it against the full operator. Matrix-free shift-invert is opt-in for a chosen branch (policy and measurements).
  • Under-resolved or unsettled fits warn instead of reporting a number.

Models and defaults

Choice Default Notes
Geometry s-alpha, Miller, VMEC/VMEX, imported [geometry] model; gkx wout_*.nc for any VMEC
Velocity space Hermite-Laguerre, (Nl, Nm) hypercollisions damp the last Hermite moments
Collisions linearized Landau conserving, H-theorem; Dougherty, Sugama alternatives (operators)
End damping one rate, [time] damp_ends_rate same on every route; no time step enters (numerics)
Time stepping no dt: nonlinear rk4-pi, or adaptive imex-ark3 for kinetic electrons at beta <= 3e-4; linear rk4 + CFL a dt gives rk2 at that step (measured speedups)
Eigensolver auto (banded, else adaptive), certified shift-invert opt-in
ky layout half: the 1 + Ny//2 non-negative rows [grid] ky_layout = "full" stores the two-sided axis; same physics to round-off, about 1.4-1.8x slower and 12-25% more memory
Precision float32; float64 with JAX_ENABLE_X64=true eigensolver, Krylov residual and conditioning checks need float64
CPU threads XLA's own; Eigen pool off on fewer than four CPUs steps do not scale past about four threads (performance)

Resolution, step and solver guidance says what to set for kinetic electrons and electromagnetic runs, and how to check it.

Agreement with other codes

Case gamma omega
KAW 0.0004% 0.051%
ETG 0.040% 0.074%
W7-X 0.265% 0.296%
HSX 0.577% 0.273%
Cyclone Miller 5.51% 1.25%
Cyclone ITG 6.83% 1.59%
KBM 20.0% 11.1%

100 * max|GKX - ref| / max|ref| over the tracked scan, recomputed by CI from the evidence ledger. The Cyclone rows compare a time-trace fit, not the certified eigenvalue, and KBM is the known outlier. Against GX's repaired launch limit the certified Cyclone eigenpairs agree to 0.3% in growth rate at seven of eight k_y; against converged GS2 GKX is within 1.0% at the three k_y compared. These are agreements on shared test cases, not a ranking of codes. Open items (TEM velocity convergence, stella's mirror-term sensitivity, weakly growing modes) and the figures are in validation.

Nonlinear turbulence

Replicated nonlinear heat flux and trajectory agreement with GX

(a) A circular tokamak run straight from a VMEC wout, replicated with two seeds and a second time step: window means 18.7, 19.3 and 18.9 over t = 350-700, a 3.5% spread against a 15% gate. (b) Mean relative difference from GX runs of the same decks in heat flux, free energy and field energy for Cyclone, Cyclone Miller, W7-X, HSX and KBM, all below 10%. This is a window comparison, not a validation of saturated transport.

Derivatives and optimization

Eigenvalue derivatives use dλ/dp = wᴴ(dA/dp)v / (wᴴv). The nonlinear heat flux over a post-saturation window is differentiated through a block-checkpointed discrete adjoint (figure): on a 16x16x16 Cyclone case over 1024 steps, checkpointing cuts temporary memory from 7.8 GB to 187 MB for about twice the runtime, and the gradient matches finite differences to 1e-11 through 512 steps.

heat_flux, gradient = jax.value_and_grad(loss)(shape0)

VMEX composes its implicit equilibrium derivative with GKX's, so a growth rate, quasilinear flux or nonlinear heat flux sits next to quasisymmetry, aspect ratio and iota in one least-squares problem. examples/10_vmex_optimization/run.py extends VMEX's QA_optimization.py with the nonlinear heat flux as a fourth objective on the vacuum QA ladder (equilibria, traces).

The boundary change is small (aspect ratio +0.0115%, mean iota -0.044%). The preliminary 12.26% reduction across 24 nominal pairs (conditional 95% CI 10.64-13.88%) is not statistically resolved: 4 of 48 nominal traces fail the per-trace drift test. A transport claim needs matched, replicated, long post-saturation windows. The quasilinear flux is a ranking and screening measure, not a runtime/TOML absolute-flux predictor (quasilinear, stellarator optimization).

Performance

Runtime and memory comparison

  • Nonlinear step: about 196 ns per Nx*Ny*Nz*Nl*Nm element per step on CPU; 15.6 ms for 64x64x24, Nl = 4, Nm = 8 on one RTX A4000.
  • Eigenvalues: the sparse direct shift-invert route certifies the Cyclone eigenpair at n = 3,072 in about 5 s against 32-36 s matrix-free.
  • Kinetic electrons: imex-ars3 is 10x faster to solution than RK3 at 64x64x24, and does not pay on tutorial grids.
  • Parallel work: independent k_y scans and ensembles run across devices with results identical to the serial run.

Performance · parallelization.

Documentation and development

Documentation: gkx.readthedocs.io. Start with the tutorial and the guidance page; equations and algorithms are in theory, operators and numerics; modules in design.

git clone https://github.com/uwplasma/GKX
cd GKX
pip install -e ".[dev]"
pytest -n 4

CI requires 95% line coverage plus the physics, convergence, comparison, differentiability and performance gates (CONTRIBUTING.md). Figures in docs/_static/readme/ have JSON companions with every plotted number; their generators were removed from scripts/ and are listed in plan/log.md (2026-10-15). Cite GKX with CITATION.cff.

License

MIT; see LICENSE.

Metadata

Release files for gkx 2.7.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for gkx 2.7.0
File Size Uploaded Provenance Actions
gkx-2.7.0.tar.gz 628.7 kB With provenance Details for gkx-2.7.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for gkx 2.7.0
File Interpreter ABI Platform Actions
gkx-2.7.0-py3-none-any.whl Python 3 none any Details for gkx-2.7.0-py3-none-any.whl

Total release size: 1.3 MB

Release files / gkx-2.7.0.tar.gz

Download URL gkx-2.7.0.tar.gz
Size 628.7 kB
Tags Source
SHA-256 checksum
How to use checksums
27fafb033174b0aa328ee2f6936c0fd9b675b30d3a69b7cf080775144b44044e
BLAKE2b-256 checksum
How to use checksums
c5b77e95f3432557dbb920ce33b3d0343d469b1f6fc11fa0cc03a798339261f1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 25, 2026.

Transparency log

Release files / gkx-2.7.0-py3-none-any.whl

Download URL gkx-2.7.0-py3-none-any.whl
Size 693.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
ce2d82119503a8ebf23944c7b69e65ccf8a4cb55bcddef837354bc711ba81eab
BLAKE2b-256 checksum
How to use checksums
a17ec0c4a9ad6d52471167a0f1747c74b758f1a8f4cd47d3224677577b4f0a3e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 25, 2026.

Transparency log

Security for gkx 2.7.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for gkx-2.7.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 25, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page