---
title: Turbulence closure
summary: "The Spalart–Allmaras RANS closure is verified in four steps: a manufactured solution for the order of accuracy of the coupled system, exactness of its linearisation including the wall distance, the turbulent flat plate of the NASA Turbulence Modeling Resource for the model itself, and adjoint derivatives against finite differences."
section: verification
order: 7
level: 2
study: rans_flat_plate
studies: [rans_mms, rans_linearization, rans_adjoint, rans_extruded_3d]
keywords: [RANS, Spalart-Allmaras, flat plate, skin friction, manufactured solution, wall distance, adjoint]
---
<!-- gyre docs: expanded Markdown of verification/turbulence.md (generated tables, verification numbers and chart data are written out). Base level of this page: L2 Practice; passages at another level are bracketed by 'begin level N' / 'end level N' comments and start with [LN Name]. Built from revision ceb1f4b0be. -->

A turbulence model adds an equation whose terms are stiff, non-conservative and singular at
the wall. Each of the four studies below isolates one way in which that can go wrong: the
discretization of the new terms, their derivatives, the model as implemented against two
established codes, and the total derivatives an optimizer would consume. The formulation is
described under [Turbulence closure](../theory/turbulence-model.md).

## Order of accuracy

**Verification status: Manufactured solutions: RANS with the Spalart-Allmaras model** (study `rans_mms`): **PASSED**, 9 of 9 checks passed, 455.8 s.

Steady manufactured solution of the compressible RANS equations coupled to the negative Spalart-Allmaras model on the unit box (M = 0.5, Re = 1000, nu_tilde / nu = 8 (1 + 0.4 sin), a smooth positive manufactured wall distance between 0.1 and 0.8), Dirichlet data from the exact state on all sides. The forcing is generated by automatic differentiation of the same flux and source kernels the solver uses (turbulence.manufactured_source). Errors: L2 norm of the mean-flow conserved variables, and of rho nu_tilde scaled by Re. The solve starts from the nodal values of the exact solution and removes the truncation-error residual with p-multigrid Newton-Krylov. The eddy viscosity of the manufactured state is 4.7 times the molecular one, so the mean flow sees an effective Reynolds number of about 175: between the diffusion- and the convection-dominated regimes of the laminar manufactured solutions, where the state converges at a rate between p and p + 1. The laminar manufactured solution with the same mean state is therefore solved at that Reynolds number on the same meshes, and the checks require the guaranteed rate p of both equations and that the model changes neither the order nor the size of the mean-flow error.

| Check | Value | Expected | Result |
|---|---|---|---|
| p = 1: order of the mean-flow state (finest pair) | 1.91436 | >= 0.75 (guaranteed rate p = 1, tolerance 0.25; design rate 2) | pass |
| p = 1: order of nu_tilde (finest pair) | 2.20221 | >= 0.75 (guaranteed rate p = 1, tolerance 0.25; design rate 2) | pass |
| p = 1: mean-flow order with the model minus the laminar order at the effective Reynolds number | 0.00686569 | > -0.15 | pass |
| p = 1: mean-flow error with the model over the laminar error at the effective Reynolds number (finest mesh) | 1.02439 | 0.5 .. 1.5 | pass |
| p = 2: order of the mean-flow state (finest pair) | 2.47676 | >= 1.75 (guaranteed rate p = 2, tolerance 0.25; design rate 3) | pass |
| p = 2: order of nu_tilde (finest pair) | 2.61163 | >= 1.75 (guaranteed rate p = 2, tolerance 0.25; design rate 3) | pass |
| p = 2: mean-flow order with the model minus the laminar order at the effective Reynolds number | -0.0720563 | > -0.15 | pass |
| p = 2: mean-flow error with the model over the laminar error at the effective Reynolds number (finest mesh) | 1.14806 | 0.5 .. 1.5 | pass |
| every model term is active at the domain centre (smallest \|term\| Re) | 0.00168964 | > 1e-3 | pass |

Provenance: gyre 0.4.0; revision `39979fcf90` (commit `39979fcf902ad6116eb550b881b4278d4599c8e2`); 2026-11-12T11:33:19-0500; device cpu; quick suite. **Revision check: Same code as this build.** Produced by 39979fcf902ad6116eb550b881b4278d4599c8e2. Every commit between it and the commit this site was built from (ceb1f4b0bed41de53e586df10858079f5a2bcdd8) changes only documentation text, evidence records or bookkeeping: the code is the same. Full record: [rans_mms.json](../data/verification/rans_mms.json).

**Chart: RANS-SA manufactured solution** (Manufactured solutions: RANS with the Spalart-Allmaras model). Convergence chart of L2 error against h, x axis log, y axis log; 6 series. The table holds the plotted data. Reference slopes drawn: 2 (h^2), 3 (h^3).

| h | mean flow, p = 1 | nu_tilde Re, p = 1 | laminar at the effective Re, p = 1 | mean flow, p = 2 | nu_tilde Re, p = 2 | laminar at the effective Re, p = 2 |
|---|---|---|---|---|---|---|
| 0.25 | 0.0784061 | 0.488579 | 0.0766958 | 0.00508349 | 0.0363521 | 0.00493946 |
| 0.125 | 0.0223437 | 0.106304 | 0.0217082 | 8.6746e-04 | 0.00424742 | 7.9429e-04 |
| 0.0625 | 0.00592756 | 0.0231004 | 0.00578644 | 1.5584e-04 | 6.9494e-04 | 1.3574e-04 |

Provenance: gyre 0.4.0; revision `39979fcf90` (commit `39979fcf902ad6116eb550b881b4278d4599c8e2`); 2026-11-12T11:33:19-0500; device cpu; quick suite. **Revision check: Same code as this build.** Produced by 39979fcf902ad6116eb550b881b4278d4599c8e2. Every commit between it and the commit this site was built from (ceb1f4b0bed41de53e586df10858079f5a2bcdd8) changes only documentation text, evidence records or bookkeeping: the code is the same. Full record: [rans_mms.json](../data/verification/rans_mms.json).

**Table: Errors on the finest mesh and observed orders (finest pair)** (Manufactured solutions: RANS with the Spalart-Allmaras model)

| p | mean-flow error | order | nu_tilde error x Re | order | laminar error at the effective Re | order |
|---|---|---|---|---|---|---|
| 1 | 0.00592756 | 1.91436 | 0.0231004 | 2.20221 | 0.00578644 | 1.90749 |
| 2 | 1.5584e-04 | 2.47676 | 6.9494e-04 | 2.61163 | 1.3574e-04 | 2.54882 |

Provenance: gyre 0.4.0; revision `39979fcf90` (commit `39979fcf902ad6116eb550b881b4278d4599c8e2`); 2026-11-12T11:33:19-0500; device cpu; quick suite. **Revision check: Same code as this build.** Produced by 39979fcf902ad6116eb550b881b4278d4599c8e2. Every commit between it and the commit this site was built from (ceb1f4b0bed41de53e586df10858079f5a2bcdd8) changes only documentation text, evidence records or bookkeeping: the code is the same. Full record: [rans_mms.json](../data/verification/rans_mms.json).

<!-- begin level 2 (Practice) -->
**[L2 Practice] What is solved**

A smooth manufactured state of the coupled system (mean flow and $\tilde\nu$) on the unit
square, with a manufactured, strictly positive wall-distance field so that production,
destruction and the gradient terms are all active. The forcing is generated by automatic
differentiation of the kernels the solver itself uses, and the steady problem is solved with
the implicit solver on three meshes per degree. The second table lists the size of each model
term of the manufactured state, to show that none of them is negligible in the test.

<!-- end level 2 -->

**Table: Model terms of the manufactured state at (0.5, 0.5), times Re** (Manufactured solutions: RANS with the Spalart-Allmaras model)

| term | value |
|---|---|
| production | 0.00168964 |
| destruction | 2.22251 |
| cb2 | 0.0839335 |
| density_gradient | -0.0667243 |
| eddy viscosity / molecular viscosity | 7.20704 |

Provenance: gyre 0.4.0; revision `39979fcf90` (commit `39979fcf902ad6116eb550b881b4278d4599c8e2`); 2026-11-12T11:33:19-0500; device cpu; quick suite. **Revision check: Same code as this build.** Produced by 39979fcf902ad6116eb550b881b4278d4599c8e2. Every commit between it and the commit this site was built from (ceb1f4b0bed41de53e586df10858079f5a2bcdd8) changes only documentation text, evidence records or bookkeeping: the code is the same. Full record: [rans_mms.json](../data/verification/rans_mms.json).

<!-- begin level 3 (Mechanics) -->
**[L3 Mechanics] Reading the orders**

The mean flow and the turbulence variable are measured separately, the latter scaled by the
Reynolds number so that both are of order one. The study requires the rate that the laminar
manufactured solutions establish for this discretization
([order of accuracy](order-of-accuracy.md)); the observed orders are reported next to it.

<!-- end level 3 -->

## Exact linearisation

**Verification status: Exact linearization with the Spalart-Allmaras model** (study `rans_linearization`): **PASSED**, 20 of 20 checks passed, 158.6 s.

Jacobian-vector products of the weak RANS-SA residual from automatic differentiation against central differences (best of three step sizes), the dot-product identity of tangent and adjoint products, the element-diagonal blocks from the split-argument residual against the dense Jacobian (2-D), and the derivative with respect to the geometry nodes, which includes the wall distance. States are random perturbations of the free stream with nu_tilde / nu between -2 and 12, so both branches of the model and its limiters are differentiated; every boundary-condition type appears.

| Check | Value | Expected | Result |
|---|---|---|---|
| 2-D ring, adiabatic wall, far field: JVP vs central difference | 4.1315e-10 | < 1e-6 | pass |
| 2-D ring, adiabatic wall, far field: JVP vs central difference, turbulence row | 3.9495e-09 | < 1e-6 | pass |
| 2-D ring, adiabatic wall, far field: <v,Ju> = <J^T v,u> | 7.5077e-15 | < 1e-12 | pass |
| 2-D ring, adiabatic wall, far field: shape derivative of the residual vs central difference | 1.6640e-10 | < 1e-6 | pass |
| 2-D ring, adiabatic wall, far field: derivative of the wall distance w.r.t. the nodes | 1.4456e-09 | < 1e-6 | pass |
| 2-D ring, adiabatic wall, far field: share of nodes on the negative branch | 0.175926 | 0.05 .. 0.5 | pass |
| 2-D ring, adiabatic wall, far field: block inverse times dense diagonal block | 9.0650e-14 | < 1e-8 | pass |
| 2-D channel: isothermal wall, inlet, outlet, slip wall: JVP vs central difference | 2.0567e-10 | < 1e-6 | pass |
| 2-D channel: isothermal wall, inlet, outlet, slip wall: JVP vs central difference, turbulence row | 1.3754e-09 | < 1e-6 | pass |
| 2-D channel: isothermal wall, inlet, outlet, slip wall: <v,Ju> = <J^T v,u> | 2.3291e-14 | < 1e-12 | pass |
| 2-D channel: isothermal wall, inlet, outlet, slip wall: shape derivative of the residual vs central difference | 7.9132e-11 | < 1e-6 | pass |
| 2-D channel: isothermal wall, inlet, outlet, slip wall: derivative of the wall distance w.r.t. the nodes | 3.7334e-10 | < 1e-6 | pass |
| 2-D channel: isothermal wall, inlet, outlet, slip wall: share of nodes on the negative branch | 0.209877 | 0.05 .. 0.5 | pass |
| 2-D channel: isothermal wall, inlet, outlet, slip wall: block inverse times dense diagonal block | 8.2334e-13 | < 1e-8 | pass |
| 3-D box: adiabatic wall, far field, symmetry: JVP vs central difference | 2.6557e-10 | < 1e-6 | pass |
| 3-D box: adiabatic wall, far field, symmetry: JVP vs central difference, turbulence row | 6.4804e-09 | < 1e-6 | pass |
| 3-D box: adiabatic wall, far field, symmetry: <v,Ju> = <J^T v,u> | 1.7685e-14 | < 1e-12 | pass |
| 3-D box: adiabatic wall, far field, symmetry: shape derivative of the residual vs central difference | 6.7631e-11 | < 1e-6 | pass |
| 3-D box: adiabatic wall, far field, symmetry: derivative of the wall distance w.r.t. the nodes | 4.2069e-10 | < 1e-6 | pass |
| 3-D box: adiabatic wall, far field, symmetry: share of nodes on the negative branch | 0.12963 | 0.05 .. 0.5 | pass |

Provenance: gyre 0.4.0; revision `39979fcf90` (commit `39979fcf902ad6116eb550b881b4278d4599c8e2`); 2026-11-12T11:40:59-0500; device cpu; quick suite. **Revision check: Same code as this build.** Produced by 39979fcf902ad6116eb550b881b4278d4599c8e2. Every commit between it and the commit this site was built from (ceb1f4b0bed41de53e586df10858079f5a2bcdd8) changes only documentation text, evidence records or bookkeeping: the code is the same. Full record: [rans_linearization.json](../data/verification/rans_linearization.json).

**Table: Relative defects** (Exact linearization with the Spalart-Allmaras model)

| configuration | p | DOF | negative nu_tilde share | JVP - FD | JVP - FD (turbulence row) | dot product | block inverse | shape derivative | wall distance |
|---|---|---|---|---|---|---|---|---|---|
| 2-D ring, adiabatic wall, far field | 2 | 540 | 0.175926 | 4.1315e-10 | 3.9495e-09 | 7.5077e-15 | 9.0650e-14 | 1.6640e-10 | 1.4456e-09 |
| 2-D channel: isothermal wall, inlet, outlet, slip wall | 2 | 405 | 0.209877 | 2.0567e-10 | 1.3754e-09 | 2.3291e-14 | 8.2334e-13 | 7.9132e-11 | 3.7334e-10 |
| 3-D box: adiabatic wall, far field, symmetry | 2 | 1296 | 0.12963 | 2.6557e-10 | 6.4804e-09 | 1.7685e-14 | — | 6.7631e-11 | 4.2069e-10 |

Provenance: gyre 0.4.0; revision `39979fcf90` (commit `39979fcf902ad6116eb550b881b4278d4599c8e2`); 2026-11-12T11:40:59-0500; device cpu; quick suite. **Revision check: Same code as this build.** Produced by 39979fcf902ad6116eb550b881b4278d4599c8e2. Every commit between it and the commit this site was built from (ceb1f4b0bed41de53e586df10858079f5a2bcdd8) changes only documentation text, evidence records or bookkeeping: the code is the same. Full record: [rans_linearization.json](../data/verification/rans_linearization.json).

<!-- begin level 2 (Practice) -->
**[L2 Practice] What the columns mean**

Random states with $\tilde\nu/\nu$ between $-2$ and $12$ put a share of the nodes on the
negative branch of the model (column 4), so both branches and the limiters are
differentiated. The Jacobian-vector product from automatic differentiation is compared with a
central difference of the residual, for all equations and for the turbulence equation alone;
the dot-product identity ties the adjoint product to the tangent product; the block inverses
of the preconditioner are multiplied with the diagonal blocks of a dense Jacobian (2-D). The
last two columns differentiate with respect to the mesh nodes: the residual, and the wall
distance by itself.

<!-- end level 2 -->

<!-- begin level 3 (Mechanics) -->
**[L3 Mechanics] Why the wall-distance column matters**

The wall distance is a minimum over the wall, and the solver stores the minimiser as
interpolation weights on wall nodes instead of recomputing it when the geometry moves. The
check moves the nodes, recomputes the closest points from scratch, and compares the
difference quotient with the derivative of the stored representation. Agreement to the
accuracy of the finite difference confirms the envelope argument of the
[theory page](../theory/turbulence-model.md#wall-distance) on these meshes.

<!-- end level 3 -->

## Turbulent flat plate

**Verification status: Turbulent flat plate (NASA TMR) with the Spalart-Allmaras model** (study `rans_flat_plate`): **PASSED**, 8 of 8 checks passed, 162.1 s.

Zero-pressure-gradient turbulent flat plate of the NASA Turbulence Modeling Resource (2D Zero Pressure Gradient Flat Plate Verification Case: M = 0.2, Re = 5e6 per unit length, plate from x = 0 to 2, symmetry upstream to x = -0.33, far field at y = 1, total-pressure inflow, pressure outflow, adiabatic wall, free-stream nu_tilde = 3 nu). Each run starts from the uniform free stream and is converged nine orders by the pseudo-transient Newton-Krylov solver. The skin friction, taken from the numerical wall flux of the residual, is compared with the TMR's SA results on its finest grid (545 x 385 points; file FlatPlate/SA/cf_plate.dat, mean of CFL3D and FUN3D, which differ by less than 0.1 % at the stations used; at x = 0.97008 their grid-converged value is cf = 2.705513e-03). The meshes here are far coarser: the coarse mesh has 15 x 10 elements with a first element height of 5e-05. The comparison is with the reference model implementation (standard SA with the ft2 term; this code solves SA-neg, identical for positive nu_tilde), not with experiment.

| Check | Value | Expected | Result |
|---|---|---|---|
| coarse mesh, p = 1: converged from the free stream (residual drop) | 8.2135e-10 | <= 1e-9 | pass |
| coarse mesh, p = 1: Newton steps | 33 | <= 100 (cap 150) | pass |
| coarse mesh, p = 2: converged from the free stream (residual drop) | 2.3071e-11 | <= 1e-9 | pass |
| coarse mesh, p = 2: Newton steps | 34 | <= 100 (cap 150) | pass |
| p = 2: \|cf / cf_TMR - 1\| at x = 0.97 | 0.00165649 | < 0.02 | pass |
| p = 2: largest \|cf / cf_TMR - 1\| over the stations x >= 0.5 | 0.0215281 | < 0.04 | pass |
| p = 1: largest \|cf / cf_TMR - 1\| over the stations x >= 0.5 | 0.099885 | < 0.15 | pass |
| raising the degree from 1 to 2 reduces the largest difference (ratio) | 0.215529 | < 0.5 | pass |

Run notes: The leading-edge region (x < 0.3) is the least resolved: the first element on the plate is 0.02 long. Negative nu_tilde occurs at the edge of the boundary layer, where the negative branch of the model takes over; it is reported, not clipped. Not covered: a mesh-converged result, the velocity profile in wall units, other Reynolds numbers.

Provenance: gyre 0.4.0; revision `39979fcf90` (commit `39979fcf902ad6116eb550b881b4278d4599c8e2`); 2026-11-12T11:36:05-0500; device cpu; quick suite. **Revision check: Same code as this build.** Produced by 39979fcf902ad6116eb550b881b4278d4599c8e2. Every commit between it and the commit this site was built from (ceb1f4b0bed41de53e586df10858079f5a2bcdd8) changes only documentation text, evidence records or bookkeeping: the code is the same. Full record: [rans_flat_plate.json](../data/verification/rans_flat_plate.json).

**Chart: Skin friction along the plate** (Turbulent flat plate (NASA TMR) with the Spalart-Allmaras model). Line chart of cf against x; 3 series. The table holds the plotted data.

| series | x | cf |
|---|---|---|
| coarse mesh, p = 1 | 0.02 | 0.00491592 |
| coarse mesh, p = 1 | 0.02 | 0.00499258 |
| coarse mesh, p = 1 | 0.0469419 | 0.0047353 |
| coarse mesh, p = 1 | 0.0469419 | 0.00447534 |
| coarse mesh, p = 1 | 0.0832353 | 0.0045294 |
| coarse mesh, p = 1 | 0.0832353 | 0.00422098 |
| coarse mesh, p = 1 | 0.132126 | 0.00410448 |
| coarse mesh, p = 1 | 0.132126 | 0.00384376 |
| coarse mesh, p = 1 | 0.197987 | 0.00392741 |
| coarse mesh, p = 1 | 0.197987 | 0.0037168 |
| coarse mesh, p = 1 | 0.286707 | 0.00369003 |
| coarse mesh, p = 1 | 0.286707 | 0.00355616 |
| coarse mesh, p = 1 | 0.406222 | 0.003343 |
| coarse mesh, p = 1 | 0.406222 | 0.00325364 |
| coarse mesh, p = 1 | 0.567221 | 0.00316472 |
| coarse mesh, p = 1 | 0.567221 | 0.00307648 |
| coarse mesh, p = 1 | 0.784101 | 0.00309139 |
| coarse mesh, p = 1 | 0.784101 | 0.00303047 |
| coarse mesh, p = 1 | 1.07626 | 0.00293727 |
| coarse mesh, p = 1 | 1.07626 | 0.00291624 |
| coarse mesh, p = 1 | 1.46983 | 0.00273476 |
| coarse mesh, p = 1 | 1.46983 | 0.00271152 |
| coarse mesh, p = 1 | 2 | 0.0026595 |
| coarse mesh, p = 2 | 0.02 | 0.00452362 |
| coarse mesh, p = 2 | 0.02 | 0.00457282 |
| coarse mesh, p = 2 | 0.033471 | 0.00429405 |
| coarse mesh, p = 2 | 0.0469419 | 0.00410478 |
| coarse mesh, p = 2 | 0.0469419 | 0.00410667 |
| coarse mesh, p = 2 | 0.0650886 | 0.00385725 |
| coarse mesh, p = 2 | 0.0832353 | 0.00367193 |
| coarse mesh, p = 2 | 0.0832353 | 0.0036691 |
| coarse mesh, p = 2 | 0.107681 | 0.00359358 |
| coarse mesh, p = 2 | 0.132126 | 0.00352584 |
| coarse mesh, p = 2 | 0.132126 | 0.00352445 |
| coarse mesh, p = 2 | 0.165056 | 0.00347637 |
| coarse mesh, p = 2 | 0.197987 | 0.00339196 |
| coarse mesh, p = 2 | 0.197987 | 0.00339568 |
| coarse mesh, p = 2 | 0.242347 | 0.00327457 |
| coarse mesh, p = 2 | 0.286707 | 0.0031657 |
| coarse mesh, p = 2 | 0.286707 | 0.0031628 |
| coarse mesh, p = 2 | 0.346465 | 0.00309734 |
| coarse mesh, p = 2 | 0.406222 | 0.00303715 |
| coarse mesh, p = 2 | 0.406222 | 0.00303692 |
| coarse mesh, p = 2 | 0.486722 | 0.00299737 |
| coarse mesh, p = 2 | 0.567221 | 0.00294754 |
| coarse mesh, p = 2 | 0.567221 | 0.00294702 |
| coarse mesh, p = 2 | 0.675661 | 0.00288963 |
| coarse mesh, p = 2 | 0.784101 | 0.00280593 |
| coarse mesh, p = 2 | 0.784101 | 0.0028098 |
| coarse mesh, p = 2 | 0.930181 | 0.00272065 |
| coarse mesh, p = 2 | 1.07626 | 0.00265873 |
| coarse mesh, p = 2 | 1.07626 | 0.00265545 |
| coarse mesh, p = 2 | 1.27304 | 0.00261528 |
| coarse mesh, p = 2 | 1.46983 | 0.00257447 |
| coarse mesh, p = 2 | 1.46983 | 0.00257404 |
| coarse mesh, p = 2 | 1.73491 | 0.00254306 |
| coarse mesh, p = 2 | 2 | 0.00250226 |
| NASA TMR, SA, CFL3D 545 x 385 | 0.100573 | 0.00379176 |
| NASA TMR, SA, CFL3D 545 x 385 | 0.199971 | 0.00341813 |
| NASA TMR, SA, CFL3D 545 x 385 | 0.299841 | 0.00321455 |
| NASA TMR, SA, CFL3D 545 x 385 | 0.50151 | 0.0029769 |
| NASA TMR, SA, CFL3D 545 x 385 | 0.747281 | 0.00280852 |
| NASA TMR, SA, CFL3D 545 x 385 | 0.970084 | 0.00270562 |
| NASA TMR, SA, CFL3D 545 x 385 | 1.24823 | 0.00261128 |
| NASA TMR, SA, CFL3D 545 x 385 | 1.49524 | 0.00254679 |
| NASA TMR, SA, CFL3D 545 x 385 | 1.75299 | 0.00249255 |
| NASA TMR, SA, CFL3D 545 x 385 | 1.90334 | 0.00246638 |

Provenance: gyre 0.4.0; revision `39979fcf90` (commit `39979fcf902ad6116eb550b881b4278d4599c8e2`); 2026-11-12T11:36:05-0500; device cpu; quick suite. **Revision check: Same code as this build.** Produced by 39979fcf902ad6116eb550b881b4278d4599c8e2. Every commit between it and the commit this site was built from (ceb1f4b0bed41de53e586df10858079f5a2bcdd8) changes only documentation text, evidence records or bookkeeping: the code is the same. Full record: [rans_flat_plate.json](../data/verification/rans_flat_plate.json).

**Table: Runs** (Turbulent flat plate (NASA TMR) with the Spalart-Allmaras model)

| run | elements | unknowns | y+ of the first node off the wall (x = 0.97) | Newton steps | residual drop | cf(x = 0.97) | difference to TMR at x = 0.97 [%] | largest difference, x >= 0.5 [%] | cd (one wetted side, reference length 1) | max nu_tilde / nu | min nu_tilde / nu | nodes with nu_tilde < 0 [%] |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| coarse mesh, p = 1 | 150 | 3000 | 9.63577 | 33 | 8.2135e-10 | 0.00297114 | 9.81794 | 9.9885 | 0.00628466 | 327.141 | -3.16499 | 0.166667 |
| coarse mesh, p = 2 | 150 | 6750 | 4.59367 | 34 | 2.3071e-11 | 0.00270103 | -0.165649 | 2.15281 | 0.00575365 | 386.72 | -42.5509 | 1.55556 |

Provenance: gyre 0.4.0; revision `39979fcf90` (commit `39979fcf902ad6116eb550b881b4278d4599c8e2`); 2026-11-12T11:36:05-0500; device cpu; quick suite. **Revision check: Same code as this build.** Produced by 39979fcf902ad6116eb550b881b4278d4599c8e2. Every commit between it and the commit this site was built from (ceb1f4b0bed41de53e586df10858079f5a2bcdd8) changes only documentation text, evidence records or bookkeeping: the code is the same. Full record: [rans_flat_plate.json](../data/verification/rans_flat_plate.json).

<!-- begin level 2 (Practice) -->
**[L2 Practice] The case and the reference**

Zero-pressure-gradient flat plate at $M = 0.2$ and $\mathit{Re} = 5\times10^6$ per unit
length, on the domain of the NASA Turbulence Modeling Resource. The reference is the skin
friction that two independent codes, CFL3D and FUN3D, obtain with the same model on the
finest grid of that resource (545 × 385 points); their values agree with each other to four
digits, so the comparison tests the implementation of the model, not the model. Gyre runs
the case on a mesh of a few hundred elements whose first element is thin enough for the
polynomial inside it to resolve the sublayer; the table reports $y^+$ of the first solution
node off the wall.

<!-- end level 2 -->

**Table: Skin friction at the TMR stations** (Turbulent flat plate (NASA TMR) with the Spalart-Allmaras model)

| run | x | cf | cf TMR | difference [%] |
|---|---|---|---|---|
| coarse mesh, p = 1 | 0.100573 | 0.00417967 | 0.00379009 | 10.2788 |
| coarse mesh, p = 1 | 0.199971 | 0.0037162 | 0.0034172 | 8.75013 |
| coarse mesh, p = 1 | 0.299841 | 0.00353274 | 0.00321396 | 9.91855 |
| coarse mesh, p = 1 | 0.50151 | 0.00320101 | 0.00297659 | 7.53952 |
| coarse mesh, p = 1 | 0.747281 | 0.00308886 | 0.00280835 | 9.9885 |
| coarse mesh, p = 1 | 0.970084 | 0.00297114 | 0.00270551 | 9.81794 |
| coarse mesh, p = 1 | 1.24823 | 0.00283694 | 0.0026112 | 8.64499 |
| coarse mesh, p = 1 | 1.49524 | 0.00270903 | 0.00254669 | 6.37439 |
| coarse mesh, p = 1 | 1.75299 | 0.00268374 | 0.00249222 | 7.68478 |
| coarse mesh, p = 1 | 1.90334 | 0.00266898 | 0.0024652 | 8.26632 |
| coarse mesh, p = 2 | 0.100573 | 0.00361473 | 0.00379009 | -4.62671 |
| coarse mesh, p = 2 | 0.199971 | 0.00339 | 0.0034172 | -0.795826 |
| coarse mesh, p = 2 | 0.299841 | 0.00314796 | 0.00321396 | -2.05354 |
| coarse mesh, p = 2 | 0.50151 | 0.00298899 | 0.00297659 | 0.416487 |
| coarse mesh, p = 2 | 0.747281 | 0.0028373 | 0.00280835 | 1.03093 |
| coarse mesh, p = 2 | 0.970084 | 0.00270103 | 0.00270551 | -0.165649 |
| coarse mesh, p = 2 | 1.24823 | 0.00262038 | 0.0026112 | 0.351467 |
| coarse mesh, p = 2 | 1.49524 | 0.0025715 | 0.00254669 | 0.973867 |
| coarse mesh, p = 2 | 1.75299 | 0.00254059 | 0.00249222 | 1.94095 |
| coarse mesh, p = 2 | 1.90334 | 0.00251827 | 0.0024652 | 2.15281 |

Provenance: gyre 0.4.0; revision `39979fcf90` (commit `39979fcf902ad6116eb550b881b4278d4599c8e2`); 2026-11-12T11:36:05-0500; device cpu; quick suite. **Revision check: Same code as this build.** Produced by 39979fcf902ad6116eb550b881b4278d4599c8e2. Every commit between it and the commit this site was built from (ceb1f4b0bed41de53e586df10858079f5a2bcdd8) changes only documentation text, evidence records or bookkeeping: the code is the same. Full record: [rans_flat_plate.json](../data/verification/rans_flat_plate.json).

<!-- begin level 3 (Mechanics) -->
**[L3 Mechanics] What the comparison does and does not show**

* The check is made at the station where the resource reports grid convergence
  ($x = 0.97$) and over the stations of the downstream three quarters of the plate. Near
  the leading edge the coarse streamwise mesh and the numerical transition of the model
  dominate, and the difference is larger; the chart shows the whole plate.
* The solution contains nodes with negative $\tilde\nu$ at the edge of the boundary layer
  (last columns of the run table): the situation the negative branch of the model exists
  for.
* This is one attached boundary layer on one mesh family. It says nothing about separated
  flow, pressure gradients, curvature or three-dimensional boundary layers.

<!-- end level 3 -->

**Chart: Residual history (weighted norm, relative to the free stream)** (Turbulent flat plate (NASA TMR) with the Spalart-Allmaras model). Line chart of |R| / |R0| against Newton step, y axis log; 2 series. The table holds the plotted data.

| series | Newton step | \|R\| / \|R0\| |
|---|---|---|
| coarse mesh, p = 1 | 0 | 1 |
| coarse mesh, p = 1 | 1 | 4.89573 |
| coarse mesh, p = 1 | 2 | 5.41247 |
| coarse mesh, p = 1 | 3 | 2.23355 |
| coarse mesh, p = 1 | 4 | 0.336976 |
| coarse mesh, p = 1 | 5 | 0.171881 |
| coarse mesh, p = 1 | 6 | 0.140768 |
| coarse mesh, p = 1 | 7 | 0.103329 |
| coarse mesh, p = 1 | 8 | 0.0703721 |
| coarse mesh, p = 1 | 9 | 0.0457075 |
| coarse mesh, p = 1 | 10 | 0.0326526 |
| coarse mesh, p = 1 | 11 | 0.0279033 |
| coarse mesh, p = 1 | 12 | 0.0236092 |
| coarse mesh, p = 1 | 13 | 0.0230931 |
| coarse mesh, p = 1 | 14 | 0.0149979 |
| coarse mesh, p = 1 | 15 | 0.0166568 |
| coarse mesh, p = 1 | 16 | 0.0146755 |
| coarse mesh, p = 1 | 17 | 0.0113993 |
| coarse mesh, p = 1 | 18 | 0.0106557 |
| coarse mesh, p = 1 | 19 | 0.0128619 |
| coarse mesh, p = 1 | 20 | 0.0119742 |
| coarse mesh, p = 1 | 21 | 0.0149637 |
| coarse mesh, p = 1 | 22 | 0.0206963 |
| coarse mesh, p = 1 | 23 | 0.0181075 |
| coarse mesh, p = 1 | 24 | 0.0196957 |
| coarse mesh, p = 1 | 25 | 0.0110184 |
| coarse mesh, p = 1 | 26 | 0.00441607 |
| coarse mesh, p = 1 | 27 | 9.9709e-04 |
| coarse mesh, p = 1 | 28 | 9.7204e-05 |
| coarse mesh, p = 1 | 29 | 8.2838e-06 |
| coarse mesh, p = 1 | 30 | 5.1405e-07 |
| coarse mesh, p = 1 | 31 | 6.4240e-08 |
| coarse mesh, p = 1 | 32 | 5.8135e-09 |
| coarse mesh, p = 1 | 33 | 8.2135e-10 |
| coarse mesh, p = 2 | 0 | 1 |
| coarse mesh, p = 2 | 1 | 6.25644 |
| coarse mesh, p = 2 | 2 | 3.41048 |
| coarse mesh, p = 2 | 3 | 0.488431 |
| coarse mesh, p = 2 | 4 | 0.580143 |
| coarse mesh, p = 2 | 5 | 0.392395 |
| coarse mesh, p = 2 | 6 | 0.209359 |
| coarse mesh, p = 2 | 7 | 0.100348 |
| coarse mesh, p = 2 | 8 | 0.0499584 |
| coarse mesh, p = 2 | 9 | 0.0350756 |
| coarse mesh, p = 2 | 10 | 0.0269743 |
| coarse mesh, p = 2 | 11 | 0.023996 |
| coarse mesh, p = 2 | 12 | 0.0244786 |
| coarse mesh, p = 2 | 13 | 0.0185963 |
| coarse mesh, p = 2 | 14 | 0.015646 |
| coarse mesh, p = 2 | 15 | 0.0126737 |
| coarse mesh, p = 2 | 16 | 0.00959785 |
| coarse mesh, p = 2 | 17 | 0.0088486 |
| coarse mesh, p = 2 | 18 | 0.00828078 |
| coarse mesh, p = 2 | 19 | 0.00937068 |
| coarse mesh, p = 2 | 20 | 0.0107984 |
| coarse mesh, p = 2 | 21 | 0.0125768 |
| coarse mesh, p = 2 | 22 | 0.0180937 |
| coarse mesh, p = 2 | 23 | 0.0159537 |
| coarse mesh, p = 2 | 24 | 0.0167172 |
| coarse mesh, p = 2 | 25 | 0.0137778 |
| coarse mesh, p = 2 | 26 | 0.0157868 |
| coarse mesh, p = 2 | 27 | 0.0104857 |
| coarse mesh, p = 2 | 28 | 0.00516797 |
| coarse mesh, p = 2 | 29 | 0.00191466 |
| coarse mesh, p = 2 | 30 | 3.0095e-04 |
| coarse mesh, p = 2 | 31 | 1.2303e-05 |
| coarse mesh, p = 2 | 32 | 2.1421e-07 |
| coarse mesh, p = 2 | 33 | 2.6006e-09 |
| coarse mesh, p = 2 | 34 | 2.3071e-11 |

Provenance: gyre 0.4.0; revision `39979fcf90` (commit `39979fcf902ad6116eb550b881b4278d4599c8e2`); 2026-11-12T11:36:05-0500; device cpu; quick suite. **Revision check: Same code as this build.** Produced by 39979fcf902ad6116eb550b881b4278d4599c8e2. Every commit between it and the commit this site was built from (ceb1f4b0bed41de53e586df10858079f5a2bcdd8) changes only documentation text, evidence records or bookkeeping: the code is the same. Full record: [rans_flat_plate.json](../data/verification/rans_flat_plate.json).

## Three dimensions

**Verification status: Three-dimensional consistency with the Spalart-Allmaras model** (study `rans_extruded_3d`): **PASSED**, 10 of 10 checks passed, 675.1 s.

The turbulent flat plate of the preset flat_plate_sa (M = 0.2, Re = 5e6, degree 2, first cell 5e-5 high) is solved on its 2-D section and on a spanwise-periodic extrusion of that section into hexahedra (3 across a span of 3), both from the free stream with line Jacobi as the smoother of the p-multigrid levels 2-1-0. A correct 3-D implementation of the RANS equations (viscous and turbulent fluxes, the source terms of the model, the wall distance, the boundary conditions, the line smoother, force integration and the discrete adjoint) must give the drag of the section per unit span, its skin friction and the adjoint derivative of the drag. Section and extrusion have the same in-plane equations only at the same BR2 penalty, whose default is the number of faces of an element (4 for quadrilaterals, 6 for hexahedra): the section is therefore solved with 6, the default of the extrusion, and once more with its own default, which is reported without a check. Three kinds of statement are checked. Before the 3-D solve, the solution of the section is extruded and put into the 3-D residual: the equations the section has must be satisfied as well as the section satisfies them (below 1e-8 of the free-stream residual; the flow solves stop at a drop of 1e-9), which tests the 3-D operator without the 3-D solver. The spanwise momentum equation is not satisfied by the extruded solution, for the reason given in the notes, so that the 3-D solution has a small spanwise velocity that alternates within each element: it must leave the layers identical and mirror-symmetric and exert no net spanwise force (round-off only: below 1e-8). Being odd across the mid-plane of an element, it cannot change the mean over the span at first order: drag, mean skin friction and the derivative must agree with the section to 1e-6. The size of the spanwise velocity itself is reported, not checked.

| Check | Value | Expected | Result |
|---|---|---|---|
| the three flow solves converged from the free stream | yes | true | pass |
| the solution of the section, extruded, in the 3-D discretization: residual of the equations of the section, relative to the residual of the free stream | 6.8406e-10 | < 1e-8 | pass |
| drag coefficient per unit span: \|3-D - 2-D\| / \|2-D\| | 5.2271e-09 | < 1e-6 | pass |
| skin friction at x = 0.97008, mean over the span: \|3-D - 2-D\| / \|2-D\| | 3.8640e-09 | < 1e-6 | pass |
| transposed solves reached their tolerance of 1e-10 (section and extrusion) | yes | true | pass |
| adjoint derivative of the drag with respect to the Mach number: \|3-D - 2-D\| / \|2-D\| | 2.4161e-11 | < 1e-6 | pass |
| the spanwise layers repeat each other: largest difference of the state between a layer and the first | 7.6936e-12 | < 1e-8 | pass |
| every layer is symmetric about its mid-plane (spanwise momentum odd, the other variables even): largest defect | 1.0819e-11 | < 1e-8 | pass |
| no net spanwise force: \|cs\| | 3.0839e-19 | < 1e-8 | pass |
| lines of the extrusion: those of the section in each spanwise layer (elements in lines) | 393 | = 3 x 131, in 3 x 18 lines | pass |

Run notes: The 3-D solution is not exactly uniform along the span: its spanwise momentum reaches 6.9e-07 and the in-plane variables differ by up to 7.4e-07 between spanwise nodes (table 'span'). This is a property of the BR2 scheme, not of the extrusion: the viscous flux inside an element is evaluated with the gradient lifted from all its faces, the flux through a face with the local gradient and the lifting of that face alone. Where the in-plane velocity jumps across in-plane faces, the two differ in the normal stress on the spanwise faces, which leaves a residual in the spanwise momentum equation of every element (table 'span': the extruded solution of the section). It changes sign across the mid-plane of the element, which is why the layers repeat each other and there is no net spanwise force; how little the mean over the span is affected is what the comparison with the section shows. With the default penalty of quadrilaterals (4) the section gives cd = 5.753647e-03 and cf = 2.701031e-03 at the station; the extrusion, whose default is 6, differs from these by 0.26 % and 0.16 %. That is a difference between two discretizations on a mesh of 150 elements, not an error of the 3-D implementation, and it is why the comparison is made at equal penalty. The extruded mesh has 54 lines holding 393 of its 450 elements (the longest 12 elements, 3 colours); 72900 unknowns in blocks of 162. An extrusion has only faces whose two sides use the same local axes, and the flow has no spanwise component to speak of: the study does not exercise the face-orientation tables, the two further components of the vorticity in the model or a flow that varies along the span.

Provenance: gyre 0.4.0; revision `39979fcf90` (commit `39979fcf902ad6116eb550b881b4278d4599c8e2`); 2026-11-12T11:33:26-0500; device gpu · NVIDIA GeForce RTX 3060 Ti; quick suite. **Revision check: Same code as this build.** Produced by 39979fcf902ad6116eb550b881b4278d4599c8e2. Every commit between it and the commit this site was built from (ceb1f4b0bed41de53e586df10858079f5a2bcdd8) changes only documentation text, evidence records or bookkeeping: the code is the same. Full record: [rans_extruded_3d.json](../data/verification/rans_extruded_3d.json).

**Table: 2-D section versus 3-D extrusion** (Three-dimensional consistency with the Spalart-Allmaras model)

| quantity | 2-D section, penalty 6 | 3-D extrusion (per unit span) | relative difference | 2-D section, default penalty | relative difference of the extrusion to it |
|---|---|---|---|---|---|
| drag coefficient cd | 0.00576871 | 0.00576871 | 5.2271e-09 | 0.00575365 | 0.00261786 |
| skin friction cf at x = 0.97008 (mean over the span) | 0.00270543 | 0.00270543 | 3.8640e-09 | 0.00270103 | 0.00162879 |
| d cd / d Mach (adjoint) | -0.0499672 | -0.0499672 | 2.4161e-11 | -0.0498736 | 0.00187671 |

Provenance: gyre 0.4.0; revision `39979fcf90` (commit `39979fcf902ad6116eb550b881b4278d4599c8e2`); 2026-11-12T11:33:26-0500; device gpu · NVIDIA GeForce RTX 3060 Ti; quick suite. **Revision check: Same code as this build.** Produced by 39979fcf902ad6116eb550b881b4278d4599c8e2. Every commit between it and the commit this site was built from (ceb1f4b0bed41de53e586df10858079f5a2bcdd8) changes only documentation text, evidence records or bookkeeping: the code is the same. Full record: [rans_extruded_3d.json](../data/verification/rans_extruded_3d.json).

<!-- begin level 2 (Practice) -->
**[L2 Practice] What the extrusion tests**

The flat plate is solved on its two-dimensional section and on a spanwise-periodic
extrusion of that section into hexahedra (`mesh.params.nz`, `span`). Everything the model
adds runs through the three-dimensional code path there: the turbulent fluxes and source
terms, the wall distance, the boundary conditions, the line smoother on a wall-resolved
mesh of hexahedra, the force integration and the discrete adjoint. The drag per unit span,
the skin friction at the reference station and the adjoint derivative of the drag with
respect to the Mach number must be those of the section.

Section and extrusion have the same in-plane equations only at the same BR2 penalty, whose
default is the number of faces of an element: four for quadrilaterals, six for hexahedra.
The comparison is therefore made with the section at penalty six; the last two columns of
the table show the section at its own default, which differs by the amount two
discretizations differ on this coarse mesh.

<!-- end level 2 -->

**Table: The 3-D solution along the span (reported, not checked)** (Three-dimensional consistency with the Spalart-Allmaras model)

| quantity | value |
|---|---|
| residual of the extruded solution of the section: its own equations / free stream | 6.8406e-10 |
| residual of the extruded solution of the section: spanwise momentum / free stream | 2.0127e-08 |
| largest spanwise momentum \|rho w\| of the 3-D solution (free stream: rho u = 1) | 6.9476e-07 |
| largest difference between spanwise nodes, in-plane variables | 7.4299e-07 |
| skin friction at x = 0.97008: largest \|cf / mean - 1\| over the spanwise node lines | 2.4340e-09 |
| 3-D state, mean over the span, against the section (in-plane variables) | 1.6715e-08 |
| 3-D state against the section, node for node (in-plane variables) | 4.9774e-07 |
| side-force coefficient cs | 3.0839e-19 |

Provenance: gyre 0.4.0; revision `39979fcf90` (commit `39979fcf902ad6116eb550b881b4278d4599c8e2`); 2026-11-12T11:33:26-0500; device gpu · NVIDIA GeForce RTX 3060 Ti; quick suite. **Revision check: Same code as this build.** Produced by 39979fcf902ad6116eb550b881b4278d4599c8e2. Every commit between it and the commit this site was built from (ceb1f4b0bed41de53e586df10858079f5a2bcdd8) changes only documentation text, evidence records or bookkeeping: the code is the same. Full record: [rans_extruded_3d.json](../data/verification/rans_extruded_3d.json).

<!-- begin level 3 (Mechanics) -->
**[L3 Mechanics] Why the three-dimensional solution is not exactly uniform along the span**

The solution of the section, extruded, satisfies the in-plane equations of the
three-dimensional discretization as well as the section satisfies its own, which is checked
before the three-dimensional solve and tests the operator without the solver. It does not
satisfy the spanwise momentum equation exactly. In the BR2 scheme the viscous flux inside
an element uses the gradient lifted from all its faces, the flux through a face the local
gradient and the lifting of that face alone; where the in-plane velocity jumps across
in-plane faces, the two differ in the normal stress on the spanwise faces. The converged
three-dimensional solution therefore carries a small spanwise momentum that changes sign
across the mid-plane of every element: the layers repeat each other, every layer is
symmetric about its mid-plane and there is no net spanwise force, which are the three
structural checks of the study. The table reports its size.

<!-- end level 3 -->

**Table: Problem sizes and solver statistics** (Three-dimensional consistency with the Spalart-Allmaras model)

| case | dim | elements | unknowns | BR2 penalty | reference area | Newton steps | Krylov iterations | residual drop | Krylov iterations of the adjoint solve | residual reduction of the adjoint solve |
|---|---|---|---|---|---|---|---|---|---|---|
| 2-D section | 2 | 150 | 6750 | 6 | 1 | 32 | 248 | 7.4716e-10 | 57 | 6.8090e-11 |
| 3-D extrusion | 3 | 450 | 72900 | 6 | 3 | 32 | 249 | 5.3546e-10 | 70 | 8.6562e-11 |
| 2-D section, default penalty | 2 | 150 | 6750 | 4 | 1 | 34 | 267 | 1.5218e-11 | 58 | 6.1890e-11 |

Provenance: gyre 0.4.0; revision `39979fcf90` (commit `39979fcf902ad6116eb550b881b4278d4599c8e2`); 2026-11-12T11:33:26-0500; device gpu · NVIDIA GeForce RTX 3060 Ti; quick suite. **Revision check: Same code as this build.** Produced by 39979fcf902ad6116eb550b881b4278d4599c8e2. Every commit between it and the commit this site was built from (ceb1f4b0bed41de53e586df10858079f5a2bcdd8) changes only documentation text, evidence records or bookkeeping: the code is the same. Full record: [rans_extruded_3d.json](../data/verification/rans_extruded_3d.json).

**Table: Lines of the meshes** (Three-dimensional consistency with the Spalart-Allmaras model)

| case | lines | elements in lines | elements | longest line | colours |
|---|---|---|---|---|---|
| 2-D section | 18 | 131 | 150 | 12 | 3 |
| 3-D extrusion | 54 | 393 | 450 | 12 | 3 |
| 2-D section, default penalty | 18 | 131 | 150 | 12 | 3 |

Provenance: gyre 0.4.0; revision `39979fcf90` (commit `39979fcf902ad6116eb550b881b4278d4599c8e2`); 2026-11-12T11:33:26-0500; device gpu · NVIDIA GeForce RTX 3060 Ti; quick suite. **Revision check: Same code as this build.** Produced by 39979fcf902ad6116eb550b881b4278d4599c8e2. Every commit between it and the commit this site was built from (ceb1f4b0bed41de53e586df10858079f5a2bcdd8) changes only documentation text, evidence records or bookkeeping: the code is the same. Full record: [rans_extruded_3d.json](../data/verification/rans_extruded_3d.json).

<!-- begin level 3 (Mechanics) -->
**[L3 Mechanics] What an extrusion does not cover**

An extrusion has only faces whose two sides use the same local axes, and the flow has
no spanwise component to speak of: the face-orientation tables, the two further components
of the vorticity in the model and a flow that varies along the span are not exercised
here. The orientation tables are covered for laminar flow on the
[sphere](three-dimensional.md); a turbulent flow that is three-dimensional in itself has not
been run.

<!-- end level 3 -->

## Adjoint derivatives

**Verification status: Adjoint gradients with the Spalart-Allmaras model** (study `rans_adjoint`): **PASSED**, 6 of 6 checks passed, 119 s.

Total derivatives of the drag coefficient of the turbulent flat plate (NASA TMR conditions, M = 0.2, Re = 5e6, coarse mesh of 150 elements, p = 1, 3000 unknowns, cd = 6.284664e-03) from one discrete-adjoint solve of the coupled RANS-SA system, against central differences of re-converged solutions. Inputs: Mach number, Reynolds number, angle of the inflow, free-stream nu_tilde / nu, and a wall-normal bump of the plate surface (a shape derivative, which includes the sensitivity of the wall distance).

| Check | Value | Expected | Result |
|---|---|---|---|
| dcd/dmach: adjoint vs central difference (rel.) | 5.4084e-09 | < 1e-5 | pass |
| dcd/dre: adjoint vs central difference (rel.) | 4.0069e-09 | < 1e-5 | pass |
| dcd/dalpha: adjoint vs central difference (rel.) | 6.5461e-11 | < 1e-5 | pass |
| dcd/dchi_inf: adjoint vs central difference (rel., best of 3 steps) | 3.1754e-08 | < 1e-5 | pass |
| dcd/dshape (wall bump, directional): adjoint vs central difference (rel.) | 1.7934e-08 | < 1e-5 | pass |
| adjoint linear solve reached its tolerance (residual reduction) | 9.2074e-11 | < 1e-10 | pass |

Run notes: The mesh is wall resolved, with element aspect ratios of the order of 1000 at the wall. Element-block Jacobi does not see that anisotropy: as the only preconditioner it left the adjoint solve short of its tolerance (see the comment in the study); the piecewise-constant coarse level of the p-multigrid hierarchy is what makes it converge. There is no line-implicit or incomplete-factorisation preconditioner.

Provenance: gyre 0.4.0; revision `39979fcf90` (commit `39979fcf902ad6116eb550b881b4278d4599c8e2`); 2026-11-12T11:43:02-0500; device cpu; quick suite. **Revision check: Same code as this build.** Produced by 39979fcf902ad6116eb550b881b4278d4599c8e2. Every commit between it and the commit this site was built from (ceb1f4b0bed41de53e586df10858079f5a2bcdd8) changes only documentation text, evidence records or bookkeeping: the code is the same. Full record: [rans_adjoint.json](../data/verification/rans_adjoint.json).

**Table: Adjoint and finite-difference derivatives** (Adjoint gradients with the Spalart-Allmaras model)

| derivative | adjoint | central difference | step | relative difference |
|---|---|---|---|---|
| dcd/dmach | -0.0566437 | -0.0566437 | 1.0000e-05 | 5.4084e-09 |
| dcd/dre | -2.4900e-10 | -2.4900e-10 | 50 | 4.0069e-09 |
| dcd/dalpha | -83.2169 | -83.2169 | 1.0000e-05 | 6.5461e-11 |
| dcd/dchi_inf | 7.2791e-06 | 7.2791e-06 | 0.001 | 3.1754e-08 |
| dcd/dshape (wall bump, directional) | 0.00757566 | 0.00757566 | 1.0000e-06 | 1.7934e-08 |

Provenance: gyre 0.4.0; revision `39979fcf90` (commit `39979fcf902ad6116eb550b881b4278d4599c8e2`); 2026-11-12T11:43:02-0500; device cpu; quick suite. **Revision check: Same code as this build.** Produced by 39979fcf902ad6116eb550b881b4278d4599c8e2. Every commit between it and the commit this site was built from (ceb1f4b0bed41de53e586df10858079f5a2bcdd8) changes only documentation text, evidence records or bookkeeping: the code is the same. Full record: [rans_adjoint.json](../data/verification/rans_adjoint.json).

<!-- begin level 2 (Practice) -->
**[L2 Practice] What is differentiated**

Total derivatives of the drag coefficient of the turbulent plate with respect to the flow
parameters, the model data and a displacement of the wall, from one adjoint solve each,
against central differences of flows re-converged to the round-off floor. The shape
derivative includes the change of the wall distance; the finite difference recomputes the
distance for the displaced wall.

<!-- end level 2 -->

**Table: Solver statistics** (Adjoint gradients with the Spalart-Allmaras model)

| quantity | value |
|---|---|
| Newton steps of the baseline solve | 37 |
| Krylov iterations of the baseline solve | 971 |
| Krylov iterations of the adjoint solve | 149 |
| residual reduction of the adjoint solve | 9.2074e-11 |
| multigrid levels (polynomial degrees) | 1, 0 |

Provenance: gyre 0.4.0; revision `39979fcf90` (commit `39979fcf902ad6116eb550b881b4278d4599c8e2`); 2026-11-12T11:43:02-0500; device cpu; quick suite. **Revision check: Same code as this build.** Produced by 39979fcf902ad6116eb550b881b4278d4599c8e2. Every commit between it and the commit this site was built from (ceb1f4b0bed41de53e586df10858079f5a2bcdd8) changes only documentation text, evidence records or bookkeeping: the code is the same. Full record: [rans_adjoint.json](../data/verification/rans_adjoint.json).

<!-- begin level 3 (Mechanics) -->
**[L3 Mechanics] The linear solve on a wall-resolved mesh**

The mesh has element aspect ratios of the order of a thousand at the wall. With element-block
Jacobi as the only preconditioner the adjoint solve of this case stopped short of its
tolerance after 960 Krylov iterations, and since a stalled linear solve is an error and not
a number ([discipline contract](discipline-contract.md)), the study would have ended there.
It runs with two multigrid levels, the solution degree and the piecewise-constant degree
zero; the table shows what the solve then takes. This is a statement about iteration counts
on one small case, not about cost.

<!-- end level 3 -->
