Skip to content
cfd-lab:~/en/posts/2026-05-07-circulation-l…● online

Translated from the author's Korean original. Read the original (한국어)

NOTE #034DAY THU 유체역학DATE 2026.05.07UPDATED 2026.10.19READ 6 min read#Fluid-Dynamics#Lift#Magnus#Kutta-Joukowski#Circulation#Potential-Flow

Why a Spinning Ball Curves — Circulation, Magnus, and the Kutta–Joukowski Theorem

The lift formula keeps circulation and erases shape, but viscosity is what sets that circulation.

The day a spinning shell refused to fly straight#

Berlin, 1853. Heinrich Magnus took a question gunners already knew and put it in a wind tunnel. A spinning shell does not fly straight. It slides sideways. A cylinder with its axis upright produced a steady side force perpendicular to that axis.

In an inviscid fluid the surface slips. The top is still faster than the bottom. The quantity that makes the difference is the circulation Γ\Gamma.

Raise the Γ\Gamma slider from zero and the yellow stagnation point moves down; past 4πU∞R4\pi U_\infty R that point leaves the surface.

Streamlines from uniform flow U∞ + doublet (cylinder) + point vortex Γ. Top flow accelerates, bottom decelerates: by Bernoulli, low pressure on top → upward force L′ = ρU∞Γ. Yellow dots are stagnation points; when |Γ| > 4πU∞R they merge and detach below the cylinder (red dot).

The critical spin is the moment the stagnation point sits on the bottom. Above it, the streamline wraps the cylinder once and does not drop away underneath.

The same circulation can sit on a wing. Inviscid theory cannot start that process by itself. The starting vortex closes it later.

Circulation — one closed-curve integral#

Circulation Γ\Gamma is one line.

Γ=∮Cu⋅ds\Gamma = \oint_{C} \mathbf{u}\cdot d\mathbf{s}

Tangential speed, once around a closed curve CC. u\mathbf{u} is velocity, dsd\mathbf{s} the tangent element.

Stokes moves it to a surface integral.

Γ=∬Sω⋅dA\Gamma = \iint_{S} \boldsymbol{\omega}\cdot d\mathbf{A}

ω=∇×u\boldsymbol{\omega}=\nabla\times\mathbf{u} is vorticity, dAd\mathbf{A} the normal area element inside the loop. Circulation is the vorticity trapped there.

A loop can hold no vorticity at any interior point and still have nonzero circulation. A large loop around a point vortex does that. The units differ too. Vorticity is [1/s]. Circulation is [m²/s], vorticity times area.

Why a rotating cylinder is pulled upward#

In inviscid, irrotational, incompressible flow the clean steady solution is a stack of elementary ones. Uniform flow plus a doublet is a cylinder at rest. A point vortex at the center makes it spin.

As one complex potential,

W(z)=U∞z+U∞R2z+iΓ2πln⁡zW(z) = U_\infty z + \frac{U_\infty R^2}{z} + \frac{i\Gamma}{2\pi}\ln z

Uniform flow, doublet, point vortex. Positive Γ\Gamma is clockwise. On r=Rr=R the tangential speed is

uθ(R,θ)=−2U∞sin⁡θ−Γ2πRu_\theta(R, \theta) = -2 U_\infty \sin\theta - \frac{\Gamma}{2\pi R}

At the top, θ=π/2\theta=\pi/2, the two terms share a sign and ∣uθ∣|u_\theta| grows. At the bottom, θ=−π/2\theta=-\pi/2, they cancel. Faster flow on top means lower pressure, by Bernoulli

p+12ρu2=constp + \tfrac{1}{2}\rho u^2 = \text{const}

Integrate the pressure difference around the cylinder and an upward force remains.

Stagnation is uθ=0u_\theta=0, so sin⁡θ=−Γ/(4πU∞R)\sin\theta=-\Gamma/(4\pi U_\infty R). At the critical circulation Γ=4πU∞R\Gamma=4\pi U_\infty R, sin⁡θ=−1\sin\theta=-1, and the only root is θ=−π/2\theta=-\pi/2, the bottom. That is where the yellow point in the figure collects.

The Kutta–Joukowski theorem — L′ = ρU∞Γ#

The surface-pressure integral comes out short. In steady inviscid flow the drag is zero, and lift per unit span is

L′=ρU∞ΓL' = \rho U_\infty \Gamma

Lanchester stated it as a conjecture in 1894. Early in the next century Kutta and Joukowski proved it separately.

Shape drops out of the formula. Any 2D section with the same circulation around it gets the same lift. Lift scales with circulation, not with spin rate. A wing that does not spin still grows a circulation if the section and the angle of attack allow it, and that circulation is the lift.

Zero drag is the same place as the cylinder with no circulation. A complex potential built from uniform flow plus a doublet leaves that zero drag as d'Alembert's paradox. The W(z)W(z) here is that potential plus one point-vortex term.

The starting vortex, and the silent role of viscosity#

A contradiction remains. A fluid at rest has no vorticity, so every closed loop has zero circulation. Kelvin's theorem — circulation on a material curve stays constant in inviscid flow with conservative body forces — says that zero holds.

How does an airplane get lift?

Viscosity. The instant a wing accelerates, inviscid theory wants infinite speed at the sharp trailing edge. A real fluid strips that kinetic energy at once, and a vortex leaves the edge. Counterclockwise. The starting vortex.

Kelvin still wants the total circulation on a large loop around wing and wake to be zero. So an equal clockwise circulation stays on the wing. The bound vortex. The Γ\Gamma in Kutta–Joukowski.

Turn on start motion and a counterclockwise vortex leaves the trailing edge; raise the angle of attack and that vortex and the wing's clockwise circulation grow by the same amount.

Press start motion: a counterclockwise starting vortex sheds from the trailing edge while an equal-magnitude clockwise bound circulation grows around the wing. Their sum is zero (Kelvin's circulation theorem). The bound circulation is what produces lift L′ = ρU∞Γ_bound. t=0.00 s, Γ_bound=0.00, Γ_shed=0.00.

The two circulations still sum to zero. Inviscid theory is rereading the state after viscosity has already shed once.

Code: surface speed and lift coefficient#

The same surface speed, in NumPy. Stream function, surface pressure coefficient, lift coefficient.

import numpy as np
 
def cylinder_streamfunction(x, y, U_inf, gamma, R):
    """Stream function: ψ = U sinθ (r - R²/r) + Γ/(2π) ln(r/R), Γ>0 = clockwise."""
    r = np.hypot(x, y)
    theta = np.arctan2(y, x)
    safe = np.maximum(r, 1e-9)
    psi_uniform = U_inf * np.sin(theta) * (safe - R ** 2 / safe)
    psi_vortex = (gamma / (2 * np.pi)) * np.log(safe / R)
    return psi_uniform + psi_vortex
 
def surface_pressure_coeff(theta, U_inf, gamma, R):
    """Surface (r = R) pressure coefficient Cp = 1 - (u/U∞)^2."""
    u_theta = -2 * U_inf * np.sin(theta) - gamma / (2 * np.pi * R)
    return 1.0 - (u_theta / U_inf) ** 2
 
def magnus_lift_coefficient(gamma, U_inf, R):
    """L' = ρU∞Γ → C_L = 2Γ/(U∞·d) with diameter d = 2R."""
    return gamma / (U_inf * R)
 
# A quick three-shot run (ρ = 1 implied)
U_inf, R = 10.0, 0.5
for gamma in [0.0, np.pi * U_inf * R, 4 * np.pi * U_inf * R]:
    theta = np.linspace(-np.pi, np.pi, 360)
    cp = surface_pressure_coeff(theta, U_inf, gamma, R)
    L_per_span = U_inf * gamma
    cl = magnus_lift_coefficient(gamma, U_inf, R)
    print(f"Γ={gamma:6.2f}  C_L={cl:5.2f}"
          f"  Cp_top={cp[270]:+.2f}  Cp_bot={cp[90]:+.2f}"
          f"  L'/ρ={L_per_span:6.2f}")

At Γ=0\Gamma=0 the lift is zero and the pressure coefficient is symmetric top to bottom. The loop uses three circulations: 00, πU∞R\pi U_\infty R, 4πU∞R4\pi U_\infty R. With U∞=10U_\infty=10 and R=0.5R=0.5, the surface formula at θ=±π/2\theta=\pm\pi/2 closes on numbers.

Γ/(2πR)\Gamma/(2\pi R) is 00, then U∞/2=5U_\infty/2=5, then 2U∞=202U_\infty=20. Top speed is −20-20, −25-25, −40-40. Bottom speed is 2020, 1515, 00. With Cp=1−(u/U∞)2C_p=1-(u/U_\infty)^2 the top values are −3-3, −5.25-5.25, −15-15 and the bottom values are −3-3, −1.25-1.25, 11. The last bottom entry, speed 0 and Cp=1C_p=1, is the stagnation point on the floor.

CL=Γ/(U∞R)C_L=\Gamma/(U_\infty R) is 00, π\pi, 4π4\pi. The comment's 2Γ/(U∞d)2\Gamma/(U_\infty d) is the same relation because d=2Rd=2R. L′/ρ=U∞ΓL'/\rho=U_\infty\Gamma is 00, 50π50\pi, 200π200\pi. These are the analytic values at θ=±π/2\theta=\pm\pi/2. The code samples 360 angles, so the printed index can sit one bin off that angle. No table was built from that print.

A force guessed from the two CpC_p values alone overshoots the integrated lift. At critical circulation the bottom CpC_p is 1 and the top is −15-15, a gap of 16. Times the dynamic pressure 12ρU∞2\tfrac{1}{2}\rho U_\infty^2, that gap is a pressure difference of 8ρU∞28\rho U_\infty^2. Spread over the diameter 2R2R, the force per unit span would be 16ρU∞2R16\rho U_\infty^2 R. The theorem gives L′=ρU∞ΓL'=\rho U_\infty\Gamma, and with Γ=4πU∞R\Gamma=4\pi U_\infty R that is L′=4πρU∞2RL'=4\pi\rho U_\infty^2 R. The two-point guess is 4/π4/\pi times the integral, about 1.27. Pressure keeps moving between those extremes all the way around the cylinder. One stagnation CpC_p does not close the lift. The middle value Γ=πU∞R\Gamma=\pi U_\infty R gives the same ratio. There the top CpC_p is −5.25-5.25 and the bottom is −1.25-1.25, a gap of 4. The two-point guess is 4ρU∞2R4\rho U_\infty^2 R and the theorem's lift is πρU∞2R\pi\rho U_\infty^2 R, so the ratio is 4/π4/\pi again. Sampling only the top and the bottom overstates the force by a factor that does not depend on how large the circulation is.

Once the seam sets circulation, the lift formula stops being a design equation#

The cylinder is the same in all three cases. Only Γ\Gamma changes, and CLC_L runs from 0 to 4π4\pi. Kutta–Joukowski erases the shape and keeps the circulation. How that circulation is produced sits outside the formula.

A baseball seam sets separation, and separation sets circulation. If that is where the theorem stops being a design equation, which way does a real ball curve? Lift on a spinning ball opens that question again on the surface of the ball.

Share if you found it helpful.