Skip to content

Fix numerical Schlieren for single fluid IGR + add case validation guard for schlieren_alpha#1477

Open
Cowsreal wants to merge 5 commits into
MFlowCode:masterfrom
Cowsreal:minorChanges
Open

Fix numerical Schlieren for single fluid IGR + add case validation guard for schlieren_alpha#1477
Cowsreal wants to merge 5 commits into
MFlowCode:masterfrom
Cowsreal:minorChanges

Conversation

@Cowsreal
Copy link
Copy Markdown
Contributor

@Cowsreal Cowsreal commented Jun 1, 2026

Description

For N fluids, IGR tracks the volume fraction of the first N-1 fluids. The part of the code in m_derived_variables.fpp in post-processing did not account for this and writes out a field of 1.0's instead.

A guard for schlieren_alpha is also necessary since schlieren_alpha(i) is set to dflt_real and the same result is seen if that's the case.

Type of change

  • Bug fix

Testing

After fix: (IGR, single fluid)

Screenshot 2026-06-01 at 09 49 51

Checklist

  • I updated documentation if user-facing behavior changed

AI code reviews

Reviews are not triggered automatically. To request a review, comment on the PR:

  • @coderabbitai review — incremental review (new changes only)
  • @coderabbitai full review — full review from scratch
  • /review — Qodo review
  • /improve — Qodo code suggestions
  • @claude full review — Claude full review (also triggers on PR open/reopen/ready)
  • Add label claude-full-review — Claude full review via label

@Cowsreal Cowsreal requested a review from sbryngelson as a code owner June 1, 2026 15:53
Copy link
Copy Markdown
Member

@sbryngelson sbryngelson left a comment

Choose a reason for hiding this comment

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

Careful review — this is a clean, correct bug fix. I verified the core logic:

  • Index math (m_derived_variables.fpp:501–513): for IGR, eqn_idx%adv%end − eqn_idx%E = num_fluids − 1, so the loop covers schlieren_alpha(1..N−1) and the new term correctly applies schlieren_alpha(num_fluids) to the reconstructed alpha_last = 1 − Σαᵢ. This reproduces exactly what the non-IGR branch computes.
  • The if (igr) term lives inside the model_eqns /= 1 branch and IGR only exists under model_eqns == 2, so non-IGR paths are untouched.
  • Validator default schlieren_alpha = dflt_real (−1e6) confirmed, so the new "must be set" guard is well justified, and the if/else restructure preserves both original prohibits.
  • No regressions: all example cases touching schlieren (2D_IGR_triple_point, 2D_triple_point) set every schlieren_alpha; no golden/test cases generate schlieren.

Only minor, non-blocking notes inline (a comment typo, a loop-invariant branch, and an edge-config suggestion). LGTM once the typo is fixed.

end do

! IGR stores only num_fluids-1 volume fractions; the last fluid's volume fraction is untracked.
! For a single fluid this is simply 1.0 everywhere. Without this term, the entire single-fluid
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nit: stray closing paren in "the entire single-fluid Schlieren field)" — should be "the entire single-fluid Schlieren field".

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Will fix.

! IGR stores only num_fluids-1 volume fractions; the last fluid's volume fraction is untracked.
! For a single fluid this is simply 1.0 everywhere. Without this term, the entire single-fluid
! Schlieren field) is dropped, leaving exp(0) = 1 everywhere. Compute that term below.
if (igr) then
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Optional (efficiency/clarity): both if (igr) checks (here and the one inside the i loop at line 504) test a loop-invariant flag evaluated on every (j,k,l) cell. Since igr is constant for the whole run, you could hoist the IGR/non-IGR split outside the triple loop — e.g. keep the inner alpha_last accumulation only when igr, or branch once above the loops. Negligible cost in post-processing, so not blocking, just a readability note.

Also note this new term divides by gm_rho_max(1), which is 0 for a perfectly uniform density field — the same pre-existing risk as line 502, so no regression, just flagging.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Will fix.

if schlieren_alpha is not None:
if schlieren_alpha is None:
self.prohibit(
schlieren_wrt and model_eqns is not None and model_eqns != 1,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The guard correctly excludes model_eqns == 1, which matches the Fortran (the model_eqns == 1 branch never uses schlieren_alpha). One edge case to consider: IGR's adv-index layout is only set up under model_eqns == 2 (m_global_parameters.fpp), but nothing forbids igr = T with model_eqns ∈ {3,4}. In that (unsupported) combo the new if (igr) term in m_derived_variables.fpp would double-count the last fluid. IGR is fundamentally a model_eqns == 2 feature and would likely fail elsewhere, so this is theoretical — but a belt-and-suspenders self.prohibit(igr and model_eqns is not None and model_eqns != 2, ...) in check_igr would make the assumption explicit.

Minor: if model_eqns is unset (None), the guard won't fire even with schlieren_wrt on; fine in practice since model_eqns is virtually always specified.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Irrelevant, IGR is blocked to run for model_eqn /= 2

Copy link
Copy Markdown
Member

@sbryngelson sbryngelson left a comment

Choose a reason for hiding this comment

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

Requesting changes to track the follow-ups from the inline review. The core fix is correct (IGR index math reproduces the non-IGR result exactly, and the validator default dflt_real justifies the new guard), so these are small:

Please address before merge:

  1. Fix the comment typo at m_derived_variables.fpp:510 — stray closing paren in "Schlieren field)".

Optional (fine to defer or wave off):
2. Hoist the loop-invariant if (igr) branch out of the (j,k,l) triple loop in m_derived_variables.fpp (readability only).
3. Consider an explicit igr ⇒ model_eqns == 2 guard in check_igr so the new if (igr) Schlieren term can't double-count under an unsupported model_eqns ∈ {3,4} config.

See inline comments for details. Happy to approve once (1) is in.

@sbryngelson
Copy link
Copy Markdown
Member

Reviewed this carefully — nice catch on the single-fluid IGR Schlieren bug. The fix is correct: under IGR the loop covers schlieren_alpha(1..N−1) and the added term correctly applies schlieren_alpha(num_fluids) to the reconstructed last fluid (alpha_last = 1 − Σαᵢ), which reproduces exactly what the non-IGR branch computes. The case-validator guard is well justified since schlieren_alpha defaults to dflt_real (−1e6), and no example/golden cases regress.

I've left a few small inline notes (one comment typo to fix, plus a couple of optional hardening/readability suggestions) and marked the review as Request Changes just to track the typo. Everything else is non-blocking — happy to approve once that's addressed.

@codecov
Copy link
Copy Markdown

codecov Bot commented Jun 1, 2026

Codecov Report

❌ Patch coverage is 0% with 8 lines in your changes missing coverage. Please review.
✅ Project coverage is 60.63%. Comparing base (08d12f8) to head (76be6a6).
⚠️ Report is 1 commits behind head on master.

Files with missing lines Patch % Lines
src/post_process/m_derived_variables.fpp 0.00% 8 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #1477      +/-   ##
==========================================
- Coverage   60.64%   60.63%   -0.02%     
==========================================
  Files          73       73              
  Lines       20213    20219       +6     
  Branches     2936     2937       +1     
==========================================
  Hits        12259    12259              
- Misses       5966     5972       +6     
  Partials     1988     1988              

☔ View full report in Codecov by Sentry.
📢 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.

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