Skip to content

Commit 1e4809b

Browse files
authored
Merge branch 'master' into modal_shapes
2 parents b4a3862 + 202033e commit 1e4809b

104 files changed

Lines changed: 1431 additions & 407 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,11 @@ docs/documentation/*-example.png
4545
docs/documentation/examples.md
4646
docs/documentation/case_constraints.md
4747
docs/documentation/physics_constraints.md
48+
docs/documentation/architecture.md
49+
docs/pre_process/readme.md
50+
docs/simulation/readme.md
51+
docs/post_process/readme.md
52+
docs/api/readme.md
4853

4954
examples/*batch/*/
5055
examples/**/D/*

.lychee.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,6 @@ exclude_path = ["sitemap\\.xml"]
2323
exclude = [
2424
"https://mflowcode\\.github\\.io/sitemap\\.xml", # Only exists after deployment
2525
"https://cpe\\.ext\\.hpe\\.com", # HPE Cray docs have broken SSL cert
26+
"https://sc22\\.supercomputing\\.org", # Returns 415 to automated requests
27+
"https://strawberryperl\\.com", # Frequently times out
2628
]

CMakeLists.txt

Lines changed: 64 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -727,6 +727,8 @@ if (MFC_DOCUMENTATION)
727727
set(DOXYGEN_IMAGE_PATH "\"${CMAKE_CURRENT_SOURCE_DIR}/docs/res\"\
728728
\"${CMAKE_CURRENT_SOURCE_DIR}/docs/${target}\"")
729729

730+
set(DOXYGEN_WARN_LOGFILE "\"${CMAKE_CURRENT_BINARY_DIR}/${target}-doxygen-warnings.log\"")
731+
730732
file(MAKE_DIRECTORY "${DOXYGEN_OUTPUT_DIRECTORY}")
731733

732734
configure_file(
@@ -801,11 +803,69 @@ if (MFC_DOCUMENTATION)
801803
\"${CMAKE_CURRENT_SOURCE_DIR}/docs/custom.css\"")
802804

803805
# > Generate Documentation & Landing Page
804-
GEN_DOCS(pre_process "MFC: Pre-Process")
805-
GEN_DOCS(simulation "MFC: Simulation")
806-
GEN_DOCS(post_process "MFC: Post-Process")
806+
GEN_DOCS(pre_process "MFC")
807+
GEN_DOCS(simulation "MFC")
808+
GEN_DOCS(post_process "MFC")
809+
GEN_DOCS(api "MFC")
807810
GEN_DOCS(documentation "MFC")
808811

812+
# Generate API landing pages for pre_process, simulation, post_process.
813+
# Scans src/{target}/*.fpp to produce module lists in docs/{target}/readme.md.
814+
add_custom_command(
815+
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/gen-api-landing.stamp"
816+
DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/docs/gen_api_landing.py"
817+
${pre_process_FPPs} ${pre_process_F90s}
818+
${simulation_FPPs} ${simulation_F90s}
819+
${post_process_FPPs} ${post_process_F90s}
820+
COMMAND "${Python3_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/docs/gen_api_landing.py"
821+
"${CMAKE_CURRENT_SOURCE_DIR}"
822+
COMMAND "${CMAKE_COMMAND}" -E touch "${CMAKE_CURRENT_BINARY_DIR}/gen-api-landing.stamp"
823+
COMMENT "Generating API landing pages"
824+
VERBATIM
825+
)
826+
add_custom_target(gen_api_landing DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/gen-api-landing.stamp")
827+
add_dependencies(pre_process_doxygen gen_api_landing)
828+
add_dependencies(simulation_doxygen gen_api_landing)
829+
add_dependencies(post_process_doxygen gen_api_landing)
830+
add_dependencies(api_doxygen gen_api_landing)
831+
832+
# Fix @file/@brief headers to match actual module/program declarations.
833+
# Handles mixed-case Fortran names and catches stale module renames.
834+
add_custom_command(
835+
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/fix-file-briefs.stamp"
836+
DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/docs/fix_file_briefs.py"
837+
${pre_process_FPPs} ${pre_process_F90s}
838+
${simulation_FPPs} ${simulation_F90s}
839+
${post_process_FPPs} ${post_process_F90s}
840+
COMMAND "${Python3_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/docs/fix_file_briefs.py"
841+
"${CMAKE_CURRENT_SOURCE_DIR}"
842+
COMMAND "${CMAKE_COMMAND}" -E touch "${CMAKE_CURRENT_BINARY_DIR}/fix-file-briefs.stamp"
843+
COMMENT "Fixing @file brief headers"
844+
VERBATIM
845+
)
846+
add_custom_target(fix_file_briefs DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/fix-file-briefs.stamp")
847+
add_dependencies(pre_process_doxygen fix_file_briefs)
848+
add_dependencies(simulation_doxygen fix_file_briefs)
849+
add_dependencies(post_process_doxygen fix_file_briefs)
850+
851+
# Generate architecture.md from template + module_categories.json + source briefs.
852+
add_custom_command(
853+
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/gen-architecture.stamp"
854+
DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/docs/gen_architecture.py"
855+
"${CMAKE_CURRENT_SOURCE_DIR}/docs/module_categories.json"
856+
"${CMAKE_CURRENT_SOURCE_DIR}/docs/documentation/architecture.md.in"
857+
${pre_process_FPPs} ${pre_process_F90s}
858+
${simulation_FPPs} ${simulation_F90s}
859+
${post_process_FPPs} ${post_process_F90s}
860+
COMMAND "${Python3_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/docs/gen_architecture.py"
861+
"${CMAKE_CURRENT_SOURCE_DIR}"
862+
COMMAND "${CMAKE_COMMAND}" -E touch "${CMAKE_CURRENT_BINARY_DIR}/gen-architecture.stamp"
863+
COMMENT "Generating architecture page"
864+
VERBATIM
865+
)
866+
add_custom_target(gen_architecture DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/gen-architecture.stamp")
867+
add_dependencies(documentation_doxygen gen_architecture)
868+
809869
# Inject per-page last-updated dates into documentation markdown files.
810870
# Runs after auto-generated .md files exist, before Doxygen processes them.
811871
# Uses a stamp file so it only runs once per build.
@@ -834,6 +894,7 @@ if (MFC_DOCUMENTATION)
834894

835895
install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/docs/index.html"
836896
"${CMAKE_CURRENT_SOURCE_DIR}/docs/404.html"
897+
"${CMAKE_CURRENT_SOURCE_DIR}/docs/simulations.json"
837898
DESTINATION "docs/mfc")
838899
endif()
839900

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ Your first simulation:
7878
Visualize the output in `examples/3D_shockdroplet/silo_hdf5/` with ParaView, VisIt, or your favorite tool.
7979
For detailed build instructions (Linux, macOS, Windows/WSL, HPC clusters), see the [Getting Started guide](https://mflowcode.github.io/documentation/getting-started.html).
8080

81+
MFC is developed by the [Computational Physics Group at Georgia Tech](https://comp-physics.group) and collaborators.
8182
Get in touch with <a href="mailto:shb@gatech.edu">Spencer</a> if you have questions!
8283
We have an [active Slack channel](https://join.slack.com/t/mflowcode/shared_invite/zt-y75wibvk-g~zztjknjYkK1hFgCuJxVw) and development team.
8384
MFC has high- and low-level documentation, visualizations, and more on [its website](https://mflowcode.github.io/).

docs/Doxyfile.in

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -806,7 +806,7 @@ WARN_FORMAT = "$file:$line: $text"
806806
# messages should be written. If left blank the output is written to standard
807807
# error (stderr).
808808

809-
WARN_LOGFILE =
809+
WARN_LOGFILE = @DOXYGEN_WARN_LOGFILE@
810810

811811
#---------------------------------------------------------------------------
812812
# Configuration options related to the input files
@@ -983,7 +983,7 @@ USE_MDFILE_AS_MAINPAGE =
983983
# also VERBATIM_HEADERS is set to NO.
984984
# The default value is: NO.
985985

986-
SOURCE_BROWSER = NO
986+
SOURCE_BROWSER = YES
987987

988988
# Setting the INLINE_SOURCES tag to YES will include the body of functions,
989989
# classes and enums directly into the documentation.

docs/custom.css

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,44 @@
33
* Overrides for doxygen-awesome theme
44
*/
55

6+
/* Hide empty nav-path footer (kept for navtree.js height calculation) */
7+
#nav-path {
8+
height: 0;
9+
overflow: hidden;
10+
}
11+
12+
/* Cross-navigation panel at top of sidebar */
13+
#mfc-nav {
14+
display: flex;
15+
flex-direction: column;
16+
padding: 10px 12px 8px;
17+
border-bottom: 1px solid var(--separator-color);
18+
background: var(--side-nav-background);
19+
font-size: 0.8rem;
20+
}
21+
22+
#mfc-nav a {
23+
display: block;
24+
padding: 4px 8px;
25+
border-radius: 4px;
26+
color: var(--page-foreground-color);
27+
text-decoration: none;
28+
opacity: 0.75;
29+
transition: background 0.12s, opacity 0.12s;
30+
}
31+
32+
#mfc-nav a:hover {
33+
opacity: 1;
34+
background: var(--side-nav-background-highlight, rgba(0,0,0,0.05));
35+
}
36+
37+
#mfc-nav a.active {
38+
font-weight: 600;
39+
opacity: 1;
40+
color: var(--primary-color);
41+
background: var(--side-nav-background-highlight, rgba(0,0,0,0.05));
42+
}
43+
644
/* Narrower left navigation panel */
745
html {
846
--side-nav-fixed-width: 210px;
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
# Code Architecture {#architecture}
2+
3+
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.
4+
5+
## Three-Phase Pipeline
6+
7+
MFC runs as three separate executables that communicate via binary files on disk:
8+
9+
```
10+
pre_process ──> simulation ──> post_process
11+
(grid + (time (derived
12+
initial advance) quantities +
13+
conditions) visualization)
14+
```
15+
16+
| Phase | Entry Point | What It Does |
17+
|-------|-------------|--------------|
18+
| **Pre-Process** | `src/pre_process/p_main.f90` | Generates the computational grid and initial conditions from patch definitions. Writes binary grid and state files. |
19+
| **Simulation** | `src/simulation/p_main.fpp` | Reads the initial state and advances the governing equations in time. Periodically writes solution snapshots. |
20+
| **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. |
21+
22+
Each phase is an independent MPI program. The simulation phase is where nearly all compute time is spent.
23+
24+
## Directory Layout
25+
26+
```
27+
src/
28+
common/ Shared modules used by all three phases
29+
pre_process/ Pre-process source (grid generation, patch construction)
30+
simulation/ Simulation source (solver core, physics models)
31+
post_process/ Post-process source (derived quantities, formatted I/O)
32+
```
33+
34+
Shared modules in `src/common/` include MPI communication, derived types, variable conversion, and utility functions. They are compiled into each phase.
35+
36+
## Key Data Structures
37+
38+
Two arrays carry the solution through the entire simulation:
39+
40+
| Variable | Contents | When Used |
41+
|----------|----------|-----------|
42+
| `q_cons_vf` | **Conservative** variables: \f$\alpha\rho\f$, \f$\rho u\f$, \f$\rho v\f$, \f$\rho w\f$, \f$E\f$, \f$\alpha\f$ | Storage, time integration, I/O |
43+
| `q_prim_vf` | **Primitive** variables: \f$\rho\f$, \f$u\f$, \f$v\f$, \f$w\f$, \f$p\f$, \f$\alpha\f$ | Reconstruction, Riemann solving, physics |
44+
45+
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.
46+
47+
The index layout within `q_cons_vf` depends on the flow model:
48+
49+
```
50+
For model_eqns == 2 (5-equation, multi-fluid):
51+
52+
Index: 1 .. num_fluids | num_fluids+1 .. +num_vels | E_idx | adv_idx
53+
Meaning: alpha*rho_k | momentum components | energy | volume fractions
54+
```
55+
56+
Additional variables are appended for bubbles, elastic stress, magnetic fields, or chemistry species when those models are enabled. The total count is `sys_size`.
57+
58+
## The Simulation Loop
59+
60+
The simulation advances the solution through this call chain each time step:
61+
62+
```
63+
p_main (time-step loop)
64+
└─ s_perform_time_step
65+
├─ s_compute_dt [adaptive CFL time step]
66+
└─ s_tvd_rk [Runge-Kutta stages]
67+
├─ s_compute_rhs [assemble dq/dt]
68+
│ ├─ s_convert_conservative_to_primitive_variables
69+
│ ├─ s_populate_variables_buffers [MPI halo exchange]
70+
│ └─ for each direction (x, y, z):
71+
│ ├─ s_reconstruct_cell_boundary_values [WENO]
72+
│ ├─ s_riemann_solver [HLL/HLLC/HLLD]
73+
│ ├─ s_compute_advection_source_term [flux divergence]
74+
│ └─ (physics source terms: viscous, bubbles, etc.)
75+
├─ RK update: q_cons = weighted combination of stages
76+
├─ s_apply_bodyforces [if enabled]
77+
├─ s_pressure_relaxation [if 6-equation model]
78+
└─ s_ibm_correct_state [if immersed boundaries]
79+
```
80+
81+
### What happens at each stage
82+
83+
1. **Conservative → Primitive**: Convert stored `q_cons_vf` to `q_prim_vf` (density, velocity, pressure) using the equation of state. This is done by `m_variables_conversion`.
84+
85+
2. **MPI Halo Exchange**: Ghost cells at subdomain boundaries are filled by communicating with neighbor ranks. Handled by `m_mpi_proxy`.
86+
87+
3. **WENO Reconstruction** (`m_weno`): For each coordinate direction, reconstruct left and right states at cell faces from cell-average primitives using high-order weighted essentially non-oscillatory stencils.
88+
89+
4. **Riemann Solver** (`m_riemann_solvers`): At each cell face, solve the Riemann problem between left and right states to compute intercell fluxes. Available solvers: HLL, HLLC, HLLD.
90+
91+
5. **Flux Differencing** (`m_rhs`): Accumulate the RHS as \f$\partial q / \partial t = -\frac{1}{\Delta x}(F_{j+1/2} - F_{j-1/2})\f$ plus source terms (viscous stress, surface tension, bubble dynamics, body forces, etc.).
92+
93+
6. **Runge-Kutta Update** (`m_time_steppers`): Combine the RHS with the current state using TVD Runge-Kutta coefficients (1st, 2nd, or 3rd order SSP).
94+
95+
## Module Map
96+
97+
MFC has ~80 Fortran modules organized by function. Here is where to look for what:
98+
99+
<!-- MODULE_MAP -->
100+
101+
## MPI Parallelization
102+
103+
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.
104+
105+
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).
106+
107+
## Adding New Physics
108+
109+
To add a new source term or physics model:
110+
111+
1. **Create a module** in `src/simulation/` (e.g., `m_my_model.fpp`)
112+
2. **Add initialization/finalization** subroutines called from `m_start_up`
113+
3. **Add RHS contributions** called from the dimensional loop in `m_rhs:s_compute_rhs`
114+
4. **Add parameters** to `m_global_parameters` and input validation to `m_checker`
115+
5. **Add a module-level brief** (enforced by the linter in `lint_docs.py`)
116+
6. **Add the module to `docs/module_categories.json`** so it appears in this page
117+
118+
Follow the pattern of existing modules like `m_body_forces` (simple) or `m_viscous` (more involved) as a template.

docs/documentation/authors.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,6 @@
33
## Authors
44

55
Contributors to MFC since 2019 can be [viewed here](https://github.com/MFlowCode/MFC/graphs/contributors).
6+
7+
8+
<div style='text-align:center; font-size:0.75rem; color:#888; padding:16px 0 0;'>Page last updated: 2026-02-04</div>

docs/documentation/case.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1215,3 +1215,6 @@ The above variables are used for all simulations.
12151215
| hypoelastic variables | N/A |
12161216

12171217
The above variables correspond to optional physics.
1218+
1219+
1220+
<div style='text-align:center; font-size:0.75rem; color:#888; padding:16px 0 0;'>Page last updated: 2026-02-15</div>

docs/documentation/contributing.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -536,6 +536,10 @@ contains
536536
end module m_my_feature
537537
```
538538

539+
**Step 3: Register the module in the architecture docs**
540+
541+
Add your module name to the appropriate category in `docs/module_categories.json`. This ensures it appears on the @ref architecture "Code Architecture" page. The precheck linter will fail if a module is missing from this file.
542+
539543
Key conventions:
540544
- `private` by default, explicitly `public` for the module API
541545
- Initialize/finalize subroutines for allocation lifecycle
@@ -767,3 +771,6 @@ If your change touches GPU code (`src/simulation/`), see the GPU checklist in th
767771
- A maintainer will merge your PR once all reviews are approved and CI is green
768772

769773
If your PR is large or architectural, consider opening an issue first to discuss the approach.
774+
775+
776+
<div style='text-align:center; font-size:0.75rem; color:#888; padding:16px 0 0;'>Page last updated: 2026-02-15</div>

0 commit comments

Comments
 (0)