A wave that feeds itself
Drop a spark into a mixture of reactants that catalyse their own production, and something more organised than a random spread happens: a sharp front forms and advances at a single, well-defined speed, leaving fully reacted material behind it and untouched reactant ahead. This behaviour — diffusion combined with local autocatalytic growth producing a self-organised travelling wave — is described by one of the most widely reused equations in applied mathematics, the Fisher-KPP equation, independently proposed in 1937 by Ronald Fisher (studying the spatial spread of an advantageous gene through a population) and by Andrey Kolmogorov, Ivan Petrovsky and Nikolai Piskunov (studying the same mathematics more rigorously and generally).
The equation
∂u/∂t = D · ∇²u + r · u · (1 - u) u(x,t) = local concentration of "reacted" material, normalised to 0…1 D = diffusion coefficient — how fast the reaction product spreads spatially r = intrinsic growth (reaction) rate D·∇²u = DIFFUSION term — spreads the reaction outward from wherever it's high r·u·(1-u) = REACTION term — logistic growth: fast when u is small, saturating as u→1
The reaction term is exactly the logistic growth model: production is proportional to how much reactant is already present (u, autocatalysis) and to how much unreacted material remains (1-u, a saturating carrying capacity). Without diffusion this term alone would just make u climb smoothly from 0 to 1 everywhere at once. Diffusion is what turns a spatially uniform process into a genuine travelling front: it lets the small amount of product just ahead of the reacted region "seed" the next patch of unreacted material, which then grows autocatalytically and diffuses further, propagating the front forward.
Why the speed is exactly v = 2√(Dr)
Fisher-KPP admits travelling-wave solutions of the form u(x,t) = U(x − vt) for a whole continuous range of speeds v ≥ v_min, but starting from any localized, compactly-supported patch of reacted material, the front that actually emerges — proven by KPP in their original paper — always selects the minimum allowed speed:
v = 2·√(D·r) (speed selected by any sharply-localized initial condition)
The intuition is that far ahead of the front, u is very small, and there the reaction term r·u(1-u) simplifies to just r·u — pure exponential growth, with no saturation yet. Linearising the full PDE in that leading-edge region gives ∂u/∂t = D·∇²u + r·u, whose fastest-growing, non-negative solution that stays bounded travels at exactly 2√(Dr). The nonlinear saturation behind the front doesn't change this leading-edge speed — it only shapes the profile that follows behind, "mopping up" whatever the linear leading edge has already seeded.
The same law, many disguises
This diffusion-times-growth speed selection is not specific to chemistry. Fisher derived it originally for a favourable gene spreading through a spatially distributed population — the population's growth rate plays the role of r, and random dispersal (migration) plays the role of D. In combustion, the analogous premixed flame speed depends on thermal diffusivity and the reaction rate of the fuel in a structurally similar way. Ecologists use the same equation for species invasions — an introduced species with local growth rate r and random dispersal D advances its range boundary at 2√(Dr), a prediction that has matched observed invasion fronts for species ranging from muskrats in Europe to cane toads in Australia reasonably well as a first approximation.
Simulating it on a grid
A straightforward explicit finite-difference scheme reproduces the front cleanly as long as the diffusive stability limit is respected:
// explicit Euler step for 1D Fisher-KPP, grid spacing dx, step dt
for (let i = 1; i < N - 1; i++) {
const laplacian = (u[i+1] - 2*u[i] + u[i-1]) / (dx * dx);
uNext[i] = u[i] + dt * (D * laplacian + r * u[i] * (1 - u[i]));
}
// stability requires dt <= dx² / (2D) — the standard diffusion CFL limit
Measuring the front position (say, where u crosses 0.5) over time and fitting a straight line to it is the simplest way to check the simulation against the 2√(Dr) prediction — after an initial transient while the front profile settles into its self-similar shape, the fit should converge to the analytic speed to within a percent or two on a reasonably resolved grid.
Frequently asked questions
Why does the front speed settle to a fixed value instead of accelerating forever?
Because the growth term r·u(1-u) is strongest where u is small (near the leading edge) and vanishes where u is already near 1 (behind the front). The front is pulled forward at exactly the rate that keeps the small-u leading edge growing and diffusing outward as fast as it linearly can, which caps the speed at v_min = 2√(Dr) for a generic sharp initial condition — faster fronts are mathematically possible but require specially engineered, slowly-decaying initial data.
Is v = 2√(Dr) exact for any starting condition?
It's the speed selected by any initial condition that is compactly supported or decays at least exponentially fast (which covers essentially every physically realistic starting patch). Kolmogorov, Petrovsky and Piskunov proved this selection result in 1937. Initial conditions with a very slow, specially tuned power-law tail can in principle produce a faster front, but these are mathematical curiosities rather than anything you'd encounter starting from a localized seed.
Does the same equation really describe chemistry, ecology and epidemics?
The same mathematical structure — diffusion plus logistic-style saturating growth — appears whenever something spreads spatially while also multiplying locally up to a carrying capacity: an autocatalytic chemical reactant, an invading species (Ronald Fisher's original 1937 motivation, studying the spread of an advantageous gene), or, with modification, the early exponential phase of an epidemic. The details of the growth term differ by field, but the diffusion-times-growth balance and the resulting v = 2√(Dr) scaling recur across all of them.
Try it live
Everything above runs in your browser — open Reaction Front and change the parameters while it is running. Nothing is installed, nothing is uploaded, the whole model lives in one tab.
▶ Open Reaction Front simulation