Skip to content

Commit 78bb959

Browse files
authored
Complete named-constant adoption and parameter declaration generation (#1551)
1 parent ac30c32 commit 78bb959

30 files changed

Lines changed: 461 additions & 291 deletions

.claude/rules/common-pitfalls.md

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,16 +43,27 @@ covered in `docs/documentation/contributing.md`.
4343
`toolchain/mfc/params/definitions.py`; `case_validator.py` only if physics-constrained
4444
(with a `PHYSICS_DOCS` entry). Fortran declarations and namelist bindings are
4545
auto-generated at CMake configure time — re-run cmake (or `./mfc.sh build`) after editing.
46-
- Still manual: array variables and derived-type members (declare in
47-
`src/*/m_global_parameters.fpp` / the relevant type), and case-optimization parameters
48-
(`CASE_OPT_PARAMS` + the `#:else` block in `src/simulation/m_global_parameters.fpp`).
49-
Gotcha: under `--case-optimization` those are baked into the binary and dropped from
50-
the namelist, so changing one needs a *rebuild*, not a case edit.
46+
- Still manual: derived-type `TYPE` member definitions in `src/common/m_derived_types.fpp`;
47+
default-value assignments in `s_assign_default_values_to_user_inputs`; the
48+
`CASE_OPT_EXTRA_LINES` literal in `toolchain/mfc/params/generators/fortran_gen.py` (covers `num_dims`,
49+
`num_vels`, `weno_polyn`, `muscl_polyn`, `weno_num_stencils`, `wenojs`);
50+
multi-variable declaration lines (`bc_x/y/z`, `x/y/z_domain`, `x/y/z_output`, post's
51+
`G`); and MPI broadcast lists in `m_mpi_proxy`. Everything else — scalar declarations,
52+
plain arrays (`FORTRAN_ARRAY_DIMS` table in `definitions.py`), derived-type namelist
53+
declarations including `GPU_DECLARE` lines and Doxygen descs (`TYPED_DECLS` table in
54+
`definitions.py`), and the simulation case-optimization declaration block — is
55+
auto-generated at CMake configure time.
56+
Gotcha: after editing a generator or table, force regen via `cmake_gen.py` into
57+
`build/staging/*/` or simply reconfigure (`./mfc.sh build`) — cached builds compile
58+
stale includes. Under `--case-optimization` the baked-in constants are dropped from the
59+
namelist, so changing one needs a *rebuild*, not a case edit.
5160
- Runtime checks (`@:PROHIBIT`) go where they run: shared →
5261
`src/common/m_checker_common.fpp`; simulation-only → `src/simulation/m_checker.fpp`;
5362
pre/post-only → `src/{pre,post}_process/m_checker.fpp` (their `s_check_inputs` are
5463
currently empty — that IS the right place, not m_checker_common).
55-
- Analytic ICs are compiled into the binary (syntax error = build failure, not runtime).
64+
- Analytic ICs are compiled into the binary. Expressions are AST-validated at case load
65+
(syntax errors and unknown variables are immediate, named errors; bare `e` is not a
66+
variable — write `exp(1.0)`).
5667
Each IC variable maps to an `eqn_idx%…` expression in `QPVF_IDX_VARS`
5768
(`toolchain/mfc/case.py`); a new patch-settable conserved variable means updating that
5869
map AND the Fortran `eqn_idx` builder to agree — a mismatch is a silent wrong index.

CMakeLists.txt

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -418,9 +418,9 @@ macro(HANDLE_SOURCES target useCommon)
418418

419419
# Gather:
420420
# * src/[<target>,common]/include/*.fpp
421-
# * (if any) <build>/include/<target>/*.fpp
422-
file(GLOB ${target}_incs CONFIGURE_DEPENDS "${${target}_DIR}/include/*.fpp"
423-
"${CMAKE_BINARY_DIR}/include/${target}/*.fpp")
421+
# * generated includes from build/include/<target>/ (explicit list, not a GLOB)
422+
file(GLOB ${target}_incs CONFIGURE_DEPENDS "${${target}_DIR}/include/*.fpp")
423+
list(APPEND ${target}_incs ${_mfc_gen_files_${target}})
424424

425425
if (${useCommon})
426426
file(GLOB common_incs CONFIGURE_DEPENDS "${common_DIR}/include/*.fpp")
@@ -494,6 +494,47 @@ if(_mfc_needs_regen)
494494
file(TOUCH "${_mfc_gen_stamp}")
495495
endif()
496496

497+
# Enumerate the 10 generated .fpp files explicitly so ninja can track them as
498+
# build-time outputs and so HANDLE_SOURCES does not need a configure-time GLOB
499+
# of ${CMAKE_BINARY_DIR}/include/<target>/ (which fails when the dir is empty).
500+
set(_mfc_gen_inc "${CMAKE_BINARY_DIR}/include")
501+
set(_mfc_gen_files_pre_process
502+
"${_mfc_gen_inc}/pre_process/generated_namelist.fpp"
503+
"${_mfc_gen_inc}/pre_process/generated_decls.fpp"
504+
"${_mfc_gen_inc}/pre_process/generated_constants.fpp"
505+
)
506+
set(_mfc_gen_files_simulation
507+
"${_mfc_gen_inc}/simulation/generated_namelist.fpp"
508+
"${_mfc_gen_inc}/simulation/generated_decls.fpp"
509+
"${_mfc_gen_inc}/simulation/generated_constants.fpp"
510+
"${_mfc_gen_inc}/simulation/generated_case_opt_decls.fpp"
511+
)
512+
set(_mfc_gen_files_post_process
513+
"${_mfc_gen_inc}/post_process/generated_namelist.fpp"
514+
"${_mfc_gen_inc}/post_process/generated_decls.fpp"
515+
"${_mfc_gen_inc}/post_process/generated_constants.fpp"
516+
)
517+
set(_mfc_gen_files_syscheck)
518+
set(_mfc_all_gen_files
519+
${_mfc_gen_files_pre_process}
520+
${_mfc_gen_files_simulation}
521+
${_mfc_gen_files_post_process}
522+
)
523+
524+
# Build-time regeneration: ninja re-runs cmake_gen.py and re-preprocesses
525+
# any .fpp that includes a generated file whenever a params .py changes.
526+
add_custom_command(
527+
OUTPUT ${_mfc_all_gen_files}
528+
COMMAND "${Python3_EXECUTABLE}"
529+
"${CMAKE_CURRENT_SOURCE_DIR}/toolchain/mfc/params/generators/cmake_gen.py"
530+
"${CMAKE_BINARY_DIR}"
531+
DEPENDS ${_mfc_gen_inputs}
532+
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
533+
COMMENT "Regenerating Fortran parameter includes"
534+
VERBATIM
535+
)
536+
add_custom_target(mfc_params_gen DEPENDS ${_mfc_all_gen_files})
537+
497538
HANDLE_SOURCES(pre_process ON)
498539
HANDLE_SOURCES(simulation ON)
499540
HANDLE_SOURCES(post_process ON)

docs/documentation/contributing.md

Lines changed: 16 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -276,35 +276,27 @@ def check_my_feature(self):
276276

277277
If your check enforces a physics constraint, also add a `PHYSICS_DOCS` entry (see [How to Document Physics Constraints](#how-to-document-physics-constraints) below).
278278

279-
**Step 5: Declare in Fortran** (`src/<target>/m_global_parameters.fpp`)
279+
**Step 5: Fortran declaration and namelist binding (auto-generated)**
280280

281-
Add the variable declaration in the appropriate target's global parameters module. Choose the target(s) where the parameter is used:
281+
Scalar declarations, GPU declare lines, Doxygen descriptions, and namelist bindings are
282+
auto-generated at CMake configure time from the `TYPED_DECLS` and `FORTRAN_ARRAY_DIMS`
283+
tables in `toolchain/mfc/params/definitions.py`. For a plain scalar registered with
284+
`_r()` / `_nv()` above, no manual Fortran edit is needed — reconfigure (`./mfc.sh build`)
285+
and the generated include in each target's `m_global_parameters.fpp` is updated
286+
automatically.
282287

283-
- `src/pre_process/m_global_parameters.fpp`
284-
- `src/simulation/m_global_parameters.fpp`
285-
- `src/post_process/m_global_parameters.fpp`
288+
Still manual (not auto-generated):
286289

287-
```fortran
288-
real(wp) :: my_param !< Description of the parameter
289-
```
290-
291-
If the parameter is used in GPU kernels, add a GPU declaration:
292-
293-
```fortran
294-
$:GPU_DECLARE(create='[my_param]')
295-
```
296-
297-
**Step 6: Add to Fortran namelist** (`src/<target>/m_start_up.fpp`)
298-
299-
Add the parameter name to the `namelist /user_inputs/` declaration:
300-
301-
```fortran
302-
namelist /user_inputs/ ... , my_param, ...
303-
```
290+
- `TYPE` member definitions inside derived types in `src/common/m_derived_types.fpp`
291+
- Default-value assignments in `s_assign_default_values_to_user_inputs`
292+
- Multi-variable declaration lines (`bc_x/y/z`, `x/y/z_domain`, `x/y/z_output`)
293+
- MPI broadcast lists in `src/*/m_mpi_proxy.fpp`
294+
- `CASE_OPT_EXTRA_LINES` in `toolchain/mfc/params/generators/fortran_gen.py` for case-optimization constants
304295

305-
The toolchain writes the parameter to the input file and Fortran reads it via this namelist. No other I/O code is needed.
296+
After editing any generator or table, force regen by reconfiguring (`./mfc.sh build`) —
297+
cached builds compile stale includes.
306298

307-
**Step 7: Use in Fortran code**
299+
**Step 6: Use in Fortran code**
308300

309301
Reference `my_param` anywhere in the target's modules. It is available as a global after the namelist is read at startup.
310302

src/common/m_constants.fpp

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,7 @@ module m_constants
5050
real(wp), parameter :: broadband_spectral_level_constant = 20._wp
5151
!> The spectral level constant to correct the magnitude at each frequency to ensure the source is overall broadband
5252
real(wp), parameter :: broadband_spectral_level_growth_rate = 10._wp
53-
! Reconstruction Types
54-
integer, parameter :: WENO_TYPE = 1 !< Using WENO for reconstruction type
55-
integer, parameter :: MUSCL_TYPE = 2 !< Using MUSCL for reconstruction type
56-
! Interface Compression
53+
! Reconstruction Types Interface Compression
5754
real(wp), parameter :: dflt_ic_eps = 1e-4_wp !< Ensure compression is only applied to surface cells in THINC
5855
real(wp), parameter :: dflt_ic_beta = 1.6_wp !< Sharpness parameter's default value used in THINC
5956
real(wp), parameter :: moncon_cutoff = 1e-8_wp !< Monotonicity constraint's limiter to prevent extremas in THINC

src/common/m_helper_basic.fpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ module m_helper_basic
99

1010
use m_derived_types
1111
use m_precision_select
12+
use m_constants, only: recon_type_weno, recon_type_muscl
1213

1314
implicit none
1415

@@ -125,13 +126,13 @@ contains
125126

126127
if (igr) then
127128
buff_size = (igr_order - 1)/2 + 2
128-
else if (recon_type == WENO_TYPE) then
129+
else if (recon_type == recon_type_weno) then
129130
if (viscous) then
130131
buff_size = 2*weno_polyn + 2
131132
else
132133
buff_size = weno_polyn + 2
133134
end if
134-
else if (recon_type == MUSCL_TYPE) then
135+
else if (recon_type == recon_type_muscl) then
135136
buff_size = muscl_polyn + 2
136137
end if
137138

src/common/m_mpi_common.fpp

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ module m_mpi_common
1717
use m_helper
1818
use ieee_arithmetic
1919
use m_nvtx
20+
use m_constants, only: recon_type_weno, format_silo
2021

2122
implicit none
2223

@@ -1031,7 +1032,7 @@ contains
10311032
integer :: i, j !< Generic loop iterators
10321033
integer :: ierr !< Generic flag used to identify and report MPI errors
10331034

1034-
if (recon_type == WENO_TYPE) then
1035+
if (recon_type == recon_type_weno) then
10351036
recon_order = weno_order
10361037
else
10371038
recon_order = muscl_order
@@ -1194,14 +1195,14 @@ contains
11941195

11951196
#ifdef MFC_POST_PROCESS
11961197
! Ghost zone at the beginning
1197-
if (proc_coords(3) > 0 .and. format == 1) then
1198+
if (proc_coords(3) > 0 .and. format == format_silo) then
11981199
offset_z%beg = 2
11991200
else
12001201
offset_z%beg = 0
12011202
end if
12021203

12031204
! Ghost zone at the end
1204-
if (proc_coords(3) < num_procs_z - 1 .and. format == 1) then
1205+
if (proc_coords(3) < num_procs_z - 1 .and. format == format_silo) then
12051206
offset_z%end = 2
12061207
else
12071208
offset_z%end = 0
@@ -1306,14 +1307,14 @@ contains
13061307

13071308
#ifdef MFC_POST_PROCESS
13081309
! Ghost zone at the beginning
1309-
if (proc_coords(2) > 0 .and. format == 1) then
1310+
if (proc_coords(2) > 0 .and. format == format_silo) then
13101311
offset_y%beg = 2
13111312
else
13121313
offset_y%beg = 0
13131314
end if
13141315

13151316
! Ghost zone at the end
1316-
if (proc_coords(2) < num_procs_y - 1 .and. format == 1) then
1317+
if (proc_coords(2) < num_procs_y - 1 .and. format == format_silo) then
13171318
offset_y%end = 2
13181319
else
13191320
offset_y%end = 0
@@ -1389,14 +1390,14 @@ contains
13891390

13901391
#ifdef MFC_POST_PROCESS
13911392
! Ghost zone at the beginning
1392-
if (proc_coords(1) > 0 .and. format == 1) then
1393+
if (proc_coords(1) > 0 .and. format == format_silo) then
13931394
offset_x%beg = 2
13941395
else
13951396
offset_x%beg = 0
13961397
end if
13971398

13981399
! Ghost zone at the end
1399-
if (proc_coords(1) < num_procs_x - 1 .and. format == 1) then
1400+
if (proc_coords(1) < num_procs_x - 1 .and. format == format_silo) then
14001401
offset_x%end = 2
14011402
else
14021403
offset_x%end = 0

src/common/m_variables_conversion.fpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ module m_variables_conversion
1414
use m_helper_basic
1515
use m_helper
1616
use m_constants, only: riemann_solver_hll, riemann_solver_hlld, model_eqns_gamma_law, model_eqns_5eq, model_eqns_6eq, &
17-
& model_eqns_4eq
17+
& model_eqns_4eq, avg_state_roe
1818
use m_thermochem, only: num_species, get_temperature, get_pressure, gas_constant, get_mixture_molecular_weight, &
1919
& get_mixture_energy_mass
2020

@@ -1267,7 +1267,7 @@ contains
12671267
integer :: q
12681268

12691269
if (chemistry) then ! Reacting mixture sound speed
1270-
if (avg_state == 1 .and. abs(c_c) > verysmall) then
1270+
if (avg_state == avg_state_roe .and. abs(c_c) > verysmall) then
12711271
c = sqrt(c_c - (gamma - 1.0_wp)*(vel_sum - H))
12721272
else
12731273
c = sqrt((1.0_wp + 1.0_wp/gamma)*pres/rho)

0 commit comments

Comments
 (0)