---
title: Turbulent flat plate
summary: A Reynolds-averaged case with the Spalart–Allmaras model — the zero-pressure-gradient flat plate at a Reynolds number of five million — showing how a turbulent case is specified, what its boundary layer looks like in wall units, and that its drag can be differentiated like any other output.
section: examples
order: 4
level: 1
study: example_flat_plate
keywords: [turbulence, RANS, Spalart-Allmaras, flat plate, law of the wall, skin friction, example]
---
<!-- gyre docs: expanded Markdown of examples/turbulent-flat-plate.md (generated tables, verification numbers and chart data are written out). Base level of this page: L1 Essentials; passages at another level are bracketed by 'begin level N' / 'end level N' comments and start with [LN Name]. Built from revision ceb1f4b0be. -->

**Verification status: Example: turbulent flat plate (Spalart-Allmaras)** (study `example_flat_plate`): **PASSED**, 5 of 5 checks passed, 119.9 s.

The preset flat_plate_sa: zero-pressure-gradient flat plate at M = 0.2 and Re = 5e6 per unit length with the negative Spalart-Allmaras model, 150 elements of degree 2 (6750 unknowns), solved from the uniform free stream. Skin friction along the plate against the NASA Turbulence Modeling Resource reference (CFL3D and FUN3D, 545 x 385 grid), and the boundary-layer profile at x = 0.97 in wall units with the eddy viscosity across the layer.

| Check | Value | Expected | Result |
|---|---|---|---|
| converged from the free stream | yes | true | pass |
| cf at x = 0.97 against the TMR reference (relative difference) | 0.00165649 | < 0.02 | pass |
| first solution node off the wall, y+ | 4.59367 | < 10 | pass |
| logarithmic layer, 40 <= y+ <= 200: largest relative difference of u+ to ln(y+) / 0.41 + 5.0 | 0.00259964 | < 0.08 (a bound observed with margin on this mesh, not a property of the model) | pass |
| eddy viscosity over molecular viscosity, largest value on the profile | 194.403 | > 50 (the layer is turbulent) | pass |

Provenance: gyre 0.4.0; revision `39979fcf90` (commit `39979fcf902ad6116eb550b881b4278d4599c8e2`); 2026-11-12T11:48:33-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: [example_flat_plate.json](../data/verification/example_flat_plate.json).

```bash
gyre run flat_plate_sa -o runs/plate
```

The preset is the flat plate of the NASA Turbulence Modeling Resource at Mach 0.2 and
$\mathit{Re} = 5\times10^6$ per unit length, on 150 elements of degree 2 whose first row is
$5\times10^{-5}$ high. One line of the case switches the model on:

```yaml
flow:
  mach: 0.2
  reynolds: 5.0e6
  turbulence: sa
```

**Table: Outputs** (Example: turbulent flat plate (Spalart-Allmaras))

| cd (one side, reference length 1) | cf at x = 0.97 | difference to TMR [%] | y+ of the first node | largest mu_t / mu | smallest nu_tilde / nu | largest u+ difference in the log layer [%] | largest u+ / y+ - 1 for y+ <= 3 [%] | Newton steps | DOF |
|---|---|---|---|---|---|---|---|---|---|
| 0.00575365 | 0.00270103 | -0.165649 | 4.59367 | 194.403 | 0.00109241 | 0.259964 | — | 34 | 6750 |

Provenance: gyre 0.4.0; revision `39979fcf90` (commit `39979fcf902ad6116eb550b881b4278d4599c8e2`); 2026-11-12T11:48:33-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: [example_flat_plate.json](../data/verification/example_flat_plate.json).

**Chart: Skin friction along the plate** (Example: turbulent flat plate (Spalart-Allmaras)). Line chart of cf against x; 2 series. The table holds the plotted data.

| series | x | cf |
|---|---|---|
| Gyre, p = 2 | 0.02 | 0.00452362 |
| Gyre, p = 2 | 0.02 | 0.00457282 |
| Gyre, p = 2 | 0.033471 | 0.00429405 |
| Gyre, p = 2 | 0.0469419 | 0.00410478 |
| Gyre, p = 2 | 0.0469419 | 0.00410667 |
| Gyre, p = 2 | 0.0650886 | 0.00385725 |
| Gyre, p = 2 | 0.0832353 | 0.00367193 |
| Gyre, p = 2 | 0.0832353 | 0.0036691 |
| Gyre, p = 2 | 0.107681 | 0.00359358 |
| Gyre, p = 2 | 0.132126 | 0.00352584 |
| Gyre, p = 2 | 0.132126 | 0.00352445 |
| Gyre, p = 2 | 0.165056 | 0.00347637 |
| Gyre, p = 2 | 0.197987 | 0.00339196 |
| Gyre, p = 2 | 0.197987 | 0.00339568 |
| Gyre, p = 2 | 0.242347 | 0.00327457 |
| Gyre, p = 2 | 0.286707 | 0.0031657 |
| Gyre, p = 2 | 0.286707 | 0.0031628 |
| Gyre, p = 2 | 0.346465 | 0.00309734 |
| Gyre, p = 2 | 0.406222 | 0.00303715 |
| Gyre, p = 2 | 0.406222 | 0.00303692 |
| Gyre, p = 2 | 0.486722 | 0.00299737 |
| Gyre, p = 2 | 0.567221 | 0.00294754 |
| Gyre, p = 2 | 0.567221 | 0.00294702 |
| Gyre, p = 2 | 0.675661 | 0.00288963 |
| Gyre, p = 2 | 0.784101 | 0.00280593 |
| Gyre, p = 2 | 0.784101 | 0.0028098 |
| Gyre, p = 2 | 0.930181 | 0.00272065 |
| Gyre, p = 2 | 1.07626 | 0.00265873 |
| Gyre, p = 2 | 1.07626 | 0.00265545 |
| Gyre, p = 2 | 1.27304 | 0.00261528 |
| Gyre, p = 2 | 1.46983 | 0.00257447 |
| Gyre, p = 2 | 1.46983 | 0.00257404 |
| Gyre, p = 2 | 1.73491 | 0.00254306 |
| Gyre, p = 2 | 2 | 0.00250226 |
| TMR reference (CFL3D / FUN3D mean) | 0.100573 | 0.00379009 |
| TMR reference (CFL3D / FUN3D mean) | 0.199971 | 0.0034172 |
| TMR reference (CFL3D / FUN3D mean) | 0.299841 | 0.00321396 |
| TMR reference (CFL3D / FUN3D mean) | 0.50151 | 0.00297659 |
| TMR reference (CFL3D / FUN3D mean) | 0.747281 | 0.00280835 |
| TMR reference (CFL3D / FUN3D mean) | 0.970084 | 0.00270551 |
| TMR reference (CFL3D / FUN3D mean) | 1.24823 | 0.0026112 |
| TMR reference (CFL3D / FUN3D mean) | 1.49524 | 0.00254669 |
| TMR reference (CFL3D / FUN3D mean) | 1.75299 | 0.00249222 |
| TMR reference (CFL3D / FUN3D mean) | 1.90334 | 0.0024652 |

Provenance: gyre 0.4.0; revision `39979fcf90` (commit `39979fcf902ad6116eb550b881b4278d4599c8e2`); 2026-11-12T11:48:33-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: [example_flat_plate.json](../data/verification/example_flat_plate.json).

<!-- begin level 2 (Practice) -->
**[L2 Practice] What to look for**

* **Skin friction.** Downstream of the leading-edge region the curve follows the reference
  of the resource, computed with the same model on a grid of 545 × 385 points.
* **Law of the wall.** In wall units the velocity profile leaves the sublayer line
  $u^+ = y^+$ at the first nodes and follows the logarithmic law with the model's von Kármán
  constant of 0.41 further out. Where two elements meet, the chart shows both nodal values:
  the small jumps between them are the discontinuous approximation, not an error of the plot.
* **Eddy viscosity.** It is zero at the wall, several hundred times the molecular viscosity
  in the outer layer, and returns to the small free-stream value outside the boundary
  layer. At that edge $\tilde\nu$ undershoots below zero in a few nodes, which is what the
  negative branch of the model is for.

<!-- end level 2 -->

**Chart: Velocity profile at x = 0.97 in wall units** (Example: turbulent flat plate (Spalart-Allmaras)). Line chart of u+ against y+, x axis log; 3 series. The table holds the plotted data. u_tau from the computed skin friction; first node at y+ = 4.59.

| series | y+ | u+ |
|---|---|---|
| Gyre, p = 2 (solution nodes) | 4.59367 | 4.65382 |
| Gyre, p = 2 (solution nodes) | 9.18734 | 8.53631 |
| Gyre, p = 2 (solution nodes) | 9.18734 | 8.81174 |
| Gyre, p = 2 (solution nodes) | 22.3499 | 12.2512 |
| Gyre, p = 2 (solution nodes) | 35.5125 | 13.5829 |
| Gyre, p = 2 (solution nodes) | 35.5125 | 13.7032 |
| Gyre, p = 2 (solution nodes) | 73.2281 | 15.4443 |
| Gyre, p = 2 (solution nodes) | 110.944 | 16.4426 |
| Gyre, p = 2 (solution nodes) | 110.944 | 16.4885 |
| Gyre, p = 2 (solution nodes) | 219.013 | 18.2004 |
| Gyre, p = 2 (solution nodes) | 327.082 | 19.2646 |
| Gyre, p = 2 (solution nodes) | 327.082 | 19.3034 |
| Gyre, p = 2 (solution nodes) | 636.74 | 21.3076 |
| Gyre, p = 2 (solution nodes) | 946.398 | 22.6731 |
| Gyre, p = 2 (solution nodes) | 946.398 | 22.6859 |
| Gyre, p = 2 (solution nodes) | 1833.68 | 25.6229 |
| Gyre, p = 2 (solution nodes) | 2720.97 | 26.9992 |
| Gyre, p = 2 (solution nodes) | 2720.97 | 27.1728 |
| Gyre, p = 2 (solution nodes) | 5263.37 | 27.1772 |
| u+ = y+ | 0.316228 | 0.316228 |
| u+ = y+ | 0.398107 | 0.398107 |
| u+ = y+ | 0.501187 | 0.501187 |
| u+ = y+ | 0.630957 | 0.630957 |
| u+ = y+ | 0.794328 | 0.794328 |
| u+ = y+ | 1 | 1 |
| u+ = y+ | 1.25893 | 1.25893 |
| u+ = y+ | 1.58489 | 1.58489 |
| u+ = y+ | 1.99526 | 1.99526 |
| u+ = y+ | 2.51189 | 2.51189 |
| u+ = y+ | 3.16228 | 3.16228 |
| u+ = y+ | 3.98107 | 3.98107 |
| u+ = y+ | 5.01187 | 5.01187 |
| u+ = y+ | 6.30957 | 6.30957 |
| u+ = y+ | 7.94328 | 7.94328 |
| u+ = y+ | 10 | 10 |
| u+ = ln(y+) / 0.41 + 5.0 | 12.5893 | 11.1777 |
| u+ = ln(y+) / 0.41 + 5.0 | 15.8489 | 11.7393 |
| u+ = ln(y+) / 0.41 + 5.0 | 19.9526 | 12.3009 |
| u+ = ln(y+) / 0.41 + 5.0 | 25.1189 | 12.8625 |
| u+ = ln(y+) / 0.41 + 5.0 | 31.6228 | 13.4241 |
| u+ = ln(y+) / 0.41 + 5.0 | 39.8107 | 13.9857 |
| u+ = ln(y+) / 0.41 + 5.0 | 50.1187 | 14.5473 |
| u+ = ln(y+) / 0.41 + 5.0 | 63.0957 | 15.1089 |
| u+ = ln(y+) / 0.41 + 5.0 | 79.4328 | 15.6705 |
| u+ = ln(y+) / 0.41 + 5.0 | 100 | 16.2321 |
| u+ = ln(y+) / 0.41 + 5.0 | 125.893 | 16.7937 |
| u+ = ln(y+) / 0.41 + 5.0 | 158.489 | 17.3553 |
| u+ = ln(y+) / 0.41 + 5.0 | 199.526 | 17.9169 |
| u+ = ln(y+) / 0.41 + 5.0 | 251.189 | 18.4785 |
| u+ = ln(y+) / 0.41 + 5.0 | 316.228 | 19.0402 |
| u+ = ln(y+) / 0.41 + 5.0 | 398.107 | 19.6018 |
| u+ = ln(y+) / 0.41 + 5.0 | 501.187 | 20.1634 |
| u+ = ln(y+) / 0.41 + 5.0 | 630.957 | 20.725 |
| u+ = ln(y+) / 0.41 + 5.0 | 794.328 | 21.2866 |
| u+ = ln(y+) / 0.41 + 5.0 | 1000 | 21.8482 |
| u+ = ln(y+) / 0.41 + 5.0 | 1258.93 | 22.4098 |
| u+ = ln(y+) / 0.41 + 5.0 | 1584.89 | 22.9714 |
| u+ = ln(y+) / 0.41 + 5.0 | 1995.26 | 23.533 |
| u+ = ln(y+) / 0.41 + 5.0 | 2511.89 | 24.0946 |

Provenance: gyre 0.4.0; revision `39979fcf90` (commit `39979fcf902ad6116eb550b881b4278d4599c8e2`); 2026-11-12T11:48:33-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: [example_flat_plate.json](../data/verification/example_flat_plate.json).

**Chart: Eddy viscosity across the layer at x = 0.97** (Example: turbulent flat plate (Spalart-Allmaras)). Line chart of mu_t / mu against y+, x axis log; 2 series. The table holds the plotted data. nu_tilde / nu below zero at the edge of the layer is the undershoot the negative branch of the model handles; there the eddy viscosity is zero.

| y+ | mu_t / mu | nu_tilde / nu |
|---|---|---|
| 4.59367 | 0.0263411 | 1.7589 |
| 9.18734 | 0.279485 | 3.23478 |
| 9.18734 | 0.223767 | 3.04908 |
| 22.3499 | 6.01193 | 8.98167 |
| 35.5125 | 12.0375 | 13.7095 |
| 35.5125 | 12.3688 | 13.9867 |
| 73.2281 | 28.8914 | 29.3024 |
| 110.944 | 42.4966 | 42.6921 |
| 110.944 | 42.6742 | 42.8681 |
| 219.013 | 79.7334 | 79.7896 |
| 327.082 | 108.366 | 108.396 |
| 327.082 | 108.72 | 108.75 |
| 636.74 | 167.243 | 167.255 |
| 946.398 | 191.678 | 191.687 |
| 946.398 | 194.403 | 194.413 |
| 1833.68 | 168.421 | 168.434 |
| 2720.97 | 66.478 | 66.5586 |
| 2720.97 | 18.4645 | 19.3734 |
| 5263.37 | 0.222825 | 3.04568 |

Provenance: gyre 0.4.0; revision `39979fcf90` (commit `39979fcf902ad6116eb550b881b4278d4599c8e2`); 2026-11-12T11:48:33-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: [example_flat_plate.json](../data/verification/example_flat_plate.json).

<!-- begin level 2 (Practice) -->
**[L2 Practice] Resolution**

The model is integrated to the wall, so the first element must reach into the viscous
sublayer: the table gives $y^+$ of the first solution node off the wall. With a high-order
element the requirement is on the nodes inside the element, not on the element height, which
is why 10 elements across the layer are enough here. To refine:

```bash
gyre run flat_plate_sa --set mesh.params.nx=20 --set mesh.params.ny=12 --set mesh.params.h_wall=3e-5
gyre run flat_plate_sa --set discretization.order=3
```

<!-- end level 2 -->

<!-- begin level 2 (Practice) -->
**[L2 Practice] Derivatives**

The turbulence model is part of the differentiated residual, and so is the wall distance:

```bash
gyre run flat_plate_sa --gradients --of cd --wrt mach,re,chi_inf
```

returns the total derivatives of the drag from one adjoint solve. They are verified against
finite differences, including a displacement of the wall, under
[Turbulence closure](../verification/turbulence.md#adjoint-derivatives).

<!-- end level 2 -->

<!-- begin level 3 (Mechanics) -->
**[L3 Mechanics] Solver settings of the preset**

Turbulent cases start from a uniform free stream with a small pseudo-time step and a
moderate growth (`cfl0: 1`, `cfl_growth: 3`), and they keep the piecewise-constant multigrid
level (`levels: [2, 1, 0]`): on a wall-resolved mesh the linear solves need it
([why](../theory/turbulence-model.md#solver)).

The line smoother (`solver.smoother: line`) cuts the Krylov iterations of linear solves
to a tight tolerance to less than half on this mesh; the flow solve from the free stream
does not get faster with it, and a single run with one adjoint solve is not where it pays
([measured](../verification/solvers.md#line-smoothing-on-a-wall-resolved-mesh)). It is meant
for a case that is kept, in a session or a design loop, for many derivative evaluations at
one flow state after another:

```yaml
solver:
  levels: [2, 1, 0]
  smoother: line
  precond_lag: 2      # assemble the blocks every second step of a flow solve
```

`gyre run` prints, under the line of the case, how many lines the smoother found on the
mesh, and `gyre mesh info` reports the same for a mesh file before anything is run.

<!-- end level 3 -->
