diff --git a/.claude/agents/clean-code-reviewer.md b/.claude/agents/clean-code-reviewer.md
index 86fe2436..09dc7ec8 100644
--- a/.claude/agents/clean-code-reviewer.md
+++ b/.claude/agents/clean-code-reviewer.md
@@ -20,7 +20,7 @@ You adhere strictly to:
**Context awareness**: You are working with JPEC, a Julia/Fortran hybrid codebase for MHD equilibrium and stability analysis. Consider:
- Julia 1.11 conventions and idioms
-- The existing module structure (Splines, Equilibrium, Vacuum, DCON)
+- The existing module structure (Splines, Equilibrium, Vacuum, ForceFreeStates, ForcingTerms, PerturbedEquilibrium)
- The ongoing Fortran-to-Julia conversion effort
- The need for parity between Fortran and Julia implementations
@@ -93,6 +93,6 @@ For each issue, provide:
- Follow the commit message format: `MODULE - TAG - Detailed message`
- Be aware of 0-based to 1-based indexing conversions from Fortran
- Ensure compatibility with the existing test structure in `test/`
-- Consider whether changes affect diagnostic outputs (gsec.h5, gse.h5, gsei.h5)
+- Consider whether changes affect diagnostic outputs (jpec.h5, and legacy files gsec.h5, gse.h5, gsei.h5)
Your goal is to help create code that a fusion physicist with moderate Julia experience can read, understand, and maintain confidently.
diff --git a/.claude/agents/julia-performance-optimizer.md b/.claude/agents/julia-performance-optimizer.md
index 480e0c48..5a21a07d 100644
--- a/.claude/agents/julia-performance-optimizer.md
+++ b/.claude/agents/julia-performance-optimizer.md
@@ -1,6 +1,6 @@
---
name: julia-performance-optimizer
-description: Use this agent when you need to optimize Julia code for maximum performance. Specifically:\n\n\nContext: User has written a function that processes large arrays and suspects it could be faster.\nuser: "I wrote this function to compute pairwise distances but it's really slow on large datasets:\n\nfunction pairwise_distances(points)\n n = length(points)\n distances = []\n for i in 1:n\n for j in 1:n\n d = sqrt(sum((points[i] .- points[j]).^2))\n push!(distances, d)\n end\n end\n return distances\nend\n\nCan you help optimize it?"\nassistant: "I'll use the julia-performance-optimizer agent to analyze and optimize this code for maximum performance."\n\n\n\n\nContext: User has completed implementing a new ODE solver in JPEC and wants to ensure it's optimally performant.\nuser: "I just finished implementing the new stability ODE solver in src/DCON/Ode.jl. Here's the core integration loop:\n\nfunction integrate_stability_equation(psi_grid, q_profile, omega)\n results = []\n for i in 1:length(psi_grid)\n # Complex calculation here\n val = compute_eigenvalue(psi_grid[i], q_profile, omega)\n push!(results, val)\n end\n return results\nend\n\nCan you review it for performance?"\nassistant: "Let me use the julia-performance-optimizer agent to analyze this code and identify any performance bottlenecks specific to your ODE solver implementation."\n\n\n\n\nContext: User is proactively seeking optimization after writing vacuum response calculations.\nuser: "I've converted the vacuum wall geometry calculation from Fortran to Julia in src/Vacuum/Vacuum_vac.jl. The function works correctly and passes tests, but I want to make sure it's as fast as the Fortran version."\nassistant: "Excellent - let me use the julia-performance-optimizer agent to analyze your converted code and ensure it matches or exceeds the Fortran performance."\n\n\n\n\nContext: User mentions performance concerns during code discussion.\nuser: "The bicubic spline interpolation in src/Splines/BicubicSpline.jl seems slower than expected when evaluating on dense grids."\nassistant: "I'll launch the julia-performance-optimizer agent to profile the bicubic spline code and identify optimization opportunities."\n\n
+description: Use this agent when you need to optimize Julia code for maximum performance. Specifically:\n\n\nContext: User has written a function that processes large arrays and suspects it could be faster.\nuser: "I wrote this function to compute pairwise distances but it's really slow on large datasets:\n\nfunction pairwise_distances(points)\n n = length(points)\n distances = []\n for i in 1:n\n for j in 1:n\n d = sqrt(sum((points[i] .- points[j]).^2))\n push!(distances, d)\n end\n end\n return distances\nend\n\nCan you help optimize it?"\nassistant: "I'll use the julia-performance-optimizer agent to analyze and optimize this code for maximum performance."\n\n\n\n\nContext: User has completed implementing a new ODE solver in JPEC and wants to ensure it's optimally performant.\nuser: "I just finished implementing the new stability ODE solver in src/ForceFreeStates/Ode.jl. Here's the core integration loop:\n\nfunction integrate_stability_equation(psi_grid, q_profile, omega)\n results = []\n for i in 1:length(psi_grid)\n # Complex calculation here\n val = compute_eigenvalue(psi_grid[i], q_profile, omega)\n push!(results, val)\n end\n return results\nend\n\nCan you review it for performance?"\nassistant: "Let me use the julia-performance-optimizer agent to analyze this code and identify any performance bottlenecks specific to your ODE solver implementation."\n\n\n\n\nContext: User is proactively seeking optimization after writing vacuum response calculations.\nuser: "I've converted the vacuum wall geometry calculation from Fortran to Julia in src/Vacuum/Vacuum_vac.jl. The function works correctly and passes tests, but I want to make sure it's as fast as the Fortran version."\nassistant: "Excellent - let me use the julia-performance-optimizer agent to analyze your converted code and ensure it matches or exceeds the Fortran performance."\n\n\n\n\nContext: User mentions performance concerns during code discussion.\nuser: "The bicubic spline interpolation in src/Splines/BicubicSpline.jl seems slower than expected when evaluating on dense grids."\nassistant: "I'll launch the julia-performance-optimizer agent to profile the bicubic spline code and identify optimization opportunities."\n\n
model: opus
color: green
---
@@ -82,7 +82,7 @@ When presented with code to optimize, follow this structured approach:
You are working on JPEC, a scientific computing codebase for MHD equilibrium and stability analysis:
- Target Julia version: 1.11
-- Key modules: Splines, Equilibrium, Vacuum, DCON
+- Key modules: Splines, Equilibrium, Vacuum, ForceFreeStates, ForcingTerms, PerturbedEquilibrium
- Often deals with large numerical arrays and spline interpolations
- Performance parity with legacy Fortran code is important
- Many functions use 0-based indexing converted to 1-based Julia indexing
diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md
index c27c5b3b..42422c0e 100644
--- a/.github/copilot-instructions.md
+++ b/.github/copilot-instructions.md
@@ -1,21 +1,23 @@
# Copilot instructions for JPEC
## Project overview
-- JPEC is a Julia/Fortran hybrid port of GPEC for MHD equilibrium and stability analysis. Core modules live in [src](src): Splines, Equilibrium, Vacuum, DCON (see [CLAUDE.md](CLAUDE.md)).
+- JPEC is a Julia/Fortran hybrid port of GPEC for MHD equilibrium and stability analysis. Core modules live in [src](src): Splines, Equilibrium, Vacuum, ForceFreeStates, ForcingTerms, PerturbedEquilibrium (see [CLAUDE.md](CLAUDE.md)).
- Data flow: equilibrium setup → vacuum response → stability analysis (documented in [CLAUDE.md](CLAUDE.md)).
- Vacuum is mid-conversion from Fortran to Julia; Fortran libraries are built and called via `ccall` (see [deps/build.jl](deps/build.jl)).
## Architecture and entry points
+- Main entry point: `JPEC.main()` in [src/JPEC.jl](src/JPEC.jl).
- Equilibrium: `setup_equilibrium(path|config)`; types in [src/Equilibrium](src/Equilibrium).
- Vacuum: `compute_vacuum_response()` (Julia) and `mscvac()` (Fortran); code in [src/Vacuum](src/Vacuum) and [src/Vacuum/fortran](src/Vacuum/fortran).
-- DCON stability: entry points in [src/DCON/Main.jl](src/DCON/Main.jl).
+- ForceFreeStates (ideal MHD stability): types and functions in [src/ForceFreeStates](src/ForceFreeStates).
+- PerturbedEquilibrium (plasma response): entry point in [src/PerturbedEquilibrium](src/PerturbedEquilibrium).
- Splines: Julia + Fortran implementations in [src/Splines](src/Splines).
## Data flow and key structures
- Equilibrium: TOML config → read equilibrium → solve → diagnostics (gse*.h5) when relevant.
- Vacuum: initialize plasma/wall surfaces → compute response matrix → return wv, grri, xzpts.
- Stability: equilibrium + vacuum response → integrate ODEs → compute energies.
-- Core types: `PlasmaEquilibrium` and `EquilibriumConfig` in [src/Equilibrium/EquilibriumTypes.jl](src/Equilibrium/EquilibriumTypes.jl); `DconControl` in [src/DCON/DconStructs.jl](src/DCON/DconStructs.jl).
+- Core types: `PlasmaEquilibrium` and `EquilibriumConfig` in [src/Equilibrium/EquilibriumTypes.jl](src/Equilibrium/EquilibriumTypes.jl); `ForceFreeStatesControl` and `ForceFreeStatesInternal` in [src/ForceFreeStates/ForceFreeStatesStructs.jl](src/ForceFreeStates/ForceFreeStatesStructs.jl).
## Build, test, docs
- Build Fortran libraries:
@@ -48,7 +50,8 @@
- Add new Fortran builds via `build_*_fortran()` in [deps/build_helpers.jl](deps/build_helpers.jl).
## Configuration examples
-- TOML configs: `equil.toml` uses `[EQUIL_CONTROL]` and `[EQUIL_OUTPUT]`; `dcon.toml` uses `[DCON_CONTROL]` and `[WALL]`.
+- Unified configuration: `jpec.toml` uses `[Equilibrium]`, `[Wall]`, `[ForceFreeStates]`, `[PerturbedEquilibrium]`, and `[ForcingTerms]` sections.
+- Legacy configs (`equil.toml`, `dcon.toml`, `vac.in`) are deprecated.
- Example configs in [examples/DIIID-like_ideal_example](examples/DIIID-like_ideal_example) and [examples/Solovev_ideal_example](examples/Solovev_ideal_example).
## Development tips
diff --git a/CLAUDE.md b/CLAUDE.md
index 6744e76f..bec3424c 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -76,7 +76,7 @@ The PerturbedEquilibrium module implements GPEC-style perturbed equilibrium calc
- Published: Physics of Plasmas **24**, 032505 (2017)
- Describes: Self-consistent coupling with neoclassical effects
-### Resistive DCON Module (Future Work)
+### Resistive MHD Stability Analysis (Future Work)
JPEC will eventually implement resistive MHD stability analysis based on:
diff --git a/docs/src/set_up.md b/docs/src/set_up.md
index cd65de23..8922f0fe 100644
--- a/docs/src/set_up.md
+++ b/docs/src/set_up.md
@@ -169,7 +169,317 @@ Clone it from GitHub directly to your virtual machine.
## On macOS
-(To be completed)
+### Prerequisites
+
+Before starting, you'll need a Terminal app to enter commands. You can find it by:
+- Press `Cmd + Space` to open Spotlight
+- Type "Terminal" and press Enter
+
+Keep this Terminal window open throughout the installation process.
+
+### 1. Install Xcode Command Line Tools
+
+These tools provide the compilers needed to build Fortran code.
+
+1. Open Terminal and run:
+ ```bash
+ xcode-select --install
+ ```
+
+2. A dialog will appear asking you to install the tools. Click "Install" and wait for it to complete (this may take several minutes).
+
+3. Verify installation:
+ ```bash
+ gcc --version
+ ```
+ You should see output showing the GCC version.
+
+### 2. Install Homebrew (Package Manager)
+
+Homebrew makes it easy to install software on macOS. If you already have Homebrew installed, skip to step 3.
+
+1. Install Homebrew by running this command in Terminal:
+ ```bash
+ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
+ ```
+
+2. Follow the on-screen instructions. You may need to enter your Mac password.
+
+3. After installation completes, the installer will show you two commands to run to add Homebrew to your PATH. They will look something like:
+ ```bash
+ echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >> ~/.zprofile
+ eval "$(/opt/homebrew/bin/brew shellenv)"
+ ```
+ **Important:** Copy and run these exact commands from your Terminal output.
+
+4. Verify Homebrew is installed:
+ ```bash
+ brew --version
+ ```
+
+### 3. Install Fortran Compiler
+
+The Fortran compiler is needed to build JPEC's Fortran components.
+
+1. Install GCC (which includes gfortran):
+ ```bash
+ brew install gcc
+ ```
+ This may take several minutes to complete.
+
+2. Verify gfortran is installed:
+ ```bash
+ gfortran --version
+ ```
+
+### 4. Install Julia
+
+Julia is the programming language JPEC is written in.
+
+**Option A: Install via Homebrew (Recommended for beginners)**
+
+1. Install Julia:
+ ```bash
+ brew install julia
+ ```
+
+2. Verify Julia is installed:
+ ```bash
+ julia --version
+ ```
+ You should see something like `julia version 1.11.x`.
+
+**Option B: Install via Official Installer**
+
+1. Go to [https://julialang.org/downloads/](https://julialang.org/downloads/)
+
+2. Download the macOS installer (`.dmg` file) for the latest stable version (1.11 or higher)
+
+3. Open the downloaded `.dmg` file and drag Julia to your Applications folder
+
+4. Add Julia to your PATH by running in Terminal:
+ ```bash
+ sudo mkdir -p /usr/local/bin
+ sudo ln -s /Applications/Julia-1.11.app/Contents/Resources/julia/bin/julia /usr/local/bin/julia
+ ```
+ Replace `1.11` with your actual version if different.
+
+5. Verify Julia is installed:
+ ```bash
+ julia --version
+ ```
+
+### 5. Install Python and Jupyter (For Running Notebooks)
+
+Jupyter notebooks (`.ipynb` files) require Python. If you only want to run Julia scripts and not notebooks, you can skip this step.
+
+1. Install Python via Homebrew:
+ ```bash
+ brew install python
+ ```
+
+2. Install Jupyter:
+ ```bash
+ pip3 install jupyter jupyterlab notebook ipykernel
+ ```
+
+3. Verify Jupyter is installed:
+ ```bash
+ jupyter --version
+ ```
+
+### 6. Clone the JPEC Repository
+
+Now we'll download the JPEC code from GitHub.
+
+1. Choose where you want to put JPEC. For example, your home directory:
+ ```bash
+ cd ~
+ ```
+ Or create a Code folder:
+ ```bash
+ mkdir -p ~/Code
+ cd ~/Code
+ ```
+
+2. Clone JPEC from GitHub:
+ ```bash
+ git clone https://github.com/OpenFUSIONToolkit/JPEC.git
+ ```
+ If you don't have `git` installed, macOS will prompt you to install it.
+
+3. Enter the JPEC directory:
+ ```bash
+ cd JPEC
+ ```
+
+### 7. Build Fortran Dependencies
+
+JPEC includes Fortran code that needs to be compiled into libraries.
+
+1. Navigate to the Splines Fortran source folder:
+ ```bash
+ cd ~/Code/JPEC/src/Splines/fortran
+ ```
+ **Note:** Adjust the path if you cloned JPEC to a different location (e.g., `~/JPEC` instead of `~/Code/JPEC`).
+
+2. Clean any previous builds:
+ ```bash
+ make clean
+ ```
+
+3. Build the Fortran library:
+ ```bash
+ make
+ ```
+ You should see compilation messages and eventually "Build complete!"
+
+4. Verify the spline library was created:
+ ```bash
+ ls -l ../../../deps/libspline.dylib
+ ```
+ You should see the file listed.
+
+5. Build the Vacuum Fortran library:
+ ```bash
+ cd ~/Code/JPEC/src/Vacuum/fortran
+ make clean
+ make
+ ```
+
+6. Verify the vacuum library was created:
+ ```bash
+ ls -l ../../../deps/libvac.dylib
+ ```
+
+7. Return to the JPEC root directory:
+ ```bash
+ cd ~/Code/JPEC
+ ```
+
+### 8. Install Julia Packages
+
+Now we'll install all the Julia packages that JPEC depends on.
+
+1. Launch Julia from the JPEC directory:
+ ```bash
+ julia --project=.
+ ```
+ The `--project=.` flag tells Julia to use the JPEC project environment.
+
+2. You should now see the Julia prompt: `julia>`
+
+3. Install all dependencies by typing these commands in the Julia prompt:
+ ```julia
+ using Pkg
+ Pkg.instantiate()
+ ```
+ This will download and install all required packages. It may take several minutes the first time.
+
+4. Build the Julia kernel for Jupyter (if you installed Jupyter):
+ ```julia
+ Pkg.add("IJulia")
+ Pkg.build("IJulia")
+ ```
+
+5. Precompile all packages (optional, but speeds up first use):
+ ```julia
+ Pkg.precompile()
+ ```
+
+6. Test that JPEC loads correctly:
+ ```julia
+ using JPEC
+ ```
+ If you see no errors, everything is working!
+
+7. Exit Julia:
+ ```julia
+ exit()
+ ```
+
+### 9. Run the Example Notebook
+
+Now you're ready to run the example!
+
+1. Make sure you're in the JPEC directory:
+ ```bash
+ cd ~/Code/JPEC
+ ```
+
+2. Start Jupyter:
+ ```bash
+ jupyter notebook
+ ```
+ This will open Jupyter in your web browser.
+
+3. In the Jupyter interface, navigate to:
+ ```
+ examples/DIIID-like_ideal_example/run_and_analyze.ipynb
+ ```
+ Click on the notebook to open it.
+
+4. Select the Julia kernel:
+ - If prompted to select a kernel, choose "Julia 1.11" (or whatever version you installed)
+ - If the kernel is already selected, you're ready to go!
+
+5. Run the notebook:
+ - Click "Cell" → "Run All" from the menu, or
+ - Press `Shift + Enter` to run each cell one at a time
+
+ The first time you run the notebook, it will take a few minutes to compile. Subsequent runs will be faster.
+
+### 10. Troubleshooting
+
+**If you get an error about missing libraries:**
+
+Make sure the Fortran libraries are built. Run from the JPEC directory:
+```bash
+ls deps/
+```
+You should see `libspline.dylib` and `libvac.dylib`. If not, repeat step 7.
+
+**If Julia can't find packages:**
+
+Make sure you're running Julia with the project environment:
+```bash
+cd ~/Code/JPEC
+julia --project=.
+```
+
+**If the Jupyter kernel isn't found:**
+
+Rebuild IJulia:
+```bash
+julia --project=. -e 'using Pkg; Pkg.build("IJulia")'
+```
+Then restart Jupyter.
+
+**If you get permission errors:**
+
+Make sure you have write permissions in the JPEC directory. You may need to use `sudo` for some Homebrew commands, but avoid using `sudo` with Julia commands.
+
+### Alternative: Using VS Code (Optional)
+
+If you prefer using VS Code instead of Jupyter in the browser:
+
+1. Install VS Code from [https://code.visualstudio.com/](https://code.visualstudio.com/)
+
+2. Install the Julia extension:
+ - Open VS Code
+ - Click the Extensions icon (or press `Cmd + Shift + X`)
+ - Search for "Julia" and install the official Julia extension
+ - Search for "Jupyter" and install the Jupyter extension
+
+3. Open the JPEC folder in VS Code:
+ - Click File → Open Folder
+ - Navigate to and select your JPEC directory
+
+4. Open the notebook `examples/DIIID-like_ideal_example/run_and_analyze.ipynb`
+
+5. Click "Select Kernel" in the top right and choose "Julia 1.11"
+
+6. Run the cells using `Shift + Enter`
## Running JPEC
@@ -237,8 +547,6 @@ JPEC uses TOML configuration files (`jpec.toml`) with the following main section
See the example directories for complete configuration file templates.
-(Setup instructions to be added)
-
## Pre-commit Hooks (Optional Developer Tools)
The repository uses pre-commit hooks to maintain code quality and prevent noisy commits from Jupyter notebook metadata and outputs.