Validation/Rotating reference frame
Solid-body rotation in a rotating frame
A closed box of fluid turning with its own frame, against an algebraic identity with no free parameter. The pressure is the measurement; the relative velocity is a cancellation check a solver with no frame in it passes perfectly.
Why this case
The single-rotating-frame family had no reference behind it at all. Rotating-machinery cases are hard to verify because their answers are not closed form — but there is one state in a rotating frame whose answer is arithmetic, and it is the state the frame terms have to get right before anything else they do can be trusted.
Fill a closed box with fluid and spin the whole thing about a fixed axis. Once the fluid turns with the box, it is at rest in the rotating frame, and the pressure holding it there is a closed form with no free parameter in it. There is no table here and no correlation; there is an algebraic identity that the frame terms either satisfy or do not.
| Physics | Incompressible laminar flow in a single rotating reference frame |
|---|---|
| Backend | OpenFOAM, SRFSimpleFoam |
| Domain | A closed box, 40 cells per side, 64 000 cells |
| Walls | noSlip on every face — exact, because every wall is at rest in the frame |
| Rotation | 16.9 rpm about (0, 0, −1) through the origin — read from the staged case |
| Frame rate | ω = 1.76976386 rad/s |
| Outermost cell | 5.5154329 m from the axis; frame speed there 9.7610138 m/s |
| Viscosity | ν = 10 m²/s — raised from the staged 1.51 × 10⁻⁵; see the Ekman section |
| Ekman number | ν/(ωL²) = 0.18575 |
| Reference | The exact rigid-body solution of the rotating-frame momentum equation: zero relative velocity, and a pressure rising as ω²r²/2 — valid at any viscosity, because rigid-body motion has zero strain rate |
| Agreement | Pressure within 0.3641 % rms of ω²r²/2, with a relative velocity 0.051852 % of frame speed against an exact zero |
The exact solution
In a frame rotating at constant ω, the momentum equation acquires a Coriolis term and a centrifugal term. Look for the state in which the fluid is stationary in that frame: Urel = 0 everywhere. Then the convective term vanishes, the Coriolis term −2ω × Urel vanishes with it, and what is left is a balance between the pressure gradient and the centrifugal acceleration alone:
grad(p) = -omega x (omega x r) = omega^2 r_perp
=> p(r) - p(0) = omega^2 r^2 / 2 (kinematic pressure)Two things make this a reference rather than a plausible expectation. First, it is exact for any viscosity: rigid-body motion has zero strain rate everywhere, so the viscous term vanishes identically rather than approximately. Nothing about the answer moves when ν moves. Second, the boundary condition is exact rather than an idealisation — every wall of the box turns with the frame, so it is at rest in the frame, and noSlip on all six faces is the condition the closed form assumes.
So there are two separate exact statements to check, and they have very different strengths.
- The pressure is the measurement with teeth. It is a nonzero field of known shape and known amplitude, and it is the only quantity here that a solver with no rotating frame in it at all cannot fake.
- The relative velocity is a cancellation check. Its continuum value is exactly zero; a run that does nothing whatsoever passes it perfectly. What it measures is not whether the physics is right but how nearly two discretised terms cancel.
Which rotation rate, and why the run is asked rather than the file
The rotation rate used on this page is 16.9 rpm, read out of the constant/SRFProperties the application itself wrote for the staged case, giving ω = 16.9 × 2π/60 = 1.76976386 rad/s about the axis (0, 0, −1) through the origin. The harness refuses to continue if the staged rotation model is not the one it knows how to convert, or if the case turns at 0 rpm — at which every number below would be zero for the trivial reason and both checks would pass on a solver that does nothing.
That is stated explicitly because getting it wrong once already cost an afternoon. On the first attempt the measured pressure came out a factor of 3.17 low and looked exactly like a product defect. It was not: the reference had been built at 30.1 rpm, read out of a different case, while the run was turning at 16.9. A frame rate is a squared quantity in this reference, and (30.1/16.9)² = 3.17.
The fix was not to be more careful with files. The run knows its own ω and can be asked for it: U − Urel is ω × r, so |U − Urel| / r recovers the frame the solver actually used, cell by cell. That recovered value is now compared against the one the case asked for, and it is the first thing checked.
| Quantity | Value |
|---|---|
| Asked for, from the staged case | 1.76976386152 rad/s |
| Recovered from the solution | 1.76976386163 rad/s |
| Relative difference | +6.18 × 10⁻¹¹ |
| Spread across the mesh | 1.41 × 10⁻⁷ rad/s |
Result
A closed box fixes the pressure only up to an additive constant, so the measured and exact fields are compared about their own means. That removes the one degree of freedom the run genuinely has, and nothing else: the amplitude and the shape are still the reference’s.
| Quantity | Measured | As a fraction |
|---|---|---|
| Exact pressure range over the mesh | 47.607375 m²/s² | — |
| Pressure error, rms | 0.17335132 m²/s² | 0.3641 % of the range |
| Pressure error, worst cell | 0.84359339 m²/s² | 1.7720 % of the range |
| Relative velocity, max | 5.061293 × 10⁻³ m/s | 0.051852 % of frame speed |
| Relative velocity, mean | 5.775581 × 10⁻⁴ m/s | 0.0059 % of frame speed |
| Frame speed at the outermost cell | 9.7610138 m/s | — |
The worst pressure cells are the corner ones — furthest from the axis, where the reference is largest, and least well resolved by a Cartesian mesh.
The relative velocity does not go to zero and is not expected to. OpenFOAM balances a cell-centred source term against a face-based pressure gradient, and the two do not cancel cell by cell. What is left is a spurious current, and the way to tell a discretisation residue from a defect is to refine and watch:
| Mesh | Max relative velocity, % of frame speed | Observed order |
|---|---|---|
| 20³ | 0.2134 % | — |
| 30³ | 0.0930 % | 2.05 |
| 40³ | 0.0519 % | 2.03 |
Why the viscosity is raised, and why that is not tuning
The case the application stages is air, ν = 1.51 × 10⁻⁵ m²/s, which puts the Ekman number ν/(ωL²) at 2.80 × 10⁻⁷. Solid-body rotation is still an exact solution there — the reference does not depend on ν at all — but it is not a stable one. The discrete imbalance above seeds a disturbance that inertia amplifies with nothing to damp it.
That run is kept, and it is a measured run rather than an expectation.
| Quantity | ν = 10 m²/s | ν = 1.51 × 10⁻⁵ m²/s |
|---|---|---|
| Ekman number | 0.185749 | 2.8048 × 10⁻⁷ |
| Relative velocity, max | 0.051852 % of frame speed | 86.930 % of frame speed |
| Pressure error, rms | 0.3641 % of the range | 17.373 % of the range |
| Pressure error, worst cell | 1.7720 % | 50.576 % |
| Run | converged at iteration 55 | never met residualControl in 3 000 |
Raised to ν = 10 the case is viscous-dominated and the spurious velocity becomes a linear response to a fixed forcing rather than the amplitude of an instability. That claim is checked rather than asserted: on the 20³ mesh the spurious velocity is 2.15 % of frame speed at ν = 1 and 0.213 % at ν = 10 — a ratio of 10.09 against a viscosity ratio of 10.
Neither exact statement moves when ν moves, because the strain rate is zero either way. So raising it changes which regime the case sits in and not what the right answer is, and a minimum Ekman number is asserted so that a future run cannot quietly drift back into the regime where the numbers stop meaning what they say.
The two fixtures that show what would otherwise pass
Two failure modes here would look healthy in the numbers a reader is drawn to, and both are kept as measured runs.
What this page does not establish
- This is not a rotor. There are no blades, no rotating wall relative to the fluid, no multiple reference frames and no interface between a rotating and a stationary zone. It is a closed box, which is what makes the reference exact and which is also what makes it a long way from a turbomachine.
- The case is not run at the viscosity it ships with. At the staged air viscosity the numbers above become 86.9 % and 17.4 %, and the run does not converge. That is a statement about the stability of solid-body rotation at Ekman 10⁻⁷, not about the frame terms — but it does mean this page verifies the frame terms in a regime the product’s own default does not sit in.
- One rotation rate, one axis, one origin. 16.9 rpm about (0, 0, −1) through (0, 0, 0). An axis-dependent error would not necessarily show at a single orientation, and an origin offset error would not show at all with the origin on the axis.
- Steady, laminar and incompressible. No turbulence model is exercised and no unsteady behaviour is measured. The exact solution is the steady state.
- The mesh refinement study covers the velocity residue only. The second-order behaviour under refinement is measured on the spurious relative velocity. No corresponding refinement study of the pressure error is reported here, so the 0.3641 % is a single-mesh number.
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
- Lid-driven cavityThe oldest benchmark in incompressible CFD, run on a deliberately coarse mesh — because one that only agrees when it is expensive is not much of a reassurance.
- Flow over a circular cylinderThe only case with no steady state: the answer is a frequency, not a field. It found that a more symmetric mesh needs a LONGER run, not a shorter one.
- 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.
All validation cases · Written by the team building SHD Sim.