Skip to content

MTHINC#1303

Open
wilfonba wants to merge 14 commits intoMFlowCode:masterfrom
wilfonba:MTHINC
Open

MTHINC#1303
wilfonba wants to merge 14 commits intoMFlowCode:masterfrom
wilfonba:MTHINC

Conversation

@wilfonba
Copy link
Copy Markdown
Contributor

@wilfonba wilfonba commented Mar 12, 2026

Description

This PR adds MTHINC to the code base and fixes the THINC bug in #1181. The existing golden files for THINC interface compression were preserved, and new golden files and tests were created for MTHINC.

Type of change

  • New feature

Testing

3D advection case with and without MTHINC.

test.mp4

2D advection with int_comp = 1 (THINC) 1 rank vs. 4 rank. Results are identical

test.mp4

2D advection with int_comp = 2 (MTHINC) 1 rank vs. 4 rank. Results are identical

test.mp4

3D advection with int_comp = 2 (MTHINC) 1 rank vs. 8 rank. Results are identical

I didn't bother making a video for this one, but the output was identical when compared in ParaView.

Performance tests in 3D

The following results are grind times for a 200^3 advection case run on 1 A100 with OpenACC. The overhead for MTHINC is ~3% while the overhead for THINC is ~1%. The grind times are:
(Updated 4/1/2026 after removing parameter from constants in m_thinc.fpp

  • int_comp = 0: 0.87488 (No compression, baseline)
  • int_comp = 1: 0.88406 (1%) (THINC compression)
  • int_comp = 2: 0.90199 (3%) (MTHINC compression)

--nsys results with int_comp = 2

This is the run time contribution for just the MTHINC routines.

Time (%) Total Time (ns) Instances Avg (ns) Med (ns) Min (ns) Max (ns) StdDev (ns) Name


  1.3       75,807,250         75   1,010,763.3   1,028,360.0     183,969   1,159,626    118,287.9  m_thinc_s_compute_mthinc_normals_253_gpu 
  0.5       26,689,214         75     355,856.2     355,779.0     354,243     357,475        582.9  m_thinc_s_compute_mthinc_normals_228_gpu                                               
  0.3       19,284,544         75     257,127.3     257,666.0     229,922     259,746      3,433.0  m_thinc_s_thinc_compression_316_gpu__1                                                 
  0.3       19,228,227         75     256,376.4     256,931.0     229,282     258,531      3,376.6  m_thinc_s_thinc_compression_316_gpu                                                    
  0.3       19,204,612         75     256,061.5     256,354.0     229,890     258,786      3,361.1  m_thinc_s_thinc_compression_316_gpu__2 

Checklist

  • I added or updated tests for new behavior
  • I updated documentation if user-facing behavior changed

See the developer guide for full coding standards.

GPU changes (expand if you modified src/simulation/)
  • GPU results match CPU results
  • Tested on NVIDIA GPU or AMD GPU

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

@github-actions
Copy link
Copy Markdown

Claude Code Review

Head SHA: 202d7da
Files changed: 81 (key source files: m_thinc.fpp [new, +499], m_muscl.fpp [-86], m_rhs.fpp [+22], m_weno.fpp [-8], m_global_parameters.fpp, m_mpi_proxy.fpp, m_start_up.fpp, toolchain/mfc/params/definitions.py, toolchain/mfc/case_validator.py, toolchain/mfc/test/cases.py)


Summary

  • Adds a new m_thinc.fpp module implementing both THINC (1D hyperbolic tangent, existing) and MTHINC (multi-dimensional, new), consolidating what was previously split between m_muscl.fpp and m_weno.fpp
  • Promotes int_comp from logical to integer (0=off, 1=THINC, 2=MTHINC) — a breaking type change for existing users
  • Fixes a pre-existing THINC bug (Fix MUSCL THINC right-state using already-overwritten left-state values #1181) where the right-reconstruction density ratios used already-overwritten left-reconstruction values; new code pre-saves rho_b/rho_e before any write
  • Moves compression call from s_weno/s_muscl to the shared s_reconstruct_cell_boundary_values in m_rhs.fpp, enabling THINC/MTHINC with any reconstruction type
  • MTHINC normals are pre-computed once per timestep in s_compute_mthinc_normals before the dimensional splitting loop — correct design

Findings

[HIGH] Missing Fortran-side runtime validation for int_comp
m_checker.fpp / m_checker_common.fpp have no @:PROHIBIT guard for invalid int_comp values or for int_comp=2 with 1D (n=0). Per project convention (CLAUDE.md, parameter-system.md), Fortran-side checks belong in m_checker*.fpp. A user passing int_comp=3 would fail only at Python validation, not at simulation startup. Suggested:

@:PROHIBIT(int_comp < 0 .or. int_comp > 2, "int_comp must be 0, 1, or 2")

[HIGH] int_comp=2 silently degrades to 1D THINC for 1D cases
m_rhs.fpp line 286 and m_thinc.fpp ~line 741 both gate MTHINC on n > 0, so a user who sets int_comp=2 on a 1D case gets quiet THINC behaviour with no warning. This should either be prohibited or documented. Currently neither the validator nor the checker warns.

[MEDIUM] Backward compatibility break: int_comp type change (logical → integer)
toolchain/mfc/params/definitions.py moves int_comp from the LOG group to INT. Existing case files with 'int_comp': True or 'int_comp': False will fail schema validation (fastjsonschema rejects bool for integer fields). A migration note or compatibility shim would help existing users.

[MEDIUM] Removed constraint on int_comp requiring MUSCL
case_validator.py deletes the check that int_comp and recon_type != 2. THINC with WENO is now actively tested and apparently intentional. However, no constraint guards against int_comp > 0 with recon_type=3 (first-order/piecewise-constant). Applying THINC sharpening on top of a piecewise-constant reconstruction seems physically questionable — worth a comment or prohibition.

[MEDIUM] f_mthinc_solve_d Newton iteration unbounded in d
m_thinc.fpp lines 532-541: d is unconstrained during iteration. For degenerate normals or extreme alpha_cell values, d can drift to large magnitudes, causing tanh(beta*(n*xi + d)) -> +/-1 and dV -> 0. The guard if (abs(dV) < 1e-14_wp) exit catches this, but the stored d is unvalidated. Consider clamping d to [-d_max, d_max] for some d_max (e.g., 10/beta).

[LOW] Hardcoded 1e-14_wp convergence thresholds in f_mthinc_solve_d (lines 536, 538) should use a named constant or verysmall consistent with MFC convention.

[LOW] Redundant precision cast m_thinc.fpp line 670: real(ac, wp)ac is already real(wp).

[LOW] MTHINC not actually exercised in some new tests
cases.py line 188: for int_comp in [0, 1, 2] with muscl_order=1. If the base case for alter_muscl is 1D, then int_comp=2 silently runs as 1D THINC (per HIGH finding above), meaning the MTHINC code path is not exercised in those tests.

@wilfonba wilfonba marked this pull request as ready for review March 12, 2026 15:52
@wilfonba wilfonba requested a review from sbryngelson as a code owner March 12, 2026 15:52
Copilot AI review requested due to automatic review settings March 12, 2026 15:52
@qodo-code-review
Copy link
Copy Markdown
Contributor

ⓘ You are approaching your monthly quota for Qodo. Upgrade your plan

Review Summary by Qodo

Add MTHINC interface compression and refactor THINC functionality

✨ Enhancement 🐞 Bug fix 🧪 Tests

Grey Divider

Walkthroughs

Description
• Implements MTHINC (multi-dimensional THINC) interface compression for volume fraction sharpening
  alongside existing THINC support
• Introduces new m_thinc module with helper functions for stable logarithmic-cosine computation,
  1D THINC integrals, and multi-dimensional volume integrals using Gaussian quadrature
• Converts int_comp parameter from logical to integer type with three states: 0=off, 1=THINC,
  2=MTHINC
• Integrates THINC/MTHINC compression into RHS computation with Newton iteration for interface
  position parameter solving
• Refactors interface compression functionality out of MUSCL module into dedicated m_thinc module
• Updates MPI communication to handle new integer parameter type
• Adds comprehensive test cases for MTHINC in 2D/3D configurations with WENO reconstruction
• Updates all example cases and parameter definitions to use new integer enum values
• Includes performance validation showing ~3% overhead for MTHINC vs ~1% for THINC
• Updates documentation and validation logic for the new parameter type and options
Diagram
flowchart LR
  A["int_comp: logical<br/>to integer"] --> B["m_thinc module<br/>THINC + MTHINC"]
  B --> C["RHS computation<br/>with compression"]
  B --> D["Startup initialization<br/>and finalization"]
  C --> E["Test cases<br/>2D/3D MTHINC"]
  A --> F["MPI broadcast<br/>parameter update"]
  A --> G["Parameter validation<br/>0/1/2 values"]
Loading

Grey Divider

File Changes

1. src/simulation/m_thinc.fpp ✨ Enhancement +499/-0

New THINC and MTHINC interface compression module

• New module implementing THINC (1D) and MTHINC (multi-dimensional) interface compression for volume
 fraction sharpening
• Contains helper functions for stable logarithmic-cosine computation, 1D THINC integrals, and
 multi-dimensional volume integrals with Gaussian quadrature
• Implements Newton iteration to solve for interface position parameter d that preserves
 cell-averaged volume fractions
• Provides subroutines to initialize/finalize MTHINC data structures, compute unit normals and
 interface positions, and apply compression to reconstructed variables

src/simulation/m_thinc.fpp


2. src/simulation/m_muscl.fpp Refactoring +1/-86

Remove interface compression from MUSCL module

• Removed s_interface_compression from public interface exports
• Interface compression functionality moved to dedicated m_thinc module

src/simulation/m_muscl.fpp


3. src/simulation/m_rhs.fpp ✨ Enhancement +22/-1

Integrate THINC/MTHINC compression into RHS computation

• Added import of m_thinc module
• Added call to s_compute_mthinc_normals before dimensional splitting loop when int_comp == 2
• Integrated s_thinc_compression call after variable reconstruction with NVTX profiling markers
• Renamed NVTX range from "RHS-WENO" to "RHS-RECONSTRUCTION" for clarity

src/simulation/m_rhs.fpp


View more (78)
4. src/simulation/m_mpi_proxy.fpp 🐞 Bug fix +2/-2

Update MPI broadcast for int_comp parameter type change

• Added int_comp to integer broadcast list for MPI communication
• Removed int_comp from logical broadcast list (changed from boolean to integer type)

src/simulation/m_mpi_proxy.fpp


5. src/simulation/m_global_parameters.fpp ✨ Enhancement +3/-3

Change interface compression parameter to integer enum

• Changed int_comp from logical to integer type with values: 0=off, 1=THINC, 2=MTHINC
• Updated default value from .false. to 0
• Updated documentation comments for ic_beta to reference both THINC and MTHINC

src/simulation/m_global_parameters.fpp


6. src/simulation/m_start_up.fpp ✨ Enhancement +3/-0

Initialize and finalize THINC module in startup

• Added import of m_thinc module
• Added initialization call s_initialize_thinc_module() when int_comp > 0
• Added finalization call s_finalize_thinc_module() when int_comp > 0

src/simulation/m_start_up.fpp


7. toolchain/mfc/test/cases.py 🧪 Tests +8/-2

Add MTHINC test cases and update parameter values

• Added MTHINC testing for WENO cases with weno_order = 5 in 2D/3D configurations
• Updated MUSCL test cases to use integer values [0, 1, 2] for int_comp instead of boolean strings

toolchain/mfc/test/cases.py


8. examples/1D_sodshocktube_muscl/case.py ⚙️ Configuration changes +1/-1

Update example case parameter to integer

• Updated int_comp parameter from string "T" to integer 1 (THINC)

examples/1D_sodshocktube_muscl/case.py


9. examples/2D_riemann_test_muscl/case.py ⚙️ Configuration changes +1/-1

Update example case parameter to integer

• Updated int_comp parameter from string "T" to integer 1 (THINC)

examples/2D_riemann_test_muscl/case.py


10. examples/2D_advection_muscl/case.py ⚙️ Configuration changes +1/-1

Update example case parameter to integer

• Updated int_comp parameter from string "T" to integer 1 (THINC)

examples/2D_advection_muscl/case.py


11. examples/2D_shockdroplet_muscl/case.py ⚙️ Configuration changes +1/-1

Update example case parameter to integer

• Updated int_comp parameter from string "T" to integer 1 (THINC)

examples/2D_shockdroplet_muscl/case.py


12. examples/3D_shockdroplet_muscl/case.py ⚙️ Configuration changes +1/-1

Update example case parameter to integer

• Updated int_comp parameter from string "T" to integer 1 (THINC)

examples/3D_shockdroplet_muscl/case.py


13. examples/3D_rayleigh_taylor_muscl/case.py ⚙️ Configuration changes +1/-1

Update example case parameter to integer

• Updated int_comp parameter from string "T" to integer 1 (THINC)

examples/3D_rayleigh_taylor_muscl/case.py


14. toolchain/mfc/params/definitions.py ⚙️ Configuration changes +2/-1

Update parameter type definition for int_comp

• Moved int_comp from logical parameter list to integer parameter list
• Changed parameter type from LOG to INT

toolchain/mfc/params/definitions.py


15. toolchain/mfc/case_validator.py 🐞 Bug fix +3/-3

Update validation for integer int_comp parameter

• Updated validation logic to check int_comp as integer with valid values [0, 1, 2]
• Changed constraint message to clarify MTHINC option and removed requirement for MUSCL-only usage

toolchain/mfc/case_validator.py


16. toolchain/mfc/params/descriptions.py 📝 Documentation +1/-1

Update parameter description for int_comp

• Updated parameter description to reflect integer type with options: 0=off, 1=THINC, 2=MTHINC

toolchain/mfc/params/descriptions.py


17. tests/6102D509/golden-metadata.txt Miscellaneous +38/-67

Update golden test metadata

• Updated test metadata with new Git commit hash and branch name
• Updated CMake and compiler versions in configuration records

tests/6102D509/golden-metadata.txt


18. tests/6775D763/golden-metadata.txt 🧪 Tests +154/-0

Add new golden test metadata

• New golden test metadata file for MTHINC test case

tests/6775D763/golden-metadata.txt


19. tests/A438B8CE/golden-metadata.txt 🧪 Tests +154/-0

Add new golden test metadata

• New golden test metadata file for MTHINC test case

tests/A438B8CE/golden-metadata.txt


20. tests/AEE7A791/golden-metadata.txt 🧪 Tests +154/-0

Add new golden test metadata

• New golden test metadata file for MTHINC test case

tests/AEE7A791/golden-metadata.txt


21. tests/CE35B602/golden-metadata.txt 🧪 Tests +154/-0

Add new golden test metadata

• New golden test metadata file for MTHINC test case

tests/CE35B602/golden-metadata.txt


22. tests/F5FABAE9/golden-metadata.txt 🧪 Tests +154/-0

Add new golden test metadata

• New golden test metadata file for MTHINC test case

tests/F5FABAE9/golden-metadata.txt


23. tests/A930AE61/golden-metadata.txt 🧪 Tests +154/-0

Add new golden test metadata

• New golden test metadata file for MTHINC test case

tests/A930AE61/golden-metadata.txt


24. tests/C420EDF3/golden-metadata.txt 🧪 Tests +154/-0

Add new golden test metadata

• New golden test metadata file for MTHINC test case

tests/C420EDF3/golden-metadata.txt


25. tests/885D5D8C/golden-metadata.txt 🧪 Tests +154/-0

Add new golden test metadata

• New golden test metadata file for MUSCL interface compression test case

tests/885D5D8C/golden-metadata.txt


26. tests/8C42A56C/golden-metadata.txt 🧪 Tests +154/-0

Add new golden test metadata

• New golden test metadata file for MUSCL interface compression test case

tests/8C42A56C/golden-metadata.txt


27. tests/FE9379D8/golden-metadata.txt 🧪 Tests +154/-0

Add new golden test metadata

• New golden test metadata file for MUSCL interface compression test case

tests/FE9379D8/golden-metadata.txt


28. tests/E11FD23A/golden-metadata.txt 🧪 Tests +154/-0

Add new golden test metadata

• New golden test metadata file for MUSCL interface compression test case

tests/E11FD23A/golden-metadata.txt


29. docs/documentation/case.md 📝 Documentation +2/-2

Update documentation for int_comp parameter

• Updated int_comp parameter documentation from logical to integer type
• Added clarification that values [1] THINC and [2] MTHINC are supported
• Updated description to indicate interface compression works with variable reconstruction

docs/documentation/case.md


30. docs/module_categories.json 📝 Documentation +2/-1

Add THINC module to documentation categories

• Added m_thinc module to the reconstruction module category

docs/module_categories.json


31. tests/A438B8CE/golden.txt 🧪 Tests +16/-0

New MTHINC golden test data file

• Added new golden file with 16 lines of test data for MTHINC interface compression
• Contains conservative and primitive variable outputs (cons and prim) across 4 variables
• Includes initial state (timestep 000000) and evolved state (timestep 000050) for validation
• Data represents a 3D advection test case with multiple spatial regions and varying values

tests/A438B8CE/golden.txt


32. tests/F5FABAE9/golden.txt 🧪 Tests +16/-0

New MTHINC golden file test data

• Added new golden file with 16 lines of test data for MTHINC interface compression
• Contains initial and evolved state data for 5 conserved/primitive variables across 320 grid points
• Includes two timesteps (000000 and 000050) showing solution evolution
• Data demonstrates compression results with values ranging from near-zero to 2.5

tests/F5FABAE9/golden.txt


33. src/simulation/m_weno.fpp Additional files +0/-8

...

src/simulation/m_weno.fpp


34. tests/09195EF4/golden-metadata.txt Additional files +0/-0

...

tests/09195EF4/golden-metadata.txt


35. tests/09195EF4/golden.txt Additional files +0/-0

...

tests/09195EF4/golden.txt


36. tests/0A362971/golden-metadata.txt Additional files +0/-160

...

tests/0A362971/golden-metadata.txt


37. tests/0A362971/golden.txt Additional files +0/-10

...

tests/0A362971/golden.txt


38. tests/11D609F6/golden-metadata.txt Additional files +0/-0

...

tests/11D609F6/golden-metadata.txt


39. tests/11D609F6/golden.txt Additional files +0/-0

...

tests/11D609F6/golden.txt


40. tests/1B300F28/golden-metadata.txt Additional files +0/-189

...

tests/1B300F28/golden-metadata.txt


41. tests/1F0C4A44/golden-metadata.txt Additional files +0/-0

...

tests/1F0C4A44/golden-metadata.txt


42. tests/1F0C4A44/golden.txt Additional files +0/-0

...

tests/1F0C4A44/golden.txt


43. tests/2C9844EF/golden-metadata.txt Additional files +0/-156

...

tests/2C9844EF/golden-metadata.txt


44. tests/2C9844EF/golden.txt Additional files +0/-24

...

tests/2C9844EF/golden.txt


45. tests/2D11A034/golden-metadata.txt Additional files +0/-0

...

tests/2D11A034/golden-metadata.txt


46. tests/2D11A034/golden.txt Additional files +0/-0

...

tests/2D11A034/golden.txt


47. tests/2E4AC44C/golden-metadata.txt Additional files +0/-0

...

tests/2E4AC44C/golden-metadata.txt


48. tests/2E4AC44C/golden.txt Additional files +0/-0

...

tests/2E4AC44C/golden.txt


49. tests/3ECA875A/golden-metadata.txt Additional files +0/-0

...

tests/3ECA875A/golden-metadata.txt


50. tests/3ECA875A/golden.txt Additional files +0/-0

...

tests/3ECA875A/golden.txt


51. tests/409B55DF/golden-metadata.txt Additional files +0/-0

...

tests/409B55DF/golden-metadata.txt


52. tests/409B55DF/golden.txt Additional files +0/-0

...

tests/409B55DF/golden.txt


53. tests/503EEFF7/golden-metadata.txt Additional files +0/-0

...

tests/503EEFF7/golden-metadata.txt


54. tests/503EEFF7/golden.txt Additional files +0/-0

...

tests/503EEFF7/golden.txt


55. tests/50EC2239/golden-metadata.txt Additional files +0/-176

...

tests/50EC2239/golden-metadata.txt


56. tests/50EC2239/golden.txt Additional files +0/-18

...

tests/50EC2239/golden.txt


57. tests/6102D509/golden.txt Additional files +10/-0

...

tests/6102D509/golden.txt


58. tests/6775D763/golden.txt Additional files +12/-0

...

tests/6775D763/golden.txt


59. tests/67C777D8/golden.txt Additional files +0/-506

...

tests/67C777D8/golden.txt


60. tests/7156050E/golden-metadata.txt Additional files +0/-0

...

tests/7156050E/golden-metadata.txt


61. tests/7156050E/golden.txt Additional files +0/-0

...

tests/7156050E/golden.txt


62. tests/845DC70C/golden-metadata.txt Additional files +0/-0

...

tests/845DC70C/golden-metadata.txt


63. tests/845DC70C/golden.txt Additional files +0/-0

...

tests/845DC70C/golden.txt


64. tests/885D5D8C/golden.txt Additional files +10/-20

...

tests/885D5D8C/golden.txt


65. tests/8876692F/golden-metadata.txt Additional files +0/-160

...

tests/8876692F/golden-metadata.txt


66. tests/8876692F/golden.txt Additional files +0/-14

...

tests/8876692F/golden.txt


67. tests/8C42A56C/golden.txt Additional files +12/-0

...

tests/8C42A56C/golden.txt


68. tests/A930AE61/golden.txt Additional files +12/-0

...

tests/A930AE61/golden.txt


69. tests/AEE7A791/golden.txt Additional files +0/-0

...

tests/AEE7A791/golden.txt


70. tests/B3C724B5/golden-metadata.txt Additional files +0/-0

...

tests/B3C724B5/golden-metadata.txt


71. tests/B3C724B5/golden.txt Additional files +0/-0

...

tests/B3C724B5/golden.txt


72. tests/B903D17E/golden-metadata.txt Additional files +0/-0

...

tests/B903D17E/golden-metadata.txt


73. tests/B903D17E/golden.txt Additional files +12/-0

...

tests/B903D17E/golden.txt


74. tests/C02D71EE/golden-metadata.txt Additional files +0/-176

...

tests/C02D71EE/golden-metadata.txt


75. tests/C02D71EE/golden.txt Additional files +0/-18

...

tests/C02D71EE/golden.txt


76. tests/C420EDF3/golden.txt Additional files +12/-0

...

tests/C420EDF3/golden.txt


77. tests/CE35B602/golden.txt Additional files +10/-0

...

tests/CE35B602/golden.txt


78. tests/E11FD23A/golden.txt Additional files +10/-0

...

tests/E11FD23A/golden.txt


79. tests/FA4D8FEF/golden-metadata.txt Additional files +0/-189

...

tests/FA4D8FEF/golden-metadata.txt


80. tests/FA4D8FEF/golden.txt Additional files +0/-32

...

tests/FA4D8FEF/golden.txt


81. tests/FE9379D8/golden.txt Additional files +12/-0

...

tests/FE9379D8/golden.txt


Grey Divider

Qodo Logo

@qodo-code-review
Copy link
Copy Markdown
Contributor

qodo-code-review bot commented Mar 12, 2026

Code Review by Qodo

🐞 Bugs (2) 📘 Rule violations (1) 📎 Requirement gaps (0)

Grey Divider


Action required

1. int_comp absent on device 🐞 Bug ⛯ Reliability
Description
In m_thinc:s_thinc_compression, the OpenACC-parallel kernel branches on int_comp (THINC vs MTHINC)
under default(present), but int_comp is not declared/created for the device in m_global_parameters,
risking an OpenACC runtime 'not present' failure in GPU builds. This risk is introduced because
int_comp is now referenced inside device code instead of only host-side conditionals.
Code

src/simulation/m_thinc.fpp[R380-383]

+                            if (aC >= ic_eps .and. aC <= 1._wp - ic_eps) then
+
+                                if (int_comp == 2 .and. n > 0) then
+                                    ! MTHINC: multi-dimensional face averages
Evidence
The project’s OpenACC loop macro defaults to default(present), meaning variables used inside the
GPU region must already be present on the device. The new THINC kernel references int_comp inside
the GPU loop, but the global parameter module’s GPU_DECLARE lists do not include int_comp, so
there is no clear path that makes it device-present.

src/common/include/acc_macros.fpp[132-158]
src/simulation/m_thinc.fpp[356-384]
src/simulation/m_global_parameters.fpp[205-216]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`int_comp` is referenced inside OpenACC GPU kernels under `default(present)`, but it is not explicitly declared/created on the device. This can produce OpenACC runtime failures (variable not present) in GPU builds.

### Issue Context
- `ACC_PARALLEL_LOOP` defaults to `default(present)`.
- `m_thinc:s_thinc_compression` branches on `int_comp` inside `$:GPU_PARALLEL_LOOP`.
- `m_global_parameters` contains the central `GPU_DECLARE` lists for globals, but does not include `int_comp`.

### Fix Focus Areas
- src/simulation/m_thinc.fpp[356-384]
- src/simulation/m_global_parameters.fpp[205-216]
- src/common/include/acc_macros.fpp[132-158]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. vR densities use vL 🐞 Bug ✓ Correctness
Description
In m_thinc:s_thinc_compression (THINC path), rho_b and rho_e are computed only from vL_rs_vf_*
ratios and then applied to overwrite both vL_rs_vf_* and vR_rs_vf_* densities, discarding the
pre-compression vR reconstructed density/alpha ratios. Since WENO/MUSCL compute vL and vR using
different polynomials, this can make the right-face state inconsistent and distort fluxes.
Code

src/simulation/m_thinc.fpp[R453-473]

+                                        ! Save original density ratios before THINC overwrites them
+                                        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))
+
+                                        ! Left reconstruction
+                                        aTHINC = qmin + 5e-1_wp*qmax*(1._wp + sgn*A)
+                                        if (aTHINC < ic_eps) aTHINC = ic_eps
+                                        if (aTHINC > 1._wp - ic_eps) aTHINC = 1._wp - ic_eps
+                                        vL_rs_vf_${XYZ}$ (j, k, l, contxb) = rho_b*aTHINC
+                                        vL_rs_vf_${XYZ}$ (j, k, l, contxe) = rho_e*(1._wp - aTHINC)
+                                        vL_rs_vf_${XYZ}$ (j, k, l, advxb) = aTHINC
+                                        vL_rs_vf_${XYZ}$ (j, k, l, advxe) = 1._wp - aTHINC
+
+                                        ! Right reconstruction
+                                        aTHINC = qmin + 5e-1_wp*qmax*(1._wp + sgn*(tanh(beta_eff) + A)/(1._wp + A*tanh(beta_eff)))
+                                        if (aTHINC < ic_eps) aTHINC = ic_eps
+                                        if (aTHINC > 1._wp - ic_eps) aTHINC = 1._wp - ic_eps
+                                        vR_rs_vf_${XYZ}$ (j, k, l, contxb) = rho_b*aTHINC
+                                        vR_rs_vf_${XYZ}$ (j, k, l, contxe) = rho_e*(1._wp - aTHINC)
+                                        vR_rs_vf_${XYZ}$ (j, k, l, advxb) = aTHINC
+                                        vR_rs_vf_${XYZ}$ (j, k, l, advxe) = 1._wp - aTHINC
Evidence
The THINC branch explicitly derives density ratios solely from vL and then uses those same ratios to
set vR values. Separately, WENO reconstruction computes vL and vR using different coefficient sets
(cbL vs cbR), so vR generally differs from vL before compression; overwriting vR with vL-derived
ratios ignores that reconstruction.

src/simulation/m_thinc.fpp[453-473]
src/simulation/m_weno.fpp[729-766]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
In the THINC (1D) compression path, right-face densities (`vR_rs_vf_*`) are overwritten using density ratios computed from the left-face reconstruction (`vL_rs_vf_*`). This discards the right-face reconstructed density/alpha ratios and can make the right state inconsistent.

### Issue Context
WENO/MUSCL reconstruct `vL` and `vR` with different coefficient sets, so they are not generally identical before compression. THINC should preserve each face’s density ratio (or use a consistent cell-averaged ratio) when updating densities alongside alpha.

### Fix Focus Areas
- src/simulation/m_thinc.fpp[453-473]
- src/simulation/m_weno.fpp[729-766]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

3. Missing precheck/build/test evidence 📘 Rule violation ⛯ Reliability
Description
The PR description does not document running ./mfc.sh precheck, ./mfc.sh build, or relevant
automated tests after adding a new Fortran module and changing parameter typing. Without this, CI
readiness and correctness of the change cannot be confirmed from the PR.
Code

src/simulation/m_thinc.fpp[R7-14]

+!> @brief THINC and MTHINC interface compression for volume fraction sharpening.
+!! THINC (int_comp=1): 1D directional interface compression applied after
+!! MUSCL/WENO reconstruction. Uses hyperbolic tangent profile per dimension.
+!! MTHINC (int_comp=2): Multi-dimensional THINC that reconstructs a tanh
+!! profile oriented along the interface normal (computed from the gradient
+!! of alpha), then integrates that profile over each cell face using
+!! Gaussian quadrature. A Newton iteration enforces the conservation
+!! constraint (cell-averaged alpha is preserved).
Evidence
Compliance ID 1 requires precheck, build, and relevant tests to be run and pass. The PR description
lists manual case runs/perf results but does not mention running the required commands, while the
diff shows substantial new Fortran functionality and a parameter type change that should be covered
by those checks.

CLAUDE.md
src/simulation/m_thinc.fpp[7-14]
toolchain/mfc/params/definitions.py[983-986]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The PR does not provide evidence that required CI-equivalent checks were run (`./mfc.sh precheck`, `./mfc.sh build`, and relevant tests).

## Issue Context
This PR adds a new Fortran module for THINC/MTHINC and changes the `int_comp` parameter type/handling; these changes should be validated by precheck/build and appropriate tests.

## Fix Focus Areas
- src/simulation/m_thinc.fpp[7-14]
- toolchain/mfc/params/definitions.py[983-986]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

ⓘ The new review experience is currently in Beta. Learn more

Grey Divider

Qodo Logo

@github-actions
Copy link
Copy Markdown

Claude Code Review

Head SHA: 202d7daedced880868e31df3614e3d4b0b742f80
Files changed: 81 (source: 15 key files + 66 golden-file renames/updates)

Key source files:

  • src/simulation/m_thinc.fpp (new, 499 lines)
  • src/simulation/m_rhs.fpp (+22/-1)
  • src/simulation/m_muscl.fpp (+1/-86)
  • src/simulation/m_weno.fpp (0/-8)
  • src/simulation/m_global_parameters.fpp (+3/-3)
  • src/simulation/m_mpi_proxy.fpp (+2/-2)
  • src/simulation/m_start_up.fpp (+3/0)
  • toolchain/mfc/case_validator.py, params/definitions.py, test/cases.py

Summary

  • Adds MTHINC (int_comp=2): multi-dimensional THINC using precomputed interface normals and Gaussian quadrature for face averages; Newton iteration enforces the conservation constraint per cell.
  • Fixes a bug in the original THINC right-reconstruction density (Fix MUSCL THINC right-state using already-overwritten left-state values #1181): the old code used the already-overwritten left-face advxb value when computing the right-face density ratio.
  • Refactors THINC out of m_muscl/m_weno into a dedicated m_thinc module called from m_rhs after reconstruction — enabling compression for both WENO and MUSCL.
  • Changes int_comp from logical to integer (0=off, 1=THINC, 2=MTHINC) throughout; correctly moves MPI broadcast from the logical list to the integer list in m_mpi_proxy.fpp.
  • Good numerics: numerically stable f_log_cosh for large arguments, analytical 1-D THINC integral, correct use of GPU Fypp macros throughout.

Findings

[Medium] Missing Fortran runtime check for int_comp range — src/simulation/m_checker.fpp

m_checker.fpp was not updated. Per project convention (CLAUDE.md, parameter-system.md), a Fortran-side @:PROHIBIT guard should be added alongside the Python-side check in case_validator.py:

@:PROHIBIT(int_comp < 0 .or. int_comp > 2, "int_comp must be 0 (off), 1 (THINC), or 2 (MTHINC)")

The Python validator catches this at case-setup time, but the Fortran check is the convention for parameters with constrained integer values.


[Medium] MTHINC silently degrades to 1-D THINC for 1-D cases — src/simulation/m_rhs.fpp:749, m_thinc.fpp

When int_comp=2 and n=0 (1-D):

  • m_rhs.fpp:749: if (int_comp == 2 .and. n > 0) is false → normals are never computed (mthinc_nhat stays zero).
  • Inside s_thinc_compression, if (int_comp == 2 .and. n > 0) is also false → the else branch (1-D THINC) executes silently.

Mathematically this is fine (MTHINC reduces to THINC in 1-D), but the user gets THINC behaviour when requesting MTHINC with no diagnostic. The old Python constraint that required recon_type = 2 was removed but no MTHINC+1D note was added. At minimum, a comment or case_validator.py note would help.


[Low] MTHINC skips monotonicity check — src/simulation/m_thinc.fpp (THINC vs MTHINC branch)

The 1-D THINC path guards with moncon > moncon_cutoff (checks (aCR - aC)*(aC - aCL) > cutoff), preventing compression in non-monotone regions. The MTHINC path only checks nh1² + nh2² + nh3² > 0.5 (valid normal exists). Non-monotone interface cells that still have a computable normal will get MTHINC applied — the ic_eps outer guard prevents pure-fluid cells, but the directional-monotonicity protection is absent. This is likely intentional (MTHINC's normal is a multi-dimensional signal), but should be confirmed or documented.


[Low] Two-fluid assumption is undocumented — src/simulation/m_thinc.fpp

Both THINC and MTHINC update only contxb, contxe, advxb, advxe — the indices for exactly two fluids. Cases with 3+ fluids (multiple adv_idx entries) receive silently incorrect density/volume-fraction reconstructions. The original m_muscl.fpp code had the same limitation, but a @:PROHIBIT(int_comp > 0 .and. num_fluids > 2, ...) or at least a comment in s_thinc_compression would prevent silent misuse.


[Positive] Correct THINC bug fix

The old right-reconstruction in m_muscl.fpp computed the density ratio as:

vR...(contxb) = vL...(contxb) / vL...(advxb) * aTHINC   ! Bug: advxb already overwritten

The new code in m_thinc.fpp correctly saves rho_b = vL.../vL...(advxb) and rho_e = vL.../((1-vL...(advxb))) before modifying the left face, then uses them for both left and right reconstructions. This is the right fix.


[Positive] Architecture improvement

Centralising interface compression into m_thinc called from m_rhs (post-reconstruction) rather than inside m_muscl/m_weno is cleaner and correctly extends THINC coverage to WENO reconstruction — verified by the new WENO + int_comp test cases added to cases.py.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR introduces a dedicated THINC/MTHINC interface-compression module and migrates the int_comp setting from a logical flag to an integer selector, while updating tests/docs/tooling accordingly.

Changes:

  • Added src/simulation/m_thinc.fpp implementing THINC (int_comp=1) and MTHINC (int_comp=2) and wired it into the reconstruction flow in m_rhs.
  • Replaced the old MUSCL/WENO-local interface-compression hooks by centralizing compression in RHS reconstruction; removed the MUSCL s_interface_compression implementation.
  • Updated toolchain parameter typing/validation and adjusted examples/docs/tests to use integer int_comp.

Reviewed changes

Copilot reviewed 42 out of 81 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
src/simulation/m_thinc.fpp New THINC/MTHINC implementation (including MTHINC normal computation and Newton solve).
src/simulation/m_rhs.fpp Calls MTHINC normal computation pre-split; runs compression post-reconstruction with NVTX ranges.
src/simulation/m_muscl.fpp Removes s_interface_compression and MUSCL-side compression call.
src/simulation/m_weno.fpp Removes MUSCL import and WENO-side compression call.
src/simulation/m_start_up.fpp Initializes/finalizes the new THINC module when int_comp > 0.
src/simulation/m_global_parameters.fpp Changes int_comp from logical to integer with updated defaults/comments.
src/simulation/m_mpi_proxy.fpp Broadcasts int_comp as an integer instead of logical.
toolchain/mfc/params/definitions.py Registers int_comp as INT instead of LOG.
toolchain/mfc/case_validator.py Validates int_comp is in {0,1,2}.
toolchain/mfc/test/cases.py Expands generated test matrix to include int_comp values {0,1,2}.
toolchain/mfc/params/descriptions.py Updates parameter description to document 0/1/2 meanings.
docs/documentation/case.md Updates docs to describe integer int_comp and mentions MTHINC.
docs/module_categories.json Adds m_thinc to documentation module grouping.
examples/*/case.py Updates examples from "T" to 1 for THINC.
tests/*/golden-metadata.txt Updates/adds golden metadata for the new/updated test set.

@wilfonba wilfonba marked this pull request as draft March 12, 2026 16:08
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 12, 2026

📝 Walkthrough

Walkthrough

This pull request refactors interface compression from a boolean flag into an integer enumeration with three states: 0 (off), 1 (THINC), and 2 (MTHINC). The implementation moves compression logic from the MUSCL module into a dedicated new THINC module. Interface compression is now integrated into RHS calculations and invoked during variable reconstruction. Documentation, parameter definitions, validation logic, and example configurations are updated to reflect the new integer-based parameter type and semantic values. Test cases are expanded to exercise the new enumeration states.

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 40.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title 'MTHINC' is concise and directly identifies the primary feature being added, though it lacks context about what MTHINC does or that it includes an interface compression feature.
Description check ✅ Passed PR description includes type of change, testing details with videos, performance measurements, and all required checklist items completed.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 9


ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 411ddfaf-e410-411e-a688-203d6a1caf71

📥 Commits

Reviewing files that changed from the base of the PR and between 506c6f5 and 202d7da.

📒 Files selected for processing (81)
  • docs/documentation/case.md
  • docs/module_categories.json
  • examples/1D_sodshocktube_muscl/case.py
  • examples/2D_advection_muscl/case.py
  • examples/2D_riemann_test_muscl/case.py
  • examples/2D_shockdroplet_muscl/case.py
  • examples/3D_rayleigh_taylor_muscl/case.py
  • examples/3D_shockdroplet_muscl/case.py
  • src/simulation/m_global_parameters.fpp
  • src/simulation/m_mpi_proxy.fpp
  • src/simulation/m_muscl.fpp
  • src/simulation/m_rhs.fpp
  • src/simulation/m_start_up.fpp
  • src/simulation/m_thinc.fpp
  • src/simulation/m_weno.fpp
  • tests/09195EF4/golden-metadata.txt
  • tests/09195EF4/golden.txt
  • tests/0A362971/golden-metadata.txt
  • tests/0A362971/golden.txt
  • tests/11D609F6/golden-metadata.txt
  • tests/11D609F6/golden.txt
  • tests/1B300F28/golden-metadata.txt
  • tests/1F0C4A44/golden-metadata.txt
  • tests/1F0C4A44/golden.txt
  • tests/2C9844EF/golden-metadata.txt
  • tests/2C9844EF/golden.txt
  • tests/2D11A034/golden-metadata.txt
  • tests/2D11A034/golden.txt
  • tests/2E4AC44C/golden-metadata.txt
  • tests/2E4AC44C/golden.txt
  • tests/3ECA875A/golden-metadata.txt
  • tests/3ECA875A/golden.txt
  • tests/409B55DF/golden-metadata.txt
  • tests/409B55DF/golden.txt
  • tests/503EEFF7/golden-metadata.txt
  • tests/503EEFF7/golden.txt
  • tests/50EC2239/golden-metadata.txt
  • tests/50EC2239/golden.txt
  • tests/6102D509/golden-metadata.txt
  • tests/6102D509/golden.txt
  • tests/6775D763/golden-metadata.txt
  • tests/6775D763/golden.txt
  • tests/67C777D8/golden.txt
  • tests/7156050E/golden-metadata.txt
  • tests/7156050E/golden.txt
  • tests/845DC70C/golden-metadata.txt
  • tests/845DC70C/golden.txt
  • tests/885D5D8C/golden-metadata.txt
  • tests/885D5D8C/golden.txt
  • tests/8876692F/golden-metadata.txt
  • tests/8876692F/golden.txt
  • tests/8C42A56C/golden-metadata.txt
  • tests/8C42A56C/golden.txt
  • tests/A438B8CE/golden-metadata.txt
  • tests/A438B8CE/golden.txt
  • tests/A930AE61/golden-metadata.txt
  • tests/A930AE61/golden.txt
  • tests/AEE7A791/golden-metadata.txt
  • tests/AEE7A791/golden.txt
  • tests/B3C724B5/golden-metadata.txt
  • tests/B3C724B5/golden.txt
  • tests/B903D17E/golden-metadata.txt
  • tests/B903D17E/golden.txt
  • tests/C02D71EE/golden-metadata.txt
  • tests/C02D71EE/golden.txt
  • tests/C420EDF3/golden-metadata.txt
  • tests/C420EDF3/golden.txt
  • tests/CE35B602/golden-metadata.txt
  • tests/CE35B602/golden.txt
  • tests/E11FD23A/golden-metadata.txt
  • tests/E11FD23A/golden.txt
  • tests/F5FABAE9/golden-metadata.txt
  • tests/F5FABAE9/golden.txt
  • tests/FA4D8FEF/golden-metadata.txt
  • tests/FA4D8FEF/golden.txt
  • tests/FE9379D8/golden-metadata.txt
  • tests/FE9379D8/golden.txt
  • toolchain/mfc/case_validator.py
  • toolchain/mfc/params/definitions.py
  • toolchain/mfc/params/descriptions.py
  • toolchain/mfc/test/cases.py
💤 Files with no reviewable changes (10)
  • tests/FA4D8FEF/golden.txt
  • tests/FA4D8FEF/golden-metadata.txt
  • tests/2C9844EF/golden-metadata.txt
  • src/simulation/m_weno.fpp
  • tests/0A362971/golden.txt
  • tests/1B300F28/golden-metadata.txt
  • tests/8876692F/golden-metadata.txt
  • tests/C02D71EE/golden-metadata.txt
  • tests/50EC2239/golden-metadata.txt
  • tests/0A362971/golden-metadata.txt

@codecov
Copy link
Copy Markdown

codecov bot commented Mar 12, 2026

Codecov Report

❌ Patch coverage is 28.92157% with 145 lines in your changes missing coverage. Please review.
✅ Project coverage is 64.32%. Comparing base (2d15ba9) to head (f515368).

Files with missing lines Patch % Lines
src/simulation/m_thinc.fpp 17.85% 133 Missing and 5 partials ⚠️
src/simulation/m_muscl.fpp 66.66% 0 Missing and 2 partials ⚠️
src/simulation/m_weno.fpp 80.00% 0 Missing and 2 partials ⚠️
src/simulation/m_global_parameters.fpp 83.33% 0 Missing and 1 partial ⚠️
src/simulation/m_rhs.fpp 90.00% 0 Missing and 1 partial ⚠️
src/simulation/m_start_up.fpp 75.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #1303      +/-   ##
==========================================
- Coverage   64.67%   64.32%   -0.35%     
==========================================
  Files          70       71       +1     
  Lines       18251    18401     +150     
  Branches     1504     1523      +19     
==========================================
+ Hits        11804    11837      +33     
- Misses       5492     5604     +112     
- Partials      955      960       +5     

☔ 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.

@github-actions
Copy link
Copy Markdown

Claude Code Review

Head SHA: 85acf5a

Files changed: 81 (key source files: m_thinc.fpp [new, +499], m_muscl.fpp [-86], m_weno.fpp [-8], m_rhs.fpp [+22], m_global_parameters.fpp, m_mpi_proxy.fpp, m_start_up.fpp, toolchain/mfc/params/definitions.py, toolchain/mfc/case_validator.py, toolchain/mfc/test/cases.py)


Summary

  • Adds MTHINC (int_comp=2), a multi-dimensional THINC variant using interface normals + Gaussian quadrature face integration; THINC becomes int_comp=1 (integer, was boolean).
  • Moves interface compression from per-solver modules (m_muscl.fpp, m_weno.fpp) into a new unified m_thinc module called from m_rhs.fpp after any reconstruction type, enabling THINC/MTHINC with WENO too.
  • Fixes the Fix MUSCL THINC right-state using already-overwritten left-state values #1181 bug: old THINC right-reconstruction density scaling read from already-overwritten vL_rs_vf values; new code saves rho_b/rho_e before any overwrite.
  • Correct MPI broadcast migration: int_comp moved from logical to integer broadcast list in m_mpi_proxy.fpp.
  • New and regenerated golden files cover THINC + MTHINC for WENO and MUSCL in 2D/3D.

Findings

[Medium] n > 0 guard for MTHINC silently degrades x-z plane 2D simulations
m_rhs.fpp:+749 and m_thinc.fpp:+142:

if (int_comp == 2 .and. n > 0) then   ! MTHINC guard

n is the number of y-direction cells. For a 2D simulation in the x-z plane (n == 0, p > 0), this guard evaluates to .false., so s_compute_mthinc_normals is never called and s_thinc_compression silently falls to the 1D-THINC branch — even though the problem is multi-dimensional. Since standard MFC 2D problems use x-y (n > 0), this is low-risk in practice, but the guard would be more correct as num_dims > 1.

[Medium] Newton solver f_mthinc_solve_d has no bounds clamping or convergence fallback
m_thinc.fpp:+174-188:

do iter = 1, 30
    ...
    d = d - residual/dV
end do

If convergence fails (e.g., degenerate normal near a triple point or machine-epsilon gradient), the function returns an unclamped d after 30 iterations without any diagnostic. A large dtanh(beta*(n·xi + d)) ≈ ±1 everywhere, collapsing the face average to 0 or 1. Adding a clamp (e.g., d = max(-50._wp/ic_beta, min(50._wp/ic_beta, d))) after the Newton step would prevent potential NaN propagation downstream.

[Low] Removed recon_type == 2 constraint without replacement
toolchain/mfc/case_validator.py:+353:
The old validator prohibited int_comp with non-MUSCL reconstruction. The new constraint only validates the integer value range. Since WENO + THINC/MTHINC is now intentionally supported (test cases confirm it), there is no correctness issue — but a note in case_validator.py or docs clarifying that both WENO and MUSCL are valid would help users.

[Low] Unused allocations for MTHINC in 1D
m_thinc.fpp:+250-263:
When int_comp == 2 and num_dims == 1, s_initialize_thinc_module allocates mthinc_nhat and mthinc_d on the GPU, but s_compute_mthinc_normals is never called (guarded by n > 0) and s_thinc_compression falls to the 1D-THINC branch (the MTHINC branch also checks n > 0 and skips). The allocations are unnecessary for 1D MTHINC. This is a minor memory overhead, not a correctness issue.

[Info] Bug fix for #1181 confirmed correct
Old m_muscl.fpp right-reconstruction:

! BUG: vL_rs_vf_XYZ(advxb) already overwritten by left reconstruction above
vR_rs_vf_XYZ(contxb) = vL_rs_vf_XYZ(contxb) / vL_rs_vf_XYZ(advxb) * aTHINC

New code correctly saves rho_b = contxb/advxb and rho_e = contxe/(1-advxb) before the left overwrite, then uses those saved values for both left and right reconstructions. The fix is correct.


Overall the implementation is well-structured. The n > 0 MTHINC guard and Newton solver robustness are the two items worth addressing before merge.

@wilfonba wilfonba changed the title MTHINC Interface Compression MTHINC Mar 15, 2026
@sbryngelson sbryngelson force-pushed the MTHINC branch 2 times, most recently from 2e0268f to 617f985 Compare March 16, 2026 14:20
@github-actions
Copy link
Copy Markdown

Claude Code Review

Incremental review from: (first review)
Head SHA: b4e110c

New findings:

1. Critical — GPU coherence: int_comp, ic_eps, ic_beta missing GPU_DECLARE and GPU_UPDATE

All three variables are read inside GPU_PARALLEL_LOOP regions in src/simulation/m_thinc.fpp (e.g., s_thinc_compression uses int_comp at the loop body branch, ic_eps and ic_beta for THINC/MTHINC profile computation) but none appear to have:

  • a $:GPU_DECLARE(create='[...]') in src/simulation/m_global_parameters.fpp
  • a $:GPU_UPDATE(device='[...]') in s_initialize_gpu_vars in src/simulation/m_start_up.fpp

By contrast, the analogous scalar weno_eps has $:GPU_DECLARE(create='[avg_state,mp_weno,weno_eps,teno_CT,hypoelasticity]'). On OpenACC or OpenMP target offload builds, the GPU will see uninitialized/stale values for int_comp, ic_eps, and ic_beta, causing either no compression (if int_comp reads as 0 on device) or silently wrong results. CPU-only builds are unaffected, which is likely why tests passed.

Fix: Add to src/simulation/m_global_parameters.fpp:

$:GPU_DECLARE(create='[int_comp,ic_eps,ic_beta]')

And add to s_initialize_gpu_vars in src/simulation/m_start_up.fpp:

$:GPU_UPDATE(device='[int_comp,ic_eps,ic_beta]')

2. Moderate — MTHINC density reconstruction silently skips intermediate fluid components for num_fluids > 2

In s_thinc_compression (src/simulation/m_thinc.fpp), the MTHINC path reconstructs face densities using only contxb and contxe:

rho1 = v_vf(contxb)%sf(ix, iy, iz)/aC
rho2 = v_vf(contxe)%sf(ix, iy, iz)/(1._wp - aC)

This implicitly assumes exactly 2 fluids. For num_fluids > 2, the intermediate partial density components (contxb+1 through contxe-1) are left unmodified by MTHINC, producing physically inconsistent states where updated volume fractions no longer match unupdated partial densities.

There is no constraint in toolchain/mfc/case_validator.py or in the Fortran checker (src/simulation/m_checker.fpp) preventing int_comp > 0 with num_fluids > 2.

Fix: Either extend the density reconstruction to loop over all fluids from contxb to contxe, or guard in the validator:

self.prohibit(int_comp > 0 and num_fluids > 2,
    "int_comp (THINC/MTHINC) only supports num_fluids <= 2")

@github-actions
Copy link
Copy Markdown

github-actions bot commented Mar 18, 2026

<!-- claude-review: thread=primary; reviewed_sha=0ed0772ee8995e5752187f6d67d035a6bc49b556; mode=incremental -->

@sbryngelson
Copy link
Copy Markdown
Member

@wilfonba can you re-run a few sanity checks to make sure this works after i made a bunch of changes? then i guess we can mark it ready to review, which ensures it works on frontier/phoenix/whatever. then merge.

@wilfonba
Copy link
Copy Markdown
Contributor Author

@wilfonba can you re-run a few sanity checks to make sure this works after i made a bunch of changes? then i guess we can mark it ready to review, which ensures it works on frontier/phoenix/whatever. then merge.

Yep. I'll send you a message and open it as ready to review when I've taken care of that.

@github-actions
Copy link
Copy Markdown

github-actions bot commented Mar 26, 2026

No description provided.

@sbryngelson sbryngelson force-pushed the MTHINC branch 4 times, most recently from 416d0ad to 755fba3 Compare March 26, 2026 19:46
@sbryngelson sbryngelson force-pushed the MTHINC branch 2 times, most recently from 878b943 to 3fe0129 Compare March 26, 2026 21:16
@wilfonba wilfonba marked this pull request as ready for review March 29, 2026 21:59
@sbryngelson sbryngelson marked this pull request as draft March 30, 2026 01:00
@sbryngelson
Copy link
Copy Markdown
Member

PRs are ready to review (non-draft) when they are verified passing on amd gpu hardware + mpi (not the case here it seems). Setting from draft to ready to review triggers larger CI runs on every push.

@wilfonba wilfonba marked this pull request as ready for review March 31, 2026 18:32
@wilfonba
Copy link
Copy Markdown
Contributor Author

@sbryngelson this is verified passing on NVIDIA with OpenACC/MP and AMD Flang with OpenMP now. It also gives correct results with parallelization. The existing PR comments from the draft state have been addressed as well.

@wilfonba
Copy link
Copy Markdown
Contributor Author

Sheesh, seems like a weird edge case with compile-time parameters on CCE compilers is causing the issue with the tests.

@wilfonba wilfonba marked this pull request as draft April 1, 2026 14:34
@wilfonba wilfonba marked this pull request as ready for review April 2, 2026 15:40
@wilfonba
Copy link
Copy Markdown
Contributor Author

wilfonba commented Apr 2, 2026

Marking this ready for review again since I've run a bunch of manual tests since the most recent changes

@qodo-code-review
Copy link
Copy Markdown
Contributor

Review Summary by Qodo

Add MTHINC multi-dimensional interface compression and refactor THINC implementation

✨ Enhancement 🐞 Bug fix 🧪 Tests

Grey Divider

Walkthroughs

Description
• Implements THINC (1D) and MTHINC (multi-dimensional) interface compression schemes for volume
  fraction sharpening in the simulation module
• Converts int_comp parameter from logical to integer type (0=off, 1=THINC, 2=MTHINC) with
  comprehensive validation
• Centralizes interface compression logic in new m_thinc module with helper functions for
  tanh-based profiles and Newton iteration for conservation constraints
• Integrates MTHINC normal computation into RHS calculation pipeline and updates WENO/MUSCL modules
  to use centralized compression interface
• Adds initialization and finalization routines for THINC module in startup sequence
• Updates MPI broadcasts to handle new integer parameter type
• Adds comprehensive test cases for THINC and MTHINC with dimension-aware testing (MTHINC only in
  2D/3D)
• Updates documentation and parameter definitions with clear descriptions of compression modes
• Includes new golden test files and metadata for MTHINC validation
• Demonstrates ~3% performance overhead for MTHINC and ~1% for THINC in 3D advection benchmarks
Diagram
flowchart LR
  A["m_thinc module<br/>THINC/MTHINC compression"] --> B["m_rhs<br/>Compute normals"]
  A --> C["m_weno<br/>Apply compression"]
  A --> D["m_muscl<br/>Apply compression"]
  E["m_global_parameters<br/>int_comp: 0/1/2"] --> A
  E --> B
  E --> C
  E --> D
  F["m_start_up<br/>Initialize/Finalize"] --> A
  G["m_mpi_proxy<br/>Broadcast int_comp"] --> E
  H["case_validator<br/>Validate int_comp"] --> E
Loading

Grey Divider

File Changes

1. src/simulation/m_thinc.fpp ✨ Enhancement +434/-0

New THINC and MTHINC interface compression module

• New module implementing THINC (1D) and MTHINC (multi-dimensional) interface compression schemes
 for volume fraction sharpening
• Contains helper functions for computing tanh-based interface profiles with Gaussian quadrature
 integration
• Implements Newton iteration to enforce conservation constraints on cell-averaged volume fractions
• Provides initialization, normal computation, compression application, and finalization subroutines

src/simulation/m_thinc.fpp


2. src/simulation/m_rhs.fpp ✨ Enhancement +29/-25

Integrate MTHINC normal computation into RHS calculation

• Added use m_thinc module import for interface compression functionality
• Integrated call to s_compute_mthinc_normals before dimensional splitting loop when `int_comp ==
 2`
• Updated nvtx range naming from "RHS-WENO" to "RHS-RECONSTRUCTION" for clarity
• Minor formatting improvements and comment clarifications throughout

src/simulation/m_rhs.fpp


3. src/simulation/m_weno.fpp ✨ Enhancement +26/-22

Update WENO module to use new THINC compression interface

• Changed import from m_muscl to selective import of s_thinc_compression from m_thinc
• Replaced old s_interface_compression call with new s_thinc_compression implementation
• Updated condition to check int_comp > 0 and added nvtx profiling range for interface compression
• Improved code comments and formatting for WENO coefficient computation

src/simulation/m_weno.fpp


View more (71)
4. src/simulation/m_global_parameters.fpp ✨ Enhancement +26/-26

Convert interface compression parameter to integer type

• Changed int_comp from logical to integer type (0=off, 1=THINC, 2=MTHINC)
• Added GPU declarations for int_comp, ic_eps, and ic_beta parameters
• Updated initialization to set int_comp = 0 instead of .false.
• Improved parameter alignment and documentation strings

src/simulation/m_global_parameters.fpp


5. src/simulation/m_muscl.fpp ✨ Enhancement +11/-74

Refactor MUSCL module to use centralized THINC compression

• Added selective import of s_thinc_compression from m_thinc module
• Removed old s_interface_compression subroutine implementation (64 lines)
• Updated interface compression call to use new s_thinc_compression with nvtx profiling
• Changed condition to check int_comp > 0 for consistency

src/simulation/m_muscl.fpp


6. src/simulation/m_start_up.fpp ✨ Enhancement +8/-6

Initialize and finalize THINC module in startup sequence

• Added use m_thinc module import with documentation comment
• Integrated calls to s_initialize_thinc_module and s_finalize_thinc_module when int_comp > 0
• Improved variable documentation comments for file existence checks
• Minor formatting and comment improvements

src/simulation/m_start_up.fpp


7. src/simulation/m_mpi_proxy.fpp 🐞 Bug fix +2/-3

Update MPI broadcasts for integer interface compression parameter

• Added int_comp to integer broadcast list for MPI communication
• Removed int_comp from logical broadcast list (now integer type)
• Updated broadcast logic to handle new integer parameter type

src/simulation/m_mpi_proxy.fpp


8. toolchain/mfc/case_validator.py ✨ Enhancement +18/-3

Enhance case validation for interface compression options

• Removed old constraint requiring int_comp to work only with MUSCL reconstruction
• Added new check_interface_compression method with comprehensive validation rules
• Validates int_comp values (0, 1, 2), MTHINC 2D requirement, and reconstruction order constraints
• Added IGR incompatibility check for int_comp > 0

toolchain/mfc/case_validator.py


9. toolchain/mfc/test/cases.py 🧪 Tests +14/-5

Add THINC and MTHINC test cases with dimension awareness

• Added THINC (int_comp=1) and MTHINC (int_comp=2) test cases for WENO order 5
• Updated MUSCL test cases to use integer values (0, 1, 2) instead of boolean strings
• Added dimension-aware testing: MTHINC only tested in 2D and 3D simulations
• Modified alter_muscl function signature to accept dimInfo parameter

toolchain/mfc/test/cases.py


10. toolchain/mfc/params/definitions.py ⚙️ Configuration changes +5/-1

Define integer interface compression parameter with labels

• Added int_comp parameter definition with choices [0, 1, 2] and descriptive labels
• Moved int_comp from LOG to INT parameter type in registration
• Provides user-friendly value labels: "off", "THINC", "MTHINC"

toolchain/mfc/params/definitions.py


11. examples/1D_sodshocktube_muscl/case.py ⚙️ Configuration changes +1/-1

Update example case parameter to integer format

• Updated int_comp from string "T" to integer 1 (THINC)

examples/1D_sodshocktube_muscl/case.py


12. examples/2D_riemann_test_muscl/case.py ⚙️ Configuration changes +1/-1

Update example case parameter to integer format

• Updated int_comp from string "T" to integer 1 (THINC)

examples/2D_riemann_test_muscl/case.py


13. examples/2D_advection_muscl/case.py ⚙️ Configuration changes +1/-1

Update example case parameter to integer format

• Updated int_comp from string "T" to integer 1 (THINC)

examples/2D_advection_muscl/case.py


14. examples/2D_shockdroplet_muscl/case.py ⚙️ Configuration changes +1/-1

Update example case parameter to integer format

• Updated int_comp from string "T" to integer 1 (THINC)

examples/2D_shockdroplet_muscl/case.py


15. examples/3D_shockdroplet_muscl/case.py ⚙️ Configuration changes +1/-1

Update example case parameter to integer format

• Updated int_comp from string "T" to integer 1 (THINC)

examples/3D_shockdroplet_muscl/case.py


16. examples/3D_rayleigh_taylor_muscl/case.py ⚙️ Configuration changes +1/-1

Update example case parameter to integer format

• Updated int_comp from string "T" to integer 1 (THINC)

examples/3D_rayleigh_taylor_muscl/case.py


17. toolchain/mfc/params/descriptions.py 📝 Documentation +1/-1

Update parameter description for interface compression modes

• Updated int_comp description to clarify three options: 0=off, 1=THINC, 2=MTHINC

toolchain/mfc/params/descriptions.py


18. toolchain/mfc/lint_docs.py 📝 Documentation +1/-0

Add interface compression to documentation linting

• Added check_interface_compression to physics documentation coverage checks

toolchain/mfc/lint_docs.py


19. tests/CF73B3B6/golden-metadata.txt 🧪 Tests +157/-0

New MTHINC test case metadata

• New golden metadata file for test case CF73B3B6 with MTHINC configuration

tests/CF73B3B6/golden-metadata.txt


20. tests/885D5D8C/golden-metadata.txt 🧪 Tests +32/-61

Update test metadata for MTHINC branch

• Updated metadata with new test generation timestamp and git commit information

tests/885D5D8C/golden-metadata.txt


21. tests/CE35B602/golden-metadata.txt 🧪 Tests +154/-0

New MTHINC test case metadata

• New golden metadata file for test case CE35B602 with MTHINC configuration

tests/CE35B602/golden-metadata.txt


22. tests/A930AE61/golden-metadata.txt 🧪 Tests +154/-0

New MTHINC test case metadata

• New golden metadata file for test case A930AE61 with MTHINC configuration

tests/A930AE61/golden-metadata.txt


23. tests/8C42A56C/golden-metadata.txt 🧪 Tests +154/-0

New MTHINC test case metadata

• New golden metadata file for test case 8C42A56C with MTHINC configuration

tests/8C42A56C/golden-metadata.txt


24. tests/FE9379D8/golden-metadata.txt 🧪 Tests +154/-0

New MTHINC test case metadata

• New golden metadata file for test case FE9379D8 with MTHINC configuration

tests/FE9379D8/golden-metadata.txt


25. docs/documentation/case.md 📝 Documentation +2/-2

Update documentation for integer interface compression parameter

• Reordered int_comp parameter documentation to appear before flux_lim
• Changed int_comp from logical type to integer with three options: 0=Off, 1=THINC, 2=MTHINC
• Updated description to clarify MTHINC as multi-dimensional variant
• Improved documentation clarity for interface compression functionality

docs/documentation/case.md


26. tests/CF73B3B6/golden.txt 🧪 Tests +16/-0

New MTHINC golden test data file

• Added new golden test file with 16 lines of numerical output data
• Contains conservative and primitive variable data for multiple timesteps
• Includes initial conditions (000000) and evolved state (000050) for 4 conservative and 4 primitive
 variables
• Data represents test case results for MTHINC compression validation

tests/CF73B3B6/golden.txt


27. tests/E11FD23A/golden-metadata.txt 🧪 Tests +154/-0

Test metadata documentation for MTHINC test case

• Added metadata file documenting test generation environment and configuration
• Records CMake build configuration for pre_process, simulation, post_process, and syscheck stages
• Captures compiler information (AppleClang, GNU Fortran), MPI settings, and system CPU details
• Timestamps test creation and git commit information for reproducibility

tests/E11FD23A/golden-metadata.txt


28. docs/module_categories.json 📝 Documentation +2/-1

Add THINC module to documentation categories

• Added m_thinc module to the reconstruction methods category
• Placed after m_variables_conversion in the module list
• Updates documentation structure to include THINC/MTHINC module classification

docs/module_categories.json


29. tests/09195EF4/golden-metadata.txt Additional files +0/-0

...

tests/09195EF4/golden-metadata.txt


30. tests/09195EF4/golden.txt Additional files +0/-0

...

tests/09195EF4/golden.txt


31. tests/0A362971/golden-metadata.txt Additional files +0/-160

...

tests/0A362971/golden-metadata.txt


32. tests/0A362971/golden.txt Additional files +0/-10

...

tests/0A362971/golden.txt


33. tests/1B300F28/golden-metadata.txt Additional files +0/-189

...

tests/1B300F28/golden-metadata.txt


34. tests/1F0C4A44/golden-metadata.txt Additional files +0/-0

...

tests/1F0C4A44/golden-metadata.txt


35. tests/1F0C4A44/golden.txt Additional files +0/-0

...

tests/1F0C4A44/golden.txt


36. tests/2C9844EF/golden-metadata.txt Additional files +0/-156

...

tests/2C9844EF/golden-metadata.txt


37. tests/2C9844EF/golden.txt Additional files +0/-24

...

tests/2C9844EF/golden.txt


38. tests/2D11A034/golden-metadata.txt Additional files +0/-0

...

tests/2D11A034/golden-metadata.txt


39. tests/2D11A034/golden.txt Additional files +0/-0

...

tests/2D11A034/golden.txt


40. tests/2E4AC44C/golden-metadata.txt Additional files +0/-0

...

tests/2E4AC44C/golden-metadata.txt


41. tests/2E4AC44C/golden.txt Additional files +0/-0

...

tests/2E4AC44C/golden.txt


42. tests/3ECA875A/golden-metadata.txt Additional files +0/-0

...

tests/3ECA875A/golden-metadata.txt


43. tests/3ECA875A/golden.txt Additional files +0/-0

...

tests/3ECA875A/golden.txt


44. tests/503EEFF7/golden-metadata.txt Additional files +0/-0

...

tests/503EEFF7/golden-metadata.txt


45. tests/503EEFF7/golden.txt Additional files +0/-0

...

tests/503EEFF7/golden.txt


46. tests/50EC2239/golden-metadata.txt Additional files +0/-176

...

tests/50EC2239/golden-metadata.txt


47. tests/50EC2239/golden.txt Additional files +0/-18

...

tests/50EC2239/golden.txt


48. tests/67C777D8/golden.txt Additional files +0/-506

...

tests/67C777D8/golden.txt


49. tests/82DA2499/golden-metadata.txt Additional files +0/-187

...

tests/82DA2499/golden-metadata.txt


50. tests/845DC70C/golden-metadata.txt Additional files +0/-0

...

tests/845DC70C/golden-metadata.txt


51. tests/845DC70C/golden.txt Additional files +0/-0

...

tests/845DC70C/golden.txt


52. tests/86E9A6D4/golden-metadata.txt Additional files +0/-187

...

tests/86E9A6D4/golden-metadata.txt


53. tests/885D5D8C/golden.txt Additional files +10/-20

...

tests/885D5D8C/golden.txt


54. tests/8876692F/golden-metadata.txt Additional files +0/-160

...

tests/8876692F/golden-metadata.txt


55. tests/8876692F/golden.txt Additional files +0/-14

...

tests/8876692F/golden.txt


56. tests/8C42A56C/golden.txt Additional files +12/-0

...

tests/8C42A56C/golden.txt


57. tests/A930AE61/golden.txt Additional files +12/-0

...

tests/A930AE61/golden.txt


58. tests/AD6ED274/golden.txt Additional files +0/-12

...

tests/AD6ED274/golden.txt


59. tests/B3C724B5/golden-metadata.txt Additional files +0/-0

...

tests/B3C724B5/golden-metadata.txt


60. tests/B3C724B5/golden.txt Additional files +0/-0

...

tests/B3C724B5/golden.txt


61. tests/B903D17E/golden-metadata.txt Additional files +0/-0

...

tests/B903D17E/golden-metadata.txt


62. tests/B903D17E/golden.txt Additional files +0/-0

...

tests/B903D17E/golden.txt


63. tests/BAF51303/golden-metadata.txt Additional files +0/-187

...

tests/BAF51303/golden-metadata.txt


64. tests/BAF51303/golden.txt Additional files +0/-10

...

tests/BAF51303/golden.txt


65. tests/BDC2A773/golden.txt Additional files +0/-16

...

tests/BDC2A773/golden.txt


66. tests/C02D71EE/golden-metadata.txt Additional files +0/-176

...

tests/C02D71EE/golden-metadata.txt


67. tests/C02D71EE/golden.txt Additional files +0/-18

...

tests/C02D71EE/golden.txt


68. tests/CE35B602/golden.txt Additional files +10/-0

...

tests/CE35B602/golden.txt


69. tests/E11FD23A/golden.txt Additional files +10/-0

...

tests/E11FD23A/golden.txt


70. tests/FA4D8FEF/golden-metadata.txt Additional files +0/-189

...

tests/FA4D8FEF/golden-metadata.txt


71. tests/FA4D8FEF/golden.txt Additional files +0/-32

...

tests/FA4D8FEF/golden.txt


72. tests/FA695993/golden-metadata.txt Additional files +0/-150

...

tests/FA695993/golden-metadata.txt


73. tests/FA695993/golden.txt Additional files +0/-137

...

tests/FA695993/golden.txt


74. tests/FE9379D8/golden.txt Additional files +12/-0

...

tests/FE9379D8/golden.txt


Grey Divider

Qodo Logo

@qodo-code-review
Copy link
Copy Markdown
Contributor

qodo-code-review bot commented Apr 2, 2026

Code Review by Qodo

🐞 Bugs (4) 📘 Rule violations (1) 📎 Requirement gaps (0)

Grey Divider


Action required

1. Multi-fluid THINC corruption 🐞 Bug ≡ Correctness ⭐ New
Description
s_thinc_compression updates only contxb/contxe and advxb/advxe (and forces `advxe = 1 -
aTHINC), which is only valid when num_fluids == 2`; with more fluids it will violate
volume-fraction normalization and corrupt partial densities. The case validator currently allows
int_comp values without checking num_fluids, so misconfigured multi-fluid runs won’t be blocked.
Code

src/simulation/m_thinc.fpp[R348-369]

+                                        rho1 = v_rs_ws(j, k, l, contxb)/aC
+                                        rho2 = v_rs_ws(j, k, l, contxe)/(1._wp - aC)
+
+                                        ! Left face (face_pos = -0.5)
+                                        aTHINC = f_mthinc_face_average(nh1, nh2, nh3, d_local, ic_beta, ${REC_DIR}$, -5e-1_wp, &
+                                                                       & num_dims)
+                                        if (aTHINC < ic_eps) aTHINC = ic_eps
+                                        if (aTHINC > 1._wp - ic_eps) aTHINC = 1._wp - ic_eps
+                                        vL_rs_vf_${XYZ}$ (j, k, l, contxb) = rho1*aTHINC
+                                        vL_rs_vf_${XYZ}$ (j, k, l, contxe) = rho2*(1._wp - aTHINC)
+                                        vL_rs_vf_${XYZ}$ (j, k, l, advxb) = aTHINC
+                                        vL_rs_vf_${XYZ}$ (j, k, l, advxe) = 1._wp - aTHINC
+
+                                        ! Right face (face_pos = +0.5)
+                                        aTHINC = f_mthinc_face_average(nh1, nh2, nh3, d_local, ic_beta, ${REC_DIR}$, 5e-1_wp, &
+                                                                       & num_dims)
+                                        if (aTHINC < ic_eps) aTHINC = ic_eps
+                                        if (aTHINC > 1._wp - ic_eps) aTHINC = 1._wp - ic_eps
+                                        vR_rs_vf_${XYZ}$ (j, k, l, contxb) = rho1*aTHINC
+                                        vR_rs_vf_${XYZ}$ (j, k, l, contxe) = rho2*(1._wp - aTHINC)
+                                        vR_rs_vf_${XYZ}$ (j, k, l, advxb) = aTHINC
+                                        vR_rs_vf_${XYZ}$ (j, k, l, advxe) = 1._wp - aTHINC
Evidence
For non-IGR volume-fraction model runs, MFC stores **N** volume fractions for **N** fluids (not
N−1). However, THINC/MTHINC compression only overwrites the first and last
volume-fraction/continuity slots, leaving any intermediate fluids untouched and breaking the
sum-to-one constraint. The Python validator introduced/updated for integer int_comp does not
restrict this usage to num_fluids==2, so users can reach this incorrect code path.

src/simulation/m_global_parameters.fpp[889-904]
src/simulation/m_thinc.fpp[323-369]
toolchain/mfc/case_validator.py[370-384]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`int_comp` (THINC/MTHINC) compression currently assumes exactly 2 fluids by writing only `contxb/contxe` and `advxb/advxe` and setting `advxe = 1 - aTHINC`. When `num_fluids > 2`, this silently corrupts reconstructed state (volume fractions no longer sum to 1 and intermediate fluids are inconsistent).

### Issue Context
- `m_global_parameters` stores `num_fluids` volume fractions when `igr = F`.
- `s_thinc_compression` only updates the first+last fluid slots.
- The case validator does not prohibit `int_comp > 0` for `num_fluids != 2`.

### Fix Focus Areas
- toolchain/mfc/case_validator.py[370-384]
- src/simulation/m_thinc.fpp[323-412]
- src/simulation/m_start_up.fpp[926-931]

### Recommended fix
1. In `check_interface_compression`, fetch `num_fluids` and **prohibit** `int_comp > 0` unless `num_fluids == 2` (and optionally `model_eqns` is a volume-fraction-capable model).
2. Add a Fortran-side runtime guard (e.g., in startup/checker) that errors out if `int_comp > 0` and `num_fluids /= 2`, to protect non-toolchain execution paths.
3. (Optional) If multi-fluid compression is desired, generalize the algorithm to update all `adv_idx` and all `cont_idx` consistently rather than hard-coding `contxb/contxe` and `advxb/advxe`.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. int_comp absent on device 🐞 Bug ≡ Correctness
Description
In m_thinc:s_thinc_compression, the OpenACC-parallel kernel branches on int_comp (THINC vs MTHINC)
under default(present), but int_comp is not declared/created for the device in m_global_parameters,
risking an OpenACC runtime 'not present' failure in GPU builds. This risk is introduced because
int_comp is now referenced inside device code instead of only host-side conditionals.
Code

src/simulation/m_thinc.fpp[R380-383]

+                            if (aC >= ic_eps .and. aC <= 1._wp - ic_eps) then
+
+                                if (int_comp == 2 .and. n > 0) then
+                                    ! MTHINC: multi-dimensional face averages
Evidence
The project’s OpenACC loop macro defaults to default(present), meaning variables used inside the
GPU region must already be present on the device. The new THINC kernel references int_comp inside
the GPU loop, but the global parameter module’s GPU_DECLARE lists do not include int_comp, so
there is no clear path that makes it device-present.

src/common/include/acc_macros.fpp[132-158]
src/simulation/m_thinc.fpp[356-384]
src/simulation/m_global_parameters.fpp[205-216]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`int_comp` is referenced inside OpenACC GPU kernels under `default(present)`, but it is not explicitly declared/created on the device. This can produce OpenACC runtime failures (variable not present) in GPU builds.
### Issue Context
- `ACC_PARALLEL_LOOP` defaults to `default(present)`.
- `m_thinc:s_thinc_compression` branches on `int_comp` inside `$:GPU_PARALLEL_LOOP`.
- `m_global_parameters` contains the central `GPU_DECLARE` lists for globals, but does not include `int_comp`.
### Fix Focus Areas
- src/simulation/m_thinc.fpp[356-384]
- src/simulation/m_global_parameters.fpp[205-216]
- src/common/include/acc_macros.fpp[132-158]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. vR densities use vL 🐞 Bug ≡ Correctness
Description
In m_thinc:s_thinc_compression (THINC path), rho_b and rho_e are computed only from vL_rs_vf_*
ratios and then applied to overwrite both vL_rs_vf_* and vR_rs_vf_* densities, discarding the
pre-compression vR reconstructed density/alpha ratios. Since WENO/MUSCL compute vL and vR using
different polynomials, this can make the right-face state inconsistent and distort fluxes.
Code

src/simulation/m_thinc.fpp[R453-473]

+                                        ! Save original density ratios before THINC overwrites them
+                                        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))
+
+                                        ! Left reconstruction
+                                        aTHINC = qmin + 5e-1_wp*qmax*(1._wp + sgn*A)
+                                        if (aTHINC < ic_eps) aTHINC = ic_eps
+                                        if (aTHINC > 1._wp - ic_eps) aTHINC = 1._wp - ic_eps
+                                        vL_rs_vf_${XYZ}$ (j, k, l, contxb) = rho_b*aTHINC
+                                        vL_rs_vf_${XYZ}$ (j, k, l, contxe) = rho_e*(1._wp - aTHINC)
+                                        vL_rs_vf_${XYZ}$ (j, k, l, advxb) = aTHINC
+                                        vL_rs_vf_${XYZ}$ (j, k, l, advxe) = 1._wp - aTHINC
+
+                                        ! Right reconstruction
+                                        aTHINC = qmin + 5e-1_wp*qmax*(1._wp + sgn*(tanh(beta_eff) + A)/(1._wp + A*tanh(beta_eff)))
+                                        if (aTHINC < ic_eps) aTHINC = ic_eps
+                                        if (aTHINC > 1._wp - ic_eps) aTHINC = 1._wp - ic_eps
+                                        vR_rs_vf_${XYZ}$ (j, k, l, contxb) = rho_b*aTHINC
+                                        vR_rs_vf_${XYZ}$ (j, k, l, contxe) = rho_e*(1._wp - aTHINC)
+                                        vR_rs_vf_${XYZ}$ (j, k, l, advxb) = aTHINC
+                                        vR_rs_vf_${XYZ}$ (j, k, l, advxe) = 1._wp - aTHINC
Evidence
The THINC branch explicitly derives density ratios solely from vL and then uses those same ratios to
set vR values. Separately, WENO reconstruction computes vL and vR using different coefficient sets
(cbL vs cbR), so vR generally differs from vL before compression; overwriting vR with vL-derived
ratios ignores that reconstruction.

src/simulation/m_thinc.fpp[453-473]
src/simulation/m_weno.fpp[729-766]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
In the THINC (1D) compression path, right-face densities (`vR_rs_vf_*`) are overwritten using density ratios computed from the left-face reconstruction (`vL_rs_vf_*`). This discards the right-face reconstructed density/alpha ratios and can make the right state inconsistent.
### Issue Context
WENO/MUSCL reconstruct `vL` and `vR` with different coefficient sets, so they are not generally identical before compression. THINC should preserve each face’s density ratio (or use a consistent cell-averaged ratio) when updating densities alongside alpha.
### Fix Focus Areas
- src/simulation/m_thinc.fpp[453-473]
- src/simulation/m_weno.fpp[729-766]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

4. Uncopied GPU THINC constants 🐞 Bug ☼ Reliability ⭐ New
Description
m_thinc declares initialized constants (gq3_pts, gq3_wts, ln2) with
GPU_DECLARE(create=...), which (per the macro expansion) creates device storage without copying
host initialization values. On OpenACC builds this can leave these constants undefined on device,
producing incorrect MTHINC integrals.
Code

src/simulation/m_thinc.fpp[R30-35]

+    real(wp) :: gq3_pts(3) = [-5e-1_wp*0.7745966692414834_wp, 0._wp, 5e-1_wp*0.7745966692414834_wp]
+    !> Weights: 5/18, 8/18, 5/18
+    real(wp) :: gq3_wts(3) = [5._wp/18._wp, 8._wp/18._wp, 5._wp/18._wp]
+    !> ln(2)
+    real(wp) :: ln2 = 0.6931471805599453_wp
+    $:GPU_DECLARE(create='[gq3_pts, gq3_wts, ln2]')
Evidence
The OpenACC ACC_DECLARE macro builds a !$acc declare directive from copyin and create
clauses; using only create means no copyin occurs. In m_thinc, the Gauss quadrature arrays and
ln2 are initialized on the host but only declare create is used and there is no later
GPU_UPDATE, so device-side values depend on compiler/runtime behavior and may be uninitialized.

src/simulation/m_thinc.fpp[28-35]
src/common/include/acc_macros.fpp[176-191]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`gq3_pts`, `gq3_wts`, and `ln2` are host-initialized module variables but are declared on the device with `GPU_DECLARE(create=...)`, which does not copy initial values to the device. This risks undefined values on OpenACC devices and wrong MTHINC integrals.

### Issue Context
`ACC_DECLARE` composes `!$acc declare` from `copyin` and `create`. Using only `create` allocates device memory without host->device initialization.

### Fix Focus Areas
- src/simulation/m_thinc.fpp[28-35]
- src/common/include/acc_macros.fpp[176-191]

### Recommended fix
Prefer one of:
1. Change to a read-only copyin declaration:
  - Replace `GPU_DECLARE(create='[gq3_pts, gq3_wts, ln2]')` with `GPU_DECLARE(copyinReadOnly='[gq3_pts, gq3_wts, ln2]')`.

2. Or keep `create` but explicitly copy values once during initialization:
  - Add `GPU_UPDATE(device='[gq3_pts, gq3_wts, ln2]')` in `s_initialize_thinc_module` (or another guaranteed initialization path) before any GPU kernels use them.

Either approach ensures deterministic device-side constants across OpenACC compilers/runtimes.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


5. Missing precheck/build/test evidence 📘 Rule violation ≡ Correctness
Description
The PR description does not document running ./mfc.sh precheck, ./mfc.sh build, or relevant
automated tests after adding a new Fortran module and changing parameter typing. Without this, CI
readiness and correctness of the change cannot be confirmed from the PR.
Code

src/simulation/m_thinc.fpp[R7-14]

+!> @brief THINC and MTHINC interface compression for volume fraction sharpening.
+!! THINC (int_comp=1): 1D directional interface compression applied after
+!! MUSCL/WENO reconstruction. Uses hyperbolic tangent profile per dimension.
+!! MTHINC (int_comp=2): Multi-dimensional THINC that reconstructs a tanh
+!! profile oriented along the interface normal (computed from the gradient
+!! of alpha), then integrates that profile over each cell face using
+!! Gaussian quadrature. A Newton iteration enforces the conservation
+!! constraint (cell-averaged alpha is preserved).
Evidence
Compliance ID 1 requires precheck, build, and relevant tests to be run and pass. The PR description
lists manual case runs/perf results but does not mention running the required commands, while the
diff shows substantial new Fortran functionality and a parameter type change that should be covered
by those checks.

CLAUDE.md
src/simulation/m_thinc.fpp[7-14]
toolchain/mfc/params/definitions.py[983-986]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The PR does not provide evidence that required CI-equivalent checks were run (`./mfc.sh precheck`, `./mfc.sh build`, and relevant tests).
## Issue Context
This PR adds a new Fortran module for THINC/MTHINC and changes the `int_comp` parameter type/handling; these changes should be validated by precheck/build and appropriate tests.
## Fix Focus Areas
- src/simulation/m_thinc.fpp[7-14]
- toolchain/mfc/params/definitions.py[983-986]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

ⓘ The new review experience is currently in Beta. Learn more

Grey Divider

Qodo Logo

@wilfonba
Copy link
Copy Markdown
Contributor Author

wilfonba commented Apr 3, 2026

@sbryngelson, I believe this is ready to merge. The failed benchmark shows good performance if you look at the generated comment. There was just some sort of error with the Slurm job. I can rerun it still if you want though.

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.

3 participants