Fix MUSCL THINC right-state using already-overwritten left-state values#1181
Fix MUSCL THINC right-state using already-overwritten left-state values#1181sbryngelson wants to merge 8 commits intoMFlowCode:masterfrom
Conversation
Nitpicks 🔍
|
There was a problem hiding this comment.
Pull request overview
Fixes MUSCL-THINC right-state reconstruction by preserving pre-overwrite density ratios from the left state and reusing them for both left and right reconstructions.
Changes:
- Save pre-reconstruction density ratios (
rho_b,rho_e) before THINC overwritesvL_rs_vf_*values. - Update left/right reconstructions to use the saved ratios instead of dividing by potentially overwritten left-state fields.
afa042e to
66a6a8c
Compare
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #1181 +/- ##
=======================================
Coverage 44.05% 44.06%
=======================================
Files 70 70
Lines 20496 20494 -2
Branches 1989 1989
=======================================
Hits 9030 9030
+ Misses 10328 10326 -2
Partials 1138 1138 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/simulation/m_muscl.fpp`:
- Around line 250-256: The GPU parallel loop's private clause for the MUSCL
reconstruction is missing scalars A, B, and C which leads to cross-thread data
races; update the private list in the GPU_PARALLEL_LOOP invocation (the clause
currently listing j,k,l,aCL,aC,aCR,aTHINC,moncon,sign,qmin,qmax,rho_b,rho_e) to
also include A, B, and C so that the loop-local temporaries A, B, C used in the
MUSCL/THINC computation are private per thread (look for the muscl_dir
conditional and the GPU_PARALLEL_LOOP macro surrounding the loop body where
A/B/C are assigned and used).
- Around line 282-284: Guard against near-zero denominators when computing rho_b
and rho_e by clamping or early-checking the MUSCL-reconstructed state
vL_rs_vf_${XYZ}$ (j,k,l,advxb) using the existing sgm_eps (or ic_eps) tolerance:
ensure advxb is not below sgm_eps before dividing for rho_b and ensure (1 -
advxb) is not below sgm_eps before dividing for rho_e; if either check fails,
use a safe fallback (e.g., set rho_b/rho_e to a clipped value or the
cell-average aC) so that rho_b, rho_e computations in this block cannot produce
NaN/Inf.
9992699 to
ac18720
Compare
f6e0b83 to
34c2a78
Compare
There was a problem hiding this comment.
♻️ Duplicate comments (1)
src/simulation/m_muscl.fpp (1)
282-301:⚠️ Potential issue | 🟡 MinorGuard
rho_b/rho_edenominators against near-zero reconstructedadvxb.Even with the
aCgate, the reconstructedadvxbcan be pushed to 0 or 1, yielding divide-by-zero/Inf inrho_b/rho_e. Clamp withsgm_epsbefore division.🛡️ Proposed fix
- rho_b = vL_rs_vf_${XYZ}$ (j, k, l, contxb)/vL_rs_vf_${XYZ}$ (j, k, l, advxb) - rho_e = vL_rs_vf_${XYZ}$ (j, k, l, contxe)/(1._wp - vL_rs_vf_${XYZ}$ (j, k, l, advxb)) + rho_b = vL_rs_vf_${XYZ}$ (j, k, l, contxb)/ & + max(vL_rs_vf_${XYZ}$ (j, k, l, advxb), sgm_eps) + rho_e = vL_rs_vf_${XYZ}$ (j, k, l, contxe)/ & + max(1._wp - vL_rs_vf_${XYZ}$ (j, k, l, advxb), sgm_eps)🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/simulation/m_muscl.fpp` around lines 282 - 301, The division that computes rho_b and rho_e can hit divide-by-zero when the reconstructed advxb/advxe are exactly 0 or 1; before computing rho_b = vL_rs_vf_${XYZ}(...,contxb)/vL_rs_vf_${XYZ}(...,advxb) and rho_e = vL_rs_vf_${XYZ}(...,contxe)/(1._wp - vL_rs_vf_${XYZ}(...,advxb)), clamp the denominators with sgm_eps (or a similar small threshold) to ensure they are at least sgm_eps (e.g. denom_b = max(vL_rs_vf_${XYZ}(...,advxb), sgm_eps); denom_e = max(1._wp - vL_rs_vf_${XYZ}(...,advxb), sgm_eps)) and then use denom_b/denom_e in place of the raw denominator so subsequent assignments to vL_rs_vf_${XYZ} and vR_rs_vf_${XYZ} (contxb, contxe, advxb, advxe) never produce Inf or NaN.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Duplicate comments:
In `@src/simulation/m_muscl.fpp`:
- Around line 282-301: The division that computes rho_b and rho_e can hit
divide-by-zero when the reconstructed advxb/advxe are exactly 0 or 1; before
computing rho_b = vL_rs_vf_${XYZ}(...,contxb)/vL_rs_vf_${XYZ}(...,advxb) and
rho_e = vL_rs_vf_${XYZ}(...,contxe)/(1._wp - vL_rs_vf_${XYZ}(...,advxb)), clamp
the denominators with sgm_eps (or a similar small threshold) to ensure they are
at least sgm_eps (e.g. denom_b = max(vL_rs_vf_${XYZ}(...,advxb), sgm_eps);
denom_e = max(1._wp - vL_rs_vf_${XYZ}(...,advxb), sgm_eps)) and then use
denom_b/denom_e in place of the raw denominator so subsequent assignments to
vL_rs_vf_${XYZ} and vR_rs_vf_${XYZ} (contxb, contxe, advxb, advxe) never produce
Inf or NaN.
34c2a78 to
8cada11
Compare
There was a problem hiding this comment.
♻️ Duplicate comments (1)
src/simulation/m_muscl.fpp (1)
282-284:⚠️ Potential issue | 🟡 MinorNear-zero denominator guard still missing on
rho_b/rho_eThe outer guard checks the cell-average
aC(fromv_rs_ws_*_muscl), but the denominators on lines 283–284 use the MUSCL-reconstructed left statevL_rs_vf_${XYZ}$(j,k,l,advxb), which can legitimately be smaller thanic_eps(or1 - advxb < ic_eps) when a neighbouring cell is nearly pure (TVD limiters allow the face value to reach the neighbour average). The existingsgm_epsin line 278 covers the same risk pattern; applying it here is consistent.🛡️ Proposed fix
- rho_b = vL_rs_vf_${XYZ}$ (j, k, l, contxb)/vL_rs_vf_${XYZ}$ (j, k, l, advxb) - rho_e = vL_rs_vf_${XYZ}$ (j, k, l, contxe)/(1._wp - vL_rs_vf_${XYZ}$ (j, k, l, advxb)) + rho_b = vL_rs_vf_${XYZ}$ (j, k, l, contxb)/ & + max(vL_rs_vf_${XYZ}$ (j, k, l, advxb), sgm_eps) + rho_e = vL_rs_vf_${XYZ}$ (j, k, l, contxe)/ & + max(1._wp - vL_rs_vf_${XYZ}$ (j, k, l, advxb), sgm_eps)🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/simulation/m_muscl.fpp` around lines 282 - 284, The division for rho_b and rho_e uses the MUSCL-reconstructed face value vL_rs_vf_${XYZ}(j,k,l,advxb) which can be near zero or near one; add the same sgm_eps safeguard used earlier (e.g., max(vL_rs_vf_${XYZ}(...,advxb), sgm_eps) and max(1._wp - vL_rs_vf_${XYZ}(...,advxb), sgm_eps)) so rho_b = vL_rs_vf_${XYZ}(j,k,l,contxb)/max(vL_rs_vf_${XYZ}(j,k,l,advxb), sgm_eps) and rho_e = vL_rs_vf_${XYZ}(j,k,l,contxe)/max(1._wp - vL_rs_vf_${XYZ}(j,k,l,advxb), sgm_eps); keep other logic and naming unchanged (references: rho_b, rho_e, sgm_eps, vL_rs_vf_${XYZ}).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Duplicate comments:
In `@src/simulation/m_muscl.fpp`:
- Around line 282-284: The division for rho_b and rho_e uses the
MUSCL-reconstructed face value vL_rs_vf_${XYZ}(j,k,l,advxb) which can be near
zero or near one; add the same sgm_eps safeguard used earlier (e.g.,
max(vL_rs_vf_${XYZ}(...,advxb), sgm_eps) and max(1._wp -
vL_rs_vf_${XYZ}(...,advxb), sgm_eps)) so rho_b =
vL_rs_vf_${XYZ}(j,k,l,contxb)/max(vL_rs_vf_${XYZ}(j,k,l,advxb), sgm_eps) and
rho_e = vL_rs_vf_${XYZ}(j,k,l,contxe)/max(1._wp - vL_rs_vf_${XYZ}(j,k,l,advxb),
sgm_eps); keep other logic and naming unchanged (references: rho_b, rho_e,
sgm_eps, vL_rs_vf_${XYZ}).
The right reconstruction divides by left-state values that were already overwritten during left reconstruction. Save original density ratios (contxb/advxb and contxe/(1-advxb)) before left reconstruction and reuse them for both left and right states. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Claude Code ReviewHead SHA: Summary
Findings1.
2. PR description claims divide-by-zero guards were added, but none appear in the diff The description states:
The actual diff has no such guards: rho_b = vL_rs_vf_${XYZ}$ (j, k, l, contxb)/vL_rs_vf_${XYZ}$ (j, k, l, advxb)
rho_e = vL_rs_vf_${XYZ}$ (j, k, l, contxe)/(1._wp - vL_rs_vf_${XYZ}$ (j, k, l, advxb))If the cell-center 3. Mathematical equivalence confirmation (informational) The original right-state code accidentally cancelled correctly: The cancellation holds for VerdictThe core refactor is sound and improves readability and GPU safety. The GPU private-list fix for |
User description
Summary
Severity: HIGH — right-state reconstruction uses overwritten left-state values.
File:
src/simulation/m_muscl.fpp, lines 285-301In the MUSCL-THINC interface reconstruction, the left-state values (
vL_rs_vfforcontxb,contxe, andadvxb) are overwritten during left reconstruction. The right-state reconstruction then divides by these already-overwritten values instead of the original cell-center values. While the math accidentally cancels (left THINC value / left THINC value = original ratio), this relies on exact cancellation and is fragile.Before
After
Why this went undetected
The algebraic cancellation makes this produce correct results in most cases. The refactor makes the intent explicit and eliminates dependence on accidental algebraic cancellation.
Test plan
🤖 Generated with Claude Code
Fixes #1200
Summary by CodeRabbit
CodeAnt-AI Description
Fix MUSCL-THINC using original density ratios for both left and right reconstructions
What Changed
Impact
✅ Fewer incorrect interface reconstructions✅ Fewer simulation crashes from divide-by-zero at interfaces✅ Fewer GPU data races during parallel reconstruction💡 Usage Guide
Checking Your Pull Request
Every time you make a pull request, our system automatically looks through it. We check for security issues, mistakes in how you're setting up your infrastructure, and common code problems. We do this to make sure your changes are solid and won't cause any trouble later.
Talking to CodeAnt AI
Got a question or need a hand with something in your pull request? You can easily get in touch with CodeAnt AI right here. Just type the following in a comment on your pull request, and replace "Your question here" with whatever you want to ask:
This lets you have a chat with CodeAnt AI about your pull request, making it easier to understand and improve your code.
Example
Preserve Org Learnings with CodeAnt
You can record team preferences so CodeAnt AI applies them in future reviews. Reply directly to the specific CodeAnt AI suggestion (in the same thread) and replace "Your feedback here" with your input:
This helps CodeAnt AI learn and adapt to your team's coding style and standards.
Example
Retrigger review
Ask CodeAnt AI to review the PR again, by typing:
Check Your Repository Health
To analyze the health of your code repository, visit our dashboard at https://app.codeant.ai. This tool helps you identify potential issues and areas for improvement in your codebase, ensuring your repository maintains high standards of code health.