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.