Background
PR #1432 consolidated directional triplets across several modules into derived type instances with %x/%y/%z components (is_muscl, bc, bf, q_prim_rs, etc.). This is load-bearing groundwork for replacing the most prevalent code-duplication pattern in the simulation target.
The pattern to eliminate
Nearly every directional sweep in m_muscl.fpp, m_cbc.fpp, m_rhs.fpp, and m_riemann_solvers.fpp currently looks like:
#:for MUSCL_DIR, XYZ, X_BND, Y_BND, Z_BND in &
[(1, 'x', 'is_muscl%x', 'is_muscl%y', 'is_muscl%z'), &
(2, 'y', 'is_muscl%y', 'is_muscl%x', 'is_muscl%z'), &
(3, 'z', 'is_muscl%z', 'is_muscl%y', 'is_muscl%x')]
if (muscl_dir == ${MUSCL_DIR}$) then
! 50–200 lines of physics, repeated verbatim 3×
end if
#:endfor
Fypp generates three near-identical blocks at compile time. Any logic bug must be fixed in three places. Any new feature must be added three times.
What the struct consolidation unlocks
With the triplets now in structs, the direction-specific roles (primary, secondary, tertiary sweep axis) can be selected at runtime using associate or a value copy on the CPU path, or via a Fypp loop that expands to a single runtime select case on the GPU path:
! CPU initialization / finalize path — no GPU needed
associate(is_x => is_muscl%x, is_y => is_muscl%y, is_z => is_muscl%z)
select case (dir)
case (1); is_primary => is_muscl%x; ...
case (2); is_primary => is_muscl%y; ...
case (3); is_primary => is_muscl%z; ...
end select
end associate
For GPU kernel bodies, the Fypp #:for loop remains, but the loop body collapses from three separately maintained copies to one template — because the struct member names (%x, %y, %z) can be the Fypp iteration variable directly.
Concrete targets
| File |
Pattern |
Current lines |
Target |
m_muscl.fpp |
muscl_dir == 1/2/3 blocks for order-1 reconstruction |
~40 |
single block |
m_muscl.fpp |
muscl_dir == 1/2/3 in order-2 limiter body |
~60 |
single template |
m_cbc.fpp |
cbc_dir == 1/2/3 sweep dispatch |
~200 |
single sweep |
m_rhs.fpp |
norm_dir dispatch blocks |
~150 |
single block |
What this enables next
Once directional dispatch is unified, the per-direction allocation/initialization code can also collapse — s_initialize_muscl_module currently sets is_muscl%x/y/z in three separate guarded blocks; a loop over [is_muscl%x, is_muscl%y, is_muscl%z] with dimension limits [m, n, p] replaces all of it.
Related
Background
PR #1432 consolidated directional triplets across several modules into derived type instances with
%x/%y/%zcomponents (is_muscl,bc,bf,q_prim_rs, etc.). This is load-bearing groundwork for replacing the most prevalent code-duplication pattern in the simulation target.The pattern to eliminate
Nearly every directional sweep in
m_muscl.fpp,m_cbc.fpp,m_rhs.fpp, andm_riemann_solvers.fppcurrently looks like:Fypp generates three near-identical blocks at compile time. Any logic bug must be fixed in three places. Any new feature must be added three times.
What the struct consolidation unlocks
With the triplets now in structs, the direction-specific roles (primary, secondary, tertiary sweep axis) can be selected at runtime using
associateor a value copy on the CPU path, or via a Fypp loop that expands to a single runtimeselect caseon the GPU path:For GPU kernel bodies, the Fypp
#:forloop remains, but the loop body collapses from three separately maintained copies to one template — because the struct member names (%x,%y,%z) can be the Fypp iteration variable directly.Concrete targets
m_muscl.fppmuscl_dir == 1/2/3blocks for order-1 reconstructionm_muscl.fppmuscl_dir == 1/2/3in order-2 limiter bodym_cbc.fppcbc_dir == 1/2/3sweep dispatchm_rhs.fppnorm_dirdispatch blocksWhat this enables next
Once directional dispatch is unified, the per-direction allocation/initialization code can also collapse —
s_initialize_muscl_modulecurrently setsis_muscl%x/y/zin three separate guarded blocks; a loop over[is_muscl%x, is_muscl%y, is_muscl%z]with dimension limits[m, n, p]replaces all of it.Related
m_riemann_solvers: reduce duplication, improve structure, add schemes #1426 (Riemann solver directional refactor)