Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Chapter 2 — Governing Equations and Discretization

Figure 3.1 — Governing Equations and Discretization

CFDrs solves the incompressible Navier-Stokes equations in primitive-variable form together with optional scalar transport equations (energy, turbulent kinetic energy, species concentration).

Incompressible Navier-Stokes

The continuity and momentum equations for a constant-density fluid:

∇·u = 0

∂u/∂t + (u·∇)u = -∇(p/ρ) + ν ∇²u + f/ρ
```text

where **u** is velocity, *p* pressure, *ρ* density, *ν* kinematic viscosity,
and **f** body forces.  CFDrs resolves the incompressibility constraint through
the **pressure-Poisson equation** (see [Chapter 3](pressure_velocity.md)).

## Energy Equation

For thermal flows, temperature *T* is transported:

```text
∂T/∂t + (u·∇)T = α ∇²T + S_T

with thermal diffusivity α = λ/(ρ c_p). Density-driven buoyancy is handled through the Boussinesq approximation: f_y = -ρ g β (T - T_ref).

Non-Newtonian Rheology

Blood and polymer flows use the generalised Newtonian model:

τ = μ_eff(γ̇) · γ̇
```text

`cfd-core` provides the rheology dispatch:

```rust
use cfd_core::physics::rheology::{Rheology, PowerLaw, Casson, CarreauYasuda};

let blood = Rheology::Casson { yield_stress: 0.015, mu_inf: 0.0035 };

Viscosity depends on shear rate γ̇ = |2D|, where D is the symmetric velocity gradient tensor.

Spatial Discretisation

CFDrs supports three spatial discretisation families, each owning a dedicated crate:

MethodCrateOrder
Finite Volume (staggered / collocated)cfd-2d, cfd-3d2nd
Spectral (Fourier / Chebyshev)cfd-3d::spectralspectral
FEM (P1, P2 tetrahedral)cfd-3d::fem1st–2nd
MUSCL reconstructioncfd-3d::musclup to 5th

Boundary conditions live in cfd-core::physics::boundary and are consumed by every discretisation layer through a single BoundaryCondition<T> enum:

use cfd_core::physics::boundary::{BoundaryCondition, BoundaryConditionSet};

let bc = BoundaryConditionSet::<f64>::new()
    .add("inlet",  BoundaryCondition::velocity_inlet([1.0, 0.0, 0.0].into()))
    .add("walls",  BoundaryCondition::wall_no_slip())
    .add("outlet", BoundaryCondition::pressure_outlet(0.0));

Examples