Skip to content
cfd-lab:~/en/posts/2026-09-03-bernoulli-con…online
NOTE #149DAY THU 유체역학DATE 2026.09.03READ 7 min read#Crocco-Theorem#Bernoulli#Vorticity#Total-Pressure#Historical

Where Total Pressure Dropped 1,080 Pa, Dissipation Was Zero — When the Bernoulli Constant Crosses Streamlines

Total pressure changing across streamlines is vorticity, not loss. Loss exists only when total pressure changes along a streamline.

In 1738 a father backdated his son's book by six years#

Daniel Bernoulli published Hydrodynamica in 1738. On the title page he described himself as "son of Johann," a gesture meant to patch things up with his father. Johann answered by publishing nearly the same material separately as Hydraulica, leaning on his printer to stamp the year 1732 on it. Six years ahead of his son, on paper.

A century and a half later Horace Lamb supplied the theorem. Integrate the Euler equations and Bernoulli's result falls out. The two books the father and son fought over were two faces of one expression. But that "integrate" carries a condition attached, and that condition is exactly what makes total-pressure contours get misread in CFD post-processing.

This post measures the condition with a single Rankine vortex. The answer first: inside the rotating core the total pressure drops 1,080 Pa, and viscous dissipation is exactly zero. Outside, where the total pressure is perfectly flat, dissipation is not zero. The two come out backwards.

Move the probe in and out of the core yourself in the simulation below.

u = 0.00 m/sp = 0.0 Pap0 = 0.0 Pad(p0)/dr = 0.0rho u omega = 0.0phi = 0.0000 W/m^3
Drag probe r across the dashed core edge. Inside the core the two right-hand numbers stay equal and nonzero, so p0 climbs with r while the red element rotates without changing shape. Outside, both go to zero — p0 is perfectly flat — yet the purple element keeps shearing, which is where a viscous fluid would actually lose energy.

Drag probe r and watch where the green p0p_0 curve on the right goes flat. At the same time watch the square on the left of the canvas, and see when it holds its shape and when it skews. The place where those two observations disagree is the subject of this post.

Integrating the Euler equations gives Bernoulli — in which direction?#

For steady inviscid flow at constant density with no body force, the momentum equation reads like this.

(u)u=1ρp(\mathbf{u}\cdot\nabla)\mathbf{u} = -\frac{1}{\rho}\nabla p

u\mathbf{u} is velocity, pp is pressure, ρ\rho is density. Apply a vector identity to the left side.

(u)u= ⁣(u22)u×ω(\mathbf{u}\cdot\nabla)\mathbf{u} = \nabla\!\left(\frac{|\mathbf{u}|^2}{2}\right) - \mathbf{u}\times\boldsymbol{\omega}

ω=×u\boldsymbol{\omega} = \nabla\times\mathbf{u} is the vorticity. Combine the two and collect the total pressure p0=p+12ρu2p_0 = p + \tfrac{1}{2}\rho|\mathbf{u}|^2, and one line is left.

p0=ρu×ω\nabla p_0 = \rho\,\mathbf{u}\times\boldsymbol{\omega}

This is the Crocco form of the Euler equation (incompressible, isentropic). When the right side is nonzero, total pressure varies in space. Which direction it varies in is the point.

u×ω\mathbf{u}\times\boldsymbol{\omega} is perpendicular to u\mathbf{u}. So dotting both sides with u\mathbf{u} makes the right side vanish.

up0=0\mathbf{u}\cdot\nabla p_0 = 0

Follow a streamline and p0p_0 is always constant. Vorticity or no vorticity, it makes no difference. That is the exact scope of Bernoulli's theorem. For p0p_0 to be the same everywhere, on the other hand, you need u×ω=0\mathbf{u}\times\boldsymbol{\omega} = 0, which in practice means irrotational flow. The difference between the two feuding books was never here. The condition sat in the footnote Lamb added.

The Rankine vortex: a core that spins, an exterior that does not#

The Rankine vortex is the example where this condition switches on and off inside one flow. Inside radius aa the fluid turns like a solid body, and outside it is a free vortex.

uθ(r)={Ωr,r<aΩa2/r,raωz(r)={2Ω,r<a0,rau_\theta(r) = \begin{cases} \Omega r, & r < a \\ \Omega a^2 / r, & r \ge a \end{cases} \qquad \omega_z(r) = \begin{cases} 2\Omega, & r < a \\ 0, & r \ge a \end{cases}

Ω\Omega is the angular velocity of the core, uθu_\theta the circumferential velocity. Pressure comes from integrating the radial momentum balance dp/dr=ρuθ2/r\mathrm{d}p/\mathrm{d}r = \rho u_\theta^2 / r. Outside, the amount the pressure falls and the amount the dynamic pressure rises cancel exactly, pinning p0p_0 at pp_\infty. Inside the core nothing cancels.

p0(r)p=ρΩ2(r2a2),r<ap_0(r) - p_\infty = \rho\Omega^2 (r^2 - a^2), \qquad r < a

At r=0r = 0 the deficit is ρΩ2a2\rho\Omega^2 a^2, that is, the square of the core-edge speed times ρ\rho. With ρ=1.2\rho = 1.2, Ω=60s1\Omega = 60\,\mathrm{s^{-1}} and a=0.5ma = 0.5\,\mathrm{m}, umax=30u_{\max} = 30 m/s and the deficit is 1,080 Pa.

Measuring both sides at the same radius in Python#

Take p0\nabla p_0 by central difference and match it against ρuθωz\rho\,u_\theta\omega_z. The dissipation function ϕ=μ(2Srθ)2\phi = \mu(2S_{r\theta})^2 goes on the same ruler.

import math
 
RHO, MU = 1.2, 1.8e-5      # kg/m^3, Pa*s
OMEGA, A = 60.0, 0.5       # 1/s, m   -> u_max = 30 m/s
P_INF = 101325.0           # Pa
 
def rankine_velocity(r):
    return OMEGA * r if r < A else OMEGA * A * A / r
 
def rankine_spin(r):
    return 2.0 * OMEGA if r < A else 0.0
 
def rankine_pressure(r):
    if r >= A:
        return P_INF - 0.5 * RHO * (OMEGA * A * A / r) ** 2
    return P_INF - RHO * OMEGA**2 * A**2 + 0.5 * RHO * OMEGA**2 * r**2
 
def total_head(r):
    return rankine_pressure(r) + 0.5 * RHO * rankine_velocity(r) ** 2
 
def shear_dissipation(r):
    s = 0.0 if r < A else -OMEGA * A * A / r**2   # 2*S_rtheta
    return MU * s * s
 
def crocco_residual(r, h=1e-6):
    lhs = (total_head(r + h) - total_head(r - h)) / (2 * h)   # d(p0)/dr
    rhs = RHO * rankine_velocity(r) * rankine_spin(r)         # rho*(u x omega)_r
    return lhs, rhs
 
print("  r[m]   u[m/s]   p[Pa]      p0[Pa]     dp0/dr    rho*u*w    phi[W/m^3]")
for r in (0.10, 0.25, 0.40, 0.60, 1.00):
    lhs, rhs = crocco_residual(r)
    print("%6.2f %8.2f %10.1f %10.1f %9.1f %10.1f %11.4f"
          % (r, rankine_velocity(r), rankine_pressure(r), total_head(r),
             lhs, rhs, shear_dissipation(r)))
 
def bernoulli_gap(r1, r2):
    return total_head(r2) - total_head(r1)
 
print()
print("core  p0(0.00) - p0(%.2f) = %8.1f Pa" % (A, total_head(0.0) - total_head(A)))
print("outer p0(%.2f) - p0(1.00) = %8.1f Pa" % (A, total_head(A) - total_head(1.0)))
print("cross-streamline gap r=0.10 -> 0.40 : %8.1f Pa" % bernoulli_gap(0.10, 0.40))
print("along-streamline  gap r=0.40 -> 0.40 : %8.1f Pa" % bernoulli_gap(0.40, 0.40))
print("dissipation at r=0.25 (core)  : %.4f W/m^3" % shear_dissipation(0.25))
print("dissipation at r=0.60 (outer) : %.4f W/m^3" % shear_dissipation(0.60))
  r[m]   u[m/s]   p[Pa]      p0[Pa]     dp0/dr    rho*u*w    phi[W/m^3]
  0.10     6.00   100266.6   100288.2     864.0      864.0      0.0000
  0.25    15.00   100380.0   100515.0    2160.0     2160.0      0.0000
  0.40    24.00   100590.6   100936.2    3456.0     3456.0      0.0000
  0.60    25.00   100950.0   101325.0       0.0        0.0      0.0313
  1.00    15.00   101190.0   101325.0       0.0        0.0      0.0040
 
core  p0(0.00) - p0(0.50) =  -1080.0 Pa
outer p0(0.50) - p0(1.00) =      0.0 Pa
cross-streamline gap r=0.10 -> 0.40 :    648.0 Pa
along-streamline  gap r=0.40 -> 0.40 :      0.0 Pa
dissipation at r=0.25 (core)  : 0.0000 W/m^3
dissipation at r=0.60 (outer) : 0.0313 W/m^3

Columns four and five agree at every radius. The Crocco relation holds down to the decimal. And inside the core the total-pressure difference between r=0.10r = 0.10 and r=0.40r = 0.40 is 648 Pa. Between two angles at the same radius it is zero. Bernoulli applied along a streamline is right; applied across one it misses 648 Pa.

Dissipation was nonzero where the total pressure was flat#

The last column is flipped. Dissipation is zero inside the core, where the total pressure drops 1,080 Pa, and nonzero outside, where the total pressure is exactly flat.

The reason is that dissipation is attached to strain, not to rotation. Solid-body rotation only turns a fluid element; it does not distort it. The strain-rate tensor is zero, so ϕ=0\phi = 0. The free vortex is the opposite. Its vorticity is zero, but uθ1/ru_\theta \propto 1/r means the inner and outer edges sweep past at different speeds. The element is sheared without pause.

The square in the simulation above shows this directly. Inside the core (red) the square keeps its shape as it turns, and outside (purple) it collapses into a parallelogram. What is conserved in a rotating frame and what is not came up in Coriolis force and rothalpy, and the axis is the same here. Spinning and doing work are entered in different ledgers.

Five flows on one table#

Vorticity and dissipation are independent. All four combinations are real.

Flowω\boldsymbol{\omega}p0p_0 along a streamlinep0p_0 across streamlinesViscous dissipation
Uniform flow0constantconstant0
Free vortex (r>ar > a)0constantconstant> 0
Rankine core (r<ar < a)2Ω2\Omegaconstantvaries by 1,080 Pa0
Shear inflow, inviscid0\ne 0constantvaries0
Viscous wake0\ne 0dropsvaries> 0

What matters is that only one cell in the table is bold. The one thing that can be called a loss is p0p_0 decreasing along a streamline. In the other four rows, the spatial variation of p0p_0 is entirely the geometry of the vorticity field, not energy that went missing.

When total-pressure contours look alike for two different reasons#

In practice this distinction breaks at the total-pressure contour on the outlet plane. Feed in an atmospheric boundary layer or a developed pipe profile as the inlet condition and p0p_0 varies in yy from the first cell onward. Loss is still zero. The total-pressure deficit a wake creates draws the same contour. That one is real loss.

Run the two channels below side by side on the same color scale.

A spread 0 PaA loss 0 PaB spread 0 PaB loss 0 Pa
Press match outlet spread — the two outlet profiles now cover the same range of p0, so a contour plot of the outlet cannot tell them apart. The dots can: in A every parcel keeps the color it entered with, in B the parcels that pass the body change color on the way out. Only a color change along a streamline is a loss.

Press match outlet spread and the outlet p0p_0 ranges of the two channels become equal. Which means the outlet contour alone can no longer tell them apart. Watch instead whether a particle's color changes while it travels. Particles in the top channel keep their color, and only in the bottom channel do they change color as they pass the body.

So when you compute a loss coefficient with a section-averaged p0p_0 as the reference, a shear inflow returns a nonzero value even though there is no loss. The reference has to be that streamline's inlet p0p_0. Even with a mass-flow-weighted average, inlet and outlet have to be averaged the same way for the difference to be loss alone.

One more thing shows up numerically. On a coarse grid, p0p_0 goes artificially flat in rotational regions. When numerical diffusion smears the vorticity, the right side of p0=ρu×ω\nabla p_0 = \rho\,\mathbf{u}\times\boldsymbol{\omega} shrinks, and the core deficit comes out shallower than it really is. On a grid that cuts through a vortex core, the depth of the total-pressure deficit works as an indicator of vorticity resolution. Just as a diameter error rode into the flow rate at the fourth power in the pipe validation, the error here also enters through a quantity that is hard to notice.

d'Alembert ran into the same place in 1752#

Johann never came around to Newton's theory of viscosity, and neither did his son Daniel nor his student Euler. Solve the flow around a body with inviscid theory alone and the drag comes out zero. That is why the field panicked when d'Alembert published this in 1752. The problem d'Alembert hit with the wave equation in the same period shares one root with it. How wide a class of solutions do you let the equation admit?

Restated in the language we use today, it reads like this. In irrotational inviscid flow p0p_0 is a single constant over the whole domain, so the pressure fore and aft of the body is symmetric and the integral comes to zero. To produce drag, p0p_0 has to fall along a streamline somewhere. What makes that place is viscosity and the vorticity it produces at the wall.

So the question to ask when a total-pressure contour is open in front of you is not "how far did it drop." It is "did it drop along a streamline, or across one?" The first is loss, the second is vorticity.

Share if you found it helpful.