This project implements the Lattice Boltzmann Method (LBM) to simulate fluid flows in both 2D and 3D, using the D2Q9 and D3Q19 models. It includes a 2D lid-driven cavity problem, a 3D lid-driven cavity simulation, a 2D wind tunnel configuration with obstacles insertion and a 2D CUDA-parallelized implementation for GPU acceleration.
The image below shows an example of a 2D Lattice simulation on a 300×100 grid with Re = 1000, including a single circular obstacle
g++
with C++17 or higher- OpenMP development package
- Python (for 2D post-processing)
- ParaView (for 3D visualization)
If you're using macOS or encountering problems related to CUDA, please refer to the dedicated guide available here
Before running the simulation, ensure that the launcher script has execution permissions:
chmod +x run.sh
Once the script is executable and you are in the directory where run.sh
is, run the simulation by passing the required arguments:
./run.sh [FLAGS]
Flag | Description |
---|---|
--2dLbm |
Run the 2D solver |
--3dLbm |
Run the 3D solver |
--cuda |
Run the 2D CUDA-based GPU solver |
Flag | Behavior | 3D LBM | 2D LBM | OBLIGATORY |
---|---|---|---|---|
-m , --mesh |
Define the grid resolution in X for 2D and for all direction in 3D. | ✅ | ✅ | ✅ |
-s , --steps |
Set total number of simulation time steps. | ✅ | ✅ | ✅ |
-r , --re , --reynolds |
Assign the Reynolds number for flow conditions. | ✅ | ✅ | ✅ |
-u |
Initial or boundary fluid velocity (default: 0.1). | ✅ | ✅ | ⛔ |
-omp , --Openmp |
Activate OpenMP. | ✅ | ✅ | ⛔ |
-h , --help |
Display usage information and exit. | ✅ | ✅ | ⛔ |
-tunnel |
Apply wind-tunnel boundary geometry. | ⛔ | ✅ | ⛔ |
-my |
Specify grid resolution in Y only for 2D(equal to X default). | ⛔ | ✅ | ⛔ |
-
3D solver with a cubic mesh of 100 points, 1000 time steps, Reynolds number = 500:
./run.sh --3dLbm -m 100 -s 1000 -r 500
-
2D solver with OpenMP, wind-tunnel geometry, mesh 200×100, 2000 steps, Re = 1000:
./run.sh --2dLbm -m 200 -my 100 -s 2000 -r 1000 -omp -tunnel
-
CUDA solver on GPU architecture SM 7.5, mesh 256, 1500 steps, Re = 750:
./run.sh --cuda -m 256 -s 1500 -r 750
To run the CUDA version without a local NVIDIA GPU, you can use Google Colab.
A ready-to-use Python notebook with detailed instructions is available here.
To visualize the results of the 2D simulation, either lid-driven cavity or tunnel-type problem, move in the 2DLBM folder with:
cd src && cd 2DLBM
Once in the correct folder, run the python script:
python visualizer.py
In case the visualizer does not work, you might have some libraries conflicts. In that case run the visualizer in a virtual environment. You can create it with:
/u/sw/toolchains/gcc-glibc/11.2.0/base/bin/python -m venv ~/newenv &&
source ~/newenv/bin/activate
The output video is saved in the 'output' directory.
To verify the correctness of our implementation, we compared our simulation results for the lid-driven cavity problem against benchmark reference data for Reynolds numbers 100, 400, and 1000.
The comparison focuses on the vertical centerline velocity profile: specifically, the y-component of the velocity (v_y
) along the line x = L/2
from the bottom to the top of the cavity (y = 0
to y = 1
).
Each plot below shows:
- Our simulation results (dashed line with markers)
- Reference values from the literature (solid line)
The simulation results for Re = 100 closely match the reference data, indicating good agreement. As the Reynolds number increases to 400 and 1000, deviations become more evident, particularly near the lower part of the cavity. This gradual build-up of error is likely due to slight differences in implementation details or parameter formulations. Nonetheless, the simulation shows consistent accuracy and stable behavior across a range of Reynolds numbers, supporting the validity of the overall approach.
250×250 Lid-Driven Cavity — Re = 100 | 250×250 Lid-Driven Cavity — Re = 10000 |
---|---|
![]() |
![]() |
600×200 Airfoil — Re = 1000 | Lift and Drag Coefficients |
---|---|
![]() |
![]() |
600×200 Circle — Re = 1000 | Lift and Drag Coefficients |
---|---|
![]() |
![]() |
-
Domain discretization: The cavity is divided into cubic grid cells, each representing local fluid populations.
-
Time-stepping cycle:
-
Collision: Particle distributions relax toward local equilibrium, modeling viscous dissipation.
-
Streaming: Updated distributions move along discrete velocity directions to neighboring cells.
-
Boundary conditions:
- Stationary walls: Halfway bounce-back enforces no-slip zero-velocity at solid faces.
- Moving lid: Zou–He velocity boundary condition prescribes a uniform tangential speed on the top plane, delivering accurate momentum transfer.
-
-
Stabilization: A two-relaxation-time collision operator separates symmetric and anti-symmetric moments, damping spurious modes at moderate Reynolds numbers.
-
Parallelization: Shared-memory threading accelerates both collision and streaming operations, scaling efficiently on multicore processors.
Simulation data are exported in VTK format and visualized using ParaView:
- Bulk import of VTK sequences for time-resolved analysis.
- Stream Tracer and Glyph filters to highlight vortex structures.
- Automated rendering of video animations via ParaView’s Python scripting interface.
Gallery of videos (click to expand)
Re=100 on 100×100×100 | |
---|---|
![]() |
|
Re=500 on 100×100×100 | |
![]() |
|
Re=1000 on 100×100×100 | |
![]() |
Re=100 on a 100x100x100 cavity | Re=500 on a 100x100x100 cavity | Re=1000 on a 100x100x100 cavity |
---|---|---|
![]() |
![]() |
![]() |
Re=100 on a 100x100x100 cavity | Re=500 on a 100x100x100 cavity | Re=1000 on a 100x100x100 cavity |
---|---|---|
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
Re=100 on a 100x100x100 cavity | Re=500 on a 100x100x100 cavity | Re=1000 on a 100x100x100 cavity |
---|---|---|
![]() |
![]() |
![]() |
Re=3000 on a 80x80x80 cavity |
---|
![]() |
![]() |
For a comprehensive quantitative and qualitative analysis of our simulation outcomes, please refer to the accompanying LaTeX report (autoref{sec:detailed_analysis} in the main document).
For validation of the 3D data we have compared this with this paper Validation Results.
- Federico Pinto
- Mattia Gotti
- Michele Milani