2D Shallow Water Equations solver for orographic wind analysis over real terrain
The Wind Flow simulation solves the 2D Shallow Water Equations (SWE) to model how a horizontal wind interacts with terrain. The atmosphere is approximated as a single layer of fluid with a free surface, flowing over an orographic (terrain) floor. Where the terrain rises, the fluid layer thins; where the terrain is lower, the layer is deeper. This reduced-gravity hydraulic analogy captures terrain-blocking, orographic lifting, lee-side acceleration, and hydraulic jumps — the main mechanisms that shape wind patterns relevant to paragliding site analysis.
The simulation runs entirely in the browser using a Web Worker on a 2D grid aligned with the terrain bounding box. It is fast (seconds to a few minutes) and does not require a 3D pressure solve. Elevation data is fetched from Terrarium tiles; no land cover is used in this model.
h = H₀ − Z. Cells where
H₀ − Z ≤ h_min are immediately treated as dry
(terrain-blocked).
The atmosphere is treated as a single, vertically integrated layer of
depth h flowing over terrain of elevation Z.
The free-surface height is η = h + Z. The governing
equations in conservative form are:
The four physical terms in each momentum equation are:
U·∂U/∂x + V·∂U/∂y: the fluid
carries its own momentum. Causes flow to accelerate through
constrictions (mountain passes).
g'·∂η/∂x: drives flow from high to low free-surface. The
terrain slope ∂Z/∂x is included via η, so flow is
deflected around or over ridges.
C_d·|u|·U/h: quadratic
friction from the terrain surface, opposing the flow. Stronger where
the layer is thin or flow is fast.
ν·∇²U: diffuses
momentum laterally, smoothing velocity gradients and preventing sharp
shocks from going numerically unstable.
The parameter g' (reduced gravity) replaces the true
gravitational acceleration g = 9.81 m/s². In the full
atmosphere, a density contrast Δρ/ρ between the flowing layer and the
air above it gives g' = g · Δρ/ρ. In practice,
g' controls the speed of gravity waves in the layer:
A small g' (e.g. 0.2 m/s²) mimics a weakly stratified
interface — waves travel slowly and the flow responds gradually to
terrain. A large g' (e.g. 2 m/s²) stiffens the free
surface, causing the layer to behave more like a rigid-lid flow with
faster pressure adjustment.
Although the SWE is 2D, a proxy for the vertical wind velocity is derived from terrain-forced lifting and flow convergence:
The first term is the kinematic uplift: wind hitting a rising slope must
go upward. The second term is the convergence: where horizontal flow
converges (∂U/∂x + ∂V/∂y < 0), mass is forced upward. Positive
w_vert (red in the viewer) indicates rising air — the
primary indicator for orographic thermals and ridge lift.
The Froude number distinguishes two flow regimes analogous to sub-sonic / super-sonic in gas dynamics:
Fr < 1 (sub-critical): disturbances can propagate
upstream. Flow smoothly adjusts to terrain; typical upwind of a
ridge.
Fr > 1 (super-critical): disturbances cannot travel
upstream. Flow accelerates through passes and over crests, producing
hydraulic jumps on the lee side — violent, turbulent transitions where
super-critical flow suddenly decelerates. In the real atmosphere this
corresponds to mountain wave / rotor conditions.
The 2D vertical vorticity measures local rotation in the horizontal wind field:
Positive ζ (red) is cyclonic (counter-clockwise); negative ζ (blue) is anticyclonic. Strong vorticity patches appear at the edges of mountain wakes, behind ridges, and in the shear layers surrounding accelerated jets. High vorticity is associated with turbulence.
The SWE are integrated with an explicit finite-difference scheme (forward Euler in time, second-order central differences in space), stabilised by a CFL time-step condition.
dt = CFL · min(dx, dy) / max(c_est, 0.1)c_est = |u|_max + √(g'·H₀) is the fastest signal
speed in the domain (advection + gravity wave). CFL is typically
0.3–0.5.
h_new = h − dt · [∂(hU)/∂x + ∂(hV)/∂y]U > 0:
∂U/∂x ≈ (U[i] − U[i−1]) / dx (backward difference)U < 0:
∂U/∂x ≈ (U[i+1] − U[i]) / dx (forward difference)
−g' · (η[i+1,j] − η[i−1,j]) / (2·dx)η = h + Z is evaluated at the current time level.
h < h_min are
treated as dry (terrain-blocked). Velocities are zeroed and fluxes are
suppressed to avoid division by near-zero depth and to represent
complete terrain blocking.
h = H₀ − Z, U = U_in,
V = V_in. Outflow edges use Neumann conditions (copy the
interior value), allowing fluid to leave freely.
The wind direction determines which edges are inflow and which are
outflow. For a wind with eastward component U_in > 0,
the left (west) edge is inflow and the right (east) edge is outflow.
Both conditions are applied simultaneously for oblique winds.
| Edge | Condition | Applied when |
|---|---|---|
| Left (West) | Inflow: h = H₀−Z, U = U_in, V = V_in | U_in > 0 |
| Right (East) | Inflow: h = H₀−Z, U = U_in, V = V_in | U_in < 0 |
| Top (North) | Inflow: h = H₀−Z, U = U_in, V = V_in | V_in < 0 |
| Bottom (South) | Inflow: h = H₀−Z, U = U_in, V = V_in | V_in > 0 |
| Any outflow edge | Neumann: copy from interior neighbour | Opposite sign of above |
| Parameter | Typical range | Effect |
|---|---|---|
| Wind direction | 0–360° | Compass bearing the wind comes from. Determines which domain edges are inflow. Changes which slopes are windward (orographic lift) and which are lee (sink/rotors). |
| Wind speed (U_in, V_in) | 0–30 m/s | Inflow velocity magnitude. Stronger wind → faster flow, larger Froude number, stronger orographic lifting and more pronounced hydraulic jumps. Too strong with low ν may cause instability. |
| Parameter | Typical range | Effect |
|---|---|---|
| H₀ (layer depth) | 500–3000 m | Undisturbed atmospheric layer depth. Mountains taller than H₀ completely block the flow (h → 0, terrain-blocked). A shallow H₀ makes more of the terrain protruding and emphasises blocking effects. A deep H₀ allows flow to pass over most terrain. |
| g' (reduced gravity) | 0.1–2.0 m/s² |
Controls the gravity wave speed c = √(g'·h) and thus
the Froude number regime. Small g' → slow wave propagation, flow is
more easily blocked and deflected around obstacles. Large g' → stiff
free surface, flow adjusts rapidly, fewer blocking effects. Also
sets the transition wind speed for hydraulic jumps.
|
| C_d (bottom drag) | 0–0.05 | Quadratic friction coefficient. Decelerates the flow proportional to speed². Higher drag → flow slows faster downstream of ridges, wake zones are wider, jet acceleration through passes is damped. Zero drag allows unphysical indefinite acceleration. |
| ν (viscosity) | 0–2000 m²/s | Turbulent (eddy) viscosity. Diffuses lateral velocity gradients. Acts as a numerical stabiliser and physical proxy for sub-grid turbulence. Too low: sharp shocks may become unstable. Too high: flow features are over-smoothed and fine-scale patterns are lost. |
| Parameter | Typical range | Effect |
|---|---|---|
| CFL | 0.2–0.5 | Courant number controlling the time-step size. Smaller → more stable but slower (more steps per second of simulated time). Values above 0.5 risk numerical instability with explicit upwind schemes. |
| h_min | 0.1–5 m | Wet/dry threshold. Cells with h below this are treated as completely blocked terrain. Too large: shallow-but-valid flow is incorrectly suppressed. Too small: near-zero h causes division instability in the drag term. |
| NX, NY (grid) | 32–256 | Horizontal resolution. Finer grids resolve narrower terrain features (passes, gullies) and produce sharper gradients. Runtime scales as NX·NY per step. |
| Field | Symbol | Description |
|---|---|---|
| Wind speed | |u| = √(U²+V²) | Horizontal wind speed at the layer. Blue→cyan→yellow gradient. Acceleration through mountain passes and deceleration in wakes are clearly visible. |
| Vertical wind | w_vert | Proxy for vertical velocity (orographic uplift + convergence). Red = rising air (windward slopes, convergence zones). Blue = sinking air (lee slopes, divergence). Most directly relevant to paragliding ridge and thermal soaring. |
| Froude number | Fr = |u|/√(g'·h) | Blue (Fr < 0.5, sub-critical) → yellow (Fr ≈ 1, critical) → red (Fr > 1, super-critical). Red zones indicate locations prone to hydraulic jumps and strong turbulence on the lee side. |
| Flow depth | h | Layer thickness. Thin (dark) where terrain is high; deep (bright) over valleys. Zero/near-zero indicates terrain-blocked cells. |
| Vorticity | ζ = ∂V/∂x − ∂U/∂y | Red = cyclonic rotation; blue = anticyclonic. Marks shear layers at the edges of mountain wakes and along the flanks of jets. |
| Elevation | Z(x, y) | Terrain height for spatial reference, overlaid with a hillshade. |
| Dataset | Used for | Source | Resolution |
|---|---|---|---|
| Elevation | Terrain height Z(i,j), layer depth initialisation, orographic lifting | AWS Terrain Tiles — Terrarium RGB encoding (IGN RGE Alti for France) | ~7 m (zoom 14) |
| Simulation output | Snapshots of h, U, V and derived fields read by the viewer | Browser IndexedDB (written by the Web Worker, read by the viewer) | — |
Elevation tiles use the Terrarium RGB encoding:
elevation = R×256 + G + B/256 − 32768 metres, delivered in
Web Mercator (EPSG:3857) and reprojected to WGS84 before use. No land
cover data is used — surface roughness is represented by the uniform
drag coefficient C_d.
H₀ to the height of the atmospheric boundary layer or
the ridge height you want to block — typically 800–2000 m.
g' ≈ 0.5 m/s² and adjust until the Froude
number map shows sub-critical flow upwind of ridges (Fr < 1, blue),
transitioning to super-critical on the crests (Fr ≈ 1, yellow). This
is the most physically meaningful regime.
ν if the simulation becomes visually noisy or
velocity spikes appear. Decrease it for sharper, more realistic
gradients on coarser grids.