Skip to content
SHD Sim
Menu

Validation/Scalar transport

Advected scalar front

The width is the measurement, not the position. Numerical diffusion is indistinguishable from physical diffusion in the answer, and the fixture that proves it is a real afternoon spent chasing a diffusivity that never reached the solve.

VerificationFront within 0.862 % of the exact position, width within 0.914 %

Why this case

A step in a scalar, carried along by a uniform flow while it spreads, has an exact answer. Two numbers come out of it and they fail independently: where the front is, which is advection, and how wide it is, which is diffusion.

The width is why this case exists. Numerical diffusion is indistinguishable from physical diffusion in the answer, so a scheme that smears reports a larger diffusivity than the case was given — with the front in exactly the right place. A check on position alone passes a solver that has quietly changed the physics, and the section below shows that exact failure measured rather than imagined.

PhysicsOne-dimensional advection–diffusion of a step, laminar
SolverscalarTransportFoam; Euler in time, Gauss limitedLinear01 1 on the divergence
Domain1.0 m long, 4 × 4 cells across, with the step at x₀ = 0.3 m
FlowUniform U = 2 m/s; diffusivity D = 0.06 m²/s
Compared att = 0.1 s, so the front centre has reached 0.5 m
Meshes40, 80 and 160 cells along the flow; time steps 8, 4 and 2 × 10⁻⁴ s
ReferenceThe erfc closed form for a step advected and diffusing in one dimension
AgreementFront 0.862 % from the exact position and 0.914 % from the exact width on the finest mesh

The exact solution

A scalar initially 1 for x < x₀ and 0 beyond it, carried at a uniform speed U through a medium of diffusivity D, is

    c(x, t) = 0.5 erfc( (x - x0 - U t) / (2 sqrt(D t)) )

on an infinite domain. The front translates at U and spreads as √(Dt), and there is nothing to transcribe from a paper and nothing that can be mis-transcribed. The two measurements are read off the profile the same way, by linear interpolation between the cells that straddle a level: the position is the c = 0.5 crossing, and the width is the distance between the c = 0.75 and c = 0.25 crossings. At t = 0.1 s those are 0.5 m exactly and 0.14777330 m.

The domain is finite and the reference is not, so the gap is measured rather than waved away. At t = 0.1 s the exact solution differs from 1 at the inlet and from 0 at the outlet by 2.505 × 10⁻⁶ — three decades below the agreements this page reports, so it contributes nothing to them. The run refuses to be judged if that number ever grows.

Result

Mesh refinement at a fixed time step of 10⁻⁴ s
CellsCourantFront (m)vs exact 0.5Width (m)vs exact 0.147773L1L∞
400.0080.4961988−0.760 %0.1480803+0.208 %2.826 × 10⁻³1.401 × 10⁻²
800.0160.4970152−0.597 %0.1470993−0.456 %2.508 × 10⁻³1.110 × 10⁻²
1600.0320.4956901−0.862 %0.1464228−0.914 %4.109 × 10⁻³1.617 × 10⁻²
Positions and widths are from the fixture; the per-cent columns are those numbers against the closed form above. The norms are over the whole profile. The 160-cell row is the one the case is judged on.
Time-step refinement on the 160-cell mesh
Time step (s)CourantFront (m)vs exactWidth (m)vs exactL1
8 × 10⁻⁴0.2560.4774457−4.511 %0.1405640−4.879 %2.185 × 10⁻²
4 × 10⁻⁴0.1280.4899376−2.012 %0.1448675−1.966 %9.605 × 10⁻³
2 × 10⁻⁴0.0640.4919144−1.617 %0.1452042−1.739 %7.800 × 10⁻³
Each study is run where the other error is small, which is why the mesh study above holds the time step at 10⁻⁴ s. Observed order in the L1 norm between these three: 1.186 and then 0.300.

The direction is the part that matters more than either number. Halving the time step moves the front closer to the exact position every time — 4.511 % to 2.012 % to 1.617 % — and the harness refuses the run if it ever does not, because a time integration that degrades under refinement is broken in a way no band on a single run would catch.

Why the width is the measurement

This is not a hypothetical failure mode. It is what this benchmark measured for an afternoon, and it is kept as a fixture.

The same case with the diffusivity in the wrong place, on the same finest mesh
QuantityExactMeasuredDifference
Front position (m)0.50.4958508−0.830 % — inside every band
Front width (m)0.14777330.0445448−69.86 % — out by a factor of three
L1 over the profile6.123 × 10⁻²15 times the healthy run’s
From the fixture recording the failure. On the judged mesh its front position is nearer the exact answer than the healthy run’s −0.862 %, and every front error it produces is inside the 3 % band, so no check on position would have caught it.

The cause is worth stating because it is a trap the case shape sets rather than a mistake anyone could see coming. A scalar case carries its diffusivity in two places: DT in constant/transportProperties, which scalarTransportFoam reads for its own transport equation, and D inside the scalar-transport function object the product writes into the control dictionary. The function object runs after the solver each step and writes its own answer over the solver’s. So for a case whose solver already transports the scalar, the field on disk is the function object’s and DT is inert.

Both are written from the same setting, so in the product’s own hands they agree and the answer is right. Edit one of them by hand — which is what a harness naturally does — and the run silently uses the other. That fixture is a DT of 0.06 against a function object still at the default 10⁻⁵, and everything else about the run looks healthy. The diffusivity is now set through the product, and both copies are asserted to carry it before anything is measured.

What this page does not establish

  • One scheme pairing, not a survey. Everything here is Euler in time and Gauss limitedLinear01 1 on the divergence, which is what the product writes. limitedLinear01 is a limited — and therefore nonlinear — scheme, and a formal order is not expected from it in the first place. No other divergence scheme was run.
  • The velocity field is imposed, not solved. The flow is a uniform 2 m/s everywhere, so nothing here says anything about scalar transport through a velocity field the solver had to compute. What is exercised is the divergence term and the Laplacian beside it.
  • The problem is one-dimensional, and the mesh is not. The domain is 4 cells across in each transverse direction with nothing to drive a variation, and the largest spread across a transverse row is 3.97 × 10⁻⁵ on the judged run. That is reported as a check that the case really is one-dimensional, not as a result about three-dimensional transport.
  • A turbulence model would add a second diffusivity. The case is asked for as laminar through the product’s own setting, because the default eddy viscosity would put a diffusivity into the problem that the closed form knows nothing about. Nothing here is a statement about turbulent scalar transport.

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.

All validation cases · Written by the team building SHD Sim.