Python interface

pysimple is a thin Python layer over SIMPLE’s Fortran library interface (src/simple_api.f90). It runs the same code path as simple.x; a Python run configured from a simple.in file reproduces simple.x exactly.

Installation

./setup-venv.sh
source .venv/bin/activate
python -c "import pysimple"

Configuration

A run is configured by the &config namelist of simple.in. The complete list of keys, with defaults and meaning, is examples/simple_full.in. init starts from the defaults, then applies a config file, an equilibrium file and keyword settings, in this order:

import pysimple

pysimple.init(config="simple.in")                      # as simple.x
pysimple.init("wout.nc", trace_time=1e-3, ntestpart=32)  # no file
pysimple.init("wout.nc", config="simple.in", n_d=2)      # file + overrides

Keyword names are &config names and are case-insensitive. Unknown names raise ValueError. The equilibrium argument sets netcdffile, field_input and coord_input. A Boozer chartmap selects isw_field_type=2 unless the field type is given. Read derived values from pysimple.params, for example pysimple.params.v0.

Tracing

States are (s, theta, phi, v/v0, v_par/v) in reference coordinates, with shape (5, n). Angles are radians and are not wrapped.

start = pysimple.sample()                  # as configured by startmode
start = pysimple.sample_surface(32, s=0.3)
start = pysimple.sample_volume(32, s_inner=0.1, s_outer=0.9)
start = pysimple.load_particles("start.dat")

result = pysimple.trace_parallel(start)    # integrator="midpoint" overrides integmode
pysimple.write_output()                    # simple.x output files

loss_times is trace_time for confined particles, -1 for particles skipped by contr_pp (deep passing; set contr_pp=-1e10 to trace them) and NaN for numerical failures. classify_parallel, classify_fast and classify_fractal add the trapped/passing flag and the J_parallel, topological and fractal classes.

Single orbits

trace_orbit(state, return_trajectory=True) returns the ntimstep samples of one orbit.

compute_canonical_frequencies(state, n_periods=1) returns the bounce/transit period, the toroidal shift per period and the frequencies omega_b and omega_phi in rad/s. A trapped cycle runs between same-direction v_par = 0 crossings, a passing cycle between signed 2*pi poloidal advances. Check status against FREQ_*; a lost orbit reports FREQ_ORBIT_LOST. Species and energy follow &config (n_e, n_d, facE_al); the default is a 3.5 MeV alpha.

trace_to_cut(state, cut="tip") traces to the next v_par = 0 point, cut="toroidal" to the next field-period plane. It needs a symplectic integrator.

invariants_from_state(state) returns h0 = (v/v0)**2, j_perp = h0 * (1 - lambda**2) / B and p_phi = (c/q) P_phi in magnetic-flux units (zero on axis, outward positive in its flux term; not the radial label s). axis_flux_native and edge_flux_native are A_phi at the axis and at the LCFS.

states_from_invariants(h0, j_perp, p_phi) inverts this for axisymmetric fields on the section grad(psi) x grad(B) = 0. It returns all regular roots on both v_par branches, ordered by major radius from the high- to the low-field side (POTATO’s R_c). states_from_potato_invariants first converts POTATO’s psi_star with the given psi_axis, psi_edge and v0_ratio = v0_POTATO / v0_SIMPLE.

IMAS IDS workflow

pysimple.imas (install pysimple[imas]) reads and writes IMAS IDS; see the user-guide page IMAS workflow (docs/user-guide/imas.rst).

Fortran

Fortran programs use the same interface through use simple_api: set params variables or call simple_read_config, then simple_init, simple_sample, simple_trace and simple_get_results. simple.x itself is the sequence in simple_main::main.

Limitation

With startmode = 1, pysimple.sample() and sample_surface(n, s) return start points with invalid angles when the start surface (s, or sbeg for sample()) equals that of the preceding init or sampling call (src/simple_api.f90: the start-surface arrays are reallocated, but the field line that fills them is not re-integrated). Change s between calls, or use sample_volume or load_particles.

Function reference: Python API. Example scripts: Example scripts.