Validation/Code verification
A manufactured solution
The only case here that checks the arithmetic rather than the answer. Pick the solution first, work out what source term it needs, and the error is then known exactly on every mesh.
Why this case
Every other page in this section asks whether a number is close to a reference — a Nusselt number, a Strouhal number, a published table. The method of manufactured solutions asks a different and harder question: is the discretisation the one that was claimed? It answers it with no reference data at all, on any mesh, to as many digits as you care to ask for.
Pick a function. Substitute it into the governing equation. Whatever is left over is a source term. Add that source, and the function you picked is now the exact solution of the modified problem — so the difference between the computed field and that function is the discretisation error, exactly, with nothing else in it. Measure it on systematically refined meshes and the rate at which it falls is the observed order of accuracy. That rate is the verification; the size of the error, on its own, says very little.
| Physics | Steady conduction on the unit square, two-dimensional |
|---|---|
| Solver | laplacianFoam, Gauss linear corrected, corrected snGrad |
| Manufactured solution | T(x, y) = sin(πx) sin(πy), Dirichlet 0 on all four sides |
| Meshes | Four uniform Cartesian, 16 through 128 cells a side, r = 2 exactly |
| Formal order | 2 |
| Agreement | Observed order 2.0021, 2.0005, 2.0001 on the three refinement pairs |
| Last run | 2026-08-27 |
The solution, and why this one
Each factor contributes −π² on being differentiated twice, so the Laplacian is the solution back again with a constant on it — no series, no special functions, nothing to mis-transcribe:
T(x,y) = sin(pi x) sin(pi y) on the unit square
laplacian(T) = -2 pi^2 sin(pi x) sin(pi y) exactly, everywhereIt is zero on all four sides, so the Dirichlet data is exact rather than a quadrature of it. That keeps the boundary out of the measurement and leaves the interior scheme alone under test.
What is actually verified
The source has to reach the solver somehow, and in this bundle it cannot go where it belongs. This changes what the study verifies, and the change is stated here rather than left for a reader to discover.
Result
| Mesh | Cells | h | L2 error | L∞ error |
|---|---|---|---|---|
| 16 × 16 | 256 | 0.0625 | 1.593496 × 10⁻³ | 3.156373 × 10⁻³ |
| 32 × 32 | 1 024 | 0.03125 | 3.978076 × 10⁻⁴ | 7.936996 × 10⁻⁴ |
| 64 × 64 | 4 096 | 0.015625 | 9.941654 × 10⁻⁵ | 1.987133 × 10⁻⁴ |
| 128 × 128 | 16 384 | 0.0078125 | 2.485193 × 10⁻⁵ | 4.969637 × 10⁻⁵ |
| Pair | Refinement ratio | Order on L2 | Order on L∞ |
|---|---|---|---|
| 16 → 32 | 2 | 2.0021 | 1.9916 |
| 32 → 64 | 2 | 2.0005 | 1.9979 |
| 64 → 128 | 2 | 2.0001 | 1.9995 |
Why the order and not the error
This is easy to say and easy not to believe, so the study carries two deliberately broken runs that make it concrete. Both are real runs, kept as failing fixtures for the automated check.
| Mesh | L2 error, degraded | L2 error, healthy | Observed order |
|---|---|---|---|
| 16 × 16 | 2.095089 × 10⁻³ | 1.593496 × 10⁻³ | — |
| 32 × 32 | 8.982054 × 10⁻⁴ | 3.978076 × 10⁻⁴ | 1.2219 |
| 64 × 64 | 5.995160 × 10⁻⁴ | 9.941654 × 10⁻⁵ | 0.5832 |
| 128 × 128 | 5.248768 × 10⁻⁴ | 2.485193 × 10⁻⁵ | 0.1918 |
On the coarsest mesh the degraded run sits within 32 % of the healthy one — no band anybody would write is going to separate those. Its finest error is 5 × 10⁻⁴, which looks entirely respectable for a field of order one. Only the order gives it away, and it gives it away completely: 1.22, 0.58, 0.19, falling towards zero as the mesh refines.
The second broken run writes no source at all. The solution is then identically zero, the error is a flat 0.5 on every mesh, and the observed order is exactly 0. That is what an fvOptions entry which never took effect looks like — and it is what happened in this project when setExprFields was handed an unnamed dictionary entry, warned about it, ignored the whole thing and exited successfully.
What had to be true for the order to mean anything
An observed order is a ratio of two errors, and there are several ways to make that ratio meaningless without making it look wrong. Four things are recorded on every mesh and checked rather than assumed.
- The source really was written. The field
setExprFieldswrote is read back and compared against the analytic function. The worst deviation across the four meshes is 5.68 × 10⁻¹⁴, which is double-precision round-off on a field of order 100. - Iterative error is negligible. The linear solve is tightened to 1 × 10⁻¹⁴ from the 1 × 10⁻⁶ the product writes. The worst achieved residual is 8.20 × 10⁻¹⁵, against a discretisation error of 2.49 × 10⁻⁵ on the finest mesh. An iterative error near that size would not make the answer slightly worse — it would make the observed order a measurement of where each solve happened to stop.
- dt and DT did not move. Both are parameters of the manufactured PDE rather than of the discretisation: dt = 126 651.4795529222 s and DT = 4 × 10⁻⁵ on all four meshes. If either changed between meshes the runs would be solving four different problems and their error ratio would not be an order of accuracy.
- The mesh actually halved. Refinement ratio 2 on every pair, and a largest-to-smallest cell volume ratio of 1.000000000000048 — nothing graded, so r is a number and not an average of one.
The third of those is the mirror image of a trap that has flattened refinement studies in this project before, where a quantity that should have been refined with the mesh was left fixed. Here a quantity that must not move with the mesh is pinned, for the same underlying reason: a refinement study only means something if exactly one thing is changing.
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
- How much of the answer is the meshEvery other page here asks how far the answer is from a reference. This one asks how much of it is the mesh — and puts an uncertainty on a result that has no reference at all.
- DC conduction through a barThe potential in this problem does not depend on the conductivity at all, so a deck that lost it entirely would still give a perfect voltage field. The derived fields are the measurement.
All validation cases · Written by the team building SHD Sim.