FAX
FAX is a lean JAX code for shear-Alfvén physics in stellarators: the continuum, AE3D-form global modes and a perturbative fast-ion drive, with first-order derivatives with respect to profiles and, through VMEX, the VMEC boundary.
Left: the n = 2 CTOK continuum with the six global modes nearest 384 kHz (red). Right: the passing-only drive of the Könies et al. (2018) TAE.
Scope
| Supported | Not supported |
|---|---|
| Low-β continuum on each Boozer surface (STELLGAP form) | Sound coupling, so no BAE or BAAE |
| AE3D-form reduced ideal-MHD global modes, signed $\omega^2$ | Continuum damping and electron damping |
finite_beta=True: restricted $J_\parallel$ and pressure terms (experimental) |
A full-MHD or compressional model |
| Drive of a fixed mode: zero orbit width, passing ions only | Trapped particles, finite orbit width, finite Larmor radius |
The drive is perturbative and valid up to about 200 keV in the Könies case ($\gamma/\omega \le 4%$). It is about 0.6 of the CAS3D-K zero-orbit-width curve, plausibly the missing trapped share; that attribution is not established. Derivatives are first order and are NaN unless the eigensolve converged and its selection is not a tie.
Install
Python 3.10 or newer, JAX 0.4.38 or newer, solvax>=0.32.1. FAX is on PyPI as alfvex; the code is imported as fax.
FAX will soon be renamed ALFVEX everywhere (repository, import and command line). Do not pip install fax: that is an unrelated package.
pip install alfvex # core
pip install "alfvex[vmex]" # VMEC solves and boundary gradients (Python >= 3.11)
pip install "alfvex[plot]" # matplotlib, for the figure examples
From a clone, pip install . (with the same extras) installs the development version.
Quickstart
This runs from an installed wheel with no data files: a continuum, a global TAE and one gradient on the analytic Könies et al. (2018) torus.
import jax, jax.numpy as jnp, fax
s = (jnp.arange(200) + 0.5) / 200
geo = fax.circular_torus(s=s, major_radius=10.0, minor_radius=1.0, B0=3.0, iota=1 / (1.71 + 0.16 * s), epsilon_B=0.1)
harmonics, rho = fax.mode_family(6, 16, 5), fax.mass_density(2e19, 1.0)
f_hz = fax.continuum(geo, harmonics, rho) # (surfaces, harmonics)
modes = fax.eigenmodes(geo, harmonics, rho, target_hz=6.46e4, count=3, ntheta=32, nzeta=4)
print(modes.frequencies_hz[-1], modes.status.converged) # the TAE, 64.63 kHz
f = lambda r: fax.frequency_hz(geo, harmonics, r, 2, 3, target_hz=6.46e4, count=3, ntheta=32, nzeta=4)
print(jax.grad(f)(rho)) # equals -f / (2 rho)
The command line runs the continuum and global-mode tasks from a TOML case; the drive, objectives and boundary gradients are Python only.
Examples (checkout only)
These read files in the repository or need an extra; each has editable settings at the top and no command-line parsing.
| File | Needs | Shows |
|---|---|---|
examples/quickstart.py |
nothing | the quickstart above |
examples/ctok_continuum.toml, ctok_eigenmodes.toml |
tests/data |
fax run <case> --plot for CTOK |
examples/qa_continuum.toml |
vmex |
VMEC solve, Boozer transform, continuum |
examples/koenies_tae_drive.py |
plot |
drive against fast-ion temperature |
examples/boundary_gradient.py |
vmex |
gradient with respect to VMEC boundary coefficients |
examples/optimize_alfven.py |
vmex, plot |
QS plus Paul's continuum cost (QH) or a classified gap-mode window (QA) |
examples/knyazev_qa.py |
Zenodo archive | rebuilds the offline fixture and the AE3D comparison |
Evidence
| Check | Result |
|---|---|
| STELLGAP CTOK continuum (97 surfaces) | 6.3e-3 mean, 6.6e-3 p95 relative |
| AE3D v31 CTOK, six global modes | within 1.4% |
| AE3D CTOK TAE, 337.9 kHz | not reproduced. On identical input three $\iota'$ terms of AE3D's bending blocks differ from the energy (pinned block comparison; real-space quadrature FAX 0.1–0.3%, AE3D 2–37%). The $J_\parallel$ blocks still disagree, cause open. Not reported upstream |
| Knyazev et al. (2026) precise QA | continuum 3.0e-3 mean from STELLGAP. The AE3D global mode (30.31 kHz) is not a FAX eigenmode (overlap 0.18, 5.1% below); cause unresolved |
| Könies et al. (2018) TAE (n = 6) | 4.061e5 rad/s (CAS3D 4.01e5, GYGLES 4.13e5), converged to 1e-4 |
| Drive, 100/200/300/400 keV | 4.26/16.27/32.48/64.02 ×10³ s⁻¹; 0.58–0.60 of CAS3D-K ZOW at 82–191 keV (content unmatched, not a validation) |
| Gradients | fixed-geometry AD vs finite differences to about 1e-9 at best; LP-QA gap-mode shift of 4 kHz predicted to 0.05 kHz, resolution budget 0.13 kHz; the $m = 1$ gauge leaves a 1e-2 floor on zs11, not closed |
The validation page has every gate, its test and what is not done.
Ecosystem
SOLVAX provides the generalized eigensolver and its implicit derivatives; VMEX the equilibrium and its implicit derivative; booz_xform_jax the Boozer transform. ESSOS orbit transport of FAX modes is planned, not implemented.
Documentation and testing
fax.readthedocs.io: getting started and TOML reference, tutorials, theory, validation, API with its derivative contract.
pip install -e ".[dev,vmex]"
python -m pytest -q -m 'not scheduled'
ruff check . && ruff format --check . && sphinx-build -W -b html docs docs/_build/html
Citing and license
Cite the repository through CITATION.cff and the papers whose models FAX implements (references). MIT license.
Metadata
Release files for alfvex 1.0.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| alfvex-1.0.1.tar.gz | 1.5 MB | With provenance | Details for alfvex-1.0.1.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| alfvex-1.0.1-py3-none-any.whl | Python 3 | none | any | Details for alfvex-1.0.1-py3-none-any.whl |
Total release size: 1.6 MB
Release files / alfvex-1.0.1.tar.gz
| Download URL | alfvex-1.0.1.tar.gz |
|---|---|
| Size | 1.5 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
c03fc881be3414e08ea1aabe463240df81f9ff4d7ff07e221c76c5b319681e62
|
|
BLAKE2b-256 checksum How to use checksums |
f3d19749e46bbf23f9a8ed145bf70d7e591d13129fbabb75653fc47b64054dfd
|
| 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 31, 2026.
Transparency logRelease files / alfvex-1.0.1-py3-none-any.whl
| Download URL | alfvex-1.0.1-py3-none-any.whl |
|---|---|
| Size | 36.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
aac37c1a965b724e9db06eb62dbae98bee83bd6ed52dc83c014ff4579ff538fe
|
|
BLAKE2b-256 checksum How to use checksums |
c5563c624ef638633217e99384f66746749fd85fb53025218d5ce39990439431
|
| 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 31, 2026.
Transparency logSecurity for alfvex 1.0.1
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.
Attestation for alfvex-1.0.1.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 31, 2026.
Transparency logA 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.