Skip to content

About

Navier-Stokes solvers written from scratch in Python, finite difference and finite volume, validated against Ghia et al. (1982), analytical solutions and OpenFOAM.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Latest commit

 

History

104 Commits

Folders and files

Repository files navigation

CFD Solver

Python finite-difference and finite-volume CFD project for rebuilding canonical incompressible-flow solvers from first principles. The focus is on numerical schemes, pressure-velocity coupling, boundary conditions, validation against analytical solutions, and visualisation of flow fields.

Implemented solvers and validation cases

Currently implemented:

  • 1D linear advection with upwind, leapfrog, Lax-Friedrichs, and Lax-Wendroff finite-difference schemes
  • 1D linear advection with an explicit upwind finite-volume method
  • 2D linear advection, with finite-difference and explicit upwind finite-volume methods
  • 1D nonlinear convection / inviscid Burgers with upwind, Lax-Friedrichs, Richtmyer, one-step and two-step Lax-Wendroff, MacCormack, and implicit Beam-Warming schemes, including conservative flux-form variants
  • 1D nonlinear convection with an explicit finite-volume method
  • 2D nonlinear convection, with finite-difference and finite-volume methods
  • 1D and 2D diffusion, with finite-difference and finite-volume methods
  • 1D and 2D Burgers equation, with finite-difference and finite-volume methods
  • 2D Laplace equation, with finite-difference and finite-volume methods
  • 2D Poisson equation with configurable source terms, with finite-difference and finite-volume methods
  • 2D lid-driven cavity flow using a pressure Poisson solve, with finite-difference and finite-volume methods
  • 2D pressure-driven channel flow with periodic x-boundaries, with finite-difference and finite-volume methods
  • uniform grid generation for finite differences, and cell-centred mesh generation with face areas, cell volumes and centre-to-centre distances for finite volumes
  • hat-function, Heaviside-style step, and Cole-Hopf initial conditions
  • explicit finite-difference time-marching solvers
  • iterative pressure/potential solves using L1 convergence or fixed iteration limits
  • contour, surface, quiver, and animation visualizations

Project structure

core/fdm/                   finite-difference configs, grids, time steps, initial conditions, operators
core/fdm/solvers/           finite-difference solvers
core/fvm/                   finite-volume configs, mesh, time steps, initial conditions, operators
core/fvm/solvers/           finite-volume solvers
core/analytical/            analytical reference solutions
data/                       Ghia et al. (1982) reference tables
data/openfoam/              OpenFOAM case setups and extracted reference data
post_processing/            contour, surface, quiver, and animation helpers
runs/fdm/                   finite-difference examples
runs/fvm/                   finite-volume examples
runs/comparisons/fdm/       finite-difference validations
runs/comparisons/fvm/       finite-volume validations
runs/comparisons/fdm_vs_fvm/  finite-difference against finite-volume
tests/fdm/                  finite-difference regression tests
tests/fvm/                  finite-volume regression tests

Example visualizations

Solver output

2D diffusion

2D diffusion

2D Poisson equation

2D Poisson

2D lid-driven cavity flow, finite difference

2D cavity flow FDM

2D lid-driven cavity flow, finite volume

2D cavity flow FVM

2D pressure-driven channel flow, finite difference

2D channel flow FDM

2D pressure-driven channel flow, finite volume

2D channel flow FVM

Scheme studies

1D nonlinear convection scheme comparison

1D convection scheme comparison

1D inviscid Burgers scheme comparison

1D inviscid Burgers scheme comparison

Validation

1D diffusion against the heat equation

1D diffusion vs heat equation

2D lid-driven cavity against Ghia et al. (1982)

Cavity flow vs Ghia

2D channel flow against the analytical Poiseuille profile

Channel flow vs analytical

Finite difference against finite volume, 2D cavity

FDM vs FVM cavity

OpenFOAM reference, 2D lid-driven cavity

OpenFOAM cavity

OpenFOAM cavity animation

OpenFOAM reference, 2D channel flow

OpenFOAM channel

OpenFOAM channel animation

Implemented models

The current solvers model:

  • the 1D linear advection equation:

    du/dt + c du/dx = 0

    using selectable explicit finite-difference schemes: upwind, leapfrog, Lax-Friedrichs, and Lax-Wendroff.

    A finite-volume variant is also included, using an explicit upwind scheme on a cell-centered mesh with conservative flux updates and a CFL-based time-step constraint.

  • the 2D linear advection equation:

    du/dt + c du/dx + c du/dy = 0

    using an explicit upwind finite-difference scheme.

  • the 1D nonlinear convection equation:

    du/dt + u du/dx = 0

    and its conservative form:

    du/dt + d(u^2 / 2)/dx = 0

    using selectable explicit schemes: upwind, Lax-Friedrichs, Richtmyer, one-step Lax-Wendroff, two-step Lax-Wendroff, and MacCormack. Conservative flux-form variants are included for shock propagation, along with implicit Beam-Warming and damped implicit Beam-Warming variants for inviscid Burgers experiments.

    A finite-volume variant is also included, using an explicit upwind scheme on a cell-centered mesh with conservative flux updates and a CFL-based time-step constraint.

  • the 2D nonlinear convection equations:

    du/dt + u du/dx + v du/dy = 0

    dv/dt + u dv/dx + v dv/dy = 0

    using an explicit upwind finite-difference scheme.

  • the 1D diffusion equation:

    du/dt = ν d²u/dx²

    using an explicit central finite-difference scheme.

  • the 1D diffusion equation:

    du/dt = nu d^2u/dx^2

    using an explicit central finite-difference scheme. A 1D finite-volume diffusion variant is also included and can be compared against the heat-equation reference solution.

  • the 1D Burgers equation:

    du/dt + u du/dx = nu d^2u/dx^2

    with the conservative convective form:

    du/dt + d(u^2 / 2)/dx = nu d^2u/dx^2

    using an explicit upwind scheme for the finite-difference convective term and a central scheme for the diffusive term. A 1D finite-volume Burgers variant is also included, using conservative flux updates for the convective term and diffusive fluxes for viscosity, and can be compared against the Cole-Hopf analytical solution.

  • the 2D Burgers equations:

    du/dt + u du/dx + v du/dy = ν (d²u/dx² + d²u/dy²)

    dv/dt + u dv/dx + v dv/dy = ν (d²u/dx² + d²u/dy²)

    using an explicit upwind scheme for the convective terms and a central scheme for the diffusive terms.

  • the 2D Laplace equation:

    d²p/dx² + d²p/dy² = 0

    solved iteratively with finite differences until an L1 target is reached.

  • the 2D Poisson equation:

    d²p/dx² + d²p/dy² = b

    solved iteratively with configurable positive and negative source terms.

  • the 2D incompressible lid-driven cavity flow problem:

    du/dt + u du/dx + v du/dy = -1/rho dp/dx + nu (d^2u/dx^2 + d^2u/dy^2)

    dv/dt + u dv/dx + v dv/dy = -1/rho dp/dy + nu (d^2v/dx^2 + d^2v/dy^2)

    d^2p/dx^2 + d^2p/dy^2 = b

    using explicit finite differences for the velocity equations and an iterative pressure Poisson solve. A finite-volume variant is also included, using conservative face fluxes for the convective terms, Green-Gauss gradients for the pressure, and a cell-centred pressure Poisson solve with zero-gradient walls and a Dirichlet lid.

  • the 2D incompressible pressure-driven channel flow problem:

    du/dt + u du/dx + v du/dy = -1/rho dp/dx + nu (d^2u/dx^2 + d^2u/dy^2) + F

    dv/dt + u dv/dx + v dv/dy = -1/rho dp/dy + nu (d^2v/dx^2 + d^2v/dy^2)

    d^2p/dx^2 + d^2p/dy^2 = b

    using explicit finite differences for the velocity equations, an iterative pressure Poisson solve, periodic boundary conditions in x, and no-slip walls at y = 0 and y = Ly. A finite-volume variant is also included, with wrap-around face fluxes on the periodic boundaries and the driving force applied to every cell.

Validation and numerical experiments

This project includes validation workflows that compare numerical finite-difference solutions with analytical reference solutions.

For the 1D diffusion equation, finite-difference and finite-volume solvers can be compared against a Fourier-based analytical solution of the heat equation.

For the 1D Burgers equation, finite-difference and finite-volume solvers can be compared against the analytical Cole-Hopf solution.

The 1D convection scheme comparison script visualizes conservative and non-conservative schemes on a Heaviside step problem, comparing grid resolution and CFL number effects. This highlights numerical diffusion, dispersive oscillations near shocks, and conservative-form shock propagation.

The inviscid Burgers scheme comparison script studies conservative shock-capturing schemes, including implicit Beam-Warming and damped implicit Beam-Warming, across grid resolutions, CFL numbers, and artificial-damping coefficients.

These comparisons are used to assess solver correctness and visualize agreement between numerical and analytical results.

The 2D lid-driven cavity is validated against Ghia, Ghia and Shin (1982) at Re = 100, comparing u along the vertical centreline and v along the horizontal centreline against Tables I and II. The 2D channel flow is validated against the analytical Poiseuille profile.

Both solvers are also compared against OpenFOAM for the same two cases. The case setups are in data/openfoam/ and the extracted reference data in data/openfoam_*.csv.

The cavity case is a unit square on a 40 x 40 mesh, one cell thick with empty front and back patches, solved with icoFoam. The lid is a fixedValue of (1 0 0), the other three walls are noSlip, and the kinematic viscosity is 0.01, giving Re = 100.

The channel case is a 2 x 1 domain on a 40 x 40 mesh, also one cell thick and solved with the incompressibleFluid solver. The inlet and outlet are cyclic, the top and bottom walls are noSlip, and the flow is driven by a semiImplicitSource momentum source of (1 0 0) applied to all cells. The kinematic viscosity is 0.1, matching the analytical peak velocity of 1.25.

Both cases run to t = 10 with a time step of 0.001.

case this solver reference
Lid-driven cavity, Re=100, 40x40 peak reverse u -0.217 Ghia et al. -0.211
Laminar channel, 40x40 peak u 1.249 analytical 1.250
2D Laplace and Poisson 3e-9 direct matrix solve
1D advection at CFL 1 machine precision exact translation

A regression suite of eighteen tests covers both packages, checking advection, diffusion, Burgers, Laplace, Poisson, cavity and channel flow against these references. Run it with pytest from the repository root.

Roadmap

  • Add convergence studies for grid spacing and time-step sensitivity.
  • Add limiters or artificial viscosity for oscillation control near shocks.
  • Study damping sensitivity for implicit Beam-Warming schemes.

Run

Install the package once, from the repository root:

pip install -e .

Run the test suite:

pytest

Run any example:

python runs/fdm/run_advection_1d.py
python runs/fdm/run_advection_2d.py
python runs/fdm/run_convection_1d.py
python runs/fdm/run_convection_2d.py
python runs/fdm/run_diffusion_1d.py
python runs/fdm/run_diffusion_2d.py
python runs/fdm/run_burgers_equation_1d.py
python runs/fdm/run_burgers_equation_2d.py
python runs/fdm/run_laplace_2d.py
python runs/fdm/run_poisson_2d.py
python runs/fdm/run_cavity_flow.py
python runs/fdm/run_channel_flow.py

python runs/fvm/run_advection_1d.py
python runs/fvm/run_advection_2d.py
python runs/fvm/run_convection_1d.py
python runs/fvm/run_convection_2d.py
python runs/fvm/run_diffusion_1d.py
python runs/fvm/run_diffusion_2d.py
python runs/fvm/run_burgers_equation_1d.py
python runs/fvm/run_burgers_equation_2d.py
python runs/fvm/run_laplace_2d.py
python runs/fvm/run_poisson_2d.py
python runs/fvm/run_cavity_flow.py
python runs/fvm/run_channel_flow.py

Run a scheme study or a validation:

python runs/comparisons/fdm/run_advection_1d_scheme_comparison.py
python runs/comparisons/fdm/run_convection_1d_scheme_comparison.py
python runs/comparisons/fdm/run_inviscid_burgers_scheme_comparison.py
python runs/comparisons/fdm/run_diffusion_1d_vs_heat.py
python runs/comparisons/fdm/run_burgers_equation_1d_vs_cole_hopf.py
python runs/comparisons/fdm/run_cavity_flow_vs_ghia.py
python runs/comparisons/fdm/run_cavity_flow_vs_openfoam.py
python runs/comparisons/fdm/run_cavity_flow_vs_ghia_vs_openfoam.py
python runs/comparisons/fdm/run_channel_flow_vs_analytical.py
python runs/comparisons/fdm/run_channel_flow_vs_openfoam.py
python runs/comparisons/fdm/run_channel_flow_vs_analytical_vs_openfoam.py

python runs/comparisons/fvm/run_diffusion_1d_vs_heat.py
python runs/comparisons/fvm/run_burgers_equation_1d_vs_cole_hopf.py
python runs/comparisons/fvm/run_cavity_flow_vs_ghia.py
python runs/comparisons/fvm/run_cavity_flow_vs_openfoam.py
python runs/comparisons/fvm/run_cavity_flow_vs_ghia_vs_openfoam.py
python runs/comparisons/fvm/run_channel_flow_vs_analytical.py
python runs/comparisons/fvm/run_channel_flow_vs_openfoam.py
python runs/comparisons/fvm/run_channel_flow_vs_analytical_vs_openfoam.py

python runs/comparisons/fdm_vs_fvm/run_cavity_flow.py
python runs/comparisons/fdm_vs_fvm/run_channel_flow.py

About

Navier-Stokes solvers written from scratch in Python, finite difference and finite volume, validated against Ghia et al. (1982), analytical solutions and OpenFOAM.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages