Skip to content

Operator-split integration for the condensed-phase reactive burn - #1831

Merged
sbryngelson merged 3 commits into
MFlowCode:masterfrom
sbryngelson:feat/reactive-burn-substeps
Sep 7, 2026
Merged

Operator-split integration for the condensed-phase reactive burn#1831
sbryngelson merged 3 commits into
MFlowCode:masterfrom
sbryngelson:feat/reactive-burn-substeps

Conversation

@sbryngelson

Copy link
Copy Markdown
Member

Added to the flow RHS, the condensed-phase burn ties the reaction time scale to the acoustic CFL: a fast burn forces a smaller step for the entire simulation, even where nothing is reacting.

This adds rburn%substeps. Above zero, the flow is frozen and the burn ODE is integrated across the step in equal sub-steps, with the mixture pressure re-evaluated from the frozen internal energy each sub-step so the rate feels its own feedback as reactant becomes product. rburn%substeps = 0 is the default and leaves the source in the flow RHS exactly as before.

Two details worth review:

  • Completion. A sub-step longer than the reaction time would carry the progress variable past one. It stops at one and hands over the reactant's remaining mass in the same sub-step. Capping the volume-fraction and mass increments independently strands reactant mass at zero reactant volume, and the mixture EOS divides one by the other.
  • One rate law. s_burn_rate now states the pressure drive, the (1 - lambda) factor and the optional Arrhenius term once; both integrators call it. Previously the new path would have carried a second copy that had to stay in step forever.

Testing

  • 1D -> Reactive Burn -> Condensed Programmed Detonation -> substeps (86893F55), substeps = 10 on 2 ranks. Two ranks deliberately: substeps is the only integer among the rburn members, and the broadcast kind is now registry-driven, so a wrong kind leaves rank 1 sub-stepping a garbage count — invisible to a single-rank golden.
  • The new golden differs from the RHS-path golden in 45.5% of values, largest relative difference 3.2e-3 in the progress variable, so the case exercises the split integrator rather than reproducing the old answer.
  • The four existing reactive-burn goldens pass unchanged on both CPU and GPU, confirming the rate-law extraction altered no behaviour.

…ubsteps > 0

Added to the flow RHS, the burn ties the reaction time scale to the acoustic CFL: a fast burn forces a smaller step for the whole simulation. With rburn%substeps > 0 the flow is frozen and the ODE is integrated over the step in equal sub-steps, re-evaluating the mixture pressure from the frozen internal energy each one so the rate feels the coefficients moving as reactant becomes product. rburn%substeps = 0, the default, keeps the source in the RHS unchanged. Completing a sub-step hands over the reactant's remaining mass along with the last of its volume fraction; capping the two separately strands mass at zero volume, which the EOS then divides by. The rate law is now stated once and called by both integrators.
Copilot AI lite review requested due to automatic review settings September 6, 2026 00:29

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Warning

Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.

Pull request overview

Adds an operator-split path for condensed-phase reactive burn by introducing rburn%substeps, allowing the burn ODE to be integrated in post-flow substeps so fast chemistry doesn’t globally constrain the acoustic CFL time step.

Changes:

  • Register/validate new parameter rburn%substeps and ensure its MPI broadcast uses the correct MPI datatype (integer vs real).
  • Integrate reactive burn via operator splitting after the flow update when rburn%substeps > 0, leaving the existing RHS source path for substeps == 0.
  • Add a new 2-rank golden test case to exercise the new substepping path and catch broadcast-kind issues.

Reviewed changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
toolchain/mfc/test/cases.py Adds a new reactive-burn test case with rburn%substeps=10 on 2 MPI ranks.
toolchain/mfc/params/generators/fortran_gen.py Updates generated MPI_BCAST code to pick MPI type per rburn member (supports new INT member).
toolchain/mfc/params/definitions.py Registers rburn%substeps as an INT reactive-burn parameter.
toolchain/mfc/case_validator.py Validates rburn%substeps >= 0 with an explanatory error message.
src/simulation/m_time_steppers.fpp Calls s_reactive_burn_substep after the flow update when substeps > 0.
src/simulation/m_rhs.fpp Skips adding burn source to RHS when substeps > 0 (operator-split path instead).
src/simulation/m_reactive_burn.fpp Factors out s_burn_rate and implements operator-split substep integrator.
src/common/m_global_parameters_common.fpp Initializes rburn%substeps default to 0.
src/common/m_derived_types.fpp Extends reactive burn parameter type with integer substeps.
tests/86893F55/golden.txt Adds new golden outputs for the new substepping test case.
tests/86893F55/golden-metadata.txt Adds metadata for the new golden generation.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/simulation/m_reactive_burn.fpp Outdated
alpha_rho(i) = q_cons_vf(i + eqn_idx%cont%beg - 1)%sf(x, y, z)
alpha(i) = q_cons_vf(i + eqn_idx%adv%beg - 1)%sf(x, y, z)
end do
rho = alpha_rho(1) + alpha_rho(2)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The second alternative already holds: case_validator.py:1932 enforces reactive_burn requires num_fluids = 2 (reactant then product), so fluids 1 and 2 are the whole mixture here. s_compute_reactive_burn computes rho the same way for the same reason. Leaving as is.

Comment thread toolchain/mfc/case_validator.py
Completing a sub-step drives the reactant volume fraction to exactly zero, and the lambda >= 1 test only covers the same iteration if the volume fractions still sum to one, which the six-equation model does not guarantee. Use the max(alpha, sgm_eps) form the Riemann solvers already use for this.
@codecov

codecov Bot commented Sep 6, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 84.44444% with 7 lines in your changes missing coverage. Please review.
✅ Project coverage is 62.35%. Comparing base (70589fd) to head (7b42ba5).

Files with missing lines Patch % Lines
src/simulation/m_reactive_burn.fpp 82.05% 2 Missing and 5 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #1831      +/-   ##
==========================================
+ Coverage   62.30%   62.35%   +0.04%     
==========================================
  Files          84       84              
  Lines       21583    21621      +38     
  Branches     3195     3199       +4     
==========================================
+ Hits        13448    13482      +34     
- Misses       5937     5939       +2     
- Partials     2198     2200       +2     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Under case optimization num_fluids is a compile-time constant, and the Case Opt lanes build cases that set it to one, where the literal reactant and product indices are then out of bounds and the compile fails. num_fluids_max is a parameter and always covers both, so the arrays no longer need the case-optimization and AMD split either.
@github-actions

github-actions Bot commented Sep 6, 2026

Copy link
Copy Markdown

Lines of Code

File Lines Diff
src/simulation/m_reactive_burn.fpp 107 +66
src/simulation/m_time_steppers.fpp 833 +6
src/common/m_derived_types.fpp 441 +1
src/common/m_global_parameters_common.fpp 240 +1
Directory Lines Diff
common 9948 +2
simulation 27740 +72
total 45545 +74

@sbryngelson
sbryngelson merged commit 926a3a5 into MFlowCode:master Sep 7, 2026
86 checks passed
@sbryngelson
sbryngelson deleted the feat/reactive-burn-substeps branch September 7, 2026 15:00
sbryngelson added a commit to sbryngelson/MFC that referenced this pull request Sep 7, 2026
m_reactive_burn.fpp: master (MFlowCode#1831) factored the rate law into s_burn_rate for the operator-split integrator; this branch had replaced the hardcoded stiffened-gas Arrhenius temperature with s_phase_temperature. Kept s_burn_rate and moved the s_phase_temperature call inside it, so both the RHS source and the substep integrator get the state-dependent EOS temperature.

m_riemann_solver_hllc.fpp: both sides added c_sum_Yi_Phi to the pure-fluid private list; master (MFlowCode#1823) did it by restructuring into _hllc_s*/_hllc_e*. Took master's version, which already carries the fix.

Claude-Session: https://claude.ai/code/session_01G77jhrA4JPDz5TqJzt8ACC
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants