Skip to content

Commit 7104b11

Browse files
sbryngelsonclaude
andcommitted
Add field indexing, ghost cells, test system, analytical IC docs
- Fix parameter checklist: first 3 mandatory, #4 only if constraints exist - Fix namelist format: &user_inputs ... &end/ (not &user_inputs / ... / &end) - Update counts: ~3,400 params (was ~3,300), 560+ tests (was 500+) - Add ghost cell allocation pattern (-buff_size:m+buff_size, idwint/idwbuff) - Add field variable indexing system (cont_idx, mom_idx, E_idx, adv_idx, sys_size) - Add test system details: programmatic generation, CaseGeneratorStack, UUID hashing - Add scalar_field uses stp (not wp) to precision types - Add analytical IC available variables (x, y, z, xc, yc, zc, lx, ly, lz, r, e, t) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 3286cfa commit 7104b11

4 files changed

Lines changed: 52 additions & 14 deletions

File tree

.claude/rules/common-pitfalls.md

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,28 @@
11
# Common Pitfalls
22

3-
## Array Bounds
4-
- Arrays use non-unity lower bounds with ghost cells
3+
## Array Bounds & Ghost Cells
4+
- Grid dimensions: `m`, `n`, `p` (cells in x, y, z). 1D: n=p=0. 2D: p=0.
5+
- Interior domain: `0:m`, `0:n`, `0:p`
6+
- Buffer/ghost region: `-buff_size:m+buff_size` (similar for n, p in multi-D)
7+
- `buff_size` depends on WENO order and features (typically `2*weno_polyn + 2`)
8+
- Domain bounds: `idwint(1:3)` (interior `0:m`), `idwbuff(1:3)` (with ghost cells)
9+
- Cell-center coords: `x_cc(-buff_size:m+buff_size)`, `y_cc(...)`, `z_cc(...)`
10+
- Cell-boundary coords: `x_cb(-1-buff_size:m+buff_size)`
511
- Riemann solver indexing: left state at `j`, right state at `j+1`
612
- Off-by-one errors in ghost cell regions are a common source of bugs
713

14+
## Field Variable Indexing
15+
- Conserved variables: `q_cons_vf(1:sys_size)`. Primitive: `q_prim_vf(1:sys_size)`.
16+
- Index ranges depend on `model_eqns` and enabled features (set in `m_global_parameters.fpp`):
17+
- `cont_idx` — continuity (partial densities, one per fluid)
18+
- `mom_idx` — momentum components
19+
- `E_idx` — total energy (scalar)
20+
- `adv_idx` — volume fractions (advection equations)
21+
- `bub_idx`, `stress_idx`, `xi_idx`, `species_idx`, `B_idx`, `c_idx` — optional
22+
- Shorthand scalars: `momxb`/`momxe`, `contxb`/`contxe`, `advxb`/`advxe`, etc.
23+
- `sys_size` = total number of conserved variables (computed at startup)
24+
- Changing `model_eqns` or enabling features changes ALL index positions
25+
826
## Blast Radius
927
- `src/common/` is shared by ALL three executables (pre_process, simulation, post_process)
1028
- Any change to common/ requires testing all three targets
@@ -23,12 +41,15 @@
2341
- Fypp macros must expand correctly for both GPU and CPU builds
2442
- GPU builds only work with nvfortran, Cray ftn, and AMD flang
2543

26-
## Test Golden Files
27-
- Tests compare output against golden files in `tests/<hash>/golden.txt`
44+
## Test System
45+
- Tests are generated **programmatically** in `toolchain/mfc/test/cases.py`, not standalone files
46+
- Each test is a parameter modification on top of `BASE_CFG` defaults
47+
- Test UUID = CRC32 hash of the test's trace string; `./mfc.sh test -l` lists all
48+
- To add a test: modify `cases.py` using `CaseGeneratorStack` push/pop pattern
49+
- Golden files: `tests/<UUID>/golden.txt` — tolerance-based comparison, not exact match
2850
- If your change intentionally modifies output, regenerate golden files:
2951
`./mfc.sh test --generate --only <affected_tests> -j 8`
3052
- Do not regenerate ALL golden files unless you understand every output change
31-
- Golden file diffs are compared with tolerance, not exact match
3253

3354
## PR Checklist
3455
Before submitting a PR:

.claude/rules/fortran-conventions.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,11 @@ Enforced by convention/code review (not automated):
5050
- Always use generic intrinsics: `sqrt` not `dsqrt`, `abs` not `dabs`.
5151
- Cast with `real(..., wp)` or `real(..., stp)`, never `dble(...)`.
5252

53+
Key derived types (`m_derived_types.fpp`):
54+
- `scalar_field``real(stp), pointer :: sf(:,:,:)`. Uses `stp`, NOT `wp`.
55+
- `vector_field` — allocatable array of `scalar_field` components.
56+
- New field arrays MUST use `stp` for storage precision consistency.
57+
5358
## Size Guidelines (soft)
5459
- Subroutine: ≤500 lines
5560
- Helper routine: ≤150 lines

.claude/rules/parameter-system.md

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# Parameter System
22

33
## Overview
4-
MFC has ~3,300 simulation parameters defined in Python and read by Fortran via namelist files.
4+
MFC has ~3,400 simulation parameters defined in Python and read by Fortran via namelist files.
55

66
## Parameter Flow: Python → Fortran
77

@@ -17,15 +17,16 @@ MFC has ~3,300 simulation parameters defined in Python and read by Fortran via n
1717

1818
3. **Input Generation**: `toolchain/mfc/run/input.py`
1919
- Python case dict → Fortran namelist `.inp` file
20-
- Format: `&user_inputs / ... / &end`
20+
- Format: `&user_inputs` ... `&end/`
2121

2222
4. **Fortran Reading**: `src/*/m_start_up.fpp`
2323
- Reads `&user_inputs` namelist
2424
- Each parameter must be declared in the namelist statement
2525

2626
## Adding a New Parameter (4-location checklist)
2727

28-
YOU MUST update all 4 locations. Missing any causes silent failures or compile errors.
28+
YOU MUST update the first 3 locations. Missing any causes silent failures or compile errors.
29+
Location 4 is required only if the parameter has physics constraints.
2930

3031
1. **`toolchain/mfc/params/definitions.py`**: Add parameter with type, default, constraints
3132
2. **`src/*/m_global_parameters.fpp`**: Declare the Fortran variable in the relevant
@@ -52,3 +53,14 @@ add Fortran-side checks here in addition to `case_validator.py`.
5253
## Analytical Initial Conditions
5354
String expressions in parameters become Fortran code via `case.py.__get_analytic_ic_fpp()`.
5455
These are compiled into the binary, so syntax errors cause build failures, not runtime errors.
56+
57+
Available variables in analytical IC expressions:
58+
- `x`, `y`, `z` — cell-center coordinates (mapped to `x_cc(i)`, `y_cc(j)`, `z_cc(k)`)
59+
- `xc`, `yc`, `zc` — patch centroid coordinates
60+
- `lx`, `ly`, `lz` — patch lengths
61+
- `r` — patch radius; `eps`, `beta` — vortex parameters
62+
- `e` — Euler's number (2.71828...)
63+
- Standard Fortran math intrinsics available: `sin`, `cos`, `exp`, `sqrt`, `abs`, etc.
64+
- For moving immersed boundaries: `t` (simulation time) is also available
65+
66+
Example: `'patch_icpp(1)%vel(2)': '(x - xc) * exp(-((x-xc)**2 + (y-yc)**2))'`

CLAUDE.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ All commands run from the repo root via `./mfc.sh`.
2929
./mfc.sh run case.py -e batch -N 2 -n 4 -c phoenix -a ACCOUNT # Batch submit on Phoenix
3030

3131
# Testing
32-
./mfc.sh test -j 8 # Run full test suite (500+ tests)
32+
./mfc.sh test -j 8 # Run full test suite (560+ tests)
3333
./mfc.sh test --only 1D -j 8 # Only 1D tests
3434
./mfc.sh test --only 2D Bubbles -j 8 # Only 2D bubble tests
3535
./mfc.sh test --only <UUID> -j 8 # Run one specific test by UUID
@@ -50,7 +50,7 @@ source ./mfc.sh load -c p -m c # Load Phoenix CPU modules
5050

5151
# Other
5252
./mfc.sh validate case.py # Validate case file without running
53-
./mfc.sh params <query> # Search ~3300 case parameters
53+
./mfc.sh params <query> # Search ~3,400 case parameters
5454
./mfc.sh clean # Remove build artifacts
5555
./mfc.sh new <name> # Create new case from template
5656
```
@@ -117,11 +117,11 @@ src/
117117
simulation/ # CFD solver (GPU-accelerated via OpenACC / OpenMP target offload)
118118
post_process/ # Data output and visualization
119119
toolchain/ # Python CLI, build system, testing, parameter management
120-
mfc/params/definitions.py # ~3300 parameter definitions (source of truth)
120+
mfc/params/definitions.py # ~3,400 parameter definitions (source of truth)
121121
mfc/case_validator.py # Physics constraint validation
122122
mfc/test/ # Test runner and case generation
123123
examples/ # Example simulation cases (case.py files)
124-
tests/ # 500+ regression test golden files
124+
tests/ # 560+ regression test golden files
125125
```
126126

127127
Source files are `.fpp` (Fortran + Fypp macros), preprocessed to `.f90` by CMake.
@@ -137,11 +137,11 @@ NEVER use `stop` or `error stop`. Use `call s_mpi_abort()` or `@:PROHIBIT()`/`@:
137137
NEVER use `goto`, `COMMON` blocks, or global `save` variables.
138138

139139
Every `@:ALLOCATE(...)` MUST have a matching `@:DEALLOCATE(...)`.
140-
Every new parameter MUST be added in 4 places:
140+
Every new parameter MUST be added in at least 3 places (4 if it has constraints):
141141
1. `toolchain/mfc/params/definitions.py` (parameter definition)
142142
2. Fortran variable declaration in `src/*/m_global_parameters.fpp`
143143
3. Fortran namelist in `src/*/m_start_up.fpp` (namelist binding)
144-
4. `toolchain/mfc/case_validator.py` (if constraints exist)
144+
4. `toolchain/mfc/case_validator.py` (only if parameter has physics constraints)
145145

146146
Changes to `src/common/` affect ALL three executables. Test comprehensively.
147147

0 commit comments

Comments
 (0)