Code Architecture & Module Topology

Code Architecture & Module Topology

This section provides a structural atlas of the codebase, mapping the source tree layout, module dependencies, and core datatype structures.

1. Directory Structure

The solver directory layout is split cleanly by functional components:

good_chemistry/
├── Makefile                        # Central project compiler configuration
├── src/                            # Source Code Directory
│   ├── app/                        # Main driver programs
│   │   └── main.f90                # The main transient CFD time-marching program
│   ├── core/                       # Foundational datatypes, parameters, and profiling
│   │   ├── mod_precision.f90       # Real precision definition (rk = double precision)
│   │   ├── mod_input.f90           # Fortran Namelist parsing and parameter verification
│   │   └── mod_profiling.f90       # Profiling timers and performance instrumentation
│   ├── mesh/                       # Grid topology and file loaders
│   │   ├── mod_mesh.f90            # Hexahedral face-to-cell connection maps
│   │   └── mod_mesh_io.f90         # Loader for native mesh files
│   ├── mpi/                        # Parallel communication routines
│   │   ├── mod_mpi_flow.f90        # Parallel domain halo updates and scalar/matrix reductions
│   │   └── mod_mpi_radiation.f90   # MPI handlers for angular radiation communication
│   ├── flow/                       # Hydrodynamic momentum and BCs
│   │   ├── mod_flow_fields.f90     # Velocity, pressure, and mass flux variables
│   │   ├── mod_bc.f90              # Cell-face boundary condition evaluation
│   │   └── mod_flow_projection.f90 # low-Mach projection routines and momentum predictors
│   ├── numerics/                   # Sparse matrix algorithms and solvers
│   │   ├── mod_reconstruction.f90  # Cell-face gradient and MUSCL limiters
│   │   └── mod_linear_solver.f90   # Preconditioned Conjugate Gradient (PCG) Poisson solvers
│   ├── species/                    # Mass transport and simplex projections
│   │   ├── mod_species.f90         # Transport equations and dominant bath gas corrections
│   │   └── mod_species_registry.f90# Chemical species indexing registries
│   ├── energy/                     # Thermal transport
│   │   └── mod_energy.f90          # Enthalpy, Fourier conduction, and temperature recovery
│   ├── chemistry/                  # Chemistry backend bridges
│   │   ├── mod_cantera.f90         # Fortran binding wrappers for chemistry bridges
│   │   ├── cantera_interface.cpp   # C++ bridge and transport caching layer for Cantera
│   │   └── pelephysics_interface.cpp# C++ bridge, CVODE reactors, and AMReX templates for PelePhysics
│   ├── radiation/                  # Radiative heat transfer
│   │   ├── mod_radiation.f90       # Central radiation solver interface
│   │   └── models/                 # Specialized radiation models (DOM, P1, None, Spectral)
│   └── io/                         # Checkpoints and visualization builders
│       ├── mod_output.f90          # VTU unstructured meshes and PVD time collection builders
│       └── mod_restart.f90         # Rank-independent binary restart reader/writer
└── doc_src/                        # Project documentation sources

2. Module Compilation Dependency Topology

Because Fortran enforces compile-time module dependencies (use statements), compilation follows a strict, non-circular hierarchy:

graph TD
    classDef core fill:#f9f,stroke:#333,stroke-width:2px;
    classDef mesh fill:#9f9,stroke:#333,stroke-width:1px;
    classDef flow fill:#99f,stroke:#333,stroke-width:1px;
    classDef numerics fill:#ff9,stroke:#333,stroke-width:1px;
    classDef physics fill:#f99,stroke:#333,stroke-width:1px;

    precision["mod_precision.f90"] --> input["mod_input.f90"]
    input --> mesh["mod_mesh.f90"]
    mesh --> mpi["mod_mpi_flow.f90"]
    mpi --> bc["mod_bc.f90"]
    bc --> fields["mod_flow_fields.f90"]
    fields --> recon["mod_reconstruction.f90"]
    recon --> solver["mod_linear_solver.f90"]
    solver --> chem["mod_cantera.f90"]
    chem --> species["mod_species.f90"]
    species --> energy["mod_energy.f90"]
    energy --> restart["mod_restart.f90"]
    restart --> radiation["mod_radiation.f90"]
    radiation --> output["mod_output.f90"]
    output --> main["main.f90"]

    class precision,input,profiling core;
    class mesh,mesh_io mesh;
    class bc,fields,flow_projection flow;
    class recon,solver numerics;
    class species,energy,chem,radiation physics;

3. Standard C-Bindings Layer

Communication between the C++ chemistry bridges and the Fortran solver is managed through the standard ISO_C_BINDING module:

interface
   subroutine cantera_integrate_const_p_chemistry_c(Y, T, rhs, dt, ncells, nspecies, ...) &
              bind(C, name="cantera_integrate_const_p_chemistry_c")
      use, intrinsic :: iso_c_binding
      real(c_double), intent(inout) :: Y(*), T(*)
      real(c_double), intent(out) :: rhs(*)
      real(c_double), value :: dt
      integer(c_int), value :: ncells, nspecies
   end subroutine cantera_integrate_const_p_chemistry_c
end interface
  • Raw Contiguous Storage: Fortran arrays are passed as flat, contiguous 1D pointers to C++ to avoid array-descriptor mismatches.
  • Column-Major Alignment: The C++ layers index multi-species matrices assuming standard Fortran layout rules.