Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
bf430ad
feat(params): add str_len to ParamDef for STR character length
sbryngelson May 28, 2026
4e85b30
style(params): use inline comment for str_len field
sbryngelson May 28, 2026
84b53c2
feat(params): add namelist_targets.py with per-target namelist variab…
sbryngelson May 28, 2026
283fb29
feat(params): add fortran_gen.py to generate namelist and decl .fpp f…
sbryngelson May 28, 2026
dee2f0c
feat(params): wire fortran_gen into generate.py, add generated .fpp f…
sbryngelson May 28, 2026
71f9a1f
refactor(fortran): replace hand-written namelists with generated incl…
sbryngelson May 28, 2026
7921c8f
refactor(fortran): replace hand-written scalar decls with generated i…
sbryngelson May 28, 2026
56cfa23
feat(precheck): add 7/7 check for generated Fortran files
sbryngelson May 28, 2026
13f24b1
fix: move generated .fpp files to CMake build dir, remove from source…
sbryngelson May 28, 2026
08b7f08
chore: remove plan doc from vcs
sbryngelson May 28, 2026
5f88f31
refactor: clean up codegen — remove dead alias, stale comments, docst…
sbryngelson May 28, 2026
504a348
refactor(params): consolidate codegen, eliminate duplicate descriptio…
sbryngelson May 28, 2026
373a496
refactor: fix four accumulated code quality issues
sbryngelson May 28, 2026
692c1a7
refactor: extract repeated patterns in case_validator and test/cases
sbryngelson May 28, 2026
53f08e1
fix: restore alpha_wrt scalar registration missing from refac-params
sbryngelson May 28, 2026
d85b5b6
fix(codegen): exclude CASE_OPT_PARAMS from sim generated_decls.fpp
sbryngelson May 28, 2026
7517ada
refactor: fix cantera_file NameError, unify archive relpath, derive c…
sbryngelson May 28, 2026
d6c9228
fix: restore CASE_OPT_PARAMS declarations in #:else branch
sbryngelson May 28, 2026
fdb97f0
fix: remove stray scalar registration of alpha_wrt (array in Fortran)
sbryngelson May 28, 2026
2c171f1
fix: restore alpha_wrt registration; skip array vars in decl gen; add…
sbryngelson May 28, 2026
98b24cf
feat(precheck): add generate --check and conditional build; 8/9 checks
sbryngelson May 28, 2026
c684a13
fix(precheck): remove build step — compilation takes too long for pre…
sbryngelson May 28, 2026
ea3bb93
ci: trigger fresh CI run
sbryngelson May 28, 2026
999cde9
fix(precheck): remove generate --check — platform-dependent output br…
sbryngelson May 28, 2026
4901c32
fix(gen): use #:if/#:else guard for case-opt namelist — prevents dang…
sbryngelson May 28, 2026
b3cf25e
fix(review): 6 issues from PR self-review
sbryngelson May 28, 2026
29f0836
style: collapse parts= list to one line (ruff)
sbryngelson May 28, 2026
0fada8f
chore(deps): pin ruff==0.6.5; bump ffmt to 0.4.1 from master
sbryngelson May 28, 2026
8e0a394
docs: update parameter-addition rule from 4-location to 2-location
sbryngelson May 28, 2026
27476a7
fix(cmake): replace hand-rolled _mfc_gen_inputs list with GLOB_RECURSE
sbryngelson May 28, 2026
0c5f183
feat(codegen): auto-generate array declarations via FORTRAN_ARRAY_DIMS
sbryngelson May 28, 2026
46d3584
refactor(fortran_gen): harden errors, improve readability, add tests
sbryngelson May 28, 2026
7923676
fix(precheck): use ruff/ffmt --check mode; fix formatting of fortran_…
sbryngelson May 28, 2026
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
2 changes: 1 addition & 1 deletion .claude/rules/common-pitfalls.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ Before submitting a PR:
- [ ] `./mfc.sh precheck -j 8` (5 CI lint checks)
- [ ] `./mfc.sh build -j 8` (compiles)
- [ ] `./mfc.sh test --only <relevant> -j 8` (tests pass)
- [ ] If adding parameters: all 4 locations updated
- [ ] If adding parameters: definitions.py (_r + _nv) updated; cmake reconfigured; case_validator.py if constraints
- [ ] If modifying `src/common/`: all three targets tested
- [ ] If changing output: golden files regenerated for affected tests
- [ ] One logical change per commit
22 changes: 12 additions & 10 deletions .claude/rules/parameter-system.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,20 +23,22 @@ MFC has ~3,400 simulation parameters defined in Python and read by Fortran via n
- Reads `&user_inputs` namelist
- Each parameter must be declared in the namelist statement

## Adding a New Parameter (4-location checklist)
## Adding a New Parameter (2-location checklist)

YOU MUST update the first 3 locations. Missing any causes silent failures or compile errors.
Location 4 is required only if the parameter has physics constraints.
Fortran declarations and namelist bindings are now auto-generated from definitions.py
at CMake configure time — no manual Fortran edits needed for simple scalar parameters.

1. **`toolchain/mfc/params/definitions.py`**: Add parameter with type, default, constraints
2. **`src/*/m_global_parameters.fpp`**: Declare the Fortran variable in the relevant
target(s). If the param is used by simulation only, add it there. If shared, add to
all three targets' m_global_parameters.fpp.
3. **`src/*/m_start_up.fpp`**: Add to the Fortran `namelist` declaration in the relevant
target(s).
4. **`toolchain/mfc/case_validator.py`**: Add validation rules if the parameter has
1. **`toolchain/mfc/params/definitions.py`**: Add parameter with `_r()` (type, default,
constraints) AND add it to `NAMELIST_VARS` via `_nv()` for the relevant target(s).
After editing, re-run cmake (or `./mfc.sh build`) to regenerate the Fortran includes.
2. **`toolchain/mfc/case_validator.py`**: Add validation rules if the parameter has
physics constraints. Include `PHYSICS_DOCS` entry with title, category, explanation.

**Exceptions — still require manual Fortran edits:**
- Array variables (e.g. `logical, dimension(num_fluids_max)`) → declare in `src/*/m_global_parameters.fpp`
- Derived-type members (`fluid_pp%attr`, `patch_icpp(i)%attr`) → declare in the relevant derived type
- Case-optimization parameters → add to `CASE_OPT_PARAMS` and the `#:else` block in `src/simulation/m_global_parameters.fpp`

## Case Files
- Case files are Python scripts (`.py`) that define a dict of parameters
- Validated with `./mfc.sh validate case.py`
Expand Down
11 changes: 6 additions & 5 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -139,11 +139,12 @@ NEVER use `stop` or `error stop`. Use `call s_mpi_abort()` or `@:PROHIBIT()`/`@:
NEVER use `goto`, `COMMON` blocks, or global `save` variables.

Every `@:ALLOCATE(...)` MUST have a matching `@:DEALLOCATE(...)`.
Every new parameter MUST be added in at least 3 places (4 if it has constraints):
1. `toolchain/mfc/params/definitions.py` (parameter definition)
2. Fortran variable declaration in `src/*/m_global_parameters.fpp`
3. Fortran namelist in `src/*/m_start_up.fpp` (namelist binding)
4. `toolchain/mfc/case_validator.py` (only if parameter has physics constraints)
Every new parameter MUST be added in at least 2 places (3 if it has constraints):
1. `toolchain/mfc/params/definitions.py` (parameter definition + NAMELIST_VARS target set)
2. `toolchain/mfc/case_validator.py` (only if parameter has physics constraints)
Note: Fortran declarations and namelist bindings are auto-generated from definitions.py
at CMake configure time. Simple scalars need no manual Fortran edits. Array/derived-type
variables still require a manual declaration in `src/*/m_global_parameters.fpp`.

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

Expand Down
33 changes: 33 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -461,6 +461,39 @@ macro(HANDLE_SOURCES target useCommon)
endmacro()


# Generate Fortran parameter namelist/decl includes into the per-target build
# include directories before HANDLE_SOURCES globs them for Fypp.
find_package(Python3 REQUIRED COMPONENTS Interpreter)
set(_mfc_gen_stamp "${CMAKE_BINARY_DIR}/mfc_params_gen.stamp")
file(GLOB_RECURSE _mfc_gen_inputs
"${CMAKE_CURRENT_SOURCE_DIR}/toolchain/mfc/params/*.py"
)
set(_mfc_needs_regen FALSE)
if(NOT EXISTS "${_mfc_gen_stamp}")
set(_mfc_needs_regen TRUE)
else()
foreach(_input IN LISTS _mfc_gen_inputs)
if("${_input}" IS_NEWER_THAN "${_mfc_gen_stamp}")
set(_mfc_needs_regen TRUE)
break()
endif()
endforeach()
endif()
if(_mfc_needs_regen)
execute_process(
COMMAND "${Python3_EXECUTABLE}"
"${CMAKE_CURRENT_SOURCE_DIR}/toolchain/mfc/params/generators/cmake_gen.py"
"${CMAKE_BINARY_DIR}"
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
RESULT_VARIABLE _mfc_gen_result
ERROR_VARIABLE _mfc_gen_error
)
if(NOT _mfc_gen_result EQUAL 0)
message(FATAL_ERROR "Fortran param generation failed:\n${_mfc_gen_error}")
endif()
file(TOUCH "${_mfc_gen_stamp}")
endif()

HANDLE_SOURCES(pre_process ON)
HANDLE_SOURCES(simulation ON)
HANDLE_SOURCES(post_process ON)
Expand Down
139 changes: 12 additions & 127 deletions src/post_process/m_global_parameters.fpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,19 @@ module m_global_parameters

implicit none

#:include 'generated_decls.fpp'

!> @name Logistics
!> @{
integer :: num_procs !< Number of processors
character(LEN=path_len) :: case_dir !< Case folder location
integer :: num_procs !< Number of processors
!> @}

! Computational Domain Parameters

integer :: proc_rank !< Rank of the local processor
!> @name Number of cells in the x-, y- and z-coordinate directions
!> @{
integer :: m, m_root
integer :: n
integer :: p
integer :: m_root
!> @}

!> @name Max and min number of cells in a direction of each combination of x-,y-, and z-
Expand All @@ -39,7 +38,6 @@ module m_global_parameters

!> @name Cylindrical coordinates (either axisymmetric or full 3D)
!> @{
logical :: cyl_coord
integer :: grid_geometry
!> @}

Expand All @@ -66,50 +64,24 @@ module m_global_parameters
real(wp), allocatable, dimension(:) :: dx, dy, dz
!> @}

integer :: buff_size !< Number of ghost cells for boundary condition storage
integer :: t_step_start !< First time-step directory
integer :: t_step_stop !< Last time-step directory
integer :: t_step_save !< Interval between consecutive time-step directory
integer :: buff_size !< Number of ghost cells for boundary condition storage
!> @name IO options for adaptive time-stepping
!> @{
logical :: cfl_adap_dt, cfl_const_dt, cfl_dt
real(wp) :: t_save
real(wp) :: t_stop
real(wp) :: cfl_target
integer :: n_save
integer :: n_start
logical :: cfl_dt
integer :: n_save
!> @}

! NOTE: m_root, x_root_cb, x_root_cc = defragmented grid (1D only; equals m, x_cb, x_cc in serial)

!> @name Simulation Algorithm Parameters
!> @{
integer :: model_eqns !< Multicomponent flow model
integer :: num_fluids !< Number of different fluids present in the flow
logical :: relax !< phase change
integer :: relax_model !< Phase change relaxation model
logical :: mpp_lim !< Maximum volume fraction limiter
integer :: sys_size !< Number of unknowns in the system of equations
integer :: recon_type !< Which type of reconstruction to use
integer :: weno_order !< Order of accuracy for the WENO reconstruction
integer :: muscl_order !< Order of accuracy for the MUSCL reconstruction
logical :: mixture_err !< Mixture error limiter
logical :: alt_soundspeed !< Alternate sound speed
logical :: mhd !< Magnetohydrodynamics
logical :: relativity !< Relativity for RMHD
logical :: hypoelasticity !< Turn hypoelasticity on
logical :: hyperelasticity !< Turn hyperelasticity on
logical :: elasticity !< elasticity modeling, true for hyper or hypo
integer :: b_size !< Number of components in the b tensor
integer :: tensor_size !< Number of components in the nonsymmetric tensor
logical :: cont_damage !< Continuum damage modeling
logical :: hyper_cleaning !< Hyperbolic cleaning for MHD
logical :: igr !< enable IGR
integer :: igr_order !< IGR reconstruction order
logical, parameter :: chemistry = .${chemistry}$. !< Chemistry modeling
!> @}

integer :: avg_state !< Average state evaluation method
!> @name Annotations of the structure, i.e. the organization, of the state vectors
!> @{
type(eqn_idx_info) :: eqn_idx !< All conserved-variable equation index ranges and scalars.
Expand All @@ -122,7 +94,6 @@ module m_global_parameters

! Cell indices (InDices With BUFFer): includes buffer in simulation only
type(int_bounds_info) :: idwbuff(1:3)
integer :: num_bc_patches
logical :: bc_io
!> @name Boundary conditions in the x-, y- and z-coordinate directions
!> @{
Expand All @@ -133,12 +104,8 @@ module m_global_parameters
integer, dimension(3) :: shear_indices !< Indices of the stress components that represent shear stress
integer :: shear_BC_flip_num !< Number of shear stress components to reflect for boundary conditions
integer, dimension(3, 2) :: shear_BC_flip_indices !< Shear stress BC reflection indices (1:3, 1:shear_BC_flip_num)
logical :: parallel_io !< Format of the data files
logical :: sim_data
logical :: file_per_process !< output format
integer, allocatable, dimension(:) :: proc_coords !< Processor coordinates in MPI_CART_COMM
integer, allocatable, dimension(:) :: start_idx !< Starting cell-center index of local processor in global grid
integer :: num_ibs !< Number of immersed boundaries
#ifdef MFC_MPI
type(mpi_io_var), public :: MPI_IO_DATA
type(mpi_io_ib_var), public :: MPI_IO_IB_DATA
Expand All @@ -159,10 +126,6 @@ module m_global_parameters
real(wp), allocatable, dimension(:) :: adv !< Advection variables
! Formatted Database File(s) Structure Parameters

integer :: format !< Format of the database file(s)
integer :: precision !< Floating point precision of the database file(s)
logical :: down_sample !< down sampling of the database file(s)
logical :: output_partial_domain !< Specify portion of domain to output for post-processing
type(bounds_info) :: x_output, y_output, z_output !< Portion of domain to output for post-processing
type(int_bounds_info) :: x_output_idx, y_output_idx, z_output_idx !< Indices of domain to output for post-processing
!> @name Size of the ghost zone layer in the x-, y- and z-coordinate directions. The definition of the ghost zone layers is only
Expand All @@ -172,101 +135,23 @@ module m_global_parameters
type(int_bounds_info) :: offset_x, offset_y, offset_z
!> @}

!> @name The list of all possible flow variables that may be written to a database file. It includes partial densities, density,
!! momentum, velocity, energy, pressure, volume fraction(s), specific heat ratio function, specific heat ratio, liquid stiffness
!! function, liquid stiffness, primitive variables, conservative variables, speed of sound, the vorticity, and the numerical
!! Schlieren function.
!> @{
logical, dimension(num_fluids_max) :: alpha_rho_wrt
logical :: rho_wrt
logical, dimension(3) :: mom_wrt
logical, dimension(3) :: vel_wrt
integer :: flux_lim
logical, dimension(3) :: flux_wrt
logical :: E_wrt
logical, dimension(num_fluids_max) :: alpha_rho_e_wrt
logical :: fft_wrt
logical :: pres_wrt
logical, dimension(num_fluids_max) :: alpha_wrt
logical :: gamma_wrt
logical :: heat_ratio_wrt
logical :: pi_inf_wrt
logical :: pres_inf_wrt
logical :: prim_vars_wrt
logical :: cons_vars_wrt
logical :: c_wrt
logical, dimension(3) :: omega_wrt
logical :: qm_wrt
logical :: liutex_wrt
logical :: schlieren_wrt
logical :: cf_wrt
logical :: ib
logical :: ib_state_wrt
logical :: chem_wrt_Y(1:num_species)
logical :: chem_wrt_T
logical :: lag_header
logical :: lag_txt_wrt
logical :: lag_db_wrt
logical :: lag_id_wrt
logical :: lag_pos_wrt
logical :: lag_pos_prev_wrt
logical :: lag_vel_wrt
logical :: lag_rad_wrt
logical :: lag_rvel_wrt
logical :: lag_r0_wrt
logical :: lag_rmax_wrt
logical :: lag_rmin_wrt
logical :: lag_dphidt_wrt
logical :: lag_pres_wrt
logical :: lag_mv_wrt
logical :: lag_mg_wrt
logical :: lag_betaT_wrt
logical :: lag_betaC_wrt
!> @}

real(wp), dimension(num_fluids_max) :: schlieren_alpha !< Per-fluid Schlieren intensity amplitude coefficients
integer :: fd_order !< Finite-difference order for vorticity and Schlieren derivatives
integer :: fd_number !< Finite-difference half-stencil size: MAX(1, fd_order/2)
!> @name Reference parameters for Tait EOS
!> @{
real(wp) :: rhoref, pref
!> @}

! alpha_rho_wrt, mom_wrt, vel_wrt, flux_wrt, alpha_rho_e_wrt, alpha_wrt,
! omega_wrt, chem_wrt_Y, schlieren_alpha: auto-generated in generated_decls.fpp
integer :: fd_number !< Finite-difference half-stencil size: MAX(1, fd_order/2)
type(chemistry_parameters) :: chem_params
!> @name Bubble modeling variables and parameters
!> @{
integer :: nb
real(wp) :: Eu, Ca, Web, Re_inv
real(wp) :: Eu
real(wp), dimension(:), allocatable :: weight, R0
logical :: bubbles_euler
logical :: qbmm
logical :: polytropic
logical :: polydisperse
logical :: adv_n
integer :: thermal !< 1 = adiabatic, 2 = isotherm, 3 = transfer
real(wp) :: phi_vg, phi_gv, Pe_c, Tw, k_vl, k_gl
real(wp) :: gam_m
real(wp), dimension(:), allocatable :: pb0, mass_g0, mass_v0, Pe_T, k_v, k_g
real(wp), dimension(:), allocatable :: Re_trans_T, Re_trans_c, Im_trans_T, Im_trans_c, omegaN
real(wp) :: R0ref, p0ref, rho0ref, T0ref, ss, pv, vd, mu_l, mu_v, mu_g, gam_v, gam_g, M_v, M_g, cp_v, cp_g, R_v, R_g
real(wp) :: p0ref, rho0ref, T0ref, ss, pv, vd, mu_l, mu_v, mu_g, gam_v, gam_g, M_v, M_g, cp_v, cp_g, R_v, R_g
real(wp) :: G
real(wp) :: poly_sigma
real(wp) :: sigR
integer :: nmom
!> @}

!> @name surface tension coefficient
!> @{
real(wp) :: sigma
logical :: surface_tension
!> @}

!> @name Lagrangian bubbles
!> @{
logical :: bubbles_lagrange
!> @}

real(wp) :: Bx0 !< Constant magnetic field in the x-direction (1D)
real(wp) :: wall_time, wall_time_avg !< Wall time measurements

contains
Expand Down
13 changes: 1 addition & 12 deletions src/post_process/m_start_up.fpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,18 +59,7 @@ contains
integer :: iostatus
character(len=1000) :: line

namelist /user_inputs/ case_dir, m, n, p, t_step_start, t_step_stop, t_step_save, model_eqns, num_fluids, mpp_lim, &
& weno_order, bc_x, bc_y, bc_z, fluid_pp, bub_pp, format, precision, output_partial_domain, x_output, y_output, &
& z_output, hypoelasticity, G, mhd, chem_wrt_Y, chem_wrt_T, avg_state, alpha_rho_wrt, rho_wrt, mom_wrt, vel_wrt, &
& E_wrt, fft_wrt, pres_wrt, alpha_wrt, gamma_wrt, heat_ratio_wrt, pi_inf_wrt, pres_inf_wrt, cons_vars_wrt, &
& prim_vars_wrt, c_wrt, omega_wrt, qm_wrt, liutex_wrt, schlieren_wrt, schlieren_alpha, fd_order, mixture_err, &
& alt_soundspeed, flux_lim, flux_wrt, cyl_coord, parallel_io, rhoref, pref, bubbles_euler, qbmm, sigR, R0ref, nb, &
& polytropic, thermal, Ca, Web, Re_inv, polydisperse, poly_sigma, file_per_process, relax, relax_model, cf_wrt, &
& sigma, adv_n, ib, num_ibs, cfl_adap_dt, cfl_const_dt, t_save, t_stop, n_start, cfl_target, surface_tension, &
& bubbles_lagrange, sim_data, hyperelasticity, Bx0, relativity, cont_damage, hyper_cleaning, num_bc_patches, igr, &
& igr_order, down_sample, recon_type, muscl_order, lag_header, lag_txt_wrt, lag_db_wrt, lag_id_wrt, lag_pos_wrt, &
& lag_pos_prev_wrt, lag_vel_wrt, lag_rad_wrt, lag_rvel_wrt, lag_r0_wrt, lag_rmax_wrt, lag_rmin_wrt, lag_dphidt_wrt, &
& lag_pres_wrt, lag_mv_wrt, lag_mg_wrt, lag_betaT_wrt, lag_betaC_wrt, alpha_rho_e_wrt, ib_state_wrt
#:include 'generated_namelist.fpp'

file_loc = 'post_process.inp'
inquire (FILE=trim(file_loc), EXIST=file_check)
Expand Down
Loading
Loading