JP | EN | ZH
TOPCFD / Fluid AnalysisCFD Solver Methods

CFD Solver Methods — Pressure-Velocity Coupling and Discretization

Incompressible CFD has a fundamental complication: pressure and velocity are coupled but there is no explicit equation for pressure. The SIMPLE family of algorithms solves this problem iteratively. Understanding them lets you tune convergence and diagnose divergence.

By NovaSolver Contributors (Anonymous Engineers & AI)  |  CFD / Fluid Analysis  |  日本語版 →

1. The Pressure-Velocity Coupling Problem

🧑‍🎓

I know we have the continuity equation and momentum equations, but why is pressure-velocity coupling such a big deal in CFD? What makes it hard?

🎓

For incompressible flow, the density is constant, so there's no thermodynamic equation of state linking density, pressure, and temperature. Pressure appears in the momentum equation as a gradient term, but there is no dedicated pressure transport equation — instead, pressure is implicitly constrained by the divergence-free condition on velocity ($\nabla \cdot \mathbf{u} = 0$). You have to find a pressure field that, when you solve momentum, gives you a velocity field that satisfies continuity. It's a constraint rather than a direct equation. The SIMPLE algorithm is the most widely used approach to handle this: it iterates between a momentum "predictor" step and a pressure "corrector" step until both are satisfied simultaneously.

2. The SIMPLE Algorithm

🧑‍🎓

Can you walk me through the SIMPLE algorithm step by step? I've seen the name but never understood how the three steps actually work together.

🎓

Sure. SIMPLE stands for Semi-Implicit Method for Pressure-Linked Equations, developed by Patankar and Spalding in 1972. Here are the three stages repeated until convergence. Step 1: solve the momentum equation using the current (guessed) pressure field to get a predicted velocity u* that does not yet satisfy continuity. Step 2: derive a pressure correction equation by requiring the corrected velocity to be divergence-free — this gives a Poisson equation for the pressure correction p'. Step 3: update both velocity and pressure using the corrections. Then repeat. The under-relaxation factors control how aggressively you update between iterations — too aggressive and you diverge; too conservative and convergence is slow.

Step 1 — Momentum Predictor

Solve momentum with current pressure $p^n$: $\quad A \mathbf{u}^* = \mathbf{H}(\mathbf{u}^n) - \nabla p^n$. The predicted velocity $\mathbf{u}^*$ violates continuity.

Step 2 — Pressure Correction

Derive a Poisson equation for pressure correction $p'$: $\quad \nabla \cdot \left(\frac{1}{A} \nabla p'\right) = \nabla \cdot \mathbf{u}^*$. Solving this gives $p' = p^{n+1} - p^n$.

Step 3 — Velocity and Pressure Update

Update: $p^{n+1} = p^n + \alpha_p \, p'$, $\quad \mathbf{u}^{n+1} = \mathbf{u}^* - \frac{1}{A}\nabla p'$. Apply under-relaxation $\alpha_p$ (typically 0.3) and $\alpha_U$ (typically 0.7).

3. SIMPLEC, SIMPLER, PISO, and PIMPLE Variants

🧑‍🎓

OpenFOAM has PIMPLE and PISO too. What's the practical difference between all these variants? Which one should I pick for a transient simulation?

🎓

Great practical question. SIMPLE is for steady-state only — it relies on under-relaxation to damp out the time-evolution and find a steady solution. PISO (Pressure Implicit with Splitting of Operators) is for transient flows: it does multiple pressure corrections within each time step to satisfy continuity tightly, with no under-relaxation. It requires a small Courant number (Co < 1) to be stable. PIMPLE is OpenFOAM's combination of PISO outer loops with SIMPLE-like under-relaxation — it can handle Courant numbers up to 5–10, making it much more practical for LES and transient RANS where the time step is set by physics rather than stability. SIMPLEC is an improved SIMPLE with a tighter pressure-velocity coupling that allows larger under-relaxation for pressure (up to 1.0), improving convergence speed.

AlgorithmSteady/TransientCorrector StepsCourant LimitOpenFOAM Usage
SIMPLESteady1 (outer loop iterations)N/A (steady)simpleFoam, rhoSimpleFoam
SIMPLECSteady1 (improved coupling)N/AsimpleFoam (SIMPLECCorrection option)
SIMPLERSteady1 + initial pressure estimateN/ALess common in OpenFOAM
PISOTransient2–3 per time stepCo < 1pisoFoam (legacy)
PIMPLETransientOuter loops + inner PISOCo up to 5–10pimpleFoam, buoyantPimpleFoam, LES solvers

4. Under-Relaxation Factors

🧑‍🎓

I've seen warnings about "reducing relaxation factors" when my simulation diverges. What do these factors actually control, and what's a safe starting point?

🎓

Under-relaxation limits how much any field changes between SIMPLE iterations: $\phi^{new} = \phi^{old} + \alpha(\phi^{computed} - \phi^{old})$. With $\alpha = 1$ you apply the full correction — fast convergence but risk of divergence. With $\alpha = 0.1$ you take tiny steps — very stable but painfully slow. The pressure and velocity factors are the most sensitive. The rule of thumb taught in every CFD course: $\alpha_p + \alpha_U \approx 1$, so the default $\alpha_U = 0.7$, $\alpha_p = 0.3$ is a safe starting point. For highly non-linear or buoyancy-driven flows, try $\alpha_U = 0.5$, $\alpha_p = 0.2$. For simple attached flow, you can push to $\alpha_U = 0.9$ to speed things up. Turbulence quantities (k, ε, ω) typically use 0.5–0.7.

FieldTypical ValueConservative (Difficult Cases)Aggressive (Simple Cases)
Velocity U0.70.3–0.50.8–0.9
Pressure p0.30.1–0.20.5–0.7 (SIMPLEC)
Turbulent kinetic energy k0.50.30.7
Turbulent dissipation ε / ω0.50.30.7
Temperature T0.90.51.0
Turbulent viscosity μ_t1.00.5–0.81.0

5. Convergence Criteria

🧑‍🎓

How do I know when to stop a SIMPLE simulation? OpenFOAM prints residuals every iteration, but I'm not sure what the target should be.

🎓

The residuals in OpenFOAM are normalized initial residuals — the ratio of the current equation imbalance to the initial imbalance. There is no universal threshold, but a good rule of thumb: continuity residual below 1e-3, momentum and turbulence below 1e-4 for engineering accuracy. For aeroacoustics or precise heat transfer, push to 1e-5 or below. More importantly, also monitor your key output variable — drag coefficient, pressure drop, maximum temperature — and check that it has stopped changing. It's common for all residuals to look "converged" but the actual quantity of interest is still drifting if the convergence is asymptotic.

VariableEngineering AccuracyHigh Accuracy (heat transfer, acoustics)
Continuity (p)1e-31e-5
Momentum (Ux, Uy, Uz)1e-41e-6
Turbulence (k, ε, ω)1e-41e-5
Temperature (T)1e-61e-8

6. Linear Solvers — GAMG and smoothSolver

🧑‍🎓

In fvSolution I have to set a solver for each equation — GAMG for pressure, smoothSolver for velocity. What is GAMG and why does pressure need a different solver?

🎓

GAMG is Geometric Algebraic MultiGrid — it's dramatically faster for the pressure Poisson equation because pressure information propagates across the whole domain (it's an elliptic equation). A simple iterative solver like Gauss-Seidel handles nearby cells fast but takes ages to propagate information across the domain — that's the "multigrid problem." GAMG builds successively coarser representations of the mesh, solves cheaply on the coarse levels to spread information globally, then refines back. For a million-cell pressure field, GAMG can be 50–100x faster than a non-multigrid solver. Velocity and turbulence are advection-dominated (hyperbolic-like) — they don't need multigrid; smoothSolver or PBiCGStab with an ILU preconditioner works well and is simpler to configure.

// system/fvSolution -- standard OpenFOAM settings for incompressible RANS solvers { p { solver GAMG; smoother GaussSeidel; nCellsInCoarsestLevel 10; tolerance 1e-6; relTol 0.01; } pFinal { $p; relTol 0; // tighter convergence on final correction } U { solver smoothSolver; smoother GaussSeidel; nSweeps 2; tolerance 1e-8; relTol 0.1; } "(k|epsilon|omega|nuTilda)" { solver smoothSolver; smoother GaussSeidel; tolerance 1e-8; relTol 0.1; } }

7. Time Integration Schemes

For transient simulations, the choice of time derivative discretization affects accuracy and stability:

SchemeOrderOpenFOAM KeywordProperties
Euler (1st order implicit)1stEulerUnconditionally stable; introduces temporal diffusion; fast convergence per step
Crank-Nicolson (2nd order)2ndCrankNicolson 1Less temporal diffusion; can oscillate on coarse time steps; best for LES
Bounded Crank-Nicolson~2ndCrankNicolson 0.9Blends 90% CN + 10% Euler for stability; recommended for LES in OpenFOAM
Backward (2nd order, 3-level)2ndbackwardThree time-level scheme; accurate but more memory; good for URANS
// system/fvSchemes -- time integration for LES (transient, 2nd order) ddtSchemes { default CrankNicolson 0.9; // bounded CN for LES } // For steady RANS simpleFoam -- no time derivative needed // ddtSchemes { default steadyState; } divSchemes { default none; div(phi,U) Gauss linearUpwind grad(U); // 2nd order, bounded div(phi,k) Gauss linearUpwind grad(k); div(phi,omega) Gauss linearUpwind grad(omega); } laplacianSchemes { default Gauss linear corrected; // corrected for non-orthogonality }
Divergence troubleshooting checklist: (1) Check mesh non-orthogonality — if max > 70°, increase nNonOrthogonalCorrectors to 2–3. (2) Reduce under-relaxation factors by half. (3) Tighten linear solver tolerance (relTol 0.01 → 0.001). (4) If continuity residual is not falling, your mesh has a problem (non-closed boundary, zero-thickness faces). (5) For transient cases: reduce time step to bring Co below 1.
Residual plateau warning: If your residuals drop quickly for 100 iterations then plateau at, say, 1e-3 and stop falling, this usually indicates a physically unsteady flow being forced into a steady simulation. The wake is oscillating but SIMPLE can only find a time-averaged solution. Try URANS (PIMPLE) or check if physical oscillation is expected.
Cross-topics: RANS Turbulence Modeling | LES / DNS | CFD Meshing | Error Database