Skip to content

Fortran CFD simulator for 2D lid-driven cavity flow with modular design, OpenMP parallelization, HDF5 output, and extensible solvers for research and education.

License

Notifications You must be signed in to change notification settings

pgomur/lid-driven-cavity-2D

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

17 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

lid-driven-cavity-2D

Industrial CFD simulator for lid-driven cavity flow, implemented in Fortran with a modular architecture (params, grid, numerics, solver, I/O). Supports 2D uniform Cartesian meshes and second-order differential operators (gradient, divergence, Laplacian, curl) with advective schemes upwind/QUICK. Dirichlet/Neumann boundary conditions and adaptive CFL control ensure incompressibility and momentum conservation. The solver applies Chorin’s fractional step projection method, solving the Poisson equation via an optimized Red-Black SOR, with adaptive residual computation and OpenMP parallelization, maximizing cache efficiency and avoiding race conditions. Hierarchical HDF5 I/O with DEFLATE compression, optimized chunking, and full metadata guarantees bit-exact reproducibility, comprehensive logging, and traceability of physical and numerical parameters. Automatic diagnostics for kinetic energy, enstrophy, vorticity, and divergence, validation against Ghia et al. (1982) benchmarks, and real-time NaN/Inf detection ensure numerical robustness. Extensible and configurable design for RK2/RK4 schemes, multigrid/Krylov solvers, MPI, and AMR, optimizing scalability, throughput, and computational robustness for research, advanced education, and industrial development.

📂 Project Structure

lid-driven-cavity-2D/
├── CMakeLists.txt          # Build configuration
├── docker-compose.yml      # Docker compose setup
├── Dockerfile              # Docker container definition
├── LICENSE                 # Project license
├── README.md               # Project documentation
├── build/                  # Build output directory (generated)
└── src/
    └── fortran/
        ├── grid_mod.f90       # Mesh generation and grid utilities
        ├── io_hdf5_mod.f90    # HDF5 I/O routines (read/write, metadata, compression)
        ├── main.f90           # Main program entry point
        ├── numerics_mod.f90   # Differential operators, advective schemes, validation
        ├── params.f90.in      # Template for project parameters (filled by CMake)
        └── solver_mod.f90     # Fractional step solver, SOR Red-Black, diagnostics

🚀 Running the Project

Build the Docker image

docker-compose build

Start the container

docker-compose up -d

Enter the container shell

docker exec -it lid_driven_cavity_2d_container bash

Compile and run the simulator inside the container

Inside the container, run the following command to compile and execute the CFD simulator:

cd build && cmake .. -DHDF5_ROOT=/opt/hdf5 -DCMAKE_Fortran_COMPILER=gfortran -DCMAKE_Fortran_FLAGS="-O3 -march=native -funroll-loops -fopenmp -Wall" -DPARAM_NX=32 -DPARAM_NY=32 -DPARAM_LX=1.0 -DPARAM_LY=1.0 -DPARAM_XMIN=0.0 -DPARAM_XMAX=1.0 -DPARAM_YMIN=0.0 -DPARAM_YMAX=1.0 -DPARAM_RE=100.0 -DPARAM_ULID=1.0 -DPARAM_RHO=1.0 -DPARAM_NU=0.01 -DPARAM_GRAVITY=0.0 -DPARAM_BETA=0.0 -DPARAM_T_END=1.0 -DPARAM_DT=0.005 -DPARAM_CFL=0.5 -DPARAM_TIME_SCHEME=RK4 -DPARAM_OUTPUT_EVERY=20 -DPARAM_OUTPUT_FORMAT=hdf5 -DPARAM_OUTPUT_DIR=results -DPARAM_SAVE_VELOCITY=TRUE -DPARAM_SAVE_PRESSURE=TRUE -DPARAM_BC_TOP=Dirichlet -DPARAM_BC_BOTTOM=Dirichlet -DPARAM_BC_LEFT=Dirichlet -DPARAM_BC_RIGHT=Dirichlet -DPARAM_SOLVER_TYPE=explicit -DPARAM_MAX_ITERS=5000 -DPARAM_TOL=1.0e-6 -DPARAM_LINEAR_SOLVER=CG -DPARAM_PRECONDITIONER=ILU -DPARAM_NUM_SCHEME=central -DPARAM_ORDER=2 -DPARAM_STABILIZATION=0.0 -DPARAM_VERBOSE=TRUE -DPARAM_CHECK_BOUNDS=TRUE && cmake --build . -j$(nproc) && export OMP_NUM_THREADS=$(nproc) && ./bin/lid_driven_cavity

💡 Note: This command will build the project using all CPU cores and then run the simulator with the configured parameters.

📂 Simulation Results: The output files are saved inside the build/results folder in HDF5 format.

📊 HDF5 Dataset Structure

/lid_cavity.h5
├── x_coords [1D array]        (X coordinates)
├── y_coords [1D array]        (Y coordinates)
├── U_000000 [2D array]        (X velocity, step 0)
├── V_000000 [2D array]        (Y velocity, step 0)
├── P_000000 [2D array]        (Pressure, step 0)
├── time_000000 [attribute]    (Physical time)
├── step_000000 [attribute]    (Step number)
├── ...                        (Subsequent steps)
└── Attributes                 (Re, nu, dt, version, etc.)

Explanation of the command:

  • cd build
    Move into the build directory, where the project will be compiled.
  • cmake ..
    Configure the project using CMake, pointing to the source code in the parent folder. This prepares the Makefiles or build system for compilation.
  • cmake --build . -j$(nproc)
    Compile the project using all available CPU cores (-j$(nproc)). Produces the executable in the bin/ folder.
  • export OMP_NUM_THREADS=$(nproc)
    Set the number of threads for OpenMP parallelization to use all CPU cores.
  • ./bin/lid_driven_cavity
    Run the simulator executable, which will start the CFD simulation using the configured parameters.

⚙️ Simulation Parameters

Parameter Type Typical Values Description
PARAM_NXint>1Number of nodes in X-direction
PARAM_NYint>1Number of nodes in Y-direction
PARAM_LXreal>0Domain length in X
PARAM_LYreal>0Domain length in Y
PARAM_XMINreal≥0Minimum X coordinate
PARAM_XMAXreal> XMINMaximum X coordinate
PARAM_YMINreal≥0Minimum Y coordinate
PARAM_YMAXreal> YMINMaximum Y coordinate
PARAM_REreal>0Reynolds number
PARAM_ULIDreal≥0Lid velocity
PARAM_RHOreal>0Fluid density
PARAM_NUreal>0Kinematic viscosity ν
PARAM_GRAVITYreal≥0Gravitational acceleration (Boussinesq)
PARAM_BETAreal≥0Thermal expansion coefficient (Boussinesq)
PARAM_T_ENDreal>0Total simulation time
PARAM_DTreal>0Time step
PARAM_CFLreal0–1CFL number (advection stability)
PARAM_TIME_SCHEMEstring"RK4", "Euler", "RK2"Time integration scheme
PARAM_OUTPUT_EVERYint≥1Save output every N steps
PARAM_OUTPUT_FORMATstring"hdf5", "txt"Output file format
PARAM_OUTPUT_DIRstringany valid folder nameFolder where results are saved
PARAM_SAVE_VELOCITYboolTRUE / FALSESave velocity field
PARAM_SAVE_PRESSUREboolTRUE / FALSESave pressure field
PARAM_BC_TOPstring"Dirichlet", "Neumann"Top boundary condition
PARAM_BC_BOTTOMstring"Dirichlet", "Neumann"Bottom boundary condition
PARAM_BC_LEFTstring"Dirichlet", "Neumann"Left boundary condition
PARAM_BC_RIGHTstring"Dirichlet", "Neumann"Right boundary condition
PARAM_SOLVER_TYPEstring"explicit", "implicit"Time-stepping solver type
PARAM_MAX_ITERSint>0Maximum iterations for iterative solvers
PARAM_TOLreal>0Convergence tolerance for solvers
PARAM_LINEAR_SOLVERstring"CG", "GMRES", "BiCGStab"Linear solver algorithm
PARAM_PRECONDITIONERstring"ILU", "Jacobi", "None"Preconditioner for linear solver
PARAM_NUM_SCHEMEstring"central", "upwind"Spatial discretization scheme
PARAM_ORDERint1,2Order of spatial scheme
PARAM_STABILIZATIONreal≥0Numerical stabilization (artificial diffusion)
PARAM_VERBOSEboolTRUE / FALSEDisplay console messages
PARAM_CHECK_BOUNDSboolTRUE / FALSECheck indices and grid boundaries