Turbulent flat plate
In one minuteA 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.
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.
- converged from the free streamyesexpected truepass
- cf at x = 0.97 against the TMR reference (relative difference)0.001656expected < 0.02pass
- first solution node off the wall, y+4.594expected < 10pass
- logarithmic layer, 40 <= y+ <= 200: largest relative difference of u+ to ln(y+) / 0.41 + 5.00.0026expected < 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 profile194.4expected > 50 (the layer is turbulent)pass
gyre 0.4.0 · 39979fcf90 · · cpu · quick suite · record (JSON)Same code as this build
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 per unit length, on 150 elements of degree 2 whose first row is high. One line of the case switches the model on:
flow:
mach: 0.2
reynolds: 5.0e6
turbulence: sa
| 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 |
gyre 0.4.0 · 39979fcf90 · · cpu · quick suite · record (JSON)Same code as this build
Data table
| 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 |
gyre 0.4.0 · 39979fcf90 · · cpu · quick suite · record (JSON)Same code as this build
- 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 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 undershoots below zero in a few nodes, which is what the negative branch of the model is for.
u_tau from the computed skin friction; first node at y+ = 4.59.
Data table
| 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 |
gyre 0.4.0 · 39979fcf90 · · cpu · quick suite · record (JSON)Same code as this build
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.
Data table
| 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 |
gyre 0.4.0 · 39979fcf90 · · cpu · quick suite · record (JSON)Same code as this build
The model is integrated to the wall, so the first element must reach into the viscous sublayer: the table gives 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:
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
The turbulence model is part of the differentiated residual, and so is the wall distance:
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.
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).
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). 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:
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.