Aerofoil Dynamics
An interactive flow visualisation around a wing section — see how angle of attack and airspeed change the air flowing over the wing, and where stall comes from.
Lift is invisible. Students hear that wings work because of how the air moves around them, but without seeing the flow it is hard to build a feel for why changing the angle of attack changes the lift — or what is actually happening when a wing stalls.
This tool is an attempt to put the airflow and turbulence on screen. Move the angle of attack slider and watch the flow respond in real time: faster air over the top, slower air underneath, and at high angles a messy separated wake where the wing stops flying. NOTE: the calculation does collapse at the extremes — which is why there’s a reset button. There are also still some issues I need to resolve with the lift.
Description
The Aerofoil Dynamics tool runs a live two-dimensional fluid simulation around a standard wing section (a NACA aerofoil). Air flows in from the left, the wing sits in the middle, and the wake trails off to the right. Coloured streaks show the direction and intensity of the swirling motion in the air, and small particles drift along with the flow so you can see the streamlines themselves.
The on-screen controls let you change what the wing is doing:
- Speed — how fast the air is flowing over the wing
- AoA — the wing’s angle of attack, from −16° to +16°
- NACA — the wing profile, from a thin symmetric section through to a high-camber wing
- ↺ — reset the simulation if it gets unsettled
A small heads-up display in the corner reports the lift and drag coefficients (C_L and C_D) the simulation is producing, and an orange arrow shows the total aerodynamic reaction with its lift and drag components dashed in.
For instructors
Use it during Principles of Flight briefings to make the airflow story concrete:
- Why lift changes with angle of attack — start at 0°, then sweep AoA upward and watch C_L climb with it. The pressure imbalance you describe in theory shows up as visible flow acceleration over the top surface
- What a stall actually looks like — push AoA past about 12–15° and the smooth wake breaks down into a thick, chaotic separated region. Students can see the flow detaching rather than just hearing about it
- Camber and shape — switch between the symmetric 0012 and the cambered 4412 or 6412 sections to show that camber gives lift at zero angle of attack, and that the wing shape itself does work
- Speed and lift together — drop the speed slider and the lift arrow shrinks even at the same angle of attack — useful for setting up the lift formula before you write it on the board
For trainees
A few minutes with this before your Principles of Flight session pays off:
- Set the NACA profile to 2412 (a typical light-aircraft wing) and the AoA to 5° — note how the flow accelerates over the top and the lift arrow points upward
- Slowly increase AoA toward 15° and watch the wake. The point where the smooth flow breaks down is the stall
- Reduce AoA back to a small positive value, then drop the speed — observe that lift falls off even though the angle of attack hasn’t changed
- Switch to the symmetric 0012 profile and set AoA to 0° — there is no lift. Then increase AoA — the symmetric wing only produces lift when angled into the flow
- Try a high-camber 6412 section at 0° AoA — it produces lift just from its shape
A note on what you are seeing
The simulation is a real fluid model, but it runs at a much lower scale than a real aircraft (closer to insect-flight conditions than a Cessna). The flow patterns — pressure-driven lift, the wake, the onset of stall — are physically correct and useful for teaching. The actual numbers (C_L, C_D) should not be compared with published aerofoil data for full-size aircraft.
The background colours show vorticity (how the air is spinning), not pressure. Red marks the upper-surface boundary layer, blue marks the lower one, and the white free-stream surrounds them. When red and blue regions grow large and disorganised in the wake, that is the visual signature of stall.
Physics
The simulation uses the Lattice Boltzmann Method (LBM) D2Q9 scheme — a mesoscopic approach where fluid is modelled as populations of particles streaming and colliding on a regular grid. At each timestep:
- Collision — each cell relaxes its distribution functions toward a local Maxwell–Boltzmann equilibrium (BGK operator with relaxation time τ ≈ 0.59).
- Streaming — populations propagate to neighbouring cells along their velocity directions.
- Bounce-back — populations hitting the solid aerofoil surface reverse direction, enforcing a no-slip boundary.
The aerofoil is a National Advisory Committee for Aeronautics (NACA) 4-digit profile (default: 2412) generated analytically at startup and rasterised onto the LBM grid. Lift and drag are computed each frame via Ladd’s momentum-exchange method: every time a fluid particle bounces off the solid surface, the reaction impulse is accumulated and averaged over the frame to give the net hydrodynamic force vector. This is then decomposed into lift (perpendicular to freestream) and drag (parallel to freestream) and normalised by dynamic pressure and chord to give C_L and C_D.
Reynolds number and simulation fidelity
The Reynolds number Re = u · c / ν sets the ratio of inertial to viscous forces and determines how realistic the force coefficients are.
At the default speed (0.4) the LBM runs at Re ≈ 150, because the lattice Mach stability limit caps the maximum flow speed and the relaxation time sets a lower bound on viscosity. Re ≈ 150 is insect-flight scale — physically equivalent to, for example, a bumblebee wing rather than an aircraft wing:
| Platform | Chord | Speed | Re |
|---|---|---|---|
| Cessna 172 | 1.5 m | 55 m/s | ~5,500,000 |
| RC model | 0.15 m | 15 m/s | ~150,000 |
| Bumblebee | 3 mm | 1 m/s | ~200 |
| This simulation (speed=0.4) | — | — | ~150 |
At Re ≈ 150, viscous skin friction is roughly 50× larger than at Cessna Re, so C_D is greatly inflated and the lift-to-drag ratio (≈ 0.9 here vs ≈ 50–80 for a real wing) is not representative of aircraft performance. C_L rises with AoA, has the right sign, and shows visible flow separation and wake growth as α approaches the real stall angle.
Note on post-stall behaviour. A real wing’s lift drops sharply at the stall angle because the upper-surface boundary layer detaches close to the leading edge and the suction peak collapses. Resolving that requires a boundary layer many cells thick across the chord — at the simulated Re and grid resolution there is essentially no resolved boundary layer (δ/chord ≈ 1/√Re ≈ 1 grid cell), so the suction-peak-collapse mechanism cannot be reproduced. Past the real stall angle C_L would therefore plateau rather than drop, which is misleading; for this reason the AoA slider is capped at ±16°, around the real-world stall angle of NACA 2412.
The simulation cannot be simply rescaled to Cessna Re: the flow topology is different (thick separated boundary layer vs thin attached one), so the coefficients reflect different physics, not the same physics at a different magnitude. Achieving Re > 1 000 in a real-time 200 × 80 browser simulation would require turbulence modelling and a larger grid.
The component is therefore best used as a qualitative flow visualiser — it correctly shows flow acceleration over the upper surface, pressure-driven lift, wake formation, and the onset of stall up to α_stall. The displayed C_L and C_D values are physically correct for the simulated Re but should not be compared directly to published aerofoil data.
Incompressible assumption
Air is treated as incompressible — an excellent approximation below Mach 0.3 (≈ 360 km/h at sea level). Even XFOIL, the standard subsonic aerofoil analysis tool, uses incompressible potential flow. Compressibility effects are less than 1% for all speeds relevant to light-aircraft training.
Rendering
The background colours show vorticity — how fast and in which direction the fluid is spinning at each point:
- Red/orange — fluid spinning as in the upper-surface boundary layer (faster flow further from the wall, slower near it)
- Blue — fluid spinning as in the lower-surface boundary layer
- White — no spin (undisturbed free stream)
Vorticity is highest in the thin boundary layers hugging the aerofoil surfaces and in the turbulent wake. It is a good indicator of stall: at high AoA the red and blue regions in the wake grow large and chaotic as flow separates from the upper surface.
Note that the colours do not show pressure. Red is always on the upper surface and blue on the lower regardless of angle of attack — this is because the boundary-layer shear always points the same way relative to the wall, whatever the AoA. Pressure would tell a different story (high pressure on the windward side, low on the leeward side), but vorticity was chosen here because it makes stall and separation far more visible.
The aerofoil silhouette is drawn as a smooth path on top of the upscaled vorticity field, independent of grid resolution, so the outline remains crisp regardless of zoom level. Moving particles are coloured by local flow speed from dark blue (slow) through green to red (fast).
Embedding this component
<script type="module"> import 'https://unpkg.com/@open-aviation-solutions/components/dist/lib/define.es.js';</script>
<aerofoil-dynamics naca="2412" speed="0.4" aoa="5" show-controls></aerofoil-dynamics>Attributes
| Attribute | Default | Description |
|---|---|---|
height | 420px | CSS height of the component |
naca | 2412 | National Advisory Committee for Aeronautics (NACA) 4-digit profile code |
speed | 0.4 | Normalised inflow speed (0–1) |
aoa | 5 | Angle of attack in degrees (−16 to +16) |
show-controls | (absent) | Renders speed and AoA sliders inside the component |
show-help | — | Set to "false" to hide the in-component help (?) link |
Events
| Event | Detail | Description |
|---|---|---|
aerofoil-state | { lift, drag, aoa, speed } | Fired each frame with computed lift and drag coefficients |
JavaScript API
const el = document.querySelector('aerofoil-dynamics')el.aoa = 10 // set angle of attack programmaticallyel.speed = 0.15 // set inflow speed
el.addEventListener('aerofoil-state', e => { console.log('Cl:', e.detail.lift, 'Cd:', e.detail.drag)})