SU2 CFD Solver

Category: Open-Source CAE | Revised 2026-10-02
CAE visualization for su2 cfd theory - technical simulation diagram
SU2 CFD Solver

Theory: shape-optimisation gradients from one adjoint solve

Overview

🙋

OpenFOAM is the well-known open-source CFD code — why choose SU2?

🎓

When you want to improve shapes automatically. SU2 came out of Stanford's aerospace design lab; beyond solving the flow, it computes efficiently — by the adjoint method — the gradient that says which way to move the shape to cut drag further. When a wing is parametrised by tens to hundreds of variables, the cost of that gradient decides total run time. OpenFOAM wins on range and flexibility of physics models, but SU2 ships the whole shape-optimisation loop (shape deformation, flow solve, adjoint solve, gradient, shape update) out of the box. Choose by purpose.

Adjoint equations

$$ \frac{dJ}{d\boldsymbol{\alpha}} = \frac{\partial J}{\partial \boldsymbol{\alpha}} + \boldsymbol{\psi}^{\mathsf T}\frac{\partial \mathbf{R}}{\partial \boldsymbol{\alpha}},\qquad \left(\frac{\partial \mathbf{R}}{\partial \mathbf{U}}\right)^{\mathsf T}\boldsymbol{\psi} = -\left(\frac{\partial J}{\partial \mathbf{U}}\right)^{\mathsf T} $$

J is the objective (e.g. drag), α the design variables, U the flow solution, R the residual of the discrete equations and ψ the adjoint variables. Solving the right-hand adjoint equation once gives every gradient via the left-hand formula, however many design variables there are. SU2 implements the discrete adjoint — differentiating the discretised equations directly — by algorithmic differentiation.

Coffee Break Trivia

A tool born from aerofoil design

Bringing the adjoint method seriously into aerodynamic shape design is credited to Jameson's work from the late 1980s, which solved aerofoil inverse design with the adjoint of the flow equations. SU2 was released in 2012 by a Stanford lab in that lineage, and universities and companies worldwide have since joined its development, extending it to turbulence, multiphysics and multi-stage optimisation.

Worked examples

Example 1: gradient cost (2-hour flow solve, 20 iterations)

Design variablesFinite difference (per gradient)Adjoint (per gradient)Ratio20 iterations: FD20 iterations: adjoint
1022 h4.6 h5440 h (18 days)92 h
50102 h4.6 h222,040 h (85 days)92 h
200402 h4.6 h878,040 h (335 days)92 h

Adjoint cost is assumed to be 1.3 times a flow solve (it varies with problem and settings). Adjoint time does not depend on the number of design variables.

Example 2: first-cell height for a turbulent flat-plate check (air, 50 m/s)

$$ C_f = 0.0592\,Re_x^{-0.2},\qquad u_\tau = U\sqrt{C_f/2},\qquad \Delta y = \frac{y^+\,\nu}{u_\tau} $$
Position xRe_xC_fu_τHeight for y⁺=1Height for y⁺=30
0.1 m3.33×10⁵0.004652.41 m/s6.2 μm187 μm
0.5 m1.67×10⁶0.003372.05 m/s7.3 μm219 μm
1.0 m3.33×10⁶0.002941.92 m/s7.8 μm235 μm

Wall-resolved turbulence models (such as the standard SA model) target y⁺ ≈ 1; friction is larger near the leading edge, so the first layer must be thinner there. Compare computed skin friction with the correlation above and check for agreement within a few per cent.

🙋

How is the configuration file written?

🎓

SU2 puts every setting in one text configuration file (.cfg). For a turbulent flat plate, choose equations and model with SOLVER= RANS and KIND_TURB_MODEL= SA, set flow conditions with MACH_NUMBER and REYNOLDS_NUMBER, an adiabatic wall with MARKER_HEATFLUX= ( wall, 0.0 ) and the far field with MARKER_FAR. The usual numerics are a second-order upwind scheme via CONV_NUM_METHOD_FLOW= ROE and MUSCL_FLOW= YES. For shape optimisation, set MATH_PROBLEM= DISCRETE_ADJOINT and OBJECTIVE_FUNCTION= DRAG, parametrise the shape with free-form-deformation (FFD) control points, and loop flow, adjoint and shape updates with the bundled Python script (shape_optimization.py). Starting from an official tutorial configuration and swapping in your mesh and conditions is the least error-prone route.

Workflow

  1. Reproduce a similar official tutorial as-is.
  2. Swap in your mesh and check y⁺ and convergence (residual and drag histories).
  3. Verify friction and pressure against reference solutions on cases like the flat plate.
  4. Check adjoint gradients against finite differences on a few variables.
  5. Parametrise with FFD, add constraints (thickness, lift) and run the optimisation.
Coffee Break Trivia

“An optimisation whose gradients didn't match”

In optimising a duct's pressure loss, the objective refused to fall however many iterations ran. Comparing adjoint gradients with finite differences for two design variables showed not even the signs agreed. The flow solves had been passed to the adjoint before converging adequately. Tightening convergence to four orders of residual reduction, including the turbulence equation, brought gradients within 1% of finite differences, and loss began dropping within a few iterations.

Common mistakes

Mistakes and fixes

MistakeEffectFix
Under-converged flowWrong gradientsConverge residuals deeply
Unchecked gradientsOptimisation stallsCompare with finite differences
Not checking y⁺Wrong friction dragSize first layer from y⁺
No constraintsUnrealistically thin shapesThickness and lift constraints
FFD box not enclosing the shapeNo or broken deformationCheck box placement
🙋

I'd like to learn related topics.

Related Simulators

Experience the theory firsthand with the interactive simulator for this field

All Simulators

Related fields

Structural AnalysisFluid Analysis (CFD)Thermal Analysis
Rate this article
Thank you for your feedback!
Helpful
More details
Report error
Helpful
0
More details
0
Report error
0