Summary
model_eqns = 1 (the Γ/Π∞ model) is documented and accepted by the case validator, and pre_process / post_process implement it, but simulation has no working path for it. A gamma-law case run through simulation computes rho = gamma = pi_inf = 0 in the conversion and Riemann layers.
This is pre-existing on master. Filing after an audit of the whole branch; nothing here is introduced by an open PR.
Why it fails
For model_eqns = 1 the state vector carries gamma and pi_inf as transported variables (m_global_parameters_common.fpp:115):
eqn_idx%cont%beg = 1; eqn_idx%cont%end = 1 ! single density
eqn_idx%mom%beg = 2; eqn_idx%mom%end = 1 + num_vels
eqn_idx%E = mom%end + 1
eqn_idx%adv%beg = E + 1 ! = eqn_idx%gamma
eqn_idx%adv%end = adv%beg + 1 ! = eqn_idx%pi_inf
sys_size = adv%end
Correct conversion is therefore a direct read (s_convert_mixture_to_mixture_variables), not the volume-fraction sum used by the other models.
case_validator.py:355 prohibits setting num_fluids when model_eqns == 1, so a valid case never supplies it. pre_process and post_process compensate:
src/pre_process/m_global_parameters.fpp:441 — if (model_eqns == model_eqns_gamma_law) num_fluids = 1
src/post_process/m_global_parameters.fpp:326 — same
simulation has no equivalent, so num_fluids stays at dflt_int = -100. Consequences in simulation:
s_compute_species_fraction declares alpha_rho_K(num_fluids) / alpha_K(num_fluids) — zero-size arrays.
- Every
do i = 1, num_fluids accumulation loop is empty, so rho_K, gamma_K, pi_inf_K, qv_K stay 0.
s_accumulate_mixture_properties (m_riemann_state.fpp:1015, called from m_riemann_solver_hll.fpp:202-203 and m_riemann_solver_lf.fpp:197-198) returns zeros for both Riemann states.
Forcing num_fluids = 1 alone is necessary but not sufficient. With it, s_compute_species_fraction takes its num_fluids == 1 branch and sets alpha_K(1) = q_vf(eqn_idx%adv%beg) — which for gamma-law is the transported gamma, not a volume fraction. The kernel then computes gamma_K = alpha_K(1)*gammas(1) and pi_inf_K = alpha_K(1)*pi_infs(1), i.e. the transported gamma scaled by fluid_pp-derived constants.
What is missing in simulation
num_fluids = 1 for gamma-law — the one-line gap that pre_process and post_process both close.
- A gamma-law branch in the conversion layer.
s_convert_conservative_to_primitive_variables (m_variables_conversion.fpp:~473) guards only model_eqns /= model_eqns_4eq, so gamma-law reaches the species kernel. s_convert_species_to_mixture_variables_kernel has no gamma-law case, and it is a GPU_ROUTINE, so the device path needs one too.
- A gamma-law branch in
s_convert_primitive_to_flux_variables, which also calls the species kernel unconditionally.
- A gamma-law branch in the Riemann states.
s_accumulate_mixture_properties must read gamma/pi_inf from the state vector instead of summing over fluids.
- Any test or example. No case in
tests/ or examples/ sets model_eqns = 1, which is why this has never surfaced.
Partial support that already exists
The endpoints were clearly intended to work, which is what makes the gap easy to miss:
src/simulation/m_global_parameters.fpp:778 — skips Re_idx setup for gamma-law
src/simulation/m_cbc.fpp:836 — has an explicit gamma-law case
src/pre_process/m_check_patches.fpp:476-480 — validates patch rho/gamma/pi_inf for gamma-law
src/post_process/{m_start_up,m_data_output,m_derived_variables}.fpp — write gamma/pi_inf output
src/common/m_variables_conversion.fpp:62 — the host dispatcher already routes gamma-law correctly
So pre_process can build a gamma-law initial condition and post_process can render it; only the solver in between is missing.
Suggested resolution
Either:
(a) Implement it — add num_fluids = 1 in simulation, plus gamma-law cases in the conversion kernel (host and device), s_convert_primitive_to_flux_variables, and s_accumulate_mixture_properties; add a 1D regression case.
(b) Reject it — have case_validator.py prohibit model_eqns = 1 for simulation, and mark it pre/post-only in docs/documentation/case.md:492,567-568, which currently presents it as a supported model on equal footing with 2 and 3.
Option (b) is much cheaper and matches the current reality; option (a) is only worth it if the Γ/Π∞ solver is actually wanted.
Note for reviewers of #1679
That PR changes the conversion guard from #ifdef MFC_SIMULATION to #ifdef MFC_GPU, so a CPU simulation build now reaches the correct host dispatcher for gamma-law while a GPU build still takes the species kernel. It does not introduce the bug, but it does make it asymmetric between CPU and GPU, which is worth resolving deliberately.
Summary
model_eqns = 1(the Γ/Π∞ model) is documented and accepted by the case validator, andpre_process/post_processimplement it, butsimulationhas no working path for it. A gamma-law case run throughsimulationcomputesrho = gamma = pi_inf = 0in the conversion and Riemann layers.This is pre-existing on
master. Filing after an audit of the whole branch; nothing here is introduced by an open PR.Why it fails
For
model_eqns = 1the state vector carriesgammaandpi_infas transported variables (m_global_parameters_common.fpp:115):Correct conversion is therefore a direct read (
s_convert_mixture_to_mixture_variables), not the volume-fraction sum used by the other models.case_validator.py:355prohibits settingnum_fluidswhenmodel_eqns == 1, so a valid case never supplies it.pre_processandpost_processcompensate:src/pre_process/m_global_parameters.fpp:441—if (model_eqns == model_eqns_gamma_law) num_fluids = 1src/post_process/m_global_parameters.fpp:326— samesimulationhas no equivalent, sonum_fluidsstays atdflt_int = -100. Consequences insimulation:s_compute_species_fractiondeclaresalpha_rho_K(num_fluids)/alpha_K(num_fluids)— zero-size arrays.do i = 1, num_fluidsaccumulation loop is empty, sorho_K,gamma_K,pi_inf_K,qv_Kstay0.s_accumulate_mixture_properties(m_riemann_state.fpp:1015, called fromm_riemann_solver_hll.fpp:202-203andm_riemann_solver_lf.fpp:197-198) returns zeros for both Riemann states.Forcing
num_fluids = 1alone is necessary but not sufficient. With it,s_compute_species_fractiontakes itsnum_fluids == 1branch and setsalpha_K(1) = q_vf(eqn_idx%adv%beg)— which for gamma-law is the transported gamma, not a volume fraction. The kernel then computesgamma_K = alpha_K(1)*gammas(1)andpi_inf_K = alpha_K(1)*pi_infs(1), i.e. the transported gamma scaled byfluid_pp-derived constants.What is missing in
simulationnum_fluids = 1for gamma-law — the one-line gap thatpre_processandpost_processboth close.s_convert_conservative_to_primitive_variables(m_variables_conversion.fpp:~473) guards onlymodel_eqns /= model_eqns_4eq, so gamma-law reaches the species kernel.s_convert_species_to_mixture_variables_kernelhas no gamma-law case, and it is aGPU_ROUTINE, so the device path needs one too.s_convert_primitive_to_flux_variables, which also calls the species kernel unconditionally.s_accumulate_mixture_propertiesmust readgamma/pi_inffrom the state vector instead of summing over fluids.tests/orexamples/setsmodel_eqns = 1, which is why this has never surfaced.Partial support that already exists
The endpoints were clearly intended to work, which is what makes the gap easy to miss:
src/simulation/m_global_parameters.fpp:778— skipsRe_idxsetup for gamma-lawsrc/simulation/m_cbc.fpp:836— has an explicit gamma-law casesrc/pre_process/m_check_patches.fpp:476-480— validates patchrho/gamma/pi_inffor gamma-lawsrc/post_process/{m_start_up,m_data_output,m_derived_variables}.fpp— writegamma/pi_infoutputsrc/common/m_variables_conversion.fpp:62— the host dispatcher already routes gamma-law correctlySo
pre_processcan build a gamma-law initial condition andpost_processcan render it; only the solver in between is missing.Suggested resolution
Either:
(a) Implement it — add
num_fluids = 1in simulation, plus gamma-law cases in the conversion kernel (host and device),s_convert_primitive_to_flux_variables, ands_accumulate_mixture_properties; add a 1D regression case.(b) Reject it — have
case_validator.pyprohibitmodel_eqns = 1forsimulation, and mark it pre/post-only indocs/documentation/case.md:492,567-568, which currently presents it as a supported model on equal footing with 2 and 3.Option (b) is much cheaper and matches the current reality; option (a) is only worth it if the Γ/Π∞ solver is actually wanted.
Note for reviewers of #1679
That PR changes the conversion guard from
#ifdef MFC_SIMULATIONto#ifdef MFC_GPU, so a CPU simulation build now reaches the correct host dispatcher for gamma-law while a GPU build still takes the species kernel. It does not introduce the bug, but it does make it asymmetric between CPU and GPU, which is worth resolving deliberately.