This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
🚨 CRITICAL: ALWAYS RUN FROM PROJECT ROOT 🚨
- Always run all commands from the repository root
- Use
make test- Never run test executables directly or use ctest manually - Use relative paths - All paths should be relative to project root (e.g.,
./build/simple.x) - Build system is CMake via
make(CMake + Ninja inbuild/) - Do not use
fpm-fpmsupport is experimental and must not be used for development, testing, or performance work
- Primary build:
make- Uses CMake with Ninja generator to build inbuild/directory - Python package: Build via scikit-build-core (see pyproject.toml)
- Clean build:
make clean- Removes build directory - Reconfigure:
make reconfigure- Forces CMake reconfiguration
- Run tests:
make test- Runs all tests including slow ones (excludes regression tests) - Fast tests only:
make test-fast- Excludes slow and regression tests - All tests:
make test-regression- Includes all tests including regression tests - Python tests: Located in
test/python/directory - Golden record testing: Use
examples/golden_record.pyto compare against reference behavior - Verbose output: Now default for all test targets. Use
VERBOSE=0to disable - Single test:
make test TEST=test_name- Run specific test by name - Note: Test system is currently under development
- Default: Release build (
-DCMAKE_BUILD_TYPE=Release) - Available types: Release, Debug, Profile, Fast
- Change config:
make CONFIG=Debug
- Build tools: CMake (>= 3.22), Ninja, git
- Compiler: GNU Fortran (gfortran)
- Required libraries: NetCDF-Fortran (and NetCDF-C), LAPACK/BLAS
- Auto-fetched: libneo, fortplot (via FetchContent)
- Optional: OpenMP (enabled by default), GVEC (experimental, off by default), CGAL (off by default)
- Minimal GVEC library automatically built from
thirdparty/gvec/ - Provides B-spline and cubic spline functionality for magnetic field interpolation
- Used by
field_gvec.f90for reading.datmagnetic field files - Library:
libgvec.awith modules ingvec_modules/ - Python interface: numpy, f90wrap (for building pysimple)
SIMPLE is a symplectic particle orbit tracer for fusion plasma physics, designed for stellarator optimization with VMEC equilibria.
Main Components:
simple_main.f90: Main simulation orchestration with OpenMP parallelizationsimple.f90: CoreTracertype and orbit integration interfacesparams.f90: Centralized configuration via namelist input
Field System (src/field/):
- Abstract
magnetic_field_tbase class infield_base.f90 - VMEC implementation in
field_vmec.f90 - Canonical coordinates: Boozer, flux, Meiss, Albert variants
- Runtime field selection via function pointers
- Detailed documentation: See
DOC/coordinates-and-fields.mdfor comprehensive coverage of coordinate systems, field representations, magfie interface, splined fields, canonical coordinates, and libneo integration
DOC/coordinates-and-fields.md to reflect the current reality. This includes changes to:
- Coordinate system implementations (VMEC, chartmap, Cartesian)
- Magnetic field classes and their evaluation
- magfie interface modes and procedure pointers
- Splined field construction or evaluation
- Canonical coordinate transformations
- libneo coordinate API usage
Integration System:
orbit_symplectic_base.f90: Base integrator types and RK coefficientsorbit_symplectic.f90: Multiple symplectic methods (Euler, midpoint, Gauss, Lobatto)orbit_symplectic_quasi.f90: Quasi-symplectic and RK45 methods
Coordinate Transformations (coordinates/):
- VMEC ↔ Cylindrical ↔ Cartesian transformations
- Extensible via function pointers
Particle Management:
samplers.f90: Surface/volume/file-based particle initializationclassification.f90: Trapped/passing and regular/chaotic orbit classification
- Strategy Pattern: Field evaluation with runtime method selection
- Template Method: Common integration interface with specialized implementations
- Abstract Base: Extensible field representations
- Load VMEC equilibrium and configuration from
simple.in - Initialize particles via selected sampling method
- Parallel orbit integration (one particle per OpenMP thread)
- Output confinement statistics and trajectories
simple.x: Primary executable requiringsimple.inand VMEC file- Example inputs in
examples/simple.inand downloadablewout.nc
simplepackage (python/simple/) - batch-oriented API withParticleBatch,BatchResults, andtrace_orbits- Example:
examples/simple_api.py- minimal usage demonstration with the cleaned API
confined_fraction.dat: Main confinement statistics over timetimes_lost.dat: Individual particle loss times and classificationstart.dat: Initial conditions (input/output depending on startmode)fort.6601: Newton iteration convergence diagnostics
-
Download test VMEC file:
wget https://github.com/hiddenSymmetries/simsopt/raw/master/tests/test_files/wout_LandremanPaul2021_QA_reactorScale_lowres_reference.nc -O wout.nc -
Run with example input:
./build/simple.x(requiressimple.inin working directory) -
Some important routines on fields and splines and ode integrators are found in ../libneo which is built and linked as a dependency in our build process
-
a prototype of meiss and albert coordinate implementation for tokamak geometry with or without perturbations is found in ../letter-canonical
ALL angles in SIMPLE are ALWAYS in RADIANS - both theta (poloidal) and zeta (toroidal).
Large angle values (e.g., 697 rad, 1310 rad) are normal and expected! They represent:
- Multiple toroidal/poloidal turns from field line following
- Angles are NOT wrapped to [0, 2π] during integration
- 697 radians ≈ 111 toroidal turns
NEVER assume large angle values are in degrees!
This applies to:
- start.dat files (input)
- times_lost.dat files (output)
- All internal coordinate representations