↑ ↓ to move · enter to open

W07 · Physics · Charge, breakdown, sound

lightning

A thunderstorm is a machine that pulls electric charge apart. Ice collides with ice, the updraft carries the pieces to different heights, and the field between them grows until the air gives way. The spark that follows finds its path in steps of a hundred feet or so, heats a channel an inch or two wide to about 30,000 K, and sends out a pressure wave you hear seconds later.

LAB 1

charging the cloud

Inside the storm, soft hail pellets called graupel fall through a crowd of small ice crystals, with supercooled water droplets (liquid below 32°F) all around. When a crystal bounces off a pellet, a little charge moves between them. In the colder upper part of the charging zone the graupel usually comes away negative and the crystal positive. The updraft (see W05 · Thunderstorms) lifts the light crystals to the top and the heavy graupel stays in the middle, so the charges separate. The lab models the result with three charged spheres and a conducting ground.

charging
1.5 C/s
Flash starts at

How to read this: left, a slice through a storm cloud. Right, a graph of how strong the electric push (the field, |E|) is at each height up the middle of that cloud. When the amber line reaches the red line, lightning fires.

  • positive charge
  • negative charge
  • small squares: ice crystals (rise)
  • circles: soft hail, or graupel (sinks)
  • white sparks: collisions that swap charge
  • V/m: volts per meter, the unit of field strength

Try this: raise Charge separation rate and watch flashes come faster; then switch to Breakdown field.

—
Main negative region
—
Field at the ground below
—
Peak field in the cloud
—
Flashes · last interval

Peak field vs breakdown—

0breakdown at this height

Coulomb's law plus an image

Ez(z) = Σ k·q·(z−zc) / max(|z−zc|, a)³ − k·q / (z+zc)²

Each charge region is a uniform sphere of radius a = 0.6 mi. The ground conducts, so it acts like a mirror: each charge q at height zc gets an opposite image at −zc. The shares are +0.85Q at 6.2 mi, −Q at 3.7 mi and +0.15Q at 1.9 mi, a simplified version of the common "tripole" picture. Real storms are messier.

Dry air at sea level breaks down at about 3 MV/m. Thinner air breaks down at a lower field, so the threshold here scales with air density from the standard atmosphere.

Why it's still a puzzle

Balloons flown through storms usually record peak fields of a few hundred kV/m. That is several times below the breakdown field, yet lightning starts anyway. Field boosts at the tips of ice particles and showers of fast electrons from cosmic rays are leading ideas. How a flash begins is still not fully understood.

Switch the trigger to the breakdown field and watch how much more charge the model needs.

CodePython

K = 8.988e9                     # Coulomb constant, N m^2 / C^2
A = 1000.0                      # radius of each charge sphere, m
REGIONS = [(10e3, +0.85),       # (height m, share of Q): upper positive
           (6e3,  -1.00),       # main negative
           (3e3,  +0.15)]       # lower positive

def field_z(z, Q):
    """Vertical field (V/m, + = up) on the storm's axis at height z."""
    E = 0.0
    for zc, f in REGIONS:
        q, d = f * Q, z - zc
        E += K * q * d / max(abs(d), A) ** 3   # uniform sphere of charge
        E -= K * q / (z + zc) ** 2             # its image, -q at -zc
    return E

def breakdown(z):
    """About 3 MV/m at sea level, scaled with standard-atmosphere density."""
    return 3.0e6 * (1 - 2.2558e-5 * z) ** 4.2559

def step(Q, I, dt, mode="measured"):
    Q += I * dt                                # I = separation rate, C/s
    zs = range(0, 14001, 50)
    if mode == "measured":
        fire = max(abs(field_z(z, Q)) for z in zs) >= 250e3
    else:
        fire = any(abs(field_z(z, Q)) >= breakdown(z) for z in zs)
    return (Q / 2, True) if fire else (Q, False)   # toy: a flash halves Q
LAB 2

the stepped leader is a fractal

A cloud-to-ground flash usually begins with a faint channel called the stepped leader. It works its way down in jumps of tens of meters, pausing between jumps and forking as it goes. The dielectric breakdown model (Niemeyer, Pietronero and Wiesmann, 1984) reproduces that shape with two rules. Solve for the electric potential around the channel, then extend the channel by one cell, choosing cells where the field is strong more often. Each cell here is 164 ft.

growing
η = 1.0

How to read this: the spark (pale blue) grows down from the cloud one cell at a time, more often where the faint bands are bunched (strong field). When it touches the ground, the gold path lights up as the main flash.

  • the stepped leader and its branches
  • path the bright return stroke takes
  • faint bands: equal electric "height"; tighter = stronger pull

Try this: click Bushy, then Sparse, and compare the branching. Tapping the picture also regrows it.

—
Cells grown
—
Branch tips
—
Cells per row of descent
—
Return-stroke path

Now

Laplace, then a weighted coin

∇²φ = 0 · P(cell) = φη / Σ φη

The cloud and the channel sit at φ = 0 and the ground at φ = 1. Relaxation repeatedly replaces each free cell with the average of its four neighbors, which solves Laplace's equation. Next to the channel, φ itself is the field across one cell, so the growth weight is (local field)η.

At η = 1 the model behaves like diffusion-limited aggregation, whose large 2D clusters have a fractal dimension near 1.7. Larger η favors the strongest tip and the channel straightens toward a line, dimension 1. This grid is too small to measure a dimension reliably, so the readout counts how many cells the pattern uses per row it descends: 1 for a straight line, more for a bushier one.

The return stroke

When a leader tip gets close to the ground, a short upward streamer rises to meet it and the circuit closes. A bright wave of current then runs up the connected path in tens of microseconds. That return stroke heats the channel to around 30,000 K, about five times the temperature of the Sun's surface. Side branches that never connected stay dim.

CodePython

import random

def relax(phi, chan, sweeps=20, w=1.8):
    """SOR for Laplace's equation. Row 0 (cloud) and the channel are
    held at 0, the last row (ground) at 1. Side walls mirror."""
    H, W = len(phi), len(phi[0])
    for _ in range(sweeps):
        for i in range(1, H - 1):
            for j in range(W):
                if chan[i][j]:
                    continue
                l = phi[i][j - 1] if j > 0 else phi[i][j + 1]
                r = phi[i][j + 1] if j < W - 1 else phi[i][j - 1]
                avg = (phi[i - 1][j] + phi[i + 1][j] + l + r) / 4
                phi[i][j] += w * (avg - phi[i][j])

def grow(phi, chan, eta):
    """Add one cell touching the channel (8 neighbors), weight phi**eta."""
    H, W = len(phi), len(phi[0])
    cells, wts = [], []
    for i in range(1, H - 1):
        for j in range(W):
            if not chan[i][j] and any(chan[a][b]
                    for a in (i - 1, i, i + 1)
                    for b in (j - 1, j, j + 1) if 0 <= b < W):
                cells.append((i, j))
                wts.append(max(phi[i][j], 0.0) ** eta)
    i, j = random.choices(cells, weights=wts)[0]
    chan[i][j], phi[i][j] = True, 0.0
    return i == H - 2                     # reached the row above ground
LAB 3

flash to bang

The return stroke heats the channel so fast that the air in it cannot expand in time, and the pressure jumps. The channel then bursts outward and launches a shock that soon weakens into ordinary sound: thunder. Light reaches you almost instantly and sound travels about 1,125 ft/s at 68°F, so counting the seconds between flash and bang gives the distance. Press Strike and count along.

side view
1.9 mi
68°F

How to read this: sound (faint amber rings) spreads from every part of the bolt. Amber dots mark the parts you're hearing right now. The bars along the bottom show how loud the thunder is at each moment.

  • sound spreading out
  • the part of the bolt you hear now
  • bar height: loudness at that moment
—
Seconds since flash
—
Speed of sound
—
Flash-to-bang time
—
Distance = c · t
—
5-seconds-per-mile rule
—
Rumble length

Now

Distance from a count

c ≈ 331.3 + 0.606·T m/s · d = c · t

Sound is faster in warm air. At 68°F, c ≈ 1,125 ft/s, so a mile takes about 4.7 s, hence the rule of 5 seconds per mile (3 seconds per km). Light covers the same mile in about 5 µs, which the formula ignores.

The first sound comes from the nearest piece of the channel, which can be overhead rather than at the strike point. So the count measures your distance to the closest part of the flash.

Why thunder rumbles

The channel is miles long and every part of it bangs at once. Each part is a different distance from you, so its sound arrives at a different time. The trace under the scene shows when each part is heard: the nearest point gives the crack and the far end of the in-cloud branch gives the last rumble. Echoes off hills and bending of sound by temperature layers stretch it further.

If you can hear thunder, you are close enough to be struck. Thunder is rarely heard beyond about 10–12 miles, because sound bends upward away from the ground and fades.

CodePython

import math

def sound_speed(T_c):
    return 331.3 + 0.606 * T_c            # m/s in dry air, T in deg C

def distance(t_s, T_c):
    return t_s * sound_speed(T_c)         # light's delay (d / 3e8 s) ignored

def thunder(channel, T_c, bin_s=0.1):
    """channel: (x, z) points in m. Listener at (0, 0)."""
    c = sound_speed(T_c)
    r = [math.hypot(x, z) for x, z in channel]
    first, last = min(r) / c, max(r) / c      # the crack, the last rumble
    trace = [0.0] * (int(last / bin_s) + 1)
    for k in range(len(r) - 1):
        seg = math.dist(channel[k], channel[k + 1])
        rm = (r[k] + r[k + 1]) / 2
        trace[int(rm / c / bin_s)] += seg / rm  # length heard, 1/r spreading
    return first, last - first, trace