HomeBiology & LifePopulation Wave — Spatial Spread of Species

🌊 Population Wave — Spatial Spread of Species

Simulate the spatial spread of an invasive species using the Fisher-KPP equation on a 2D grid. Watch the wave front advance at speed v=2√(Dr), with Allee effect option slowing the invasion.

Biology & Life3DModerate60 FPS
population-wave ↗ Open standalone

About this simulation

This simulation models the spatial spread of an invasive species using the Fisher-KPP reaction-diffusion equation, ∂u/∂t = D∇²u + ru(1−u), solved numerically on a 150×150 grid. A small central colony expands outward as a travelling wave whose speed converges to the theoretical minimum v = 2√(Dr), and an optional Allee effect term can slow or stall the invasion below a density threshold.

🔬 What it shows

Population density u(x,y) evolving on a 150×150 grid via explicit finite differences with a five-point Laplacian stencil and zero-flux (Neumann) boundaries. Blue marks empty habitat (u=0), green marks half-capacity (u=0.5), and red marks a saturated colony (u=1). The strip below the grid plots total population over time, and the live stats compare the measured wave speed to the theoretical value 2√(Dr).

🎮 How to use

Adjust Diffusivity D and Growth rate r to change how fast individuals disperse and reproduce — watch the theoretical wave speed update instantly. Enable the Allee effect and raise the threshold a to see the invasion slow down or fail entirely. Toggle Heterogeneous landscape to randomise local diffusivity by ±50%, producing an irregular, fingered front instead of a smooth circle. Reset restarts from a fresh central colony; Pause/Play freezes the animation.

💡 Did you know?

The same v = 2√(Dr) formula that governs this simulated colony has been fitted to real invasions — muskrats spreading across Europe after their 1905 introduction advanced at roughly 1 km/year, matching a Fisher-KPP wave with D≈51 km²/yr. The same mathematics also describes the spread of chestnut blight, HIV within lymph nodes, and even the historical advance of farming across Neolithic Europe.

Frequently asked questions

What sliders control the simulation and what do they change?

Diffusivity D (0.1–3.0) sets how fast individuals disperse by random movement; Growth rate r (0.1–2.0) sets the logistic reproduction rate; and Allee threshold a (0–0.5) sets the minimum density penalty used when the Allee effect toggle is enabled. Both D and r feed directly into the theoretical wave speed shown as 2√(Dr), so moving either slider updates that stat immediately, while Reset reseeds a fresh 8-cell-radius colony at the centre of the 150×150 grid.

How does the simulation actually compute the wave each frame?

Each frame runs four explicit Euler steps of the Fisher-KPP equation. The Laplacian is approximated with the five-point stencil (sum of four neighbours minus four times the centre cell, divided by Δx²=1), the time step is capped at dt = min(0.1, 1/(4D)) to satisfy the 2D diffusion CFL stability condition, and growth uses either ru(1−u) or, with Allee effect on, ru(u−a)(1−u). Boundaries are zero-flux, so density cannot leave the grid.

How is the measured wave speed different from the "Theory 2√(Dr)" stat?

The simulation tracks the radius where density first drops to 0.5 by scanning outward from the centre, then divides the change in that radius by elapsed simulated time to get a measured speed, updated roughly every half a time unit. The "Theory 2√(Dr)" stat is the closed-form Fisher prediction computed directly from the current D and r sliders. Early in a run the measured speed is below theory while the front steepens from its initial smooth profile; after a short transient the two values converge.

What does enabling the Allee effect actually change in the model?

With the Allee toggle off, growth is the standard logistic term ru(1−u), and any positive density eventually invades the whole grid. Switching it on changes growth to ru(u−a)(1−u): once local density falls below the Allee threshold a, that term turns negative, so patches below a shrink instead of growing. Raising a with the slider makes the effective invasion threshold stricter, and a high enough value can stall the front completely or make the colony collapse rather than spread.

What happens when Heterogeneous landscape is switched on?

Turning it on builds a per-cell diffusivity map where each of the 150×150 cells gets D multiplied by a random factor between 0.5 and 1.5, generated once at reset. During stepping, the simulation uses this local value instead of the uniform D everywhere the toggle is active, so the wave front advances faster through high-diffusivity patches and lags in low-diffusivity ones — producing the same kind of irregular, fingered spread seen when real invasions follow roads, rivers, or forest corridors rather than open, uniform ground.

⚙ Under the hood

Simulate the spatial spread of an invasive species using Fisher-KPP on a 2D grid. Wave front advances at v=2√(Dr). Optional Allee effect.

Fisher-KPPpopulation dynamicsinvasionreaction-diffusionAllee effect

3D · Three.js / WebGL renderer · 60 FPS target · runs fully client-side, no install

What did you find?

Add reproduction steps (optional)