This is a real 2D cross-section (x = along the free surface, z = depth) of an elastic half-space. The engine builds the Rayleigh characteristic equation from the material's P-wave and S-wave speeds and finds its physical root by bisection, live, every time you move a slider — nothing is a hard-coded constant:
ξ = (v_R / v_S)²
f(ξ) = (2 − ξ)² − 4·√(1 − ξ·v_S²/v_P²)·√(1 − ξ)
solve f(ξ) = 0 for ξ ∈ (0,1), ξ ≠ 0 → v_R = v_S·√ξ
The root gives q_P = √(1−v_R²/v_P²) and q_S = √(1−v_R²/v_S²), the exponential depth-decay rates of the compressional and shear-vertical potentials. Solving the free-surface (traction-free) boundary conditions for the P+SV potential pair gives the coupled displacement field animated below:
u_x(x,z,t) = −[e^(−q_P·kz) − D·e^(−q_S·kz)]·sin(kx−ωt), D = 2·q_P·q_S/(1+q_S²)
u_z(x,z,t) = −q_P·[e^(−q_P·kz) − E·e^(−q_S·kz)]·cos(kx−ωt), E = 2/(1+q_S²)
Both terms decay exponentially with depth z at different rates (q_P and q_S), so the energy stays trapped within roughly one wavelength of the surface. At z = 0 this reduces to the textbook u_x/u_z ≈ 0.68 surface amplitude ratio for a Poisson solid (ν = 0.25) — the simulator reproduces that number from the general formula, not a lookup. Because the two components are 90° out of phase, a particle traces an ellipse; the engine checks the rotation sense numerically every frame (sign of u_x·v_z − u_z·v_x) rather than assuming it, so the retrograde-near-surface / prograde-at-depth flip you see is measured, not scripted.
- ν sets v_P/v_S = √(2(1−ν)/(1−2ν)); v_S sets the absolute scale. Together they re-solve the characteristic equation for a new v_R.
- The Rayleigh speed always comes out slightly below the shear speed (v_R/v_S ≈ 0.87–0.96 across realistic ν) — that gap is the whole reason a distinct Rayleigh-wave arrival exists in a seismogram.
- Ellipse traces plot each tracked depth's last orbit so you can see it shrink and flip with depth directly; Depth colour tints particles by z instead of by rotation sense.