|
MFC
Exascale flow solver
|
This page explains how MFC's source code is organized, how data flows through the solver, and where to find things. Read this before diving into the source.
MFC runs as three separate executables that communicate via binary files on disk:
| Phase | Entry Point | What It Does |
|---|---|---|
| Pre-Process | src/pre_process/p_main.f90 | Generates the computational grid and initial conditions from patch definitions. Writes binary grid and state files. |
| Simulation | src/simulation/p_main.fpp | Reads the initial state and advances the governing equations in time. Periodically writes solution snapshots. |
| Post-Process | src/post_process/p_main.fpp | Reads snapshots, computes derived quantities (vorticity, Schlieren, etc.), and writes Silo/HDF5 files for VisIt or ParaView. |
Each phase is an independent MPI program. The simulation phase is where nearly all compute time is spent.
Shared modules in src/common/ include MPI communication, derived types, variable conversion, and utility functions. They are compiled into each phase.
Two arrays carry the solution through the entire simulation:
| Variable | Contents | When Used |
|---|---|---|
| q_cons_vf | Conservative variables: \(\alpha\rho\), \(\rho u\), \(\rho v\), \(\rho w\), \(E\), \(\alpha\) | Storage, time integration, I/O |
| q_prim_vf | Primitive variables: \(\rho\), \(u\), \(v\), \(w\), \(p\), \(\alpha\) | Reconstruction, Riemann solving, physics |
Both are vector_field types (defined in m_derived_types), which are arrays of scalar_field. Each scalar_field wraps a 3D real array sf(0:m, 0:n, 0:p) representing one variable on the grid.
The index layout within q_cons_vf depends on the flow model:
Additional variables are appended for bubbles, elastic stress, magnetic fields, or chemistry species when those models are enabled. The total count is sys_size.
The simulation advances the solution through this call chain each time step:
MFC has ~80 Fortran modules organized by function. Here is where to look for what:
| Module | Role |
|---|---|
| m_rhs | Assembles the right-hand side of the governing equations using finite-volume flux differencing, Riemann solvers, and physical source terms |
| m_time_steppers | Total-variation-diminishing (TVD) Runge–Kutta time integrators (1st-, 2nd-, and 3rd-order SSP) |
| m_weno | WENO/WENO-Z/TENO reconstruction with optional monotonicity-preserving bounds and mapped weights |
| m_riemann_solvers | Approximate and exact Riemann solvers (HLL, HLLC, HLLD, exact) for the multicomponent Navier–Stokes equations |
| m_muscl | MUSCL reconstruction with interface sharpening for contact-preserving advection |
| m_variables_conversion | Conservative-to-primitive variable conversion, mixture property evaluation, and pressure computation |
| Module | Role |
|---|---|
| m_viscous | Computes viscous stress tensors and diffusive flux contributions for the Navier–Stokes equations |
| m_surface_tension | Computes capillary source fluxes and color-function gradients for the diffuse-interface surface tension model |
| m_bubbles | Shared bubble-dynamics procedures (radial acceleration, wall pressure, sound speed) for ensemble- and volume-averaged models |
| m_bubbles_EE | Computes ensemble-averaged (Euler–Euler) bubble source terms for radius, velocity, pressure, and mass transfer |
| m_bubbles_EL | Tracks Lagrangian bubbles and couples their dynamics to the Eulerian flow via volume averaging |
| m_bubbles_EL_kernels | Kernel functions (Gaussian, delta) that smear Lagrangian bubble effects onto the Eulerian grid |
| m_qbmm | Quadrature-based moment methods (QBMM) for polydisperse bubble moment inversion and transport |
| m_hyperelastic | Computes the left Cauchy–Green deformation tensor and hyperelastic stress source terms |
| m_hypoelastic | Computes hypoelastic stress-rate source terms and damage-state evolution |
| m_phase_change | Phase transition relaxation solvers for liquid-vapor flows with cavitation and boiling |
| m_chemistry | Multi-species chemistry interface for thermodynamic properties, reaction rates, and transport coefficients |
| m_acoustic_src | Applies acoustic pressure source terms including focused, planar, and broadband transducers |
| m_body_forces | Computes gravitational and user-defined body force source terms for the momentum equations |
| m_pressure_relaxation | Pressure relaxation for the six-equation multi-component model via Newton–Raphson equilibration and volume-fraction correction |
| Module | Role |
|---|---|
| m_cbc | Characteristic boundary conditions (CBC) for slip walls, non-reflecting subsonic inflow/outflow, and supersonic boundaries |
| m_compute_cbc | Characteristic boundary condition (CBC) computations for subsonic inflow, outflow, and slip walls |
| m_boundary_common | Noncharacteristic and processor boundary condition application for ghost cells and buffer regions |
| m_ibm | Ghost-node immersed boundary method: locates ghost/image points, computes interpolation coefficients, and corrects the flow state |
| m_igr | Iterative ghost rasterization (IGR) for sharp immersed boundary treatment |
| m_ib_patches | Immersed boundary patch geometry constructors for 2D and 3D shapes |
| m_compute_levelset | Computes signed-distance level-set fields and surface normals for immersed-boundary patch geometries |
| Module | Role |
|---|---|
| m_start_up | Reads and validates user inputs, loads existing grid/IC data, and initializes pre-process modules |
| m_data_output | Writes grid and initial condition data to serial or parallel output files |
| m_data_input | Reads raw simulation grid and conservative-variable data for a given time-step and fills buffer regions |
| m_delay_file_access | Rank-staggered file access delays to prevent I/O contention on parallel file systems |
| Module | Role |
|---|---|
| m_derived_types | Shared derived types for field data, patch geometry, bubble dynamics, and MPI I/O structures |
| m_global_parameters | Defines global parameters for the computational domain, simulation algorithm, and initial conditions |
| m_mpi_common | MPI communication layer: domain decomposition, halo exchange, reductions, and parallel I/O setup |
| m_mpi_proxy | Broadcasts user inputs and decomposes the domain across MPI ranks for pre-processing |
| m_constants | Compile-time constant parameters: default values, tolerances, and physical constants |
| m_precision_select | Working-precision kind selection (half/single/double) and corresponding MPI datatype parameters |
| m_helper | Utility routines for bubble model setup, coordinate transforms, array sampling, and special functions |
| m_helper_basic | Basic floating-point utilities: approximate equality, default detection, and coordinate bounds |
| m_compile_specific | Platform-specific file and directory operations: create, delete, inquire, getcwd, and basename |
| m_fftw | Forward and inverse FFT wrappers (FFTW/cuFFT/hipFFT) for azimuthal Fourier filtering in cylindrical geometries |
| m_nvtx | NVIDIA NVTX profiling API bindings for GPU performance instrumentation |
| m_model | Binary STL file reader and processor for immersed boundary geometry |
| m_finite_differences | Finite difference operators for computing divergence of velocity fields |
| m_checker | Checks pre-process input file parameters for compatibility and correctness |
| m_checker_common | Shared input validation checks for grid dimensions and AMD GPU compiler limits |
| m_sim_helpers | Simulation helper routines for enthalpy computation, CFL calculation, and stability checks |
| m_derived_variables | Derives diagnostic flow quantities (vorticity, speed of sound, numerical Schlieren, etc.) from conservative and primitive variables |
| Module | Role |
|---|---|
| m_grid | Generates uniform or stretched rectilinear grids with hyperbolic-tangent spacing |
| m_icpp_patches | Constructs initial condition patch geometries (lines, circles, rectangles, spheres, etc.) on the grid |
| m_initial_condition | Assembles initial conditions by layering prioritized patches via constructive solid geometry |
| m_assign_variables | Assigns initial primitive variables to computational cells based on patch geometry |
| m_check_patches | Validates geometry parameters and constraints for initial condition patches |
| m_check_ib_patches | Validates geometry parameters and constraints for immersed boundary patches |
| m_perturbation | Perturbs initial mean flow fields with random noise, mixing-layer instabilities, or simplex noise |
| m_simplex_noise | 2D and 3D simplex noise generation for procedural initial condition perturbations |
| m_boundary_conditions | Applies spatially varying boundary condition patches along domain edges and faces |
The computational domain is decomposed into subdomains via MPI_Cart_create. Each rank owns a contiguous block of cells in (x, y, z). Ghost cells of width buff_size surround each subdomain and are filled by halo exchange before each RHS evaluation.
On GPUs, the same domain decomposition applies. GPU kernels operate on the local subdomain, with explicit host-device transfers for MPI communication (unless GPU-aware MPI / RDMA is available).
To add a new source term or physics model:
Follow the pattern of existing modules like m_body_forces (simple) or m_viscous (more involved) as a template.