Skip to content

Conversation

@DimAdam-01
Copy link
Contributor

@DimAdam-01 DimAdam-01 commented Dec 11, 2025

User description

User description

Description

Please include a summary of the changes and the related issue(s) if they exist.
Please also include relevant motivation and context.

Fixes #(issue) [optional]

Type of change

Added Unity Lewis transport modeling, with mixture-averaged as the default methodology.

Please delete options that are not relevant.

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Something else

Scope

  • This PR comprises a set of related changes with a common goal

If you cannot check the above box, please split your PR into multiple PRs that each have a common goal.

How Has This Been Tested?

Please describe the tests that you ran to verify your changes.
Provide instructions so we can reproduce.
Please also list any relevant details for your test configuration

  • Test A: Flamelet evolution,
image
  • Test B

Test Configuration:

  • What computers and compilers did you use to test this:

Checklist

  • I have added comments for the new code
  • I added Doxygen docstrings to the new code
  • I have made corresponding changes to the documentation (docs/)
  • I have added regression tests to the test suite so that people can verify in the future that the feature is behaving as expected
  • I have added example cases in examples/ that demonstrate my new feature performing as expected.
    They run to completion and demonstrate "interesting physics"
  • I ran ./mfc.sh format before committing my code
  • New and existing tests pass locally with my changes, including with GPU capability enabled (both NVIDIA hardware with NVHPC compilers and AMD hardware with CRAY compilers) and disabled
  • This PR does not introduce any repeated code (it follows the DRY principle)
  • I cannot think of a way to condense this code and reduce any introduced additional line count

If your code changes any code source files (anything in src/simulation)

To make sure the code is performing as expected on GPU devices, I have:

  • Checked that the code compiles using NVHPC compilers
  • Checked that the code compiles using CRAY compilers
  • Ran the code on either V100, A100, or H100 GPUs and ensured the new feature performed as expected (the GPU results match the CPU results)
  • Ran the code on MI200+ GPUs and ensure the new features performed as expected (the GPU results match the CPU results)
  • Enclosed the new feature via nvtx ranges so that they can be identified in profiles
  • Ran a Nsight Systems profile using ./mfc.sh run XXXX --gpu -t simulation --nsys, and have attached the output file (.nsys-rep) and plain text results to this PR
  • Ran a Rocprof Systems profile using ./mfc.sh run XXXX --gpu -t simulation --rsys --hip-trace, and have attached the output file and plain text results to this PR.
  • Ran my code using various numbers of different GPUs (1, 2, and 8, for example) in parallel and made sure that the results scale similarly to what happens if you run without the new code/feature

PR Type

Enhancement


Description

  • Add Unity Lewis transport model as alternative to mixture-averaged

  • Implement transport model selection via chem_params%transport_model parameter

  • Add new thermochemistry functions for specific heat and enthalpy calculations

  • Fix bug in ExtrusionHardcodedIC where global offset was incorrectly applied

  • Extend MPI broadcasting to include transport model parameter


Diagram Walkthrough

flowchart LR
  A["Chemistry Module"] -->|transport_model=1| B["Mixture-Averaged Transport"]
  A -->|transport_model=2| C["Unity Lewis Transport"]
  B --> D["Species Diffusivities"]
  C --> E["Thermal Diffusivity"]
  D --> F["Flux Computation"]
  E --> F
  F --> G["Updated Flux Arrays"]
Loading

File Walkthrough

Relevant files
Bug fix
ExtrusionHardcodedIC.fpp
Fix global offset bug in extrusion IC                                       

src/common/include/ExtrusionHardcodedIC.fpp

  • Fixed bug where global offset was incorrectly applied to stored values
    index
  • Changed from stored_values(idx, 1, f) to stored_values(i + 1, 1, f)
    for 1D case
+1/-1     
Enhancement
m_chemistry.fpp
Implement Unity Lewis transport model option                         

src/common/m_chemistry.fpp

  • Added imports for get_mixture_specific_heat_cp_mass and
    get_mixture_enthalpy_mass functions
  • Refactored diffusion flux computation into two transport models
  • Model 1: Mixture-averaged transport (original implementation)
  • Model 2: Unity Lewis number transport with simplified diffusivity
    calculation
  • Added new variables for Unity Lewis model: dYk_dxi, Cp_L, Cp_R,
    diffusivity_L/R/cell, hmix_L/R, dh_dxi
+210/-108
m_derived_types.fpp
Add transport model parameter to chemistry type                   

src/common/m_derived_types.fpp

  • Added transport_model integer field to chemistry_parameters type
  • Allows selection between different transport modeling approaches
+1/-0     
m_mpi_proxy.fpp
Broadcast transport model via MPI                                               

src/simulation/m_mpi_proxy.fpp

  • Extended MPI broadcast to include transport_model parameter
  • Ensures all MPI processes have consistent transport model selection
+1/-1     
Configuration changes
m_global_parameters.fpp
Initialize chemistry parameters in post-process                   

src/post_process/m_global_parameters.fpp

  • Added chem_params variable declaration of type chemistry_parameters
  • Initialize chem_params%gamma_method and chem_params%transport_model to
    default values (1)
+4/-0     
m_global_parameters.fpp
Initialize chemistry parameters in pre-process                     

src/pre_process/m_global_parameters.fpp

  • Added chem_params variable declaration of type chemistry_parameters
  • Initialize chem_params%gamma_method and chem_params%transport_model to
    default values (1)
+4/-0     
m_global_parameters.fpp
Initialize transport model in simulation                                 

src/simulation/m_global_parameters.fpp

  • Added initialization of chem_params%transport_model to 1
    (mixture-averaged default)
  • Ensures consistent default transport model selection across simulation
+1/-0     
case_dicts.py
Add transport model to case configuration                               

toolchain/mfc/run/case_dicts.py

  • Added transport_model to integer parameter dictionary for chemistry
    parameters
  • Allows user configuration of transport model selection in case files
+1/-1     


CodeAnt-AI Description

Add selectable transport models (mixture-averaged default) and fix extrusion IC indexing

What Changed

  • Introduces a transport model option for chemistry with two behaviors: model 1 uses mixture‑averaged transport (set as the default) and model 2 implements the Unity Lewis number transport; diffusion flux calculations now follow the selected model and update species and energy fluxes accordingly
  • Adds the new transport setting to global parameters, configuration dictionaries, and MPI broadcasts so the chosen transport model is consistently applied across processes and cases
  • Fixes an incorrect index when assigning hardcoded extrusion initial-condition values so stored values map to fields correctly

Impact

✅ Can select Unity Lewis transport for diffusion
✅ Mixture‑averaged transport used by default for existing cases
✅ Fewer incorrect extrusion initial conditions

💡 Usage Guide

Checking Your Pull Request

Every time you make a pull request, our system automatically looks through it. We check for security issues, mistakes in how you're setting up your infrastructure, and common code problems. We do this to make sure your changes are solid and won't cause any trouble later.

Talking to CodeAnt AI

Got a question or need a hand with something in your pull request? You can easily get in touch with CodeAnt AI right here. Just type the following in a comment on your pull request, and replace "Your question here" with whatever you want to ask:

@codeant-ai ask: Your question here

This lets you have a chat with CodeAnt AI about your pull request, making it easier to understand and improve your code.

Example

@codeant-ai ask: Can you suggest a safer alternative to storing this secret?

Preserve Org Learnings with CodeAnt

You can record team preferences so CodeAnt AI applies them in future reviews. Reply directly to the specific CodeAnt AI suggestion (in the same thread) and replace "Your feedback here" with your input:

@codeant-ai: Your feedback here

This helps CodeAnt AI learn and adapt to your team's coding style and standards.

Example

@codeant-ai: Do not flag unused imports.

Retrigger review

Ask CodeAnt AI to review the PR again, by typing:

@codeant-ai: review

Check Your Repository Health

To analyze the health of your code repository, visit our dashboard at https://app.codeant.ai. This tool helps you identify potential issues and areas for improvement in your codebase, ensuring your repository maintains high standards of code health.

Summary by CodeRabbit

  • New Features

    • Added configurable transport models for chemistry simulations (Mixture-Average and Unity Lewis Number) and new mixture thermodynamic routines for specific heat and enthalpy.
  • Configuration

    • Introduced a transport_model chemistry parameter with default initialization and propagation to distributed runs.
  • Documentation

    • Expanded chemistry documentation with transport model and Cantera configuration details.
  • Examples

    • Added a Cantera-based multispecies diffusion example and adjusted test/example handling.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 11, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

📝 Walkthrough

Walkthrough

Adds a chemistry transport_model parameter and wires it through initialization, MPI, tooling, docs, and an example; replaces a single diffusion flux computation with two transport-model-specific branches (Mixture-Average and Unity Lewis Number) in the chemistry module.

Changes

Cohort / File(s) Summary
Type Definitions
src/common/m_derived_types.fpp
Added integer :: transport_model to chemistry_parameters.
Global Parameters
src/pre_process/m_global_parameters.fpp, src/post_process/m_global_parameters.fpp, src/simulation/m_global_parameters.fpp
Added chem_params (type chemistry_parameters) and set default chem_params%transport_model = 1 in initialization paths.
Core Chemistry & Transport Logic
src/common/m_chemistry.fpp
Replaced single diffusion-block with two branches selected by transport_model (==1: Mixture-Average, ==2: Unity Lewis Number); introduced model-specific temporaries (Cp, diffusivities, hmix, dh_dxi, etc.), expanded GPU parallel-loop private/copyin lists, and duplicated loop structures per model.
MPI Broadcasts
src/simulation/m_mpi_proxy.fpp
Extended chemistry parameter broadcast to include chem_params%transport_model.
Tooling & Tests
toolchain/mfc/run/case_dicts.py, toolchain/mfc/test/cases.py
Added transport_model to SIMULATION param mapping as INT; added 1D_multispecies_diffusion to skipped example tests.
Docs & Examples
docs/documentation/case.md, examples/1D_multispecies_diffusion/case.py
Inserted a Chemistry section (appears duplicated) documenting new params and added an example script that emits a Cantera-based 1D multispecies diffusion case JSON.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • sbryngelson

"I hopped through code with a twitchy nose,
New branches bloom where the transport model grows.
Diffusion split, two paths to explore,
MPI whispers, examples knock on the door.
A joyful thump — commits in rows! 🐰"

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title directly references the main feature introduced: Unity Lewis transport model selection, which is the primary enhancement described throughout the PR.
Description check ✅ Passed The description includes all major template sections with substantive content: feature type (new feature), scope confirmation, testing results, and comprehensive checklist completion, though some GPU profiling items remain unchecked.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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.

@codecov
Copy link

codecov bot commented Dec 11, 2025

Codecov Report

❌ Patch coverage is 63.63636% with 4 lines in your changes missing coverage. Please review.
✅ Project coverage is 43.99%. Comparing base (2902000) to head (0e8124f).
⚠️ Report is 4 commits behind head on master.

Files with missing lines Patch % Lines
src/common/m_chemistry.fpp 33.33% 4 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #1084      +/-   ##
==========================================
- Coverage   43.99%   43.99%   -0.01%     
==========================================
  Files          71       71              
  Lines       20289    20292       +3     
  Branches     1982     1982              
==========================================
+ Hits         8927     8928       +1     
- Misses      10225    10227       +2     
  Partials     1137     1137              

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

@sbryngelson sbryngelson marked this pull request as ready for review December 15, 2025 21:09
Copilot AI review requested due to automatic review settings December 15, 2025 21:09
@codeant-ai
Copy link

codeant-ai bot commented Dec 15, 2025

CodeAnt AI is reviewing your PR.


Thanks for using CodeAnt! 🎉

We're free for open-source projects. if you're enjoying it, help us grow by sharing.

Share on X ·
Reddit ·
LinkedIn

@qodo-code-review
Copy link
Contributor

PR Reviewer Guide 🔍

Here are some key observations to aid the review process:

⏱️ Estimated effort to review: 4 🔵🔵🔵🔵⚪
🧪 No relevant tests
🔒 No security concerns identified
⚡ Recommended focus areas for review

Possible Issue

In the 1D branch, idx is still computed using global_offset_x but the assignment now indexes stored_values(i + 1, 1, f) instead of using idx. This may reintroduce misalignment for cases where the global offset is required, and it also leaves idx effectively unused (suggesting the fix may not match the intended indexing logic).

! Data assignment
select case (num_dims)
case (1)
    idx = i + 1 + global_offset_x
    do f = 1, sys_size
        q_prim_vf(f)%sf(i, 0, 0) = stored_values(i + 1, 1, f)
    end do
Physics Consistency

The Unity Lewis transport path computes species diffusion fluxes as rho_cell * diffusivity_cell * dYk_dxi without an explicit mass-conservation correction (e.g., ensuring sum of species diffusive mass fluxes is zero) like the mixture-averaged branch does via the rho_Vic correction. This can lead to nonzero net diffusive mass flux and inconsistent coupling with continuity/energy, so the intended formulation should be validated.

    ! Model 2: Unity Lewis Number
else if (chem_params%transport_model == 2) then
    #:block UNDEF_AMD
        ! Note: Added ALL scalars and 'i'/'eqn' to private list to prevent race conditions.
        $:GPU_PARALLEL_LOOP(collapse=3, private='[x,y,z,i,eqn,Ys_L, Ys_R, Ys_cell, dYk_dxi, Mass_Diffu_Flux, grid_spacing, MW_L, MW_R, MW_cell, Rgas_L, Rgas_R, P_L, P_R, rho_L, rho_R, rho_cell, T_L, T_R, Cp_L, Cp_R, hmix_L, hmix_R, dh_dxi, lambda_L, lambda_R, lambda_Cell, diffusivity_L, diffusivity_R, diffusivity_cell, Mass_Diffu_Energy]', copyin='[offsets]')
        do z = isc3%beg, isc3%end
            do y = isc2%beg, isc2%end
                do x = isc1%beg, isc1%end
                    ! Calculate grid spacing using direction-based indexing
                    select case (idir)
                    case (1)
                        grid_spacing = x_cc(x + 1) - x_cc(x)
                    case (2)
                        grid_spacing = y_cc(y + 1) - y_cc(y)
                    case (3)
                        grid_spacing = z_cc(z + 1) - z_cc(z)
                    end select

                    ! Extract species mass fractions
                    $:GPU_LOOP(parallelism='[seq]')
                    do i = chemxb, chemxe
                        Ys_L(i - chemxb + 1) = q_prim_qp(i)%sf(x, y, z)
                        Ys_R(i - chemxb + 1) = q_prim_qp(i)%sf(x + offsets(1), y + offsets(2), z + offsets(3))
                        Ys_cell(i - chemxb + 1) = 0.5_wp*(Ys_L(i - chemxb + 1) + Ys_R(i - chemxb + 1))
                    end do

                    ! Calculate molecular weights and mole fractions
                    call get_mixture_molecular_weight(Ys_L, MW_L)
                    call get_mixture_molecular_weight(Ys_R, MW_R)
                    MW_cell = 0.5_wp*(MW_L + MW_R)

                    ! Calculate gas constants and thermodynamic properties
                    Rgas_L = gas_constant/MW_L
                    Rgas_R = gas_constant/MW_R

                    P_L = q_prim_qp(E_idx)%sf(x, y, z)
                    P_R = q_prim_qp(E_idx)%sf(x + offsets(1), y + offsets(2), z + offsets(3))

                    rho_L = q_prim_qp(1)%sf(x, y, z)
                    rho_R = q_prim_qp(1)%sf(x + offsets(1), y + offsets(2), z + offsets(3))

                    T_L = P_L/rho_L/Rgas_L
                    T_R = P_R/rho_R/Rgas_R

                    rho_cell = 0.5_wp*(rho_L + rho_R)

                    call get_mixture_specific_heat_cp_mass(T_L, Ys_L, Cp_L)
                    call get_mixture_specific_heat_cp_mass(T_R, Ys_R, Cp_R)
                    call get_mixture_enthalpy_mass(T_L, Ys_L, hmix_L)
                    call get_mixture_enthalpy_mass(T_R, Ys_R, hmix_R)
                    dh_dxi = (hmix_R - hmix_L)/grid_spacing

                    ! Get transport properties
                    call get_mixture_thermal_conductivity_mixavg(T_L, Ys_L, lambda_L)
                    call get_mixture_thermal_conductivity_mixavg(T_R, Ys_R, lambda_R)

                    ! Calculate species properties and gradients
                    $:GPU_LOOP(parallelism='[seq]')
                    do i = chemxb, chemxe
                        dYk_dxi(i - chemxb + 1) = (Ys_R(i - chemxb + 1) - &
                                                   Ys_L(i - chemxb + 1))/grid_spacing
                    end do

                    ! Calculate mixture-averaged diffusivities
                    diffusivity_L = lambda_L/rho_L/Cp_L
                    diffusivity_R = lambda_R/rho_R/Cp_R

                    lambda_Cell = 0.5_wp*(lambda_R + lambda_L)
                    diffusivity_Cell = 0.5_wp*(diffusivity_R + diffusivity_L)

                    ! Calculate mass diffusion fluxes
                    Mass_Diffu_Energy = 0.0_wp

                    $:GPU_LOOP(parallelism='[seq]')
                    do eqn = chemxb, chemxe
                        Mass_Diffu_Flux(eqn - chemxb + 1) = rho_cell* &
                                                            diffusivity_cell* &
                                                            dYk_dxi(eqn - chemxb + 1)
                    end do
                    Mass_Diffu_Energy = rho_cell*diffusivity_cell*dh_dxi

                    ! Update flux arrays
                    flux_src_vf(E_idx)%sf(x, y, z) = flux_src_vf(E_idx)%sf(x, y, z) - Mass_Diffu_Energy

                    $:GPU_LOOP(parallelism='[seq]')
                    do eqn = chemxb, chemxe
                        flux_src_vf(eqn)%sf(x, y, z) = flux_src_vf(eqn)%sf(x, y, z) - Mass_Diffu_Flux(eqn - chemxb + 1)
                    end do
                end do
            end do
        end do
        $:END_GPU_PARALLEL_LOOP()
    #:endblock UNDEF_AMD
end if
Duplicate Code

The two transport-model branches duplicate substantial logic (grid spacing computation, state extraction, MW/T/rho/P computations, lambda_Cell computation, flux array updates). This increases maintenance risk and makes it easier for the models to diverge unintentionally; consider factoring shared parts into a helper routine or shared block to reduce duplication.

! Set offsets based on direction using array indexing
offsets = 0
offsets(idir) = 1
! Model 1: Mixture-Average Transport
if (chem_params%transport_model == 1) then
    #:block UNDEF_AMD
        ! Note: Added 'i' and 'eqn' to private list.
        $:GPU_PARALLEL_LOOP(collapse=3,  private='[x,y,z,i,eqn,Ys_L, Ys_R, Ys_cell, Xs_L, Xs_R, mass_diffusivities_mixavg1, mass_diffusivities_mixavg2, mass_diffusivities_mixavg_Cell, h_l, h_r, Xs_cell, h_k, dXk_dxi,Mass_Diffu_Flux, Mass_Diffu_Energy, MW_L, MW_R, MW_cell, Rgas_L, Rgas_R, T_L, T_R, P_L, P_R, rho_L, rho_R, rho_cell, rho_Vic, lambda_L, lambda_R, lambda_Cell, dT_dxi, grid_spacing]', copyin='[offsets]')
        do z = isc3%beg, isc3%end
            do y = isc2%beg, isc2%end
                do x = isc1%beg, isc1%end
                    ! Calculate grid spacing using direction-based indexing
                    select case (idir)
                    case (1)
                        grid_spacing = x_cc(x + 1) - x_cc(x)
                    case (2)
                        grid_spacing = y_cc(y + 1) - y_cc(y)
                    case (3)
                        grid_spacing = z_cc(z + 1) - z_cc(z)
                    end select

                    ! Extract species mass fractions
                    $:GPU_LOOP(parallelism='[seq]')
                    do i = chemxb, chemxe
                        Ys_L(i - chemxb + 1) = q_prim_qp(i)%sf(x, y, z)
                        Ys_R(i - chemxb + 1) = q_prim_qp(i)%sf(x + offsets(1), y + offsets(2), z + offsets(3))
                        Ys_cell(i - chemxb + 1) = 0.5_wp*(Ys_L(i - chemxb + 1) + Ys_R(i - chemxb + 1))
                    end do

                    ! Calculate molecular weights and mole fractions
                    call get_mixture_molecular_weight(Ys_L, MW_L)
                    call get_mixture_molecular_weight(Ys_R, MW_R)
                    MW_cell = 0.5_wp*(MW_L + MW_R)

                    call get_mole_fractions(MW_L, Ys_L, Xs_L)
                    call get_mole_fractions(MW_R, Ys_R, Xs_R)

                    ! Calculate gas constants and thermodynamic properties
                    Rgas_L = gas_constant/MW_L
                    Rgas_R = gas_constant/MW_R

                    P_L = q_prim_qp(E_idx)%sf(x, y, z)
                    P_R = q_prim_qp(E_idx)%sf(x + offsets(1), y + offsets(2), z + offsets(3))

                    rho_L = q_prim_qp(1)%sf(x, y, z)
                    rho_R = q_prim_qp(1)%sf(x + offsets(1), y + offsets(2), z + offsets(3))

                    T_L = P_L/rho_L/Rgas_L
                    T_R = P_R/rho_R/Rgas_R

                    rho_cell = 0.5_wp*(rho_L + rho_R)
                    dT_dxi = (T_R - T_L)/grid_spacing

                    ! Get transport properties
                    call get_species_mass_diffusivities_mixavg(P_L, T_L, Ys_L, mass_diffusivities_mixavg1)
                    call get_species_mass_diffusivities_mixavg(P_R, T_R, Ys_R, mass_diffusivities_mixavg2)

                    call get_mixture_thermal_conductivity_mixavg(T_L, Ys_L, lambda_L)
                    call get_mixture_thermal_conductivity_mixavg(T_R, Ys_R, lambda_R)

                    call get_species_enthalpies_rt(T_L, h_l)
                    call get_species_enthalpies_rt(T_R, h_r)

                    ! Calculate species properties and gradients
                    $:GPU_LOOP(parallelism='[seq]')
                    do i = chemxb, chemxe
                        h_l(i - chemxb + 1) = h_l(i - chemxb + 1)*gas_constant*T_L/molecular_weights(i - chemxb + 1)
                        h_r(i - chemxb + 1) = h_r(i - chemxb + 1)*gas_constant*T_R/molecular_weights(i - chemxb + 1)
                        Xs_cell(i - chemxb + 1) = 0.5_wp*(Xs_L(i - chemxb + 1) + Xs_R(i - chemxb + 1))
                        h_k(i - chemxb + 1) = 0.5_wp*(h_l(i - chemxb + 1) + h_r(i - chemxb + 1))
                        dXk_dxi(i - chemxb + 1) = (Xs_R(i - chemxb + 1) - Xs_L(i - chemxb + 1))/grid_spacing
                    end do

                    ! Calculate mixture-averaged diffusivities
                    $:GPU_LOOP(parallelism='[seq]')
                    do i = chemxb, chemxe
                        mass_diffusivities_mixavg_Cell(i - chemxb + 1) = &
                            (mass_diffusivities_mixavg2(i - chemxb + 1) + mass_diffusivities_mixavg1(i - chemxb + 1))/2.0_wp
                    end do

                    lambda_Cell = 0.5_wp*(lambda_R + lambda_L)

                    ! Calculate mass diffusion fluxes
                    rho_Vic = 0.0_wp
                    Mass_Diffu_Energy = 0.0_wp

                    $:GPU_LOOP(parallelism='[seq]')
                    do eqn = chemxb, chemxe
                        Mass_Diffu_Flux(eqn - chemxb + 1) = rho_cell*mass_diffusivities_mixavg_Cell(eqn - chemxb + 1)* &
                                                            molecular_weights(eqn - chemxb + 1)/MW_cell*dXk_dxi(eqn - chemxb + 1)
                        rho_Vic = rho_Vic + Mass_Diffu_Flux(eqn - chemxb + 1)
                        Mass_Diffu_Energy = Mass_Diffu_Energy + h_k(eqn - chemxb + 1)*Mass_Diffu_Flux(eqn - chemxb + 1)
                    end do

                    ! Apply corrections for mass conservation
                    $:GPU_LOOP(parallelism='[seq]')
                    do eqn = chemxb, chemxe
                        Mass_Diffu_Energy = Mass_Diffu_Energy - h_k(eqn - chemxb + 1)*Ys_cell(eqn - chemxb + 1)*rho_Vic
                        Mass_Diffu_Flux(eqn - chemxb + 1) = Mass_Diffu_Flux(eqn - chemxb + 1) - rho_Vic*Ys_cell(eqn - chemxb + 1)
                    end do

                    ! Add thermal conduction contribution
                    Mass_Diffu_Energy = lambda_Cell*dT_dxi + Mass_Diffu_Energy

                    ! Update flux arrays
                    flux_src_vf(E_idx)%sf(x, y, z) = flux_src_vf(E_idx)%sf(x, y, z) - Mass_Diffu_Energy

                    $:GPU_LOOP(parallelism='[seq]')
                    do eqn = chemxb, chemxe
                        flux_src_vf(eqn)%sf(x, y, z) = flux_src_vf(eqn)%sf(x, y, z) - Mass_Diffu_Flux(eqn - chemxb + 1)
                    end do
                end do
            end do
        end do
        $:END_GPU_PARALLEL_LOOP()
    #:endblock UNDEF_AMD

    ! Model 2: Unity Lewis Number
else if (chem_params%transport_model == 2) then
    #:block UNDEF_AMD
        ! Note: Added ALL scalars and 'i'/'eqn' to private list to prevent race conditions.
        $:GPU_PARALLEL_LOOP(collapse=3, private='[x,y,z,i,eqn,Ys_L, Ys_R, Ys_cell, dYk_dxi, Mass_Diffu_Flux, grid_spacing, MW_L, MW_R, MW_cell, Rgas_L, Rgas_R, P_L, P_R, rho_L, rho_R, rho_cell, T_L, T_R, Cp_L, Cp_R, hmix_L, hmix_R, dh_dxi, lambda_L, lambda_R, lambda_Cell, diffusivity_L, diffusivity_R, diffusivity_cell, Mass_Diffu_Energy]', copyin='[offsets]')
        do z = isc3%beg, isc3%end
            do y = isc2%beg, isc2%end
                do x = isc1%beg, isc1%end
                    ! Calculate grid spacing using direction-based indexing
                    select case (idir)
                    case (1)
                        grid_spacing = x_cc(x + 1) - x_cc(x)
                    case (2)
                        grid_spacing = y_cc(y + 1) - y_cc(y)
                    case (3)
                        grid_spacing = z_cc(z + 1) - z_cc(z)
                    end select

                    ! Extract species mass fractions
                    $:GPU_LOOP(parallelism='[seq]')
                    do i = chemxb, chemxe
                        Ys_L(i - chemxb + 1) = q_prim_qp(i)%sf(x, y, z)
                        Ys_R(i - chemxb + 1) = q_prim_qp(i)%sf(x + offsets(1), y + offsets(2), z + offsets(3))
                        Ys_cell(i - chemxb + 1) = 0.5_wp*(Ys_L(i - chemxb + 1) + Ys_R(i - chemxb + 1))
                    end do

                    ! Calculate molecular weights and mole fractions
                    call get_mixture_molecular_weight(Ys_L, MW_L)
                    call get_mixture_molecular_weight(Ys_R, MW_R)
                    MW_cell = 0.5_wp*(MW_L + MW_R)

                    ! Calculate gas constants and thermodynamic properties
                    Rgas_L = gas_constant/MW_L
                    Rgas_R = gas_constant/MW_R

                    P_L = q_prim_qp(E_idx)%sf(x, y, z)
                    P_R = q_prim_qp(E_idx)%sf(x + offsets(1), y + offsets(2), z + offsets(3))

                    rho_L = q_prim_qp(1)%sf(x, y, z)
                    rho_R = q_prim_qp(1)%sf(x + offsets(1), y + offsets(2), z + offsets(3))

                    T_L = P_L/rho_L/Rgas_L
                    T_R = P_R/rho_R/Rgas_R

                    rho_cell = 0.5_wp*(rho_L + rho_R)

                    call get_mixture_specific_heat_cp_mass(T_L, Ys_L, Cp_L)
                    call get_mixture_specific_heat_cp_mass(T_R, Ys_R, Cp_R)
                    call get_mixture_enthalpy_mass(T_L, Ys_L, hmix_L)
                    call get_mixture_enthalpy_mass(T_R, Ys_R, hmix_R)
                    dh_dxi = (hmix_R - hmix_L)/grid_spacing

                    ! Get transport properties
                    call get_mixture_thermal_conductivity_mixavg(T_L, Ys_L, lambda_L)
                    call get_mixture_thermal_conductivity_mixavg(T_R, Ys_R, lambda_R)

                    ! Calculate species properties and gradients
                    $:GPU_LOOP(parallelism='[seq]')
                    do i = chemxb, chemxe
                        dYk_dxi(i - chemxb + 1) = (Ys_R(i - chemxb + 1) - &
                                                   Ys_L(i - chemxb + 1))/grid_spacing
                    end do

                    ! Calculate mixture-averaged diffusivities
                    diffusivity_L = lambda_L/rho_L/Cp_L
                    diffusivity_R = lambda_R/rho_R/Cp_R

                    lambda_Cell = 0.5_wp*(lambda_R + lambda_L)
                    diffusivity_Cell = 0.5_wp*(diffusivity_R + diffusivity_L)

                    ! Calculate mass diffusion fluxes
                    Mass_Diffu_Energy = 0.0_wp

                    $:GPU_LOOP(parallelism='[seq]')
                    do eqn = chemxb, chemxe
                        Mass_Diffu_Flux(eqn - chemxb + 1) = rho_cell* &
                                                            diffusivity_cell* &
                                                            dYk_dxi(eqn - chemxb + 1)
                    end do
                    Mass_Diffu_Energy = rho_cell*diffusivity_cell*dh_dxi

                    ! Update flux arrays
                    flux_src_vf(E_idx)%sf(x, y, z) = flux_src_vf(E_idx)%sf(x, y, z) - Mass_Diffu_Energy

                    $:GPU_LOOP(parallelism='[seq]')
                    do eqn = chemxb, chemxe
                        flux_src_vf(eqn)%sf(x, y, z) = flux_src_vf(eqn)%sf(x, y, z) - Mass_Diffu_Flux(eqn - chemxb + 1)
                    end do
                end do
            end do
        end do
        $:END_GPU_PARALLEL_LOOP()
    #:endblock UNDEF_AMD
end if

@codeant-ai codeant-ai bot added the size:L This PR changes 100-499 lines, ignoring generated files label Dec 15, 2025
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

1 issue found across 8 files

Prompt for AI agents (all 1 issues)

Check if these issues are valid — if so, understand the root cause of each and fix them.


<file name="src/common/include/ExtrusionHardcodedIC.fpp">

<violation number="1" location="src/common/include/ExtrusionHardcodedIC.fpp:178">
P1: This change ignores `global_offset_x` which is calculated for MPI subdomain positioning, and makes `idx` dead code. In parallel MPI runs, this could cause incorrect data mapping since the offset to the local subdomain is no longer considered. Either use `idx` as originally intended, or remove the unused `idx` calculation if the offset is truly not needed for 1D.</violation>
</file>

Since this is your first cubic review, here's how it works:

  • cubic automatically reviews your code and comments on bugs and improvements
  • Teach cubic by replying to its comments. cubic learns from your replies and gets better over time
  • Ask questions if you need clarification on any suggestion

Reply to cubic to teach it or ask questions. Re-run a review with @cubic-dev-ai review this PR

@codeant-ai
Copy link

codeant-ai bot commented Dec 15, 2025

Nitpicks 🔍

🔒 No security issues identified
⚡ Recommended areas for review

  • Indexing bug (1D mapping)
    The new assignment for the 1D case uses stored_values(i + 1, 1, f) while an idx variable is computed above as idx = i + 1 + global_offset_x. The use of i + 1 ignores the computed horizontal offset and will mis-map file data to the local grid (wrong alignment). This likely produces incorrect initial conditions when global_offset_x is non-zero.

  • Out-of-bounds risk
    There is no bounds checking before indexing stored_values(...) with the computed index (or with idx if corrected). If idx (or i+1) is outside the allocated range of stored_values, this will cause undefined behavior or runtime crash. Add explicit range checks or defensive handling.

  • Neighbor access / boundary safety
    The code reads neighbor cell values with expressions like q_prim_qp(..., x+offsets(1), ...). There is no explicit check in the new loops that the neighbor indices are inside the valid range; this relies on ghost/halo cells being present. Verify the domain halo/ghost-cell strategy and ensure accesses cannot index out-of-bounds (particularly near physical boundaries or when offsets != 1). Consider computing neighbor indices explicitly and guarding or documenting the precondition.

  • Uninitialized Field
    The new component transport_model is added to type chemistry_parameters but has no default initialization. Instances of this derived type may therefore contain an indeterminate integer value until explicitly set, which can cause unpredictable behavior when the transport model is queried before initialization.

  • Type Availability
    The newly declared chem_params uses the derived type chemistry_parameters. Confirm that this type is defined in one of the modules already used by this file (for example m_derived_types) — if it lives in a different module it will cause a compile-time error unless that module is also imported.

Copy link
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 pull request introduces Unity Lewis transport modeling to MFC's chemistry module, providing an alternative to the existing mixture-averaged transport methodology. The Unity Lewis number approximation assumes thermal diffusivity equals mass diffusivity (Le = 1), which simplifies transport calculations by using enthalpy gradients instead of species-specific diffusion coefficients. The default transport model remains mixture-averaged (transport_model = 1), with Unity Lewis available as an option (transport_model = 2).

Key Changes:

  • Added transport_model parameter to chemistry configuration, allowing selection between mixture-averaged (1) and Unity Lewis (2) transport models
  • Implemented Unity Lewis transport flux calculations using enthalpy-gradient formulation and thermal diffusivity
  • Propagated transport_model parameter through MPI broadcasts and parameter initialization across all three MFC subprograms

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
toolchain/mfc/run/case_dicts.py Added transport_model to chemistry parameters as an integer type for input validation
src/simulation/m_mpi_proxy.fpp Added MPI broadcast for transport_model parameter to ensure consistency across processes
src/simulation/m_global_parameters.fpp Initialized transport_model to default value of 1 (mixture-averaged)
src/pre_process/m_global_parameters.fpp Declared chem_params and initialized transport_model to 1 in pre-processor
src/post_process/m_global_parameters.fpp Declared chem_params and initialized transport_model to 1 in post-processor
src/common/m_derived_types.fpp Added transport_model integer field to chemistry_parameters type
src/common/m_chemistry.fpp Implemented Unity Lewis model branch with enthalpy-based diffusion flux calculation; reorganized mixture-averaged code into conditional block
src/common/include/ExtrusionHardcodedIC.fpp Fixed indexing bug in 1D case to use i + 1 directly instead of unused idx variable

Comment on lines 376 to 379
diffusivity_R = lambda_R/rho_R/Cp_R

lambda_Cell = 0.5_wp*(lambda_R + lambda_L)
diffusivity_Cell = 0.5_wp*(diffusivity_R + diffusivity_L)
Copy link

@codeant-ai codeant-ai bot Dec 15, 2025

Choose a reason for hiding this comment

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

Suggestion: Inconsistent variable name for the cell diffusivity leads to use of an uninitialized variable: the code assigns to diffusivity_Cell but uses diffusivity_cell when computing Mass_Diffu_Flux. Although Fortran is case-insensitive, this mismatch is confusing and can hide real typos; make the name consistent (use a single identifier) so the value computed is the one actually used. [possible bug]

Severity Level: Critical 🚨

Suggested change
diffusivity_R = lambda_R/rho_R/Cp_R
lambda_Cell = 0.5_wp*(lambda_R + lambda_L)
diffusivity_Cell = 0.5_wp*(diffusivity_R + diffusivity_L)
diffusivity_cell = 0.5_wp*(diffusivity_R + diffusivity_L)
Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** src/common/m_chemistry.fpp
**Line:** 376:379
**Comment:**
	*Possible Bug: Inconsistent variable name for the cell diffusivity leads to use of an uninitialized variable: the code assigns to `diffusivity_Cell` but uses `diffusivity_cell` when computing `Mass_Diffu_Flux`. Although Fortran is case-insensitive, this mismatch is confusing and can hide real typos; make the name consistent (use a single identifier) so the value computed is the one actually used.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.

Copy link
Member

Choose a reason for hiding this comment

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

i agree with this commment

@codeant-ai
Copy link

codeant-ai bot commented Dec 15, 2025

CodeAnt AI finished reviewing your PR.

Copy link
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: 0

♻️ Duplicate comments (1)
src/common/m_chemistry.fpp (1)

174-405: Validate chem_params%transport_model and consider de-duplicating common diffusion logic

The two-branch implementation of s_compute_chemistry_diffusion_flux looks internally consistent:

  • Directional offsets and grid_spacing selection are handled uniformly via offsets(idir).
  • All scalars and work arrays used inside $:GPU_PARALLEL_LOOP are in the private list, which should avoid race conditions.
  • Model 1 (mixture-averaged) correctly applies a mass-conservation correction (rho_Vic) and adds thermal conduction via lambda_Cell*dT_dxi.
  • Model 2 (unity Lewis) derives a scalar diffusivity from λ/(ρ Cp) and uses dh_dxi with a single diffusivity_cell, which automatically keeps Σ j_k = 0 for Σ Y_k = 1.

Two follow-ups are worth addressing:

  1. No guard for invalid transport_model values

    If chem_params%transport_model is set to anything other than 1 or 2, the routine silently skips diffusion (the outer if (chemistry) is still true, but neither branch runs). That can produce physically wrong results without any diagnostics.

    Consider adding an else branch that aborts clearly, for example:

    if (chem_params%transport_model == 1) then
        ! ...
    else if (chem_params%transport_model == 2) then
        ! ...
    else
        call s_mpi_abort('Unsupported chem_params%transport_model; expected 1 (mixture-avg) or 2 (unity Lewis)')
    end if

    This keeps the behavior explicit and aligns with the project’s error-handling conventions.

  2. Shared setup duplicated between the two models

    A large amount of setup (directional grid_spacing, Ys_L/R/cell, ρ/MW/Rgas/P/T computation) is effectively duplicated in both branches. This has already been called out in a prior review; factoring that shared work into a common block or helper would reduce maintenance risk when new species/thermo fields are added.

    Since this mirrors an existing high-level suggestion, treat it as a follow-on refactor rather than a blocker.

🧹 Nitpick comments (5)
src/common/include/ExtrusionHardcodedIC.fpp (1)

173-179: 1D IC extrusion now ignores global_offset_x — verify mapping and clean up

For the 1D case you still compute global_offset_x, but the assignment now uses stored_values(i + 1, 1, f) instead of stored_values(idx, 1, f). That changes semantics whenever global_offset_x /= 0 (e.g., nontrivial domain offsets or multi-rank layouts) and leaves global_offset_x as dead state.

Please verify with a 1D multi-rank (or offset) case that the intended cells still pick up the correct data; if 1D is always aligned/no-offset, consider either:

  • reverting to stored_values(idx, 1, f) and relying on global_offset_x, or
  • dropping the global_offset_x computation entirely for the 1D branch and documenting that assumption.
src/post_process/m_global_parameters.fpp (1)

303-304: Initialize all chem_params members for deterministic post-processing

You added chem_params and defaulted gamma_method/transport_model to 1, but diffusion and reactions remain uninitialized in this module. For consistency with the simulation globals (where they’re set to .false.) and to avoid any future undefined-use if post_process ever reads them, consider also initializing:

chem_params%diffusion  = .false.
chem_params%reactions  = .false.
chem_params%gamma_method   = 1
chem_params%transport_model = 1

Also applies to: 420-422

src/pre_process/m_global_parameters.fpp (1)

220-220: Pre-process chem_params should also fully initialize its flags

Here chem_params is introduced and only gamma_method/transport_model are defaulted. For consistency with the simulation module and to avoid any accidental use of undefined logicals, consider:

chem_params%diffusion       = .false.
chem_params%reactions       = .false.
chem_params%gamma_method    = 1
chem_params%transport_model = 1

This keeps semantics uniform across pre/sim/post stages.

Also applies to: 575-577

src/common/m_derived_types.fpp (1)

435-446: Document the allowed values for chemistry_parameters%transport_model

The new transport_model integer is only interpreted in m_chemistry as 1 (mixture-averaged) and 2 (unity Lewis). It would help maintenance to encode that here, e.g.:

integer :: transport_model  !< 1: mixture-averaged, 2: unity Lewis number

so callers and input tooling know the valid range.

toolchain/mfc/run/case_dicts.py (1)

356-361: Schema update for chem_params%transport_model is correct; consider future range checks

Adding chem_params%transport_model as an INT alongside gamma_method in the SIMULATION map is exactly what’s needed for the new chemistry parameter to pass validation.

If you later want to harden input, you could extend ParamType to support small integer enums and restrict this field to {1, 2} to catch invalid transport models at parse time.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8ae42aa and 259f2a5.

📒 Files selected for processing (8)
  • src/common/include/ExtrusionHardcodedIC.fpp (1 hunks)
  • src/common/m_chemistry.fpp (3 hunks)
  • src/common/m_derived_types.fpp (1 hunks)
  • src/post_process/m_global_parameters.fpp (2 hunks)
  • src/pre_process/m_global_parameters.fpp (2 hunks)
  • src/simulation/m_global_parameters.fpp (1 hunks)
  • src/simulation/m_mpi_proxy.fpp (1 hunks)
  • toolchain/mfc/run/case_dicts.py (1 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{fpp,f90}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.{fpp,f90}: Use 2-space indentation; continuation lines align beneath &
Use lower-case keywords and intrinsics (do, end subroutine, etc.)
Name modules with m_ pattern (e.g., m_transport)
Name public subroutines with s_ pattern (e.g., s_compute_flux)
Name public functions with f
_ pattern
Keep subroutine size ≤ 500 lines, helper subroutines ≤ 150 lines, functions ≤ 100 lines, files ≤ 1000 lines
Limit routine arguments to ≤ 6; use derived-type params struct if more are needed
Forbid goto statements (except in legacy code), COMMON blocks, and save globals
Every argument must have explicit intent; use dimension/allocatable/pointer as appropriate
Call s_mpi_abort() for errors, never use stop or error stop

**/*.{fpp,f90}: Indent 2 spaces; continuation lines align under &
Use lower-case keywords and intrinsics (do, end subroutine, etc.)
Name modules with m_<feature> prefix (e.g., m_transport)
Name public subroutines as s_<verb>_<noun> (e.g., s_compute_flux) and functions as f_<verb>_<noun>
Keep private helpers in the module; avoid nested procedures
Enforce size limits: subroutine ≤ 500 lines, helper ≤ 150, function ≤ 100, module/file ≤ 1000
Limit subroutines to ≤ 6 arguments; otherwise pass a derived-type 'params' struct
Avoid goto statements (except unavoidable legacy); avoid global state (COMMON, save)
Every variable must have intent(in|out|inout) specification and appropriate dimension / allocatable / pointer
Use s_mpi_abort(<msg>) for error termination instead of stop
Use !> style documentation for header comments; follow Doxygen Fortran format with !! @param and !! @return tags
Use implicit none statement in all modules
Use private declaration followed by explicit public exports in modules
Use derived types with pointers for encapsulation (e.g., pointer, dimension(:,:,:) => null())
Use pure and elemental attributes for side-effect-free functions; combine them for array ...

Files:

  • src/common/m_derived_types.fpp
  • src/post_process/m_global_parameters.fpp
  • src/common/m_chemistry.fpp
  • src/simulation/m_mpi_proxy.fpp
  • src/common/include/ExtrusionHardcodedIC.fpp
  • src/pre_process/m_global_parameters.fpp
  • src/simulation/m_global_parameters.fpp
src/**/*.fpp

📄 CodeRabbit inference engine (.cursor/rules/mfc-agent-rules.mdc)

src/**/*.fpp: Use .fpp file extension for Fypp preprocessed files; CMake transpiles them to .f90
Start module files with Fypp include for macros: #:include 'macros.fpp'
Use the fypp ASSERT macro for validating conditions: @:ASSERT(predicate, message)
Use fypp macro @:ALLOCATE(var1, var2) for device-aware allocation instead of standard Fortran allocate
Use fypp macro @:DEALLOCATE(var1, var2) for device-aware deallocation instead of standard Fortran deallocate

Files:

  • src/common/m_derived_types.fpp
  • src/post_process/m_global_parameters.fpp
  • src/common/m_chemistry.fpp
  • src/simulation/m_mpi_proxy.fpp
  • src/common/include/ExtrusionHardcodedIC.fpp
  • src/pre_process/m_global_parameters.fpp
  • src/simulation/m_global_parameters.fpp
src/simulation/**/*.{fpp,f90}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/simulation/**/*.{fpp,f90}: Wrap tight GPU loops with !$acc parallel loop gang vector default(present) reduction(...); add collapse(n) when safe; declare loop-local variables with private(...)
Allocate large GPU arrays with managed memory or move them into persistent !$acc enter data regions at start-up
Avoid stop/error stop inside GPU device code
Ensure GPU code compiles with Cray ftn, NVIDIA nvfortran, GNU gfortran, and Intel ifx/ifort compilers

src/simulation/**/*.{fpp,f90}: Mark GPU-callable helpers with $:GPU_ROUTINE(function_name='...', parallelism='[seq]') immediately after declaration
Do not use OpenACC or OpenMP directives directly; use Fypp macros from src/common/include/parallel_macros.fpp instead
Wrap tight loops with $:GPU_PARALLEL_FOR(private='[...]', copy='[...]') macro; add collapse=n for safe nested loop merging
Declare loop-local variables with private='[...]' in GPU parallel loop macros
Allocate large arrays with managed or move them into a persistent $:GPU_ENTER_DATA(...) region at start-up
Do not place stop or error stop inside device code

Files:

  • src/simulation/m_mpi_proxy.fpp
  • src/simulation/m_global_parameters.fpp
🧠 Learnings (6)
📚 Learning: 2025-11-24T21:50:46.909Z
Learnt from: CR
Repo: MFlowCode/MFC PR: 0
File: .cursor/rules/mfc-agent-rules.mdc:0-0
Timestamp: 2025-11-24T21:50:46.909Z
Learning: Applies to **/*.{fpp,f90} : Name modules with `m_<feature>` prefix (e.g., `m_transport`)

Applied to files:

  • src/common/m_derived_types.fpp
  • src/post_process/m_global_parameters.fpp
📚 Learning: 2025-11-24T21:50:46.909Z
Learnt from: CR
Repo: MFlowCode/MFC PR: 0
File: .cursor/rules/mfc-agent-rules.mdc:0-0
Timestamp: 2025-11-24T21:50:46.909Z
Learning: Applies to **/*.{fpp,f90} : Use `private` declaration followed by explicit `public` exports in modules

Applied to files:

  • src/common/m_chemistry.fpp
📚 Learning: 2025-11-24T21:50:16.713Z
Learnt from: CR
Repo: MFlowCode/MFC PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T21:50:16.713Z
Learning: Applies to src/simulation/**/*.{fpp,f90} : Wrap tight GPU loops with !$acc parallel loop gang vector default(present) reduction(...); add collapse(n) when safe; declare loop-local variables with private(...)

Applied to files:

  • src/common/m_chemistry.fpp
  • src/simulation/m_mpi_proxy.fpp
📚 Learning: 2025-11-24T21:50:46.909Z
Learnt from: CR
Repo: MFlowCode/MFC PR: 0
File: .cursor/rules/mfc-agent-rules.mdc:0-0
Timestamp: 2025-11-24T21:50:46.909Z
Learning: Applies to src/simulation/**/*.{fpp,f90} : Wrap tight loops with `$:GPU_PARALLEL_FOR(private='[...]', copy='[...]')` macro; add `collapse=n` for safe nested loop merging

Applied to files:

  • src/simulation/m_mpi_proxy.fpp
📚 Learning: 2025-11-24T21:50:46.909Z
Learnt from: CR
Repo: MFlowCode/MFC PR: 0
File: .cursor/rules/mfc-agent-rules.mdc:0-0
Timestamp: 2025-11-24T21:50:46.909Z
Learning: Applies to src/simulation/**/*.{fpp,f90} : Do not use OpenACC or OpenMP directives directly; use Fypp macros from `src/common/include/parallel_macros.fpp` instead

Applied to files:

  • src/simulation/m_mpi_proxy.fpp
📚 Learning: 2025-11-24T21:50:16.713Z
Learnt from: CR
Repo: MFlowCode/MFC PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T21:50:16.713Z
Learning: Applies to src/simulation/**/*.{fpp,f90} : Ensure GPU code compiles with Cray ftn, NVIDIA nvfortran, GNU gfortran, and Intel ifx/ifort compilers

Applied to files:

  • src/simulation/m_mpi_proxy.fpp
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (10)
  • GitHub Check: Github (macos, mpi, no-debug, false)
  • GitHub Check: Github (ubuntu, mpi, no-debug, true)
  • GitHub Check: Github (macos, mpi, debug, false)
  • GitHub Check: Github (ubuntu, no-mpi, single, no-debug, false)
  • GitHub Check: Github (ubuntu, mpi, debug, false)
  • GitHub Check: Github (ubuntu, mpi, no-debug, false)
  • GitHub Check: Github (ubuntu, mpi, debug, true)
  • GitHub Check: Coverage Test on CodeCov
  • GitHub Check: Code Cleanliness Check
  • GitHub Check: Build & Publish
🔇 Additional comments (3)
src/simulation/m_mpi_proxy.fpp (1)

123-131: Chemistry MPI broadcast extension looks consistent

Broadcasting chem_params%gamma_method and chem_params%transport_model together as MPI_INTEGER under the existing if (chemistry) guard is consistent with how chem_params is defined and how the other chem flags are handled. This should correctly propagate the new transport model across ranks.

src/simulation/m_global_parameters.fpp (1)

646-650: Defaulting chem_params%transport_model to 1 preserves prior behavior

Setting chem_params%transport_model = 1 alongside the existing defaults for diffusion, reactions, and gamma_method keeps mixture-averaged transport as the default and avoids uninitialized use of the new parameter.

src/common/m_chemistry.fpp (1)

11-49: New thermochemistry imports and viscosity helper are consistent

Importing get_mixture_viscosity_mixavg / cp / enthalpy helpers and wrapping the viscosity call in compute_viscosity_and_inversion is straightforward and keeps the inversion logic in one place. The interface (intent(inout) scalars and Ys arrays) matches the rest of this module’s style.

Copy link
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.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

@codeant-ai
Copy link

codeant-ai bot commented Dec 20, 2025

CodeAnt AI is running Incremental review


Thanks for using CodeAnt! 🎉

We're free for open-source projects. if you're enjoying it, help us grow by sharing.

Share on X ·
Reddit ·
LinkedIn

@sbryngelson
Copy link
Member

@DimAdam-01 is this ready to merge? what about all the reviewer comments?

@codeant-ai
Copy link

codeant-ai bot commented Dec 23, 2025

CodeAnt AI is running Incremental review


Thanks for using CodeAnt! 🎉

We're free for open-source projects. if you're enjoying it, help us grow by sharing.

Share on X ·
Reddit ·
LinkedIn

Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

3 issues found across 4 files (changes from recent commits).

Prompt for AI agents (all issues)

Check if these issues are valid — if so, understand the root cause of each and fix them.


<file name="examples/1D_multispecies_diffusion/case.py">

<violation number="1" location="examples/1D_multispecies_diffusion/case.py:56">
P2: Incorrect comment: `transport_model: 2` corresponds to Unity Lewis transport, not Mixture-Average. According to m_chemistry.fpp, transport_model=1 is Mixture-Average and transport_model=2 is Unity Lewis.</violation>
</file>

<file name="src/common/include/ExtrusionHardcodedIC.fpp">

<violation number="1" location="src/common/include/ExtrusionHardcodedIC.fpp:51">
P1: Hardcoded user-specific path should not be committed. This path `/Users/dimitriosadam/Desktop/MFC-Adam/examples/` is specific to a developer&#39;s local machine and will break functionality for all other users. Consider reverting to the previous placeholder or making this path configurable via a parameter/environment variable.</violation>
</file>

<file name="docs/documentation/case.md">

<violation number="1" location="docs/documentation/case.md:1004">
P3: Typo: &quot;coeffiecients&quot; should be &quot;coefficients&quot;.</violation>
</file>

Reply to cubic to teach it or ask questions. Re-run a review with @cubic-dev-ai review this PR

Copy link
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: 3

♻️ Duplicate comments (1)
src/common/include/ExtrusionHardcodedIC.fpp (1)

176-178: Revert to use idx for correct MPI subdomain data mapping.

This change removes global_offset_x from the 1D indexing, causing stored_values to be indexed with the local grid position (i + 1) rather than the global file position (i + 1 + global_offset_x). In MPI parallel runs, this will map file data to incorrect local grid positions. The 2D (line 185) and 3D (line 194) cases correctly retain offset-adjusted indexing, confirming this is an unintended regression.

🔎 Proposed fix
         idx = i + 1 + global_offset_x
         do f = 1, sys_size
-            q_prim_vf(f)%sf(i, 0, 0) = stored_values(i + 1, 1, f)
+            q_prim_vf(f)%sf(i, 0, 0) = stored_values(idx, 1, f)
         end do
🧹 Nitpick comments (1)
docs/documentation/case.md (1)

1007-1007: Fix formatting: misplaced backtick.

The backtick and colon placement is inconsistent; the value descriptions should be separated by a colon followed by a space before the backtick.

🔎 Proposed fix
-- `chem_params%transport_model` specifies the methodology for calculating diffusion coefficients and other transport properties,`1` for mixture-average, `2` for Unity-Lewis
+- `chem_params%transport_model` specifies the methodology for calculating diffusion coefficients and other transport properties: `1` for mixture-average, `2` for Unity-Lewis
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 05fd51f and cb259ec.

📒 Files selected for processing (4)
  • docs/documentation/case.md
  • examples/1D_multispecies_diffusion/case.py
  • src/common/include/ExtrusionHardcodedIC.fpp
  • toolchain/mfc/test/cases.py
✅ Files skipped from review due to trivial changes (1)
  • toolchain/mfc/test/cases.py
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{fpp,f90}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.{fpp,f90}: Use 2-space indentation; continuation lines align beneath &
Use lower-case keywords and intrinsics (do, end subroutine, etc.)
Name modules with m_ pattern (e.g., m_transport)
Name public subroutines with s_ pattern (e.g., s_compute_flux)
Name public functions with f
_ pattern
Keep subroutine size ≤ 500 lines, helper subroutines ≤ 150 lines, functions ≤ 100 lines, files ≤ 1000 lines
Limit routine arguments to ≤ 6; use derived-type params struct if more are needed
Forbid goto statements (except in legacy code), COMMON blocks, and save globals
Every argument must have explicit intent; use dimension/allocatable/pointer as appropriate
Call s_mpi_abort() for errors, never use stop or error stop

**/*.{fpp,f90}: Indent 2 spaces; continuation lines align under &
Use lower-case keywords and intrinsics (do, end subroutine, etc.)
Name modules with m_<feature> prefix (e.g., m_transport)
Name public subroutines as s_<verb>_<noun> (e.g., s_compute_flux) and functions as f_<verb>_<noun>
Keep private helpers in the module; avoid nested procedures
Enforce size limits: subroutine ≤ 500 lines, helper ≤ 150, function ≤ 100, module/file ≤ 1000
Limit subroutines to ≤ 6 arguments; otherwise pass a derived-type 'params' struct
Avoid goto statements (except unavoidable legacy); avoid global state (COMMON, save)
Every variable must have intent(in|out|inout) specification and appropriate dimension / allocatable / pointer
Use s_mpi_abort(<msg>) for error termination instead of stop
Use !> style documentation for header comments; follow Doxygen Fortran format with !! @param and !! @return tags
Use implicit none statement in all modules
Use private declaration followed by explicit public exports in modules
Use derived types with pointers for encapsulation (e.g., pointer, dimension(:,:,:) => null())
Use pure and elemental attributes for side-effect-free functions; combine them for array ...

Files:

  • src/common/include/ExtrusionHardcodedIC.fpp
src/**/*.fpp

📄 CodeRabbit inference engine (.cursor/rules/mfc-agent-rules.mdc)

src/**/*.fpp: Use .fpp file extension for Fypp preprocessed files; CMake transpiles them to .f90
Start module files with Fypp include for macros: #:include 'macros.fpp'
Use the fypp ASSERT macro for validating conditions: @:ASSERT(predicate, message)
Use fypp macro @:ALLOCATE(var1, var2) for device-aware allocation instead of standard Fortran allocate
Use fypp macro @:DEALLOCATE(var1, var2) for device-aware deallocation instead of standard Fortran deallocate

Files:

  • src/common/include/ExtrusionHardcodedIC.fpp
🧠 Learnings (2)
📚 Learning: 2025-11-24T21:50:46.909Z
Learnt from: CR
Repo: MFlowCode/MFC PR: 0
File: .cursor/rules/mfc-agent-rules.mdc:0-0
Timestamp: 2025-11-24T21:50:46.909Z
Learning: Applies to src/simulation/**/*.{fpp,f90} : Do not use OpenACC or OpenMP directives directly; use Fypp macros from `src/common/include/parallel_macros.fpp` instead

Applied to files:

  • src/common/include/ExtrusionHardcodedIC.fpp
📚 Learning: 2025-11-24T21:50:16.713Z
Learnt from: CR
Repo: MFlowCode/MFC PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T21:50:16.713Z
Learning: Applies to src/simulation/**/*.{fpp,f90} : Avoid stop/error stop inside GPU device code

Applied to files:

  • src/common/include/ExtrusionHardcodedIC.fpp
🧬 Code graph analysis (1)
examples/1D_multispecies_diffusion/case.py (1)
toolchain/mfc/case.py (1)
  • Case (19-292)
🪛 GitHub Actions: Spell Check
docs/documentation/case.md

[error] 1004-1004: During step './mfc.sh spelling', typo detected: 'coeffiecients' should be 'coefficients'.

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (17)
  • GitHub Check: Code Cleanliness Check
  • GitHub Check: Coverage Test on CodeCov
  • GitHub Check: Github (ubuntu, no-mpi, single, no-debug, false)
  • GitHub Check: Github (ubuntu, mpi, debug, false)
  • GitHub Check: Github (ubuntu, mpi, debug, true)
  • GitHub Check: Github (ubuntu, mpi, no-debug, false)
  • GitHub Check: Georgia Tech | Phoenix (gpu-omp)
  • GitHub Check: Georgia Tech | Phoenix (cpu)
  • GitHub Check: Github (macos, mpi, debug, false)
  • GitHub Check: Github (ubuntu, mpi, no-debug, true)
  • GitHub Check: Oak Ridge | Frontier (gpu-acc)
  • GitHub Check: Github (macos, mpi, no-debug, false)
  • GitHub Check: Oak Ridge | Frontier (cpu)
  • GitHub Check: Oak Ridge | Frontier (gpu-omp)
  • GitHub Check: Georgia Tech | Phoenix (gpu-acc)
  • GitHub Check: cubic · AI code reviewer
  • GitHub Check: Build & Publish
🔇 Additional comments (1)
examples/1D_multispecies_diffusion/case.py (1)

74-76: Verify species mass fraction initialization.

All species mass fractions are initialized to 0.0, which may not be physically meaningful for a multispecies diffusion test. Since the patch uses a hardcoded IC (hcid=182), verify that the hardcoded patch properly initializes the species distribution. Consider adding a comment explaining that the actual species values are set by the hardcoded IC if that's the intended behavior.

Copy link
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: 0

🧹 Nitpick comments (1)
docs/documentation/case.md (1)

1007-1007: Fix formatting: add space after comma before backtick.

Line 1007 is missing a space between the comma and the opening backtick. The text currently reads properties,1 which should be `properties, `1 (with a space after the comma).

🔎 Proposed fix
-- `chem_params%transport_model` specifies the methodology for calculating diffusion coefficients and other transport properties,`1` for mixture-average, `2` for Unity-Lewis
+- `chem_params%transport_model` specifies the methodology for calculating diffusion coefficients and other transport properties, `1` for mixture-average, `2` for Unity-Lewis
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between cb259ec and 476967a.

📒 Files selected for processing (1)
  • docs/documentation/case.md
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (13)
  • GitHub Check: Code Cleanliness Check
  • GitHub Check: Coverage Test on CodeCov
  • GitHub Check: Github (ubuntu, no-mpi, single, no-debug, false)
  • GitHub Check: Github (macos, mpi, no-debug, false)
  • GitHub Check: Github (ubuntu, mpi, debug, false)
  • GitHub Check: Oak Ridge | Frontier (gpu-omp)
  • GitHub Check: Github (ubuntu, mpi, no-debug, true)
  • GitHub Check: Georgia Tech | Phoenix (cpu)
  • GitHub Check: Github (macos, mpi, debug, false)
  • GitHub Check: Github (ubuntu, mpi, no-debug, false)
  • GitHub Check: Github (ubuntu, mpi, debug, true)
  • GitHub Check: Georgia Tech | Phoenix (gpu-acc)
  • GitHub Check: Build & Publish

sbryngelson
sbryngelson previously approved these changes Dec 23, 2025
@codeant-ai
Copy link

codeant-ai bot commented Dec 23, 2025

CodeAnt AI is running Incremental review


Thanks for using CodeAnt! 🎉

We're free for open-source projects. if you're enjoying it, help us grow by sharing.

Share on X ·
Reddit ·
LinkedIn

@sbryngelson
Copy link
Member

@DimAdam-01 close issues/conversations you have fixed... otherwise I assume they remain open.

@sbryngelson
Copy link
Member

/improve

Comment on lines +385 to +390
do eqn = chemxb, chemxe
Mass_Diffu_Flux(eqn - chemxb + 1) = rho_cell* &
diffusivity_cell* &
dYk_dxi(eqn - chemxb + 1)
end do
Mass_Diffu_Energy = rho_cell*diffusivity_cell*dh_dxi
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggestion: Invert the sign of the Unity-Lewis diffusion flux calculation for both species and energy. The current implementation incorrectly points with the gradient, which will cause anti-diffusion and instability. [possible issue, importance: 10]

Suggested change
do eqn = chemxb, chemxe
Mass_Diffu_Flux(eqn - chemxb + 1) = rho_cell* &
diffusivity_cell* &
dYk_dxi(eqn - chemxb + 1)
end do
Mass_Diffu_Energy = rho_cell*diffusivity_cell*dh_dxi
do i = chemxb, chemxe
dYk_dxi(i - chemxb + 1) = (Ys_R(i - chemxb + 1) - &
Ys_L(i - chemxb + 1))/grid_spacing
end do
...
do eqn = chemxb, chemxe
Mass_Diffu_Flux(eqn - chemxb + 1) = -rho_cell* &
diffusivity_cell* &
dYk_dxi(eqn - chemxb + 1)
end do
Mass_Diffu_Energy = -rho_cell*diffusivity_cell*dh_dxi

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The sign is correct

Copy link
Contributor

Choose a reason for hiding this comment

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

Question:

The sign is correct

Answer:

This is a classic domain-convention pitfall (sign depends on your coordinate definition, face orientation, and how you define “flux” vs “-flux” in the discretization). Qodo Merge can’t reliably infer that from a small diff, so the best mitigation is to explicitly instruct it to be conservative about “flip the sign” recommendations unless there’s hard evidence (tests, comments, clearly inconsistent usage elsewhere).

Add a repo-level instruction for /improve:

[pr_code_suggestions]
extra_instructions = """\
For PDE/numerics/physics code (fluxes, gradients, diffusion, convection):
- Do NOT suggest changing the sign of a term (e.g., flux = -D*grad(phi)) unless the PR provides explicit evidence (unit tests failing, a reference comment/equation in code, or a clear contradiction with the project's established convention in other files).
- If the sign looks suspicious, ask a verification question instead: clarify coordinate direction, face-normal orientation, and whether the stored variable is "flux" or "-flux".
- Avoid marking sign-convention suggestions as high-importance unless there is direct evidence of instability/anti-diffusion in this codebase.
"""

If you want to further reduce “speculative” suggestions, you can also tighten output by filtering low-confidence items:

[pr_code_suggestions]
suggestions_score_threshold = 2

(Keep this low; setting it too high can hide useful findings.)

Relevant Sources:

Co-authored-by: qodo-code-review[bot] <151058649+qodo-code-review[bot]@users.noreply.github.com>
@codeant-ai
Copy link

codeant-ai bot commented Dec 24, 2025

CodeAnt AI is running Incremental review


Thanks for using CodeAnt! 🎉

We're free for open-source projects. if you're enjoying it, help us grow by sharing.

Share on X ·
Reddit ·
LinkedIn

Copy link
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: 0

🧹 Nitpick comments (2)
examples/1D_multispecies_diffusion/case.py (2)

6-6: Remove unused import.

The argparse module is imported but never used in this script.

🔎 Proposed fix
-import argparse

11-12: Clarify or simplify Cantera solution initialization.

The script sets specific TPX conditions for sol_L but only uses len(sol_L.Y) to count species. The actual initial conditions come from the hardcoded IC (hcid=182). Consider either:

  • Removing the TPX assignment if only the species count is needed, or
  • Adding a comment explaining the purpose of these specific conditions
🔎 Simplified alternative

If only the species count is needed:

 ctfile = "gri30.yaml"
 sol_L = ct.Solution(ctfile)
-sol_L.TPX = 300, 8000, "O2:2,N2:2,H2O:5"
+# sol_L is used only to determine the number of species in the mechanism
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 15f1260 and 0e8124f.

📒 Files selected for processing (1)
  • examples/1D_multispecies_diffusion/case.py
🧰 Additional context used
🧬 Code graph analysis (1)
examples/1D_multispecies_diffusion/case.py (2)
toolchain/mfc/test/cases.py (4)
  • alter_3d (322-365)
  • alter_num_fluids (224-291)
  • modify_example_case (1040-1057)
  • alter_capillary (122-126)
toolchain/mfc/case.py (1)
  • Case (19-292)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (16)
  • GitHub Check: Github (ubuntu, mpi, debug, false)
  • GitHub Check: Github (ubuntu, mpi, no-debug, true)
  • GitHub Check: Github (ubuntu, no-mpi, single, no-debug, false)
  • GitHub Check: Github (ubuntu, mpi, no-debug, false)
  • GitHub Check: Github (macos, mpi, no-debug, false)
  • GitHub Check: Github (macos, mpi, debug, false)
  • GitHub Check: Georgia Tech | Phoenix (gpu-acc)
  • GitHub Check: Github (ubuntu, mpi, debug, true)
  • GitHub Check: Oak Ridge | Frontier (gpu-omp)
  • GitHub Check: Oak Ridge | Frontier (cpu)
  • GitHub Check: Georgia Tech | Phoenix (gpu-omp)
  • GitHub Check: Oak Ridge | Frontier (gpu-acc)
  • GitHub Check: Georgia Tech | Phoenix (cpu)
  • GitHub Check: Code Cleanliness Check
  • GitHub Check: Coverage Test on CodeCov
  • GitHub Check: Build & Publish
🔇 Additional comments (1)
examples/1D_multispecies_diffusion/case.py (1)

56-56: Transport model configuration is correct.

The transport_model value and comment are now consistent. Value 2 correctly corresponds to Unity-Lewis transport as documented in the source code.

Note: This addresses the issues raised in previous review comments.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Review effort 4/5 size:L This PR changes 100-499 lines, ignoring generated files

Development

Successfully merging this pull request may close these issues.

2 participants