Translated from the author's Korean original. Read the original (한국어)
Two Functions Added, and a Cylinder Appeared — Complex Potential and d'Alembert's Paradox
Shoulder pressure coefficient reaches −3 with zero circulation, and the drag integral still cancels by symmetry.
Two functions, added, and the circle closes. Drop a doublet on the uniform stream and is a streamline, though nobody sketched a circle. That circle is the wall. With circulation at zero, a trip around the surface pressure leaves no drag inside the formula.
Push U and m separately and the radius grows or shrinks. Pull Γ off zero and the upper and lower streamlines split.
W(z) = Uz + m/z + iΓ/(2π)·ln(z). When Γ=0 the picture is symmetric — d'Alembert's zero drag. Slide Γ to break the symmetry and lift appears (Kutta–Joukowski).
Turn stream and equipotential on together and the two families meet at right angles. With Γ at zero the circle in the middle is one streamline.
Why streamlines and equipotentials cross at right angles#
In two dimensions, incompressible, inviscid, and irrotational flow carries two scalars at once. The velocity potential and the stream function .
Here are the and velocities. An equipotential has slope . A streamline has slope . The product is . Wherever they meet, they meet at a right angle.
The right angle is not a drawing habit. Real and imaginary parts of a holomorphic function sit that way. One condition, that the derivative not depend on the direction of approach, ties and into a pair.
Complex velocity potential — the bridge Cauchy and Riemann built#
Write with . Complex differentiability demands the same value from every direction. Matching the real-axis limit to the imaginary-axis limit gives the next two lines.
Those are the Cauchy–Riemann equations. They are the velocity definitions from the section above. Pack and as real and imaginary parts and is holomorphic. That is the complex velocity potential.
The derivative is a velocity. From ,
is the complex velocity. It holds the conjugate of the actual velocity vector.
One line — draws a cylinder#
A uniform stream is . Split it and , . Equipotentials are vertical. Streamlines are horizontal. A doublet is , the limit of a source and a sink squeezed to zero separation. In polar form, and .
Add the two.
The stream function in polar coordinates is
is the length fixed by the ratio of doublet strength to free-stream speed. The contour is either , the -axis, or . The whole circle of radius is one streamline.
Under the inviscid assumption a streamline can stand in for a solid wall, and the outer flow does not change. Treat as the cylinder surface. Uniform stream plus doublet, two terms, is the inviscid solution for a cylinder in a uniform stream.
Add a circulation, and lift appears#
Speed on the circle is the same above and below. Bernoulli makes the pressure the same too. Net force is zero. That is why drag disappears in the next section. Breaking the symmetry takes circulation, the integral of tangential speed once around the surface. A point vortex has potential .
The top speeds up. The bottom slows down. Pressure drops on top and rises underneath. Lift shows up. The per-span statement is the same line as the calculation that bends a ball's path. Kutta wrote it in 1902, Joukowski in 1906, separately. Pull Γ off zero on the figure above and that asymmetry is the one on screen.
Superposition — every inviscid flow is an addition#
Laplace's equation for , , is linear. The sum of two solutions is a solution. Half of nineteenth-century inviscid theory is that addition.
Four blocks. Uniform is . Source and sink are . A vortex is . A doublet is . Place them and a half-body, a Rankine oval, and a lifting cylinder come out. The mode names are Cylinder, Rankine half-body, Rankine oval, and Lifting cylinder. The figure right after the printed numbers runs those four on one grid.
d'Alembert's paradox — what zero drag taught us#
Integrate surface pressure from and the drag is zero. d'Alembert derived that in 1752. Drag a stick through water and the hand feels a force. Inviscid, irrotational, incompressible assumptions do not grow that force inside the formula.
Closing the gap took a century and a half. In 1904 Prandtl pulled out the boundary layer. Viscosity is small and still not zero. In a thin layer by the wall the flow leaves the surface, and wake vortices break the fore–aft pressure symmetry. That difference is the drag.
Zero is not a bad sum. It is the answer for a fluid with the viscosity removed. The mismatch with the hand is what opened the door toward the boundary layer.
Sixty lines of NumPy — tracing #
import numpy as np
import matplotlib.pyplot as plt
def cylinder_potential(z, U=1.0, m=1.0, gamma=0.0):
"""Return (phi, psi) for W = Uz + m/z - i*gamma/(2π)*ln(z)."""
safe_z = np.where(np.abs(z) < 1e-9, 1e-9 + 0j, z)
W = U * safe_z + m / safe_z - 1j * gamma / (2 * np.pi) * np.log(safe_z)
return W.real, W.imag # (phi, psi)
def velocity_from_W(z, U=1.0, m=1.0, gamma=0.0):
"""dW/dz = u - iv. Take the conjugate to recover (u, v)."""
safe_z = np.where(np.abs(z) < 1e-9, 1e-9 + 0j, z)
dW = U - m / safe_z**2 - 1j * gamma / (2 * np.pi * safe_z)
return dW.real, -dW.imag
def cylinder_surface_pressure(theta, U=1.0, R=1.0, gamma=0.0):
"""Bernoulli surface pressure coefficient on the cylinder (with Γ)."""
u_t = -2 * U * np.sin(theta) - gamma / (2 * np.pi * R)
return 1 - (u_t / U) ** 2 # cp = 1 - (V/U)^2
def integrate_drag_lift(U=1.0, R=1.0, gamma=0.0, N=1024):
"""Inviscid surface-pressure integral → (drag, lift) / (rho U^2 R)."""
theta = np.linspace(0, 2 * np.pi, N, endpoint=False)
cp = cylinder_surface_pressure(theta, U, R, gamma)
drag = -np.trapz(cp * np.cos(theta), theta)
lift = -np.trapz(cp * np.sin(theta), theta)
return drag, lift
if __name__ == "__main__":
U, m, gamma = 1.0, 1.0, 0.0
R = np.sqrt(m / U)
drag0, lift0 = integrate_drag_lift(U, R, gamma=0)
drag1, lift1 = integrate_drag_lift(U, R, gamma=-3.0)
print(f"Γ=0 : drag = {drag0:+.4e}, lift = {lift0:+.4e}") # both ~ 0
print(f"Γ=-3.0 : drag = {drag1:+.4e}, lift = {lift1:+.4e}") # lift = -ρUΓ
x = np.linspace(-3, 3, 400)
y = np.linspace(-2, 2, 240)
X, Y = np.meshgrid(x, y)
Z = X + 1j * Y
Z_out = np.where(np.abs(Z) < R, np.nan, Z)
_, psi = cylinder_potential(Z_out, U, m, gamma=-3.0)
fig, ax = plt.subplots(figsize=(7, 4))
ax.contour(X, Y, psi, levels=24, linewidths=0.7)
ax.add_patch(plt.Circle((0, 0), R, color="white", ec="k"))
ax.set_aspect("equal"); plt.show()Run it and two lines print.
Γ=0 : drag = +1.7e-15, lift = -3.5e-16
Γ=-3.0 : drag = -2.0e-14, lift = +3.000e+00Switch the mode from Rankine half-body to Lifting cylinder and the nose-shaped stagnation point disappears while the upper and lower speeds split.
Each preset is a sum of elementary flows. The same machinery — superposition of ψ — builds half-bodies, ovals, and lifting cylinders.
Rankine oval is the closed curve between a source and a sink. Cylinder is the same circle as above.
The radius in the code is a square root. It is the square root of doublet strength over free-stream speed. Leave the defaults and both are 1, so the radius is 1. Hold the speed at 1 and raise the strength to 4, and the radius becomes 2. Flip that, speed 4 and strength 1, and the radius is 0.5. The handle that grows the circle is the strength. Raising the speed shrinks the same strength into a smaller circle.
Set the circulation to 0 and the tangential speed on the surface is twice the free stream times the sine of the angle. The sign keeps the minus written in front of that term. The pressure coefficient is 1 minus the square of that speed ratio. Stagnation sits at angle 0 and at . The sine is 0, so the coefficient is 1. The shoulders are and . The sine squared is 1, so the coefficient falls to . Top and bottom carry the same number. The cosine-weighted drag and the sine-weighted lift both settle at 0.
Set the circulation to , with radius and free stream equal to 1, and the constant added to the tangential speed is 3 divided by . About 0.477. On the upper shoulder the tangential speed is plus 0.477, which is . The pressure coefficient is about . On the lower shoulder the tangential speed is 2 plus 0.477, which is 2.477. The pressure coefficient is about . The slow side sits at a higher pressure. The fast side is dug out further.
Divide the lift by density, speed squared, and radius, and the result is the absolute circulation divided by speed and radius, which is 3. That matches the printed lift . The code comment writes that number as density times speed times circulation, with a minus in front. Density and speed are 1 and the circulation is , so the product is 3. The drag entries and are roundoff from a trapezoid sum over 1024 angles. No drag term is left inside the formula.
Integrating surface pressure with no circulation leaves only roundoff in the drag#
With circulation at zero the pressure coefficient swings between 1 at stagnation and at the shoulder. The swing is large. The cosine-weighted drag still stops at . Top and bottom cancel in pairs. Adding surface pressure alone, with no circulation put in, leaves only roundoff in the drag column.
This solution has no Reynolds number. There is a length and a speed , and the viscosity has been set to zero. How long that omission stays free is the open question. Whether the circle can keep standing as a streamline while holds at the shoulder is worth asking again at the boundary where the Reynolds number splits one flow from another.
Related
Share if you found it helpful.