Stellarator Examples, Equations, and Literature Links¶
This page is the user-facing guide for the 3D stellarator examples in
examples/geometry-3D/stellarator-fci/. The examples are intentionally written
like SIMSOPT driver scripts: constants are defined near the top, reusable
objects are imported from drbx, and the script runs from top to bottom.
This mirrors the workflow described in the
SIMSOPT overview, where
problems are configured in ordinary Python scripts rather than hidden inside
large input-file front ends. SIMSOPT itself documents the same modular style
for stellarator geometry and Biot-Savart fields in its
magnetic-field API guide.
The current examples are small enough to run on a laptop. They are not device-grade stellarator turbulence predictions; they are educational and validation-oriented scripts that show the same geometry, field-line-map, operator, plotting, and artifact APIs used by the regression campaigns.
Example Map¶
| Example | Purpose | Main APIs |
|---|---|---|
geometry_plotting.py |
Build a deterministic non-axisymmetric geometry, export arrays, and plot surfaces, ( | B |
linear_mode.py |
Evolve a single field-aligned mode with linear drive, damping, parallel FCI diffusion, and perpendicular diffusion. | laplace_parallel_fci, laplace_perp_xz, save_stellarator_sol_snapshot_panel |
vorticity_bracket.py |
Compose the JAX-native DRB RHS with a vorticity/potential solve and a tested logical \(E\times B\) bracket. | compute_fci_drb_rhs, logical_exb_bracket_xz, save_stellarator_sol_diagnostics_panel |
nonlinear_turbulence.py |
Run the compact nonlinear reduced SOL benchmark and write snapshot, diagnostic, 3D poster, and GIF movie artifacts. | simulate_reduced_stellarator_sol_dynamics, build_stellarator_sol_showcase_report, save_stellarator_sol_3d_movie |
turbulent_profile_analysis.py |
Analyze the nonlinear SOL history with radial fluctuation profiles, RMS intensity, transport-proxy profiles, connection-length weighting, and nonlinear energy traces. | build_synthetic_stellarator_geometry, NumPy/Matplotlib postprocessing of the NPZ history written by nonlinear_turbulence.py |
validation_campaign.py |
Regenerate the full promoted stellarator validation package. | Campaign builders in drbx.validation |
Run an example with:
PYTHONPATH=src python examples/geometry-3D/stellarator-fci/vorticity_bracket.py
PYTHONPATH=src python examples/geometry-3D/stellarator-fci/nonlinear_turbulence.py
PYTHONPATH=src python examples/geometry-3D/stellarator-fci/turbulent_profile_analysis.py
Every script writes arrays and figures under docs/data/stellarator_fci_example_artifacts/.
Expected Output¶
The examples regenerate lightweight versions of the promoted validation figures. The publication-quality validation gallery remains release-hosted so the repository stays small, but the scripts expose the same plotting functions used to create these artifacts.

- Stellarator reduced SOL diagnostics — release-hosted figure:
docs__data__stellarator_fci_validation_artifacts__showcase__images__stellarator_sol_showcase_diagnostics.png(requires repository access)

Geometry¶
The analytic validation geometry is constructed in
src/drbx/geometry/stellarator.py.
It is a deterministic, five-period, non-axisymmetric shell with rotating
elliptical cross-sections, helical mirror modulation, an island-like FCI map
displacement, a curvature proxy, and a connection-length proxy. In logical
coordinates \(x^1=s\), \(x^2=\phi\), \(x^3=\theta\), the physical position is
r(s, phi, theta) = (R(s, phi, theta) cos(phi),
R(s, phi, theta) sin(phi),
Z(s, phi, theta)).
The metric terms used by the conservative operators are
e_i = partial r / partial x^i,
g_ij = e_i dot e_j,
J = sqrt(det(g_ij)),
g^ij = inverse(g_ij).
The geometry campaign checks finite metric entries, \(J>0\), \(|B|>0\), and \(\max |g^{ik}g_{kj}-\delta^i_j|\) near roundoff. This mirrors the verification pattern used in recent non-axisymmetric edge-fluid work, where metric tests, field-line maps, target-aware geometry, and 3D visualization precede turbulence claims; see the open-access GRILLIX stellarator extension paper.
Field-Line-Map Operators¶
The field-line-map layer follows the flux-coordinate-independent idea: the mesh does not need to be a magnetic-flux coordinate grid, but parallel operators use forward and backward field-line intersections on neighboring toroidal planes. The original FCI method is described by Hariri and Ottaviani, Computer Physics Communications 184, 2419-2429 (2013), and later X-point applications are discussed in Hariri et al., Physics of Plasmas 21, 082509 (2014).
In drbx, the map object is
FciMaps. If \(I\) is bilinear
interpolation in logical \((s,\theta)\), then
f_up(i,j,k) = I[f(:, j+1, :)](x_fwd(i,j,k), z_fwd(i,j,k)),
f_dn(i,j,k) = I[f(:, j-1, :)](x_bwd(i,j,k), z_bwd(i,j,k)).
The compact centered operators in
src/drbx/native/fci.py
are
grad_parallel(f) = (f_up - f_dn) / (2 Delta phi),
L_parallel(f) = (f_up - 2 f + f_dn) / Delta phi^2.
The conservative diffusion form used for neutral and scalar gates is
L_K f = J^{-1} partial_parallel(J K partial_parallel f),
implemented by mapped face fluxes and zero-flux treatment when a traced map hits an open endpoint.
Linear Mode Example¶
linear_mode.py
is the smallest way to see a time-dependent stellarator calculation. It
initializes one mode,
n_tilde(s, phi, theta, 0)
= exp(-((s - s0) / w)^2) cos(m theta - n phi),
and advances
partial_t n_tilde
= chi_parallel L_parallel(n_tilde)
+ chi_perp L_perp(n_tilde)
+ gamma_C C(s, phi, theta) n_tilde
- gamma_d n_tilde.
This is deliberately linear, so the mode energy should evolve smoothly. The script exports the history as NPZ and uses the same plotting functions as the nonlinear campaign, allowing users to compare linear growth/decay against the nonlinear example without changing plotting code.
Vorticity and Bracket Example¶
vorticity_bracket.py
is the recommended first script for nonlinear stellarator physics. It builds a
full FciDrbState, calls
compute_fci_drb_rhs
for sheath/recycling, neutral reaction-diffusion, charge exchange, vorticity
diffusion, and potential inversion, then advects density, pressure, and
vorticity with the tested logical bracket
logical_exb_bracket_xz:
{phi, f}_{s,theta}
= (partial_theta phi partial_s f - partial_s phi partial_theta f) / B.
This is the discrete \(E\times B\) nonlinear coupling used by the compact non-axisymmetric demonstration. The coefficients in the example are labeled as explicit timestep/model strengths, not fitted physical constants. For publication-grade turbulence claims, use this script as a starting point and then run grid-refinement and timestep-sensitivity campaigns before interpreting the resulting transport metrics.
Nonlinear Reduced Turbulence Example¶
nonlinear_turbulence.py
calls
simulate_reduced_stellarator_sol_dynamics.
The compact reduced model evolves a fluctuation proxy according to
partial_t n_tilde
= chi_parallel L_parallel(n_tilde)
+ chi_perp L_perp(n_tilde)
+ alpha C partial_s n_tilde
+ N[n_tilde]
+ S(s, phi, theta, t)
- beta n_tilde
- gamma n_tilde^3.
Here \(C\) is a curvature proxy, \(N\) is a reduced nonlinear transfer proxy
used for fast movie QA, and the cubic term prevents the compact explicit run
from becoming an unbounded drive test. Use vorticity_bracket.py when the
goal is to inspect nonlinear coupling through a potential/vorticity solve
rather than a scalar visualization benchmark. The outputs include R-Z panels
at multiple toroidal angles, fluctuation RMS, skewness, radial-flux proxy, a
toroidal-poloidal spectrum, and a 3D opened-surface view.
The result diagnostics are patterned after the stellarator SOL literature, where fluctuation levels, skewness, coherent structures, spectra, radial flux, connection length, and target geometry are all part of the interpretation; see the stellarator island-divertor turbulence articles linked from docs/stellarator_fci_validation.md, and the broader edge/SOL modeling context in the GBS code paper, and GENE-X edge/SOL paper.
After the nonlinear script writes the NPZ history, run
turbulent_profile_analysis.py
to create a compact profile-analysis figure. The profile script bins the final
fluctuation field and time-RMS intensity over normalized radius, computes a
curvature-weighted radial-flux proxy, compares it with a connection-length
weighted amplitude, and plots the nonlinear energy trace. These are lightweight
analysis diagnostics rather than a replacement for the promoted validation
campaign, but they teach the same profile-and-transport workflow users need
before moving to larger 3D cases.
JAX Execution Model¶
The example kernels are written with jax.numpy arrays and pure functions, so
they can be staged into XLA with jax.jit, batched with jax.vmap, and
differentiated where the control flow is JAX-transformable. This follows the
official JAX model of composable transformations described in the
JAX documentation, especially the
JIT compilation guide.
The practical rule is:
file IO, plotting, and report writing: ordinary Python
geometry arrays, field-line maps, RHS kernels: JAX arrays and pure functions
That boundary is why the examples first build or load a geometry object, then call JAX-native kernels, and only at the end write NPZ/PNG/GIF artifacts.
What To Modify First¶
Change these constants first in the examples:
NX,NY,NZ: grid size and runtime.FRAMES,SUBSTEPS_PER_FRAME,DT: temporal resolution.ISLAND_AMPLITUDE,MIRROR_AMPLITUDE,IOTA_AXIS,IOTA_EDGE: geometry and field-line-map character.CHI_PARALLEL,CHI_PERP,LINEAR_DRIVE,LINEAR_DAMPING: linear-mode physics.
Use the validation campaign before interpreting new geometry as physics:
PYTHONPATH=src python examples/geometry-3D/stellarator-fci/validation_campaign.py
PYTEST_DISABLE_PLUGIN_AUTOLOAD=1 PYTHONPATH=src python -m pytest -q tests/test_validation_stellarator_fci_campaigns.py