Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,6 @@ test_util
test_util.dat

# Jupyter Notebook checkpoints
*.ipynb_checkpoints
*.ipynb_checkpoints

arXiv-0708.4399v2
54 changes: 54 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Project purpose

A teaching collection of FFTW 3.3.9 examples in C. Each example computes a 1D or 2D DFT both via FFTW and via a hand-rolled naive reference, then compares the two — the goal is to make explicit the symmetries, scaling factors, and array layouts that FFTW assumes. The README is the long-form tutorial; the `src/` programs are the runnable companions to it.

## Build / run / test

Top-level Makefile builds with `gcc` and links `-lfftw3 -lm`. Each target is a single-file executable that `#include`s `src/util.h`.

```
make # build all test_* and app_* binaries (compiled into repo root, not src/)
make test # build all targets, then run each one via the %_test pattern rule
make clean # remove binaries and generated *.dat files
make <name> # build a single target, e.g. `make test_1d_redft00` or `make app_flux_surface`
./<name> # run a single test/app (binaries land in the repo root)
```

There is no separate test framework — each `test_*.c` has its own `main` that returns non-zero on mismatch, and `make test` simply runs them in sequence.

The `eqn/` subdirectory has its own Makefile that renders `.tex` snippets to `.png` via `./pnglatex` for the README; ignore it unless touching the rendered equations.

## Architecture

**Header-only utility layer (`src/util.h`).** All shared helpers — random/zero array fills, element-wise comparison with tolerance, file dumpers in NumPy-loadable formats, a generalized-DFT reference (`dft_1d_cplx`), and the LCFS file readers — live as `static`-style definitions directly in the header. Each `.c` file is compiled into its own executable, so there is no link-time conflict. Adding a new helper means editing `util.h` directly; there is no `util.c`.

**Per-example pattern.** Every `test_*.c` follows the same skeleton:
1. Allocate input/output arrays with `fftw_alloc_real` / `fftw_alloc_complex`.
2. Create the FFTW plan **before** filling input (FFTW_ESTIMATE; some plans destroy input on execute).
3. Fill input with `fill_random_*`.
4. Compute a reference output by a direct, naive transform formula.
5. `fftw_execute`, then `compare_*` with `eps = 1e-12`.
6. Free plan and arrays.
For r2r tests (REDFT/RODFT), the reference is built by constructing the "logically equivalent" full DFT input (mirrored/anti-mirrored according to the transform's implicit symmetry) and comparing FFTW's output to a slice of that full DFT.

**Application layer (`src/app_*.c`).** Three real-world stellarator-physics examples that consume the same primitives: `app_magn_axis` (1D c2r), `app_magn_axis_stellsym` (1D REDFT01, exploits stellarator symmetry), `app_flux_surface` (2D c2r, reads `lcfs.dat`). They write `axis_R*.dat` / `lcfs_R.dat` / `lcfs_Z.dat` to the repo root for plotting; `clean` removes these.

**Python companions.** `src/plot_lcfs_realspace.py` (Mayavi) reads the `app_flux_surface` output. `src/redft_symmetries.py` and `src/redft_symmetries.ipynb` are exploratory NumPy notebooks on even/odd-harmonic DCT decomposition.

## Non-obvious conventions

- **2D arrays are row-major flat `double*` / `fftw_complex*`**, indexed as `arr[i*cols + j]`. The dumpers and comparators all assume this.
- **VMEC vs FFTW sign convention** (relevant in `app_flux_surface.c` and the corresponding README section): VMEC uses angle argument `(m θ − n ζ)` while FFTW's 2D DFT uses `(m θ + n ζ)`. Coefficients from VMEC must be placed at index `-n` in the FFTW input — see the `idx_in` computation. `m=0` row is special-cased because VMEC keeps the positive-`n` sign there.
- **Hermitian-symmetry scaling for c2r/r2c.** For real-input DFTs the complex array has `n/2+1` entries; all but DC (and Nyquist when `n` even) need a factor-of-2 weighting in the manual reference. Both array-layout figure (`img/array_structures.png`) and `test_1d_c2r.c` document this.
- **R\*DFT00 caveat.** Per the FFTW manual, `REDFT00`/`RODFT00` are numerically less stable; `app_magn_axis_stellsym` deliberately uses `REDFT01` instead. Don't "fix" a stellsym example to use 00.
- **Output `.dat` files are gitignored** but consumed by Python plotters and by some tests' own assertions — don't assume `make clean` is safe to run mid-debugging session if a Python plot is open.

## When extending

- New transform example → add `src/test_<name>.c`, add the bare name to `TARGETS` in the Makefile. The pattern rule `$(TARGETS): % : src/%.c src/util.h` handles compilation; no other wiring needed.
- New utility → add it to `src/util.h` as a definition (not just a declaration). Keep it dependency-free beyond `<fftw3.h>` and libc.
- The repo also carries Eclipse CDT (`.cproject`, `.project`) and PyDev (`.pydevproject`) project files; leave them alone unless asked.
Loading