Validation/Free-surface flow
Standing gravity wave
Three wavelengths in one tank, from deep water to shallow, against the dispersion relation — plus two quiet failures that are both the product’s own defaults.
Why this case
The potential free-surface solver had no reference behind it at all. This case gives it one, and as with the dam break and the shock tube the reference is arithmetic rather than a transcribed table, so there is nothing to mis-copy: a standing wave of wavelength L in still water of depth h oscillates at ω² = g k tanh(k h), with k = 2π/L.
It is not an idealisation of what this solver solves — it is the closed-form solution of it. The solver does not track a moving interface. The mesh top stays flat and the free surface enters as a boundary condition there, integrating dζ/dt = U·n over the patch and setting the pressure to −g·ζ. Those two are the linearised kinematic and dynamic free-surface conditions the dispersion relation comes from.
Three wavelengths are run in the same depth of water, so that what is tested is the dispersion relation and not one frequency three times. The phase speed spans 1.7638 m/s to 3.1193 m/s across them, from deep water to shallow.
| Physics | Incompressible, laminar, linearised free surface — potentialFreeSurfaceFoam |
|---|---|
| Tank | Two-dimensional, half a wavelength long, 1 m deep, one cell thick, slip walls |
| Wavelengths | L = 2, 8 and 40 m — k h = 3.14, 0.79 and 0.16 |
| Meshes | 20 × 20, 40 × 40 and 80 × 80, with the time step halved alongside |
| Release | ζ = a cos(k x) from rest, run for four periods at a fixed step |
| Amplitudes | 0.01, 0.003125 and 0.000125 m — steepness k a below 3.15 × 10⁻² |
| Fluid | g = 9.81 m/s², ν = 1.51 × 10⁻⁵ m²/s as the product writes it |
| Reference | The linear dispersion relation for surface gravity waves, across deep to shallow water |
| Agreement | Frequency within 0.042 %, 0.011 % and 0.014 % on the finest mesh at the three wavelengths |
| Last run | 2026-08-28 |
The exact solution, derived rather than quoted
The harness builds the relation instead of asserting it. Take the velocity potential of a standing wave over a flat bed,
phi = cosh(k(y + h)) cos(k x) cos(omega t)
and check numerically, by finite differences, that it does the three things it must:
harmonic d2phi/dx2 + d2phi/dy2 = 0 residual 1.10e-07
bed dphi/dy = 0 at y = -h residual 0
surface d2phi/dt2 + g dphi/dy = 0 at y = 0 residual 8.82e-09
which closes only if omega^2 = g k tanh(k h)Both limits are then confirmed against their own series rather than against a round number. The deep-water limit is exactly √(g/k). The shallow-water limit approaches √(g h) at 1.6666661 × 10⁻⁷ against the 1.6666667 × 10⁻⁷ its own (k h)²/6 expansion demands — agreement to 0.0000317 %.
| L | k h | Regime | ω (rad/s) | Period (s) | c (m/s) |
|---|---|---|---|---|---|
| 2 m | 3.1416 | Deep — 0.19 % from √(g/k) | 5.5411310 | 1.133917 | 1.763797 |
| 8 m | 0.7854 | Neither | 2.2478290 | 2.795224 | 2.862025 |
| 40 m | 0.1571 | Shallow — 0.41 % from √(g h) | 0.4899800 | 12.823342 | 3.119312 |
How the frequency is measured
The surface is released from rest as ζ = a cos(k x) and then left entirely alone. At every write, the patch values are projected onto cos(k x) using each face’s own x coordinate, read from the mesh, so that no assumption about face ordering can put the comparison against a shifted mode. That gives a modal amplitude, which is fitted to a damped cosine by least squares over the whole record.
The fit is the headline. The zero crossings of the same signal are carried alongside as a cross-check that shares none of the fitting machinery — only the samples. The two periods agree to between 0.00003 % and 0.00094 % on every run, and every healthy run has the eight crossings four periods should produce.
How much of the surface is still the mode that was released is measured too, summed over the record. The worst figure anywhere in the nine runs is 0.9999956.
Result
| L | Mesh | ω measured (rad/s) | ω reference (rad/s) | Difference |
|---|---|---|---|---|
| 2 m | 20 × 20 | 5.5069538 | 5.5411310 | −0.6168 % |
| 2 m | 40 × 40 | 5.5324064 | 5.5411310 | −0.1575 % |
| 2 m | 80 × 80 | 5.5388003 | 5.5411310 | −0.0421 % |
| 8 m | 20 × 20 | 2.2427424 | 2.2478290 | −0.2263 % |
| 8 m | 40 × 40 | 2.2467667 | 2.2478290 | −0.0472 % |
| 8 m | 80 × 80 | 2.2475780 | 2.2478290 | −0.0112 % |
| 40 m | 20 × 20 | 0.4888929 | 0.4899800 | −0.2219 % |
| 40 m | 40 × 40 | 0.4897538 | 0.4899800 | −0.0462 % |
| 40 m | 80 × 80 | 0.4899143 | 0.4899800 | −0.0135 % |
Nine runs landing within a per cent of a closed form would be a plausible coincidence of mesh and scheme. An error that falls at close to the second order the schemes claim, over a factor of four in both the mesh and the time step, is not.
| L | 20 → 40 | 40 → 80 |
|---|---|---|
| 2 m | 1.97 | 1.90 |
| 8 m | 2.26 | 2.08 |
| 40 m | 2.26 | 1.78 |
The damping is discretisation, and is reported as such
The wave loses amplitude as it runs, and it is worth being precise about where that goes. The molecular viscosity the product writes damps this wave at 2νk², which accounts for 0.034 % of the amplitude per period at L = 2 m and 0.0010 % at L = 40 m. The measured loss is far larger than that, and it halves with each refinement while the viscous figure does not move at all.
| L | 20 × 20 | 40 × 40 | 80 × 80 | Viscous, 80 × 80 |
|---|---|---|---|---|
| 2 m | 4.026 % | 2.111 % | 1.152 % | 0.0338 % |
| 8 m | 4.150 % | 1.997 % | 0.988 % | 0.0052 % |
| 40 m | 4.240 % | 2.023 % | 0.999 % | 0.0010 % |
Two failures, and both are the product’s own defaults
Neither fixture below was manufactured. Each is the same nine runs with one thing left exactly as the application writes it, rather than as the benchmark needs it.
What this page does not establish
- The tank is two-dimensional and one cell thick. There is no third direction, no side-wall boundary layer and no cross-mode.
- The free surface never leaves the mesh top. This solver does not track an interface, which is exactly why the linear relation is its exact solution — and equally why nothing here establishes anything about a solver that does.
- Four periods is the whole record. The damping is measured over that window, and no claim is made about long-time behaviour beyond it.
- The case that ships is not the case that was run. The geometry, the boundary types, the time-step control, the turbulence setting and the class of one field all had to be changed for the closed form to apply. The discretisation was not touched — the schemes and the linear solvers are the product’s own — but a user staging this solver from the application does not get the case measured here.
Repeat this yourself
Every case here is set up from the worked examples in the product, with no hand-editing of solver files — so you can run it, and get the same numbers. The free tier runs real cases up to 250,000 cells of fluids, or 100,000 nodes of solid, with no account needed to download and no time limit.
Other cases
- A tank of water that should not moveA closed tank of water under gravity, which should stay exactly still — the standard test of whether pressure and gravity are discretised consistently.
- A dam breakAn idealised dam break has a closed form, so there is nothing to argue about — including the depth at the dam itself, which is exactly four ninths of the reservoir, whatever the reservoir is.
- A pressure wave crossing a tubeA wave that stays smooth, so the answer is exact for as long as it does. It is also the case that showed refining the mesh alone can hide a first-order time scheme completely.
All validation cases · Written by the team building SHD Sim.