Skip to content

Repository files navigation

Lid-Driven Cavity Flow Solver in C++

Phase 2 verified C++17 Staggered MAC grid Build and smoke test Numerical verification MIT License

A serial C++17 solver for the two-dimensional incompressible lid-driven cavity benchmark.

The production solver uses a staggered Marker-and-Cell arrangement, a pseudo-transient projection method, compatible pressure-gradient and divergence operators, and convergence-aware termination. The repository also contains manufactured Poisson verification, discrete-operator tests, sanitizer builds, Ghia centerline comparisons, and configurable parameter studies.

What is verified

The current Phase 2 regression set has been exercised with:

  • the canonical N=32, Re=100, upwind, RBSOR case;
  • all six N=32 combinations at Re=100, 400, and 1000 with upwind and central convection using RBSOR;
  • the N=16, 32, and 64, Re=100, central, RBSOR grid sequence;
  • RBGS/RBSOR manufactured Poisson tests;
  • the compatibility test between the selected divergence, gradient, and Laplacian operators;
  • GCC and Clang builds in Debug and Release configurations;
  • AddressSanitizer and UndefinedBehaviorSanitizer checks.

The canonical strict case converges automatically rather than stopping at a configured iteration limit.

Numerical method

The solver advances the nondimensional incompressible Navier–Stokes equations using:

  1. a staggered MAC grid;
  2. an explicit pseudo-time momentum predictor;
  3. upwind or central convection differencing;
  4. a pressure-correction Poisson equation;
  5. RBGS or RBSOR pressure iteration;
  6. velocity correction using pressure gradients located consistently with the staggered velocity components;
  7. convergence checks based on velocity updates, local divergence, global mass balance, and pressure convergence.

Velocity components are stored on cell faces and pressure is stored at cell centers. Cell-centered velocity values are reconstructed for CSV output and post-processing.

Convergence contract

A production case is reported as converged only when all of the following remain satisfied for the configured number of consecutive iterations:

  • dimensionless velocity-update Linf residual;
  • dimensionless divergence Linf residual;
  • dimensionless divergence L2 residual;
  • global boundary mass imbalance;
  • successful pressure-Poisson convergence.

Possible terminal states include:

  • converged
  • max_iterations
  • pressure_not_converged
  • stagnated
  • diverged
  • non_finite

Use --strict when a script or CI job must fail if any requested case does not converge.

Quick start

On Linux, WSL, or a Linux HPC node:

bash scripts/run_single.sh

This builds the solver and runs the canonical strict case:

N = 32
Re = 100
scheme = upwind
pressure solver = RBSOR

A successful run ends with status=converged and writes CSV files to results/data/.

Available runs

bash scripts/run_smoke_test.sh   # compilation and output check only
bash scripts/run_single.sh       # canonical converged regression
bash scripts/run_quick.sh        # four fast Re=100 cases
bash scripts/run_medium.sh       # six N=32 cases at Re=100/400/1000
bash scripts/run_grid.sh         # N=16/32/64 grid sequence at Re=100
bash scripts/run_re1000.sh       # converged N=32, Re=1000 central case
bash scripts/run_full.sh         # complete 36-case configuration

The full mode includes RBGS and grids up to N=128; it is intended for a workstation or HPC node.

Direct command-line use

bash scripts/build.sh

bin/lid_cavity \
  --single \
  --N 32 \
  --Re 100 \
  --scheme upwind \
  --pressure RBSOR \
  --strict

Important numerical options include:

--maxIter
--poisson-maxIter
--tol-velocity
--tol-divergence
--tol-divergence-l2
--poisson-tol
--alpha-u
--alpha-p
--cfl
--dt-max
--min-iterations
--consecutive-passes

Run bin/lid_cavity --help for the complete interface.

CMake and tests

cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build --parallel
ctest --test-dir build --output-on-failure

The CTest suite includes:

  • discrete operator verification;
  • manufactured Poisson verification and grid refinement;
  • convergence-state logic;
  • the canonical production-solver regression.

For sanitizer checks:

cmake -S . -B build/sanitized \
  -DCMAKE_BUILD_TYPE=Debug \
  -DLIDCAVITY_ENABLE_SANITIZERS=ON
cmake --build build/sanitized --parallel
ctest --test-dir build/sanitized --output-on-failure

Output files

Each case writes:

results/data/study_summary_<mode>.csv
results/data/case_<id>_..._history.csv
results/data/case_<id>_..._fields.csv

The summary separates:

  • execution status;
  • iterative convergence;
  • pressure convergence;
  • divergence metrics;
  • runtime;
  • Ghia benchmark agreement.

The history file stores iteration-by-iteration convergence information. The field file contains cell-center coordinates, velocity, pressure, speed, and vorticity.

Ghia benchmark comparison

For Re=100, 400, and 1000, the solver compares:

  • horizontal velocity u(y) on the vertical centerline;
  • vertical velocity v(x) on the horizontal centerline.

The code reports L2 and Linf errors. These are reference-benchmark comparisons, not experimental validation.

Repository structure

src/lid_cavity.cpp              production staggered-grid solver
include/lidcavity/              reusable verification interfaces
src/verification/               operator, Poisson, and convergence components
tests/                          CTest verification programs
scripts/                        build and run helpers
postprocess/                    Python plotting scripts
docs/                           method and verification notes
results/data/                   generated CSV output
.github/workflows/              smoke and numerical-verification CI

Scope and limitations

This is an educational CFD and numerical-verification project, not a production CFD package.

Current limitations include:

  • serial CPU execution only;
  • explicit pseudo-time momentum advancement;
  • no multigrid pressure solver;
  • no formal experimental validation;
  • the exhaustive 36-case study can be computationally expensive, especially with RBGS and N=128.

Parallel C++, MPI, OpenMP, CUDA, MATLAB, and Python comparisons belong to the separate solver-comparison project and are intentionally not developed in this repository.

Reference

Ghia, U., Ghia, K. N., & Shin, C. T. (1982). High-Re solutions for incompressible flow using the Navier–Stokes equations and a multigrid method. Journal of Computational Physics, 48(3), 387–411.

Author

Ahmed Kandil — Portfolio · LinkedIn · ORCID

Released under the MIT License.

Releases

Packages

Contributors

Languages