Volcanic eruption (lava SWE + buoyant plume + ash PDE)
Full description: Read the full narrative
The eruption scenario couples three physics modules: (1) lava flow as a 2D conservative shallow-water system with Rusanov fluxes, Arrhenius temperature-dependent viscosity, Bingham yield strength, Stefan–Boltzmann radiation, crust insulation and enthalpy-porosity solidification; (2) the eruption column as a 1D Morton–Taylor buoyant plume integrated to neutral buoyancy; and (3) ash as a vertically integrated advection–diffusion–settling PDE over a height-resolved wind field, with Schiller–Naumann particle drag. Terrain is REAL ONLY — the kernel refuses to run without sampled relief.
- Execution mode
- Kaggle kernel (numpy-only, CPU accelerator instance); local in-process use for calibration & Monte-Carlo server/kaggle/simRunner.ts:126-141 server/kaggle/localRunner.ts:1-15 kaggle-kernels/volcano-sim/main.py:607-680,1383
- Verification
- MEASURED locally — benchmark suite 4/4 PASS re-executed
- Wire scenario type
volcanic_eruption— contract at src/services/kaggleSim.ts:28-240; job API at Simulation job API
MEASURED marks values produced by executing the actual code on this machine (commands in Reproduction; raw logs summarised in Methodology → Evidence runs).
Governing equations and coefficients
Source attribution as stated in the kernel header (verbatim):
Lava flow — 2D conservative shallow-water equations solved with a Rusanov (local Lax-Friedrichs) flux … The Rusanov face flux telescopes to exact mass conservation (verified by verify_closed_box). … Eruption column — 1D Morton-Taylor buoyant plume with turbulent entrainment … Terrain — REAL ONLY. … if real relief is absent the run fails fast with a legible error rather than fabricating a cone.
Coefficients and named constants
| Constant | Value | Meaning | Source |
|---|---|---|---|
| RHO_LAVA | 2600 kg/m³ | Basaltic lava density | kaggle-kernels/volcano-sim/main.py:74 |
| C_P_LAVA | 1200 J/(kg·K) | Specific heat | kaggle-kernels/volcano-sim/main.py:75 |
| K_THERMAL | 1.5 W/(m·K) | Conductivity | kaggle-kernels/volcano-sim/main.py:76 |
| ETA_REF @ T_REF | 300 Pa·s @ 1450 K | Arrhenius reference viscosity | kaggle-kernels/volcano-sim/main.py:77-78 |
| E_A | 180 kJ/mol | Activation energy (range 100–400 noted in comment) | kaggle-kernels/volcano-sim/main.py:79 |
| T_LIQ / T_SOLID / T_CRUST | 1450 / 1320 / 1360 K | Liquidus, solidus, crust-onset (tholeiitic basalt) | kaggle-kernels/volcano-sim/main.py:80-83 |
| L_FUSION | 400 kJ/kg | Latent heat | kaggle-kernels/volcano-sim/main.py:84 |
| H_COEFF | 25 W/(m²·K) | Convective transfer | kaggle-kernels/volcano-sim/main.py:85 |
| σ_SB / ε | 5.67e-8 / 0.9 | Stefan–Boltzmann / emissivity | kaggle-kernels/volcano-sim/main.py:89-90 |
| CRUST_INSULATION | 0.92 (92 % loss cut) | Keszthelyi & Self 1998 crust effect | kaggle-kernels/volcano-sim/main.py:74-79 header comment lines 91-97 |
| τ_y | 1000 → 20,000 Pa | Bingham yield, eruption → near-solid | kaggle-kernels/volcano-sim/main.py:98-99 |
| D_ASH_DEFAULT | 316 µm | Median coarse-ash diameter → v_t ≈ 1.25 m/s (Stokes-regime note says ≈3 m/s at defaults) | kaggle-kernels/volcano-sim/main.py:127-128 |
| RHO_AIR / μ_air | 1.2 kg/m³ / 1.8e-5 Pa·s | Settling medium | kaggle-kernels/volcano-sim/main.py:124-125 |
| lapse rate Γ | 0.0065 K/m | Tropospheric profile for the plume | kaggle-kernels/volcano-sim/main.py:126 |
| α (entrainment) | 0.1 | Morton–Taylor coefficient | kaggle-kernels/volcano-sim/main.py:223 |
Parameter contract
Volcano parameters. Shared request envelope (validated at the client boundary before dispatch).
| UI control | Wire field | Unit | Valid range (UI · wire · kernel) | Default | Physical meaning | Source |
|---|---|---|---|---|---|---|
| Volcanic Explosivity Index slider | vei | VEI int | UI & wire 0–8 | UI 3 · kernel 3 | Selects the order-of-magnitude mass/lava/ash bin | src/components/scenarios/ScenarioEditor.tsx:89-101 src/services/kaggleSim.ts:174 kaggle-kernels/volcano-sim/main.py:143-152 |
| Wind Speed / Direction sliders | wind_speed_ms, wind_dir_deg | m/s; ° FROM | UI 0–120 km/h, 0–360; wire 0–60, 0–360 | UI 36 km/h / 260° · kernel 10 / 270 | Ash transport (height-resolved bins) | src/components/scenarios/ScenarioEditor.tsx:89-101 src/services/kaggleSim.ts:175-176 kaggle-kernels/volcano-sim/main.py:340-341 |
| Duration slider | duration_hours | h | UI 1–168 (overwritten 8·VEI); wire ≤ 720 | UI 48 · kernel 2 | Eruption window (source active first half) | src/components/scenarios/ScenarioEditor.tsx:89-101 src/services/kaggleSim.ts:177,617 kaggle-kernels/volcano-sim/main.py:765,923 |
| Lava Yield Scale slider | yield_scale | multiplier | UI 0.05–3; wire 0.01–10 | UI 0.3 · kernel 1.0 | Multiplies Bingham τ_y — calibration knob | src/components/scenarios/ScenarioEditor.tsx:89-101 src/services/kaggleSim.ts:202 kaggle-kernels/volcano-sim/main.py:100-105,781-782 |
| Lava Volume Scale slider | mass_scale | multiplier | UI 0.5–5; wire 0.1–100 | UI 2 · kernel 1.0 | Perturbs erupted mass within the VEI bin (2–5× spread noted) | src/components/scenarios/ScenarioEditor.tsx:89-101 src/services/kaggleSim.ts:204 kaggle-kernels/volcano-sim/main.py:768-777 |
| Ash Particle Diameter slider | ash_particle_diameter_m = µm/1e6 | m | UI 50–2000 µm; wire 50e-6–2e-3 | UI 316 µm | Drives terminal settling velocity | src/components/scenarios/ScenarioEditor.tsx:89-101 src/services/kaggleSim.ts:189,509 kaggle-kernels/volcano-sim/main.py:896 |
| Ash Cloud Diffusivity slider | ash_diffusivity_m2_s | m²/s | UI & wire 10–5000 | UI 500 · kernel 500 | Sub-grid turbulent eddy diffusion | src/components/scenarios/ScenarioEditor.tsx:89-101 src/services/kaggleSim.ts:191 kaggle-kernels/volcano-sim/main.py:901 |
| Wind-Shear Factor slider | ash_wind_shear_factor | fraction | UI & wire 0–1 | UI 0.5 · kernel 0.5 | Low-level wind fraction of free stream | src/components/scenarios/ScenarioEditor.tsx:89-101 src/services/kaggleSim.ts:193 kaggle-kernels/volcano-sim/main.py:902 |
| Vent (globe click; snapped to crater floor) | vent_frac_x/y | fraction 0–1 | clamped; floor-scan within 1.5 km | 0.5, 0.5 | Column + lava source location | src/services/kaggleSim.ts:194-200,320-362 kaggle-kernels/volcano-sim/main.py:785-788 |
| Terrain (required) | terrain(+_gs) / terrain_b64 | m above ellipsoid | must be present or the run raises | — | Real sampled relief; NO synthetic fallback | kaggle-kernels/volcano-sim/main.py:800-826 |
Outputs
| Field | Unit | Meaning | Source |
|---|---|---|---|
column_height.npy | m | Ash-column height field (VEI table height × radial decay) | kaggle-kernels/volcano-sim/main.py:1015-1019,1393 |
ash_deposit.npy | kg/m² (renderer shows mm via bulk ρ 1000 kg/m³) | Cumulative deposit | kaggle-kernels/volcano-sim/main.py:127-129,1394 |
ash_column.npy | kg/m² | Airborne column mass at t_end | kaggle-kernels/volcano-sim/main.py:1395 |
lava_thickness.npy / lava_temp.npy | m / K | Lava thickness and temperature | kaggle-kernels/volcano-sim/main.py:1396-1397 |
terrain.npy + snapshots_column/ash/lava.npy + snapshot_times.npy | m; —; h | Animation series (up to 60 frames) | kaggle-kernels/volcano-sim/main.py:1398-1411 |
metadata.json | — | model/solver/plume/ash strings, settling velocity, plume_height_m, eruption_mass_rate_kg_s | kaggle-kernels/volcano-sim/main.py:1318-1333 |
Spatial-origin semantics
Square domain; row-major terrain, row 0 = north, metres above ellipsoid (server contract); vent at fractions (x = east, y = south) of the grid; column index increases east, row index south, and transport direction is the met convention +180° (wind FROM → TOWARD). Height-resolved ash bins above the domain. kaggle-kernels/volcano-sim/main.py:785-798,925-933
Documented validity limits (verbatim from the code)
'Terrain — REAL ONLY. … There is NO synthetic cone fallback: if real relief is absent the run fails fast with a legible error rather than fabricating a cone.' · 'Real eruptions of the SAME VEI bin differ 2–5× in ejected volume (Newhall & Self note the bins are order-of-magnitude).' · 'Stokes law (Cd = 24/Re) is valid only for Re < 0.5; for coarse ash (d ~ 316 µm) Re ≈ 60, so the Schiller–Naumann correction is essential.'
Before emitting, main() runs the flat closed-box conservation proof (gs = 64, 2000 steps, tol 1e-3); the suite also carries verify_steep_closed_box (well-balanced + mass on 30° slopes). kaggle-kernels/volcano-sim/main.py:607-680,1383-1386
Measured runs and timings
| Run / check | Measured result |
|---|---|
| Benchmark suite re-executed (run_benchmarks.py) | 4/4 PASS — B1 flat closed-box mass; B2 steep-terrain well-balanced mass; B3 Pinatubo 1991 ash isopach vs observed thickness–distance axes; B4 Kilauea 2018: modelled runout 15.0 km vs observed ~13.5 km, mass budget True, downslope True |
| Representative VEI 3 ×2 mass, 12 h, 20 km box on synthetic cone terrain (test input) | MER 5.56e+5 kg/s; Morton–Taylor plume integrates to 788 m while the VEI table column (10,000 m) drives ash-column height — both reported; ash budget Δ = 7.6e-15 relative, lava mass Δ = 0.0; wall 70.6 s at 156 m cells (crater pooling at this coarse resolution) |
| Boundary VEI 5, 800 µm ash, K = 1000, shear 0.8, 96² / 40 km | MER 2.22e8 kg/s; M-T plume 27,920 m (table 40,000 m); v_t(800 µm) = 3.17 m/s; both budgets PASS (Δ ≤ 2e-14); wall 3.6 s |
| Output limitation | main() writes to /kaggle/working unconditionally — local calibration/Monte-Carlo instead imports simulate_volcano() in-process via localRunner.ts; standalone local main.py runs reach the final budgets but fail at the write step (observed: Read-only file system '/kaggle') |
Reproduction
Commands
# The regression gate the docs cite (fast, in-process):
cd <repo>/kaggle-kernels/volcano-sim/benchmarks && python3 run_benchmarks.py
# → 'RESULT: 4/4 benchmarks passed'
# Server-side ensemble (no Kaggle token needed):
curl -s -X POST http://localhost:3001/api/kaggle/volcano/quantify \
-H 'Content-Type: application/json' -d '{ "request": {…volcanic_eruption params with terrain…}, "samples": 16 }'