Skip to content

Isothermal Boundary Conditions for Reacting Flows#1361

Open
DimAdam-01 wants to merge 20 commits intoMFlowCode:masterfrom
DimAdam-01:Isothermal_Slip_NoSlip
Open

Isothermal Boundary Conditions for Reacting Flows#1361
DimAdam-01 wants to merge 20 commits intoMFlowCode:masterfrom
DimAdam-01:Isothermal_Slip_NoSlip

Conversation

@DimAdam-01
Copy link
Copy Markdown
Contributor

Description

Summarize your changes and the motivation behind them.

This PR introduces isothermal wall boundary conditions to support accurate heat transfer modeling in chemically reacting flow simulations, specifically targeting solid fuel combustion geometries/

Fixes #(issue)

Type of change

  • Bug fix
  • New feature
  • Refactor
  • Documentation
  • Other: describe

Key Changes & Additions:

Isothermal Boundaries: Added support for isothermal_in and isothermal_out flags alongside T
wall_in and Twall_out parameters across all domain boundaries in m_boundary_common.fpp.

Updated the boundary condition (slip and no-slip) logic to correctly evaluate the ghost cell temperature based on the specified wall temperature and the interior domain state, driving the correct heat flux.

Testing

How did you test your changes?

Test 1: Dual Isothermal Wall.

image

Test 2: 2D Flow in a Channel with Isothermal walls

2D_Thermal_Plate.mp4
image

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
  • @claude full review — Claude full review (also triggers on PR open/reopen/ready)
  • Add label claude-full-review — Claude full review via label

@DimAdam-01 DimAdam-01 changed the title Feature: Add Isothermal Boundary Conditions for Reacting Flows Isothermal Boundary Conditions for Reacting Flows Apr 7, 2026
Dimitrios Adam and others added 2 commits April 7, 2026 15:20
@sbryngelson
Copy link
Copy Markdown
Member

Code review

Found 7 issues:

  1. s_periodic declares q_T_sf as non-optional while all other BC subroutines and its callers treat it as optional — passing an absent optional actual to a non-optional dummy is a Fortran standard violation; any periodic BC run without chemistry will crash or produce undefined behavior.

integer, intent(in) :: k, l
integer :: j, q, i
type(scalar_field), intent(inout) :: q_T_sf
if (bc_dir == 1) then !< x-direction
if (bc_loc == -1) then !< bc_x%beg

  1. q_T_sf is accessed as q_T_sf%sf(...) in routines that declare it optional, guarded only by if (chemistry) without present(q_T_sf) — if any call site omits the argument while chemistry=.true., this dereferences an absent pointer. The correct guard is if (chemistry .and. present(q_T_sf)).

integer, intent(in) :: k, l
integer :: j, i
type(scalar_field), optional, intent(inout) :: q_T_sf
if (bc_dir == 1) then !< x-direction
if (bc_loc == -1) then ! bc_x%beg

  1. Hardcoded 600.0_wp in s_slip_wall y-direction beginning boundary — the isothermal ghost-cell formula should be 2._wp*bc_y%Twall_in - q_T_sf%sf(k, j-1, l), but uses a magic number instead, silently ignoring the user-specified bc_y%Twall_in for any wall temperature other than 300 K. Every other direction in both s_slip_wall and s_no_slip_wall uses the parameterized formula correctly.

if (bc_y%isothermal_in) then
do j = 1, buff_size
q_T_sf%sf(k, -j, l) = 600.0_wp - q_T_sf%sf(k, j - 1, l)
end do
else
do j = 1, buff_size

  1. When igr=T and chemistry=T, q_T_sf is not passed to s_write_serial_boundary_condition_files — the igr branch omits q_T_sf, but s_pack_boundary_condition_buffers accesses q_T_sf%sf(...) under if (chemistry) without a present() guard, causing a NULL dereference.

if (bc_io) then
if (igr) then
call s_write_serial_boundary_condition_files(q_cons_vf, bc_type, t_step_dir, old_grid)
else
call s_write_serial_boundary_condition_files(q_prim_vf, bc_type, t_step_dir, old_grid, q_T_sf)
end if

  1. NaN check in MPI unpack reads the wrong cell index — after writing to q_T_sf%sf(j + unpack_offset, k, l), the NaN check inspects q_T_sf%sf(j, k, l) (without the offset) in all three MPI directions. The correct pattern, used for all other variables in the same function, is to check the cell that was just written. This silently fails to detect NaNs in received data.

do j = -buff_size, -1
r = nVar + v_size*(j + buff_size*((k + 1) + (n + 1)*l))
q_T_sf%sf(j + unpack_offset, k, l) = real(buff_recv(r), kind=stp)
#if defined(__INTEL_COMPILER)
if (ieee_is_nan(q_T_sf%sf(j, k, l))) then
print *, "Error", j, k, l, i
error stop "NaN(s) in recv"
end if
#endif

  1. error stop used instead of call s_mpi_abort() in the three new NaN-detection blocks (one per MPI direction) — CLAUDE.md says "NEVER use stop or error stop. Use call s_mpi_abort()". The existing NaN handlers directly above in the same file use call s_mpi_abort("NaN(s) in recv") correctly.

if (ieee_is_nan(q_T_sf%sf(j, k, l))) then
print *, "Error", j, k, l, i
error stop "NaN(s) in recv"
end if
#endif

  1. New isothermal_in/isothermal_out/Twall_in/Twall_out fields are initialized in src/simulation/m_global_parameters.fpp but not in src/pre_process/ or src/post_process/.claude/rules/parameter-system.md requires all three targets to be updated for shared parameters. The boundary condition code that checks these fields lives in src/common/ and is called by all three executables.

#:for dir in {'x', 'y', 'z'}
bc_${dir}$%isothermal_in = .false.
bc_${dir}$%isothermal_out = .false.
bc_${dir}$%Twall_in = dflt_real
bc_${dir}$%Twall_out = dflt_real
#:endfor

🤖 Generated with Claude Code

- If this code review was useful, please react with 👍. Otherwise, react with 👎.

@sbryngelson sbryngelson added the claude-full-review Trigger Claude Code review label Apr 9, 2026
@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 9, 2026

Claude Code Review

Head SHA: 87edb94

Files changed:

  • 23
  • src/common/m_boundary_common.fpp
  • src/common/m_mpi_common.fpp
  • src/common/m_chemistry.fpp
  • src/simulation/m_mpi_proxy.fpp
  • src/simulation/m_global_parameters.fpp
  • src/simulation/m_start_up.fpp
  • src/pre_process/m_initial_condition.fpp
  • toolchain/mfc/params/definitions.py
  • toolchain/mfc/test/cases.py
  • src/common/include/2dHardcodedIC.fpp

Findings

1. Hardcoded wall temperature in s_slip_wall y-direction (correctness bug)

src/common/m_boundary_common.fpp, hunk for s_slip_wall, bc_dir == 2 / bc_loc == -1:

+                if (bc_y%isothermal_in) then
+                    do j = 1, buff_size
+                        q_T_sf%sf(k, -j, l) = 600.0_wp - q_T_sf%sf(k, j - 1, l)

The y-direction beginning slip wall hardcodes 600.0_wp instead of 2._wp*bc_y%Twall_in. Every other isothermal case (x beg/end, y end, z beg/end) in both s_slip_wall and s_no_slip_wall correctly uses 2._wp*bc_*%Twall_in/out - q_T_sf%sf(...). The test cases all use bc_y%beg = -16 (no-slip), so this code path is not exercised by any regression test in this PR.

2. q_T_sf is not optional in s_periodic (correctness/crash bug)

src/common/m_boundary_common.fpp, s_periodic signature:

+        type(scalar_field), intent(inout)  :: q_T_sf   ! NOT optional

All other modified BC routines (s_ghost_cell_extrapolation, s_symmetry, s_slip_wall, s_no_slip_wall, s_dirichlet) correctly declare q_T_sf as optional. s_populate_variables_buffers declares it optional and passes it through to s_periodic. Passing an absent optional actual argument to a non-optional dummy argument is undefined behaviour in Fortran (typically a runtime segfault in non-chemistry periodic-BC cases).

3. Leading space in MPI proxy broadcast string list (MPI correctness bug)

src/simulation/m_mpi_proxy.fpp:

+            & 'bc_x%isothermal_in', 'bc_y%isothermal_in', 'bc_z%isothermal_in',        &
+            &' bc_x%isothermal_out', 'bc_y%isothermal_out', 'bc_z%isothermal_out', &

The second continuation line starts with &' bc_x%...' — the string literal includes a leading space ( bc_x%isothermal_out). If these strings are used for name-matching during broadcast dispatch, the three *%isothermal_out parameters will silently fail to be broadcast in parallel runs, leaving them at default values on all non-root ranks.

4. error stop used inside MPI receive code (forbidden pattern)

src/common/m_mpi_common.fpp, three new unpack blocks for q_T_sf (x, y, z directions):

+#if defined(__INTEL_COMPILER)
+                                    if (ieee_is_nan(q_T_sf%sf(j, k, l))) then
+                                        print *, "Error", j, k, l, i
+                                        error stop "NaN(s) in recv"
+                                    end if
+#endif

error stop is explicitly forbidden by project rules; use call s_mpi_abort() or @:PROHIBIT(). Beyond policy, error stop in an MPI job will hang all other ranks. The variable i referenced in the print statement has no local declaration in these new blocks and likely refers to a stale outer-scope value.

5. Placeholder descriptions committed to definitions.py

toolchain/mfc/params/definitions.py:

+         "Twall_in"      : "Hehe1",
+        "Twall_out"    : "hehe2",

These debug placeholders will be surfaced directly to users via ./mfc.sh params Twall.

Dimitrios Adam added 2 commits April 9, 2026 23:41
@DimAdam-01 DimAdam-01 marked this pull request as ready for review April 10, 2026 13:39
@DimAdam-01 DimAdam-01 requested a review from sbryngelson as a code owner April 10, 2026 13:39
@qodo-code-review
Copy link
Copy Markdown
Contributor

qodo-code-review bot commented Apr 10, 2026

Code Review by Qodo

🐞 Bugs (4)   📘 Rule violations (0)   📎 Requirement gaps (0)   🎨 UX Issues (0)
🐞\ ≡ Correctness (3) ☼ Reliability (1)

Grey Divider


Action required

1. Unsafe optional q_T_sf use 🐞
Description
m_boundary_common and MPI comm code write/read q_T_sf under if (chemistry) / `if (chemistry .and.
chem_params%diffusion) without checking present(q_T_sf)`, but several call sites still invoke
buffer population without passing q_T_sf. With chemistry enabled this can dereference an absent
optional argument (undefined behavior: crash or memory corruption).
Code

src/common/m_boundary_common.fpp[R300-304]

+                if (chemistry) then
+                    do j = 1, buff_size
+                        q_T_sf%sf(-j, k, l) = q_T_sf%sf(0, k, l)
+                    end do
+                end if
Evidence
q_T_sf is declared optional but is dereferenced whenever chemistry is true. The repo contains
paths that call s_populate_variables_buffers(...) without q_T_sf (e.g., down_sample in pre_process
and simulation), making the optional argument absent while the callee still dereferences it.

src/common/m_boundary_common.fpp[284-304]
src/common/m_boundary_common.fpp[827-859]
src/common/m_mpi_common.fpp[499-592]
src/pre_process/m_data_output.fpp[409-421]
src/simulation/m_start_up.fpp[741-753]
src/simulation/m_time_steppers.fpp[602-609]

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

### Issue description
Several boundary-condition and MPI-communication routines accept `q_T_sf` as an **optional** argument but dereference it whenever `chemistry` (and sometimes `chem_params%diffusion`) is enabled. There are existing call sites that invoke `s_populate_variables_buffers(...)` without passing `q_T_sf` (e.g., down-sampling output paths), which makes dereferencing the optional argument undefined behavior (can crash or silently corrupt).

### Issue Context
This PR introduced `q_T_sf` support into BC fill + MPI exchange, but the implementation currently relies on an implicit contract (“if chemistry then q_T_sf is always passed”) that the codebase does not consistently satisfy.

### Fix Focus Areas
- Add `present(q_T_sf)` guards around all `q_T_sf%sf(...)` accesses (and similarly in MPI pack/unpack) so the routines are safe when `q_T_sf` is omitted.
- Ensure temperature communication/ghost filling happens whenever it is truly required (e.g., chemistry+diffusion paths that subsequently compute diffusion fluxes).

- src/common/m_boundary_common.fpp[284-365]
- src/common/m_boundary_common.fpp[827-927]
- src/common/m_boundary_common.fpp[1152-1236]
- src/common/m_mpi_common.fpp[499-593]
- src/common/m_mpi_common.fpp[788-830]

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


2. bc_x Twall not broadcast 🐞
Description
post_process MPI input broadcast omits bc_x%Twall_in/out, so non-root ranks keep default wall
temperatures and produce incorrect parallel post-processing results for x-direction isothermal
walls. This is silent data corruption in MPI runs.
Code

src/post_process/m_mpi_proxy.fpp[R132-138]

        #:for VAR in [ 'pref', 'rhoref', 'R0ref', 'poly_sigma', 'Web', 'Ca', &
-            & 'Re_inv', 'Bx0', 'sigma', 't_save', 't_stop',   &
-            & 'x_output%beg', 'x_output%end', 'y_output%beg', &
-            & 'y_output%end', 'z_output%beg', 'z_output%end']
+            & 'Re_inv', 'Bx0', 'sigma', 't_save', 't_stop',      &
+            & 'x_output%beg', 'x_output%end', 'y_output%beg',    &
+            & 'y_output%end', 'z_output%beg', 'z_output%end',    &
+            & 'bc_y%Twall_in', 'bc_y%Twall_out', 'bc_z%Twall_in',&
+            & 'bc_z%Twall_out']
            call MPI_BCAST(${VAR}$, 1, mpi_p, 0, MPI_COMM_WORLD, ierr)
Evidence
The post_process broadcast list includes bc_y/bc_z Twall fields but not bc_x Twall fields, while
defaults are initialized to dflt_real. Simulation does broadcast all Twall fields, highlighting
the inconsistency.

src/post_process/m_mpi_proxy.fpp[132-139]
src/simulation/m_mpi_proxy.fpp[127-142]
src/simulation/m_global_parameters.fpp[767-772]

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 post_process MPI runs, `bc_x%Twall_in` and `bc_x%Twall_out` are not broadcast from rank 0. Non-root ranks therefore keep default values, producing incorrect post-processing for x-direction isothermal boundaries.

### Issue Context
The simulation and pre_process MPI proxies broadcast all 6 Twall values; post_process broadcasts only y/z.

### Fix Focus Areas
- Add `bc_x%Twall_in` and `bc_x%Twall_out` to the real-parameter `MPI_BCAST` list.

- src/post_process/m_mpi_proxy.fpp[132-139]

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


3. q_T_sf stale after smoothing 🐞
Description
pre_process computes q_T_sf before elliptic smoothing, but elliptic smoothing overwrites q_prim_vf
and does not recompute q_T_sf afterward. This leaves q_T_sf inconsistent with the final smoothed
initial condition, and any later use/serialization of q_T_sf (e.g., bc_io boundary buffers) will be
wrong.
Code

src/pre_process/m_initial_condition.fpp[R141-149]

+        if (chemistry) call s_compute_T_from_primitives(q_T_sf, q_prim_vf, idwint)

-        call s_convert_primitive_to_conservative_variables(q_prim_vf, q_cons_vf)
+        if (elliptic_smoothing .and. chemistry) then
+            call s_elliptic_smoothing(q_prim_vf, bc_type, q_T_sf)
+        else if (elliptic_smoothing) then
+            call s_elliptic_smoothing(q_prim_vf, bc_type)
+        end if

-        if (chemistry) call s_compute_T_from_primitives(q_T_sf, q_prim_vf, idwint)
+        call s_convert_primitive_to_conservative_variables(q_prim_vf, q_cons_vf)
Evidence
The initial-condition generator now calls s_compute_T_from_primitives before smoothing. The
smoothing routine updates q_prim_vf in-place but never updates/recomputes q_T_sf. Meanwhile,
boundary-condition buffer packing serializes temperature slices from q_T_sf, so stale values can
be written.

src/pre_process/m_initial_condition.fpp[137-150]
src/pre_process/m_perturbation.fpp[86-137]
src/common/m_boundary_common.fpp[2052-2068]

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

### Issue description
`q_T_sf` is computed from primitives before elliptic smoothing, but smoothing modifies `q_prim_vf` without updating `q_T_sf`. This makes temperature inconsistent with the final smoothed primitives and can lead to incorrect temperature written/used downstream (notably for `bc_io` temperature buffer serialization).

### Issue Context
`m_perturbation:s_elliptic_smoothing` only uses `q_T_sf` to populate ghost/buffer regions; it never recomputes temperature from the updated primitives.

### Fix Focus Areas
- After elliptic smoothing completes (and before any output/serialization that uses `q_T_sf`), recompute `q_T_sf` from the final `q_prim_vf`.
- Keep the pre-smoothing computation if it is needed to apply isothermal BCs during smoothing, but add a post-smoothing recomputation step.

- src/pre_process/m_initial_condition.fpp[137-150]
- src/pre_process/m_perturbation.fpp[86-137]

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



Remediation recommended

4. Twall not required 🐞
Description
The validator enforces chemistry/diffusion and wall BC codes for isothermal flags but does not
require Twall_in/out to be provided, so cases can run using default/sentinel wall temperatures and
silently compute incorrect ghost temperatures/heat fluxes. This allows misconfigured isothermal
boundaries to pass validation.
Code

toolchain/mfc/case_validator.py[R1291-1316]

+        # Fetch global chemistry and diffusion flags
+        chemistry = self.get("chemistry", "F") == "T"
+        diffusion = self.get("chem_params%diffusion", "F") == "T"
+
+        # Define what constitutes a wall (-15 for slip, -16 for no-slip)
+        wall_bcs = [-15, -16]
+
+        for dir in ["x", "y", "z"]:
+            isothermal_in = self.get(f"bc_{dir}%isothermal_in", "F") == "T"
+            isothermal_out = self.get(f"bc_{dir}%isothermal_out", "F") == "T"
+            bc_beg = self.get(f"bc_{dir}%beg")
+            bc_end = self.get(f"bc_{dir}%end")
+
+            if isothermal_in:
+                # Prohibit isothermal boundaries if chemistry or diffusion are disabled
+                self.prohibit(not chemistry or not diffusion, f"Isothermal In (bc_{dir}%isothermal_in) requires both chemistry='T' and chem_params%diffusion='T' to calculate heat conduction.")
+
+                # Prohibit if neither beg nor end is set to a valid wall condition
+                self.prohibit(bc_beg not in wall_bcs, f"Isothermal In (bc_{dir}%isothermal_in) requires a wall. Set bc_{dir}%beg to -15 (slip) or -16 (no-slip).")
+
+            if isothermal_out:
+                # Prohibit isothermal boundaries if chemistry or diffusion are disabled
+                self.prohibit(not chemistry or not diffusion, f"Isothermal Out (bc_{dir}%isothermal_out) requires both chemistry='T' and chem_params%diffusion='T' to calculate heat conduction.")
+
+                # Prohibit if neither beg nor end is set to a valid wall condition
+                self.prohibit(bc_end not in wall_bcs, f"Isothermal Out (bc_{dir}%isothermal_out) requires a wall. Set bc_{dir}%end to -15 (slip) or -16 (no-slip).")
Evidence
When isothermal is enabled, ghost temperature is computed using bc_%Twall_*, which defaults to
dflt_real in global parameter initialization. The new validator logic never checks
presence/validity of Twall_in/out, so missing Twall inputs won’t be caught pre-run.

toolchain/mfc/case_validator.py[1291-1316]
src/simulation/m_global_parameters.fpp[767-772]
src/common/m_boundary_common.fpp[849-858]

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

### Issue description
Cases can enable `bc_%isothermal_in/out` without providing `bc_%Twall_in/out`. The code will then use default/sentinel values for wall temperature in ghost temperature calculations, producing incorrect results without a clear validation error.

### Issue Context
The PR adds validation for chemistry/diffusion and wall BC codes, but it does not validate that the required wall temperature is actually supplied.

### Fix Focus Areas
- When `bc_{dir}%isothermal_in` is true, prohibit missing `bc_{dir}%Twall_in`.
- When `bc_{dir}%isothermal_out` is true, prohibit missing `bc_{dir}%Twall_out`.
- Optionally: validate Twall is numeric and > 0.

- toolchain/mfc/case_validator.py[1291-1316]

ⓘ 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

@qodo-code-review
Copy link
Copy Markdown
Contributor

qodo-code-review bot commented Apr 10, 2026

Code Review by Qodo

🐞 Bugs (7)   📘 Rule violations (0)   📎 Requirement gaps (0)   🎨 UX Issues (0)
🐞\ ≡ Correctness (5) ☼ Reliability (2) ⭐ New (3)

Grey Divider


Action required

1. MPI q_T_sf presence ignored 🐞
Description
s_mpi_sendrecv_variables_buffers packs/unpacks q_T_sf whenever `chemistry .and.
chem_params%diffusion is true, but q_T_sf` is an optional argument and is dereferenced without
present() checks. If any caller omits q_T_sf (currently true in several places), MPI buffer
packing/unpacking will read/write through an absent optional argument.
Code

src/common/m_mpi_common.fpp[R525-531]

+        else if (chemistry .and. chem_params%diffusion) then
+            v_size = nVar + 1
+            buffer_counts = (/buff_size*v_size*(n + 1)*(p + 1), buff_size*v_size*(m + 2*buff_size + 1)*(p + 1), &
+                             & buff_size*v_size*(m + 2*buff_size + 1)*(n + 2*buff_size + 1)/)
        else
            v_size = nVar
            buffer_counts = (/buff_size*v_size*(n + 1)*(p + 1), buff_size*v_size*(m + 2*buff_size + 1)*(p + 1), &
Evidence
The MPI routine sizes v_size = nVar + 1 under chemistry .and. chem_params%diffusion and then
directly reads/writes q_T_sf%sf(...) under the same condition, but q_T_sf is declared optional
and never checked with present(q_T_sf). This is unsafe when upstream calls omit the argument.

src/common/m_mpi_common.fpp[499-593]
src/common/m_mpi_common.fpp[520-533]

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

### Issue description
MPI send/recv for ghost buffers packs/unpacks temperature (`q_T_sf`) based solely on global flags (`chemistry` and `chem_params%diffusion`) even though `q_T_sf` is an optional dummy argument. This can dereference an absent optional argument and crash.

### Issue Context
Some code paths call `s_mpi_sendrecv_variables_buffers` (via `s_populate_variables_buffers`) without providing `q_T_sf` (e.g., conservative-only communications and downsample paths). The MPI routine must not assume `q_T_sf` is present.

### Fix Focus Areas
- src/common/m_mpi_common.fpp[499-593]
- src/common/m_mpi_common.fpp[564-624]
- src/common/m_mpi_common.fpp[625-713]
- src/common/m_mpi_common.fpp[756-974]

### What to change
1. Introduce a local logical like `has_T = present(q_T_sf) .and. chemistry .and. chem_params%diffusion`.
2. Use `has_T` (not just chemistry/diffusion) to:
  - set `v_size` (nVar vs nVar+1)
  - compute `buffer_counts`
  - pack `buff_send` temperature slot
  - unpack into `q_T_sf`
3. Optionally add a defensive abort if `chemistry .and. chem_params%diffusion` is true in a code path that *requires* temperature exchange but `present(q_T_sf)` is false.

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


2. Missing bc_x Twall broadcast 🐞
Description
In post_process MPI input broadcast, bc_x%Twall_in/out are not broadcast to non-root ranks,
leaving them at the default dflt_real and making post-processing rank-dependent for x-isothermal
cases. Post_process does call boundary buffer population (which can apply isothermal logic), so
incorrect bc_x%Twall_* affects computed ghost temperatures and derived outputs.
Code

src/post_process/m_mpi_proxy.fpp[R132-138]

        #:for VAR in [ 'pref', 'rhoref', 'R0ref', 'poly_sigma', 'Web', 'Ca', &
-            & 'Re_inv', 'Bx0', 'sigma', 't_save', 't_stop',   &
-            & 'x_output%beg', 'x_output%end', 'y_output%beg', &
-            & 'y_output%end', 'z_output%beg', 'z_output%end']
+            & 'Re_inv', 'Bx0', 'sigma', 't_save', 't_stop',      &
+            & 'x_output%beg', 'x_output%end', 'y_output%beg',    &
+            & 'y_output%end', 'z_output%beg', 'z_output%end',    &
+            & 'bc_y%Twall_in', 'bc_y%Twall_out', 'bc_z%Twall_in',&
+            & 'bc_z%Twall_out']
            call MPI_BCAST(${VAR}$, 1, mpi_p, 0, MPI_COMM_WORLD, ierr)
Evidence
s_mpi_bcast_user_inputs in post_process broadcasts bc_y%Twall_* and bc_z%Twall_* but omits
bc_x%Twall_*. Post_process then computes temperature and calls s_populate_variables_buffers,
which applies wall temperature logic (e.g., in slip wall) using bc_x%Twall_in/bc_x%Twall_out;
without broadcasting, only rank 0 has the intended values.

src/post_process/m_mpi_proxy.fpp[132-139]
src/post_process/m_start_up.fpp[166-173]
src/common/m_boundary_common.fpp[849-857]
src/pre_process/m_mpi_proxy.fpp[55-66]

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

### Issue description
Post-process MPI broadcast omits `bc_x%Twall_in` and `bc_x%Twall_out`, leaving defaults on non-root ranks. Post-process uses boundary-condition population that can reference these values, producing incorrect ghost temperatures and rank-dependent derived outputs.

### Issue Context
- pre_process already broadcasts `bc_x%Twall_*` alongside y/z.
- post_process should broadcast the same set for consistency.

### Fix Focus Areas
- src/post_process/m_mpi_proxy.fpp[132-139]

### What to change
Add `bc_x%Twall_in` and `bc_x%Twall_out` to the real-parameter broadcast list in `s_mpi_bcast_user_inputs` (and keep ordering consistent with pre_process/simulation if possible).

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


3. Twall not required by validator 🐞
Description
The case validator permits bc_*%isothermal_in/out = T without requiring the corresponding
bc_*%Twall_in/out to be provided, leaving it at dflt_real = -1e6. Boundary routines use
Twall_* directly to set ghost temperatures, so missing Twall configuration yields wildly
unphysical temperatures.
Code

toolchain/mfc/case_validator.py[R1291-1316]

+        # Fetch global chemistry and diffusion flags
+        chemistry = self.get("chemistry", "F") == "T"
+        diffusion = self.get("chem_params%diffusion", "F") == "T"
+
+        # Define what constitutes a wall (-15 for slip, -16 for no-slip)
+        wall_bcs = [-15, -16]
+
+        for dir in ["x", "y", "z"]:
+            isothermal_in = self.get(f"bc_{dir}%isothermal_in", "F") == "T"
+            isothermal_out = self.get(f"bc_{dir}%isothermal_out", "F") == "T"
+            bc_beg = self.get(f"bc_{dir}%beg")
+            bc_end = self.get(f"bc_{dir}%end")
+
+            if isothermal_in:
+                # Prohibit isothermal boundaries if chemistry or diffusion are disabled
+                self.prohibit(not chemistry or not diffusion, f"Isothermal In (bc_{dir}%isothermal_in) requires both chemistry='T' and chem_params%diffusion='T' to calculate heat conduction.")
+
+                # Prohibit if neither beg nor end is set to a valid wall condition
+                self.prohibit(bc_beg not in wall_bcs, f"Isothermal In (bc_{dir}%isothermal_in) requires a wall. Set bc_{dir}%beg to -15 (slip) or -16 (no-slip).")
+
+            if isothermal_out:
+                # Prohibit isothermal boundaries if chemistry or diffusion are disabled
+                self.prohibit(not chemistry or not diffusion, f"Isothermal Out (bc_{dir}%isothermal_out) requires both chemistry='T' and chem_params%diffusion='T' to calculate heat conduction.")
+
+                # Prohibit if neither beg nor end is set to a valid wall condition
+                self.prohibit(bc_end not in wall_bcs, f"Isothermal Out (bc_{dir}%isothermal_out) requires a wall. Set bc_{dir}%end to -15 (slip) or -16 (no-slip).")
Evidence
check_chemistry validates that isothermal flags require chemistry+diffusion and wall BC types, but
never checks Twall_in/out are set. Meanwhile, global parameters initialize Twall_* to
dflt_real and dflt_real is defined as -1e6, and the wall BC implementation uses bc_x%Twall_in
directly in the ghost-cell temperature formula.

toolchain/mfc/case_validator.py[1284-1316]
src/pre_process/m_global_parameters.fpp[305-310]
src/common/m_constants.fpp[10-13]
src/common/m_boundary_common.fpp[849-857]

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 validator allows enabling isothermal walls without specifying `Twall_in/out`, which defaults to `dflt_real=-1e6` and is then used directly by the wall BC implementation to set ghost temperatures.

### Issue Context
- `bc_[xyz]%Twall_in/out` defaults to `dflt_real`.
- `check_chemistry()` already checks compatibility (chemistry+diffusion, wall bc codes) but not presence/validity of Twall.

### Fix Focus Areas
- toolchain/mfc/case_validator.py[1284-1316]
- src/common/m_constants.fpp[10-13]

### What to change
1. When `bc_{dir}%isothermal_in` is true:
  - require `bc_{dir}%Twall_in` is provided
  - require it is numeric (or at least not missing)
  - require it is not equal to the default sentinel (e.g., `-1e6`) and is physically reasonable (e.g., `> 0` K)
2. Similarly, when `bc_{dir}%isothermal_out` is true, validate `bc_{dir}%Twall_out`.
3. Produce clear error messages pointing to the missing Twall parameter.

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


View more (3)
4. Unsafe optional q_T_sf use 🐞
Description
m_boundary_common and MPI comm code write/read q_T_sf under if (chemistry) / `if (chemistry .and.
chem_params%diffusion) without checking present(q_T_sf)`, but several call sites still invoke
buffer population without passing q_T_sf. With chemistry enabled this can dereference an absent
optional argument (undefined behavior: crash or memory corruption).
Code

src/common/m_boundary_common.fpp[R300-304]

+                if (chemistry) then
+                    do j = 1, buff_size
+                        q_T_sf%sf(-j, k, l) = q_T_sf%sf(0, k, l)
+                    end do
+                end if
Evidence
q_T_sf is declared optional but is dereferenced whenever chemistry is true. The repo contains
paths that call s_populate_variables_buffers(...) without q_T_sf (e.g., down_sample in pre_process
and simulation), making the optional argument absent while the callee still dereferences it.

src/common/m_boundary_common.fpp[284-304]
src/common/m_boundary_common.fpp[827-859]
src/common/m_mpi_common.fpp[499-592]
src/pre_process/m_data_output.fpp[409-421]
src/simulation/m_start_up.fpp[741-753]
src/simulation/m_time_steppers.fpp[602-609]

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

## Issue description
Several boundary-condition and MPI-communication routines accept `q_T_sf` as an **optional** argument but dereference it whenever `chemistry` (and sometimes `chem_params%diffusion`) is enabled. There are existing call sites that invoke `s_populate_variables_buffers(...)` without passing `q_T_sf` (e.g., down-sampling output paths), which makes dereferencing the optional argument undefined behavior (can crash or silently corrupt).
### Issue Context
This PR introduced `q_T_sf` support into BC fill + MPI exchange, but the implementation currently relies on an implicit contract (“if chemistry then q_T_sf is always passed”) that the codebase does not consistently satisfy.
### Fix Focus Areas
- Add `present(q_T_sf)` guards around all `q_T_sf%sf(...)` accesses (and similarly in MPI pack/unpack) so the routines are safe when `q_T_sf` is omitted.
- Ensure temperature communication/ghost filling happens whenever it is truly required (e.g., chemistry+diffusion paths that subsequently compute diffusion fluxes).
- src/common/m_boundary_common.fpp[284-365]
- src/common/m_boundary_common.fpp[827-927]
- src/common/m_boundary_common.fpp[1152-1236]
- src/common/m_mpi_common.fpp[499-593]
- src/common/m_mpi_common.fpp[788-830]

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


5. bc_x Twall not broadcast 🐞
Description
post_process MPI input broadcast omits bc_x%Twall_in/out, so non-root ranks keep default wall
temperatures and produce incorrect parallel post-processing results for x-direction isothermal
walls. This is silent data corruption in MPI runs.
Code

src/post_process/m_mpi_proxy.fpp[R132-138]

       #:for VAR in [ 'pref', 'rhoref', 'R0ref', 'poly_sigma', 'Web', 'Ca', &
-            & 'Re_inv', 'Bx0', 'sigma', 't_save', 't_stop',   &
-            & 'x_output%beg', 'x_output%end', 'y_output%beg', &
-            & 'y_output%end', 'z_output%beg', 'z_output%end']
+            & 'Re_inv', 'Bx0', 'sigma', 't_save', 't_stop',      &
+            & 'x_output%beg', 'x_output%end', 'y_output%beg',    &
+            & 'y_output%end', 'z_output%beg', 'z_output%end',    &
+            & 'bc_y%Twall_in', 'bc_y%Twall_out', 'bc_z%Twall_in',&
+            & 'bc_z%Twall_out']
           call MPI_BCAST(${VAR}$, 1, mpi_p, 0, MPI_COMM_WORLD, ierr)
Evidence
The post_process broadcast list includes bc_y/bc_z Twall fields but not bc_x Twall fields, while
defaults are initialized to dflt_real. Simulation does broadcast all Twall fields, highlighting
the inconsistency.

src/post_process/m_mpi_proxy.fpp[132-139]
src/simulation/m_mpi_proxy.fpp[127-142]
src/simulation/m_global_parameters.fpp[767-772]

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 post_process MPI runs, `bc_x%Twall_in` and `bc_x%Twall_out` are not broadcast from rank 0. Non-root ranks therefore keep default values, producing incorrect post-processing for x-direction isothermal boundaries.
### Issue Context
The simulation and pre_process MPI proxies broadcast all 6 Twall values; post_process broadcasts only y/z.
### Fix Focus Areas
- Add `bc_x%Twall_in` and `bc_x%Twall_out` to the real-parameter `MPI_BCAST` list.
- src/post_process/m_mpi_proxy.fpp[132-139]

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


6. q_T_sf stale after smoothing 🐞
Description
pre_process computes q_T_sf before elliptic smoothing, but elliptic smoothing overwrites q_prim_vf
and does not recompute q_T_sf afterward. This leaves q_T_sf inconsistent with the final smoothed
initial condition, and any later use/serialization of q_T_sf (e.g., bc_io boundary buffers) will be
wrong.
Code

src/pre_process/m_initial_condition.fpp[R141-149]

+        if (chemistry) call s_compute_T_from_primitives(q_T_sf, q_prim_vf, idwint)

-        call s_convert_primitive_to_conservative_variables(q_prim_vf, q_cons_vf)
+        if (elliptic_smoothing .and. chemistry) then
+            call s_elliptic_smoothing(q_prim_vf, bc_type, q_T_sf)
+        else if (elliptic_smoothing) then
+            call s_elliptic_smoothing(q_prim_vf, bc_type)
+        end if

-        if (chemistry) call s_compute_T_from_primitives(q_T_sf, q_prim_vf, idwint)
+        call s_convert_primitive_to_conservative_variables(q_prim_vf, q_cons_vf)
Evidence
The initial-condition generator now calls s_compute_T_from_primitives before smoothing. The
smoothing routine updates q_prim_vf in-place but never updates/recomputes q_T_sf. Meanwhile,
boundary-condition buffer packing serializes temperature slices from q_T_sf, so stale values can
be written.

src/pre_process/m_initial_condition.fpp[137-150]
src/pre_process/m_perturbation.fpp[86-137]
src/common/m_boundary_common.fpp[2052-2068]

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

## Issue description
`q_T_sf` is computed from primitives before elliptic smoothing, but smoothing modifies `q_prim_vf` without updating `q_T_sf`. This makes temperature inconsistent with the final smoothed primitives and can lead to incorrect temperature written/used downstream (notably for `bc_io` temperature buffer serialization).
### Issue Context
`m_perturbation:s_elliptic_smoothing` only uses `q_T_sf` to populate ghost/buffer regions; it never recomputes temperature from the updated primitives.
### Fix Focus Areas
- After elliptic smoothing completes (and before any output/serialization that uses `q_T_sf`), recompute `q_T_sf` from the final `q_prim_vf`.
- Keep the pre-smoothing computation if it is needed to apply isothermal BCs during smoothing, but add a post-smoothing recomputation step.
- src/pre_process/m_initial_condition.fpp[137-150]
- src/pre_process/m_perturbation.fpp[86-137]

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



Remediation recommended

7. Twall not required 🐞
Description
The validator enforces chemistry/diffusion and wall BC codes for isothermal flags but does not
require Twall_in/out to be provided, so cases can run using default/sentinel wall temperatures and
silently compute incorrect ghost temperatures/heat fluxes. This allows misconfigured isothermal
boundaries to pass validation.
Code

toolchain/mfc/case_validator.py[R1291-1316]

+        # Fetch global chemistry and diffusion flags
+        chemistry = self.get("chemistry", "F") == "T"
+        diffusion = self.get("chem_params%diffusion", "F") == "T"
+
+        # Define what constitutes a wall (-15 for slip, -16 for no-slip)
+        wall_bcs = [-15, -16]
+
+        for dir in ["x", "y", "z"]:
+            isothermal_in = self.get(f"bc_{dir}%isothermal_in", "F") == "T"
+            isothermal_out = self.get(f"bc_{dir}%isothermal_out", "F") == "T"
+            bc_beg = self.get(f"bc_{dir}%beg")
+            bc_end = self.get(f"bc_{dir}%end")
+
+            if isothermal_in:
+                # Prohibit isothermal boundaries if chemistry or diffusion are disabled
+                self.prohibit(not chemistry or not diffusion, f"Isothermal In (bc_{dir}%isothermal_in) requires both chemistry='T' and chem_params%diffusion='T' to calculate heat conduction.")
+
+                # Prohibit if neither beg nor end is set to a valid wall condition
+                self.prohibit(bc_beg not in wall_bcs, f"Isothermal In (bc_{dir}%isothermal_in) requires a wall. Set bc_{dir}%beg to -15 (slip) or -16 (no-slip).")
+
+            if isothermal_out:
+                # Prohibit isothermal boundaries if chemistry or diffusion are disabled
+                self.prohibit(not chemistry or not diffusion, f"Isothermal Out (bc_{dir}%isothermal_out) requires both chemistry='T' and chem_params%diffusion='T' to calculate heat conduction.")
+
+                # Prohibit if neither beg nor end is set to a valid wall condition
+                self.prohibit(bc_end not in wall_bcs, f"Isothermal Out (bc_{dir}%isothermal_out) requires a wall. Set bc_{dir}%end to -15 (slip) or -16 (no-slip).")
Evidence
When isothermal is enabled, ghost temperature is computed using bc_%Twall_*, which defaults to
dflt_real in global parameter initialization. The new validator logic never checks
presence/validity of Twall_in/out, so missing Twall inputs won’t be caught pre-run.

toolchain/mfc/case_validator.py[1291-1316]
src/simulation/m_global_parameters.fpp[767-772]
src/common/m_boundary_common.fpp[849-858]

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

## Issue description
Cases can enable `bc_%isothermal_in/out` without providing `bc_%Twall_in/out`. The code will then use default/sentinel values for wall temperature in ghost temperature calculations, producing incorrect results without a clear validation error.
### Issue Context
The PR adds validation for chemistry/diffusion and wall BC codes, but it does not validate that the required wall temperature is actually supplied.
### Fix Focus Areas
- When `bc_{dir}%isothermal_in` is true, prohibit missing `bc_{dir}%Twall_in`.
- When `bc_{dir}%isothermal_out` is true, prohibit missing `bc_{dir}%Twall_out`.
- Optionally: validate Twall is numeric and > 0.
- toolchain/mfc/case_validator.py[1291-1316]

ⓘ 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

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 10, 2026

📝 Walkthrough

Walkthrough

This pull request adds support for chemistry-specific isothermal boundary conditions by introducing a separate temperature scalar field (q_T_sf) that is managed independently from the primary fluid state. New boundary parameters (isothermal_in, isothermal_out, Twall_in, Twall_out) are added to each directional boundary (bc_x, bc_y, bc_z) to control temperature at slip/no-slip walls. The changes extend MPI communication, boundary condition application, data serialization, and initial condition logic to propagate this temperature field throughout pre-processing, simulation, and post-processing phases. Two new test cases demonstrate the functionality: a 1D dual isothermal wall gradient scenario and a 2D isothermal flat plate. Documentation and parameter validation are updated accordingly.

🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description is incomplete and missing critical information. It lacks proper structure, has a typo ('geometries/'), incomplete sentences, and fails to comprehensively explain the implementation details and design decisions. Complete the description by fixing the typo, removing placeholder text like 'Fixes #(issue)', providing clear motivation, and explaining implementation approach and key design decisions.
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically summarizes the main feature being added: isothermal boundary conditions for reacting flows.

✏️ 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: 10

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
src/simulation/m_rhs.fpp (1)

582-589: ⚠️ Potential issue | 🔴 Critical

Pass q_T_sf through the IGR communication path as well.

Line 588 fixes the finite-volume branch, but when igr = .true. the earlier s_populate_variables_buffers(...) call still executes without q_T_sf. That leaves the chemistry temperature field out of the boundary/MPI population path for IGR cases, so isothermal-wall chemistry runs can still fail or use stale temperature halos.

Suggested fix
         if (igr .or. dummy) then
             call nvtxStartRange("RHS-COMMUNICATION")
-            call s_populate_variables_buffers(bc_type, q_cons_vf, pb_in, mv_in)
+            call s_populate_variables_buffers(bc_type, q_cons_vf, pb_in, mv_in, q_T_sf)
             call nvtxEndRange
         end if

Based on learnings: Applies to src/{common,simulation}/**/*.{fpp,f90} : Ensure MPI pack/unpack logic is updated consistently across all sweep directions (e.g., x, y, z dimensions).

src/common/m_mpi_common.fpp (1)

499-512: ⚠️ Potential issue | 🔴 Critical

Guard q_T_sf with present(...) before using it.

q_T_sf is optional here, but the new chemistry-diffusion path is enabled from global flags alone. Every added pack/unpack block below dereferences q_T_sf%sf(...), so any caller that omits the actual argument will hit undefined behavior.

💡 Suggested fix
-        else if (chemistry .and. chem_params%diffusion) then
+        else if (chemistry .and. chem_params%diffusion .and. present(q_T_sf)) then
             v_size = nVar + 1
             buffer_counts = (/buff_size*v_size*(n + 1)*(p + 1), buff_size*v_size*(m + 2*buff_size + 1)*(p + 1), &
                              & buff_size*v_size*(m + 2*buff_size + 1)*(n + 2*buff_size + 1)/)
+        if (chemistry .and. chem_params%diffusion .and. .not. present(q_T_sf)) then
+            call s_mpi_abort('q_T_sf must be present when chemistry diffusion halo exchange is enabled')
+        end if

Also applies to: 525-528

src/pre_process/m_data_output.fpp (1)

87-92: ⚠️ Potential issue | 🔴 Critical

Pass q_T_sf through the igr boundary-output path too.

Only the non-igr calls were updated. In chemistry/isothermal cases with igr = T, the boundary writers still get called without q_T_sf, which leaves the downstream BC packing path without the temperature field.

💡 Suggested fix
         if (bc_io) then
             if (igr) then
-                call s_write_serial_boundary_condition_files(q_cons_vf, bc_type, t_step_dir, old_grid)
+                call s_write_serial_boundary_condition_files(q_cons_vf, bc_type, t_step_dir, old_grid, q_T_sf)
             else
                 call s_write_serial_boundary_condition_files(q_prim_vf, bc_type, t_step_dir, old_grid, q_T_sf)
             end if
         end if
         if (bc_io) then
             if (igr) then
-                call s_write_parallel_boundary_condition_files(q_cons_vf, bc_type)
+                call s_write_parallel_boundary_condition_files(q_cons_vf, bc_type, q_T_sf)
             else
                 call s_write_parallel_boundary_condition_files(q_prim_vf, bc_type, q_T_sf)
             end if
         end if

Also applies to: 565-570

🧹 Nitpick comments (1)
toolchain/mfc/case_validator.py (1)

1298-1298: Rename dir to avoid Ruff A001.

Using dir here shadows the Python builtin and already triggers the linter. direction or axis would keep this clean.


ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: dea48334-e1e4-4f3b-b300-e56f569f927b

📥 Commits

Reviewing files that changed from the base of the PR and between 23bbd4f and c0c2f90.

📒 Files selected for processing (31)
  • CMakeLists.txt
  • docs/documentation/case.md
  • examples/2D_Thermal_Flatplate/case.py
  • src/common/include/1dHardcodedIC.fpp
  • src/common/include/2dHardcodedIC.fpp
  • src/common/m_boundary_common.fpp
  • src/common/m_chemistry.fpp
  • src/common/m_derived_types.fpp
  • src/common/m_mpi_common.fpp
  • src/post_process/m_global_parameters.fpp
  • src/post_process/m_mpi_proxy.fpp
  • src/post_process/m_start_up.fpp
  • src/pre_process/m_data_output.fpp
  • src/pre_process/m_global_parameters.fpp
  • src/pre_process/m_initial_condition.fpp
  • src/pre_process/m_mpi_proxy.fpp
  • src/pre_process/m_perturbation.fpp
  • src/pre_process/m_start_up.fpp
  • src/simulation/m_data_output.fpp
  • src/simulation/m_global_parameters.fpp
  • src/simulation/m_mpi_proxy.fpp
  • src/simulation/m_rhs.fpp
  • src/simulation/m_start_up.fpp
  • tests/4587725A/golden-metadata.txt
  • tests/4587725A/golden.txt
  • tests/8E56ACC1/golden-metadata.txt
  • tests/8E56ACC1/golden.txt
  • toolchain/mfc/case_validator.py
  • toolchain/mfc/params/definitions.py
  • toolchain/mfc/params/descriptions.py
  • toolchain/mfc/test/cases.py

Comment on lines +525 to 531
else if (chemistry .and. chem_params%diffusion) then
v_size = nVar + 1
buffer_counts = (/buff_size*v_size*(n + 1)*(p + 1), buff_size*v_size*(m + 2*buff_size + 1)*(p + 1), &
& buff_size*v_size*(m + 2*buff_size + 1)*(n + 2*buff_size + 1)/)
else
v_size = nVar
buffer_counts = (/buff_size*v_size*(n + 1)*(p + 1), buff_size*v_size*(m + 2*buff_size + 1)*(p + 1), &
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Action required

1. Mpi q_t_sf presence ignored 🐞 Bug ☼ Reliability

s_mpi_sendrecv_variables_buffers packs/unpacks q_T_sf whenever `chemistry .and.
chem_params%diffusion is true, but q_T_sf` is an optional argument and is dereferenced without
present() checks. If any caller omits q_T_sf (currently true in several places), MPI buffer
packing/unpacking will read/write through an absent optional argument.
Agent Prompt
### Issue description
MPI send/recv for ghost buffers packs/unpacks temperature (`q_T_sf`) based solely on global flags (`chemistry` and `chem_params%diffusion`) even though `q_T_sf` is an optional dummy argument. This can dereference an absent optional argument and crash.

### Issue Context
Some code paths call `s_mpi_sendrecv_variables_buffers` (via `s_populate_variables_buffers`) without providing `q_T_sf` (e.g., conservative-only communications and downsample paths). The MPI routine must not assume `q_T_sf` is present.

### Fix Focus Areas
- src/common/m_mpi_common.fpp[499-593]
- src/common/m_mpi_common.fpp[564-624]
- src/common/m_mpi_common.fpp[625-713]
- src/common/m_mpi_common.fpp[756-974]

### What to change
1. Introduce a local logical like `has_T = present(q_T_sf) .and. chemistry .and. chem_params%diffusion`.
2. Use `has_T` (not just chemistry/diffusion) to:
   - set `v_size` (nVar vs nVar+1)
   - compute `buffer_counts`
   - pack `buff_send` temperature slot
   - unpack into `q_T_sf`
3. Optionally add a defensive abort if `chemistry .and. chem_params%diffusion` is true in a code path that *requires* temperature exchange but `present(q_T_sf)` is false.

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

@codecov
Copy link
Copy Markdown

codecov bot commented Apr 10, 2026

Codecov Report

❌ Patch coverage is 73.50427% with 62 lines in your changes missing coverage. Please review.
✅ Project coverage is 64.87%. Comparing base (23bbd4f) to head (c0c2f90).
⚠️ Report is 4 commits behind head on master.

Files with missing lines Patch % Lines
src/common/m_boundary_common.fpp 78.12% 21 Missing and 14 partials ⚠️
src/common/m_mpi_common.fpp 43.90% 23 Missing ⚠️
src/pre_process/m_initial_condition.fpp 66.66% 1 Missing and 1 partial ⚠️
src/common/m_chemistry.fpp 0.00% 1 Missing ⚠️
src/simulation/m_data_output.fpp 0.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #1361      +/-   ##
==========================================
- Coverage   64.88%   64.87%   -0.01%     
==========================================
  Files          70       70              
  Lines       18251    18389     +138     
  Branches     1508     1527      +19     
==========================================
+ Hits        11842    11930      +88     
- Misses       5446     5503      +57     
+ Partials      963      956       -7     

☔ 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

claude-full-review Trigger Claude Code review

Development

Successfully merging this pull request may close these issues.

2 participants