Skip to content
cfd-lab:~/en/posts/2026-07-21-water-wave-di…● online

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

NOTE #108DAY TUE 유체역학DATE 2026.07.21UPDATED 2026.10.19READ 5 min read#Water-Waves#Dispersion#Group-Velocity#Capillary-Wave#Flow-Phenomena

A Single Ripple Outruns Its Own Group — Wave Dispersion and Group Velocity

Energy follows the envelope, not the crest. Once the depth drops below the wavelength, crests and the group share a single speed.

Toss a pebble into a still pond. Ripples spread out in a growing ring. Everyone knows that much.

Look closely at the ring, though, and something is off. Each little ripple is born at the back of the group. It races outward. Then it dies at the leading edge. The group widens slowly, but the ripples inside it run ahead of the group.

Dispersion means every wavelength travels at its own speed. Group velocity is the separate speed of the packet. That split is why the pebble's ring looks wrong.

Pull the surface-tension slider σ toward 0 and the capillary branch on the left vanishes. The lowest point of the curve slides toward shorter waves.

1mm1cm10cm1m10m0.01.02.03.03.9m/swavelength λ (log)gravity ↔ capillaryc_min ≈ 0.23 m/sphase speed cgroup speed c_g

Lower σ toward 0 and the capillary upturn on the left flattens — only gravity is left. Shrink h and the long-wave end levels off at the shallow-water speed √(gh), where waves stop dispersing.

Check whether the minimum phase speed sits near 0.23 m/s. With gravity alone, shorter wavelengths sag downward on the curve.

The Ring the Pebble Made#

A surface wave is driven by a restoring force — the force pulling the water back toward flat. There are two of them.

One is gravity. It drags a raised crest back down. The other is surface tension (the force that pulls the water surface taut). It tries to flatten a curved surface.

For long waves, gravity wins. Once the wavelength drops below about 1.7 cm, surface tension takes over. Ocean swells are gravity waves. Pond ripples are capillary waves.

Wavelength Sets the Speed#

The physics of a surface wave boils down to one dispersion relation.

ω2=(gk+σk3ρ)tanh⁡(kh)\omega^2 = \left( g k + \frac{\sigma k^3}{\rho} \right)\tanh(k h)

Here ω\omega is the angular frequency, k=2π/λk = 2\pi/\lambda is the wavenumber (waves per unit length), λ\lambda is the wavelength, gg is gravity, σ\sigma is surface tension, ρ\rho is density, and hh is the water depth.

The speed at which a single wave advances is the phase velocity. Define it as c=ω/kc = \omega/k.

c=(gk+σkρ)tanh⁡(kh)c = \sqrt{\left( \frac{g}{k} + \frac{\sigma k}{\rho} \right)\tanh(k h)}

The key point is that cc depends on kk, hence on wavelength. Different wavelengths travel at different speeds. That is dispersion. Sound, and light in a vacuum, travel at the same speed regardless of wavelength. Water waves do not.

Gravity and Surface Tension Tug of War#

Take deep water. When khkh is large, tanh⁡(kh)→1\tanh(kh) \to 1, and the formula simplifies.

c=gk+σkρc = \sqrt{ \frac{g}{k} + \frac{\sigma k}{\rho} }

The first term is gravity's share. It grows as the wavelength grows (as kk shrinks). The second is surface tension's share. It grows as the wavelength shrinks (as kk grows).

The two terms pull in opposite directions. So the speed has a minimum. Solving dc/dk=0dc/dk = 0 gives the wavelength of slowest travel.

λ∗=2πσρg≈1.7 cm\lambda_\ast = 2\pi\sqrt{\frac{\sigma}{\rho g}} \approx 1.7\,\text{cm}

At this wavelength the phase velocity bottoms out near 0.23 m/s. The gravity term and the surface-tension term have the same size there. Drop either one and the valley goes away.

The length at which surface tension pinches a jet off comes from the same σ\sigma, ρ\rho, and gg. Plateau–Rayleigh breakup of a liquid jet reads that length off the jet radius.

Deep Water and Shallow Water#

What happens when the depth is far smaller than the wavelength? When khkh is small, tanh⁡(kh)≈kh\tanh(kh) \approx kh. Drop surface tension and the speed becomes strikingly simple.

c=ghc = \sqrt{g h}

The wavelength is gone. In shallow water every wavelength travels at the same speed. There is no dispersion. This state is called non-dispersive.

That is why a tsunami is so dangerous. Over a 4 km deep ocean, gh\sqrt{gh} reaches 700 km/h. A wave hundreds of kilometers long races along at jet-airliner speed while barely changing shape.

The Group Lags the Waves#

Now back to the opening puzzle. Why does a single ripple outrun its group?

The speed at which a wave group — a wave packet — moves is the group velocity. Define it as cg=dω/dkc_g = d\omega/dk. It is a different quantity from the phase velocity.

Consider pure gravity waves in deep water, where ω=gk\omega = \sqrt{gk}. Differentiate and the result is clean.

cg=dωdk=12gk=c2c_g = \frac{d\omega}{dk} = \frac{1}{2}\sqrt{\frac{g}{k}} = \frac{c}{2}

The group velocity is exactly half the phase velocity. The group crawls at half the speed of its own waves. So each ripple is born at the back of the group, sprints forward, and vanishes at the group's front edge.

Energy travels at the group velocity. Only the shape of the crest travels at the phase velocity. Below, follow one yellow crest.

At c_g/c = 0.5 (deep-water gravity waves) the yellow crest clearly outruns the pink envelope and fades at the front. Set the ratio to 1 and the crest freezes inside the lump — nothing disperses.

Set c_g/c to 0.5 and the yellow crest overtakes the pink envelope (the outline of the group) and fades at the front. Raise the ratio to 1 and the crest locks in place inside the group — the picture of a non-dispersive wave.

Plotting the Dispersion Curve in Python#

With the dispersion relation in hand, phase and group velocity plot straight out. Group velocity comes from differentiating ω(k)\omega(k) numerically.

import numpy as np
 
g, rho = 9.81, 1000.0          # gravity [m/s^2], water density [kg/m^3]
sigma = 0.072                  # water-air surface tension [N/m]
 
def omega(k, h):
    return np.sqrt((g * k + sigma * k**3 / rho) * np.tanh(k * h))
 
def phase_speed(lam, h):
    k = 2.0 * np.pi / lam
    return omega(k, h) / k
 
def group_speed(lam, h):
    k = 2.0 * np.pi / lam
    dk = k * 1e-5                       # central difference for domega/dk
    return (omega(k + dk, h) - omega(k - dk, h)) / (2.0 * dk)
 
lam = np.geomspace(1e-3, 10.0, 400)    # 1mm to 10m, deep-water assumption
c = phase_speed(lam, h=100.0)
i = int(np.argmin(c))
print(f"min phase speed {c[i]:.3f} m/s @ wavelength {lam[i]*100:.2f} cm")
# min phase speed 0.232 m/s @ wavelength 1.73 cm
 
lam_swell = 2.0                        # 2m swell: gravity dominated
cp = phase_speed(lam_swell, 100.0)
cg = group_speed(lam_swell, 100.0)
print(f"phase {cp:.3f} m/s, group {cg:.3f} m/s, ratio {cg/cp:.3f}")
# phase 1.767 m/s, group 0.884 m/s, ratio 0.500

The minimum phase speed matches the hand estimate: 0.232 m/s at 1.73 cm, the same valley as the 1.7 cm and 0.23 m/s quoted above. A 2 m swell comes out at phase 1.767 m/s, group 0.884 m/s, ratio 0.500. Half of 1.767 is 0.8835, which meets the printed 0.884 at the third decimal. At that wavelength the gravity term dwarfs surface tension, so cg=c/2c_g = c/2 survives intact.

Not so at the slowest wavelength. There g/kg/k and σk/ρ\sigma k/\rho have the same size. Freezing the group velocity at half the phase speed, as if the wave were pure gravity, misplaces the energy of a 1.7 cm ripple. The ratio 0.500 belongs to wavelengths where gravity has already won, like the 2 m swell.

Shallow water is the other extreme. c=ghc = \sqrt{g h} has no kk in it. Differentiating ω=ck\omega = c k gives cg=cc_g = c. Crests and the group travel together. Over a 4 km depth that speed is 700 km/h. Hauling the deep-water half-speed rule onto that wave puts the energy in the wrong place by a factor of two.

Drop the depth and c/2 puts the energy late#

A skipping-stone ring is close to deep water. Crests run at the phase speed and the group crawls at half of that. Ripples dying at the front of the ring are that gap.

Once the depth falls below the wavelength, that picture has to go. The speed is just gh\sqrt{gh}, and group and phase match. Which term to keep is the same kind of length comparison as the way a Reynolds number splits the world of a flow. Here the lengths are the depth, the wavelength, and 1.7 cm.

Share if you found it helpful.