This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
NEO-RT uses a hybrid build system with Make and CMake:
Install system dependencies:
make deps # Auto-detects OS and installs deps (Debian/Ubuntu)
make deps-debian # For Debian/Ubuntu systemsmake # Build everything (default: Release mode)
make CONFIG=Debug # Build in Debug mode
make CONFIG=Fast # Build in Fast mode with aggressive optimizationsmake test # Run all tests (both ctest and pytest)
make ctest # Run C++/Fortran tests via CTest
make pytest # Run Python testsmake clean # Remove build directory
make reconfigure # Force reconfigure CMakeNEO-RT calculates neoclassical toroidal viscosity (NTV) torque in resonant transport regimes using a Hamiltonian approach. The code is structured as follows:
-
Main Entry Point:
src/main.f90→src/neort.f90- Initializes magnetic field, profiles, and orchestrates the calculation
-
Core Physics Modules:
src/driftorbit.f90: Drift orbit calculations and resonant transportsrc/magfie.f90: Magnetic field interface and calculationssrc/profiles.f90: Plasma profiles and thermodynamic forcessrc/freq.f90: Frequency calculations (bounce, transit, etc.)src/orbit.f90: Particle orbit integrationsrc/resonance.f90: Resonance identification and analysissrc/transport.f90: Transport coefficient calculationssrc/nonlin.f90: Nonlinear physics calculations
-
Utility Modules:
src/util.f90: General utilities and mathematical functionssrc/attenuation_factor.f90: Attenuation factor calculationssrc/collis_nbi.f90: Collision and NBI-related functions
- Uses external libraries: spline, vode, BLAS/LAPACK, SuiteSparse, NetCDF
- Optionally integrates with NEO-2 (controlled by USE_STANDALONE cmake option)
NEO-RT requires specific input files in the working directory:
<runname>.in: Main namelist configuration (seeexamples/base/driftorbit.in)in_file: Boozer coordinate file for axisymmetric magnetic fieldin_file_pert: Boozer coordinate file for magnetic perturbationsplasma.in: Plasma thermodynamic profiles (required for torque calculations)profile.in: Rotation profiles (required for nonlinear calculations)
<runname>_torque.out: Torque density data<runname>_magfie_param.out: Magnetic field parameters- Various other diagnostic outputs depending on configuration
# Build first
make
# Run with input file (without .in extension)
./build/neo_rt.x runnameUse Python scripts for flux surface scans:
# Batch runs across flux surfaces
python3 python/run_driftorbit.py
# Collect results from multiple runs
python3 python/collect_data_from_individual_runs.py- Fortran unit tests in
test/directory using CMake/CTest - Python integration tests in
test/ripple_plateau/ - Example configurations in
examples/directory
- Main source in
src/ - Tests in
test/ - Examples and plotting utilities in
examples/ - Python utilities in
python/ - POTATO sub-project for magnetic field preprocessing
- Documentation in
doc/
The codebase follows Fortran 90+ standards with extensive use of modules for physics calculations and utilities.
S - Single Responsibility: Each routine has one clear purpose, max 30 lines - ENFORCED O - Open/Closed: Extend through inheritance/composition, not modification - REQUIRED L - Liskov Substitution: Derived types must work wherever base types do - MANDATORY I - Interface Segregation: Keep interfaces focused and minimal - ENFORCED D - Dependency Inversion: Depend on abstractions (abstract types), not concrete implementations - REQUIRED
DRY - Don't Repeat Yourself: Extract common functionality into shared modules - REQUIRED
- Create common modules for shared logic
- Use procedure pointers for generic operations
- Centralize constants and magic numbers in one place
KISS - Keep It Simple, Stupid: Favor simplicity over cleverness - MANDATORY
- Write clear, readable code over "clever" optimizations
- Use straightforward algorithms unless performance demands complexity
- Prefer explicit over implicit behavior
- Choose clear variable names over short abbreviations
MANDATORY TDD WORKFLOW - NEVER DEVIATE:
- WRITE FAILING TEST FIRST in
test/test_*.f90- ALWAYS START HERE - RUN
make testto confirm the test fails (RED) - Write minimal code to make test pass (GREEN)
- Refactor while keeping tests green (REFACTOR)
- Repeat RED-GREEN-REFACTOR for next feature
FORBIDDEN:
- Writing implementation code before tests
- Changing code without a test covering the change
- Assuming existing code works without tests
- Skipping tests "just this once"
TDD is not optional - it is the foundation of all development in this codebase. TESTS FIRST, ALWAYS. NO CODE WITHOUT TESTS.
Routine Size: Max 30 lines, single responsibility - NO EXCEPTIONS
Naming: Use descriptive verbs (calculate_bounds not calc) - REQUIRED
Placement: Helper routines after caller, shared utilities at module end - ENFORCED
Comments: Only for complex algorithms, let code self-document - MANDATORY
MANDATORY PRINCIPLES:
- NO GLOBAL MUTABLE STATE - All state must be explicitly passed as parameters
- IMMUTABLE BY DEFAULT - Prefer immutable data structures and pure functions
- EXPLICIT STATE MANAGEMENT - Always save/restore state when temporarily modifying context
- STATELESS OPERATIONS - Functions should not rely on hidden global state
- CLEAR OWNERSHIP - Each piece of state must have a clear owner and scope
! GOOD: Explicit state save/restore
subroutine good_draw_text(ctx, text)
real(8) :: saved_width
saved_width = ctx%current_line_width ! Save state
call ctx%set_line_width(0.5d0) ! Modify
! ... draw text ...
call ctx%set_line_width(saved_width) ! Restore - MANDATORY
end subroutine
! GOOD: Pure functions with explicit parameters
pure function calculate_position(x, y, offset) result(new_pos)
! No hidden state dependencies
end functionMANDATORY PRINCIPLES:
- NO MAGIC NUMBERS - If a number has meaning, it MUST be a named constant
- DESCRIPTIVE NAMES - Constant names must clearly indicate their purpose
- CENTRALIZED CONSTANTS - Group related constants in parameter declarations
- DOCUMENTED PURPOSE - Each constant should have a clear comment explaining its meaning
! GOOD: Named constants with clear meaning
real(8), parameter :: DEFAULT_TOLERANCE = 1.0d-12 ! Convergence tolerance
integer, parameter :: MAX_ITERATIONS = 1000 ! Maximum solver iterations
real(8), parameter :: SAFETY_FACTOR = 0.8d0 ! CFL safety factor
! Usage
if (residual < DEFAULT_TOLERANCE) then
converged = .true.
endif- Always explicitly import with
use only. No wildcard imports allowed. - MANDATORY - Use
implicit nonein all modules and programs - REQUIRED - ALL variable declarations MUST come before any executable code in routines - MANDATORY
- Variables, parameters, and type declarations first
- Then executable statements and assignments
- Fortran requires this strict ordering
- Use double precision (
real(8)) for all floating-point calculations - REQUIRED - cd COMMAND IS FORBIDDEN - Never use
cdin bash commands. Use absolute paths instead. - MANDATORY