Hazard simulations — overview & architecture
Full description: Read the full narrative
Seven disaster scenarios share one pipeline: the client builds a typed request through a zod discriminated-union contract whose bounds mirror the kernels’ own validity checks; the server either executes the kernel locally (python3) or pushes it to Kaggle; results land in a uniform results/<jobId>/ directory of NumPy grids + metadata.json and stream back over SSE.
Layers
| Layer | File | Responsibility |
|---|---|---|
| Contract | SimulationRequestSchema (7 branches) | fail-fast validation; missing values throw instead of being fabricated — the builder explicitly forbids the old Number(x) || default pattern src/services/kaggleSim.ts:28-240,381-415 |
| Geometry | bbox → centre/extent/fractions | square domain from the drawn box; vent/epicentre/landfall as 0–1 grid fractions; crater-floor snapping src/services/kaggleSim.ts:246-362 |
| Form physics | derivePhysicsFormOverrides | UI-side derived defaults computed from user inputs (e.g. Cat→pressure/radius; hidden tsunami displacement) src/services/kaggleSim.ts:589-669 |
| Transport | submit / SSE / poll / results / cancel | src/services/kaggleSim.ts:549-577 |
| Runner | simRunner.ts | route local vs Kaggle, param compaction (terrain→uint16 base64), GEBCO/land-cover auto-sampling server/kaggle/simRunner.ts:126-215,456-495,520-640 |
| Scientific endpoints | routes.ts | calibrate (μ×ξ grid), Monte-Carlo quantify, GeoTIFF export server/kaggle/routes.ts:263-810 |
Execution modes
| Kernel | Mode | GPU code? | Metadata enable_gpu | Physics executed in this review |
|---|---|---|---|---|
| earthquake-sim | local CPU | no | false | MEASURED — direct + HTTP e2e |
| fire-sim | local CPU | no | false | MEASURED — direct ×4 |
| hurricane-sim | local CPU | no | false | MEASURED — direct ×3 |
| flood-sim | Kaggle | no | true | MEASURED — solver + gates via python3 |
| tsunami-sim | Kaggle | no | false | MEASURED — in-process solver incl. real GEBCO |
| volcano-sim | Kaggle + local in-process (UQ/calibration) | no | false | MEASURED — benchmarks 4/4 PASS |
| landslide-sim | Kaggle + local in-process (UQ/calibration) | no | false | MEASURED — convergence PASS |
Job lifecycle
POST /api/kaggle/simulate→{jobId, status, streamUrl}(HTTP 400 on missing type/lat/lon or unknown type) — server/kaggle/routes.ts:164-201- States:
queued → running → complete | error(cancel → “cancelling”, local SIGKILL afterLOCAL_SIM_TIMEOUT_MSdefault 120 s) — server/kaggle/simRunner.ts:status transitions + 134 - Progress: SSE
/streamwith detail strings — local: “Running locally (2D kernel, CPU)…”, “Done locally”; Kaggle: “Uploading to Kaggle GPU…”, “Kernel pushed. Kaggle GPU booting…” — server/kaggle/simRunner.ts:169,204,927-929 server/kaggle/routes.ts:225 - Results:
/results(metadata + final stats),/grid/:name(npy bytes or JSON ≤ 5M elements),/geotiff/:name(WGS84 GeoTIFF),/jobs,/kernels— server/kaggle/routes.ts:245-442 - Measured e2e latency (local quake): submit → complete in 166 ms (server-side timestamps sim_44d5c7d7).
Real-data bridges feeding kernels
| Bridge | Source | Feeds |
|---|---|---|
| Terrain | Cesium globe sampling (256² on the run path; median-fill, retry ×3; null → kernel synthetic) | src/components/scenarios/studyAreaTerrain.ts:5-149 src/lib/terrainSampler.ts:3-31 |
| Bathymetry | GEBCO 2020 via api.opentopodata.org (64² sample, uint16-quantized) | server/kaggle/bathymetry.ts:10-40 |
| Land cover | ESA WorldCover v200 → per-cell Manning n | server/kaggle/landCover.ts:module kaggle-kernels/flood-sim/main.py:61-84 |
| Wind profiles | ERA5-derived (volcano ash bins) | server/kaggle/era5Profile.ts:module kaggle-kernels/volcano-sim/main.py:300-330 |
Calibration & uncertainty endpoints
| Endpoint | What it does | Execution | Source |
|---|---|---|---|
| POST /api/kaggle/calibrate | μ×ξ grid search fit to an observed landslide runout (grid {0.15…0.40}×{100…800}) | local python3, in-process kernel import | server/kaggle/routes.ts:479 kaggle-kernels/landslide-sim/calibrate.py:24-25 |
| POST /api/kaggle/landslide/quantify | N-sample Monte-Carlo depth maps (mean/min/max/exceedance) + summary percentiles | local python3 | server/kaggle/routes.ts:541 server/kaggle/localRunner.ts:36-60 |
| POST /api/kaggle/volcano/calibrate | yield_scale sweep vs observed lava runout | local python3 | server/kaggle/routes.ts:611 |
| POST /api/kaggle/volcano/quantify | 16-member ensemble (ash/lava P5/P50/P95 + plume stats) | local python3 | server/kaggle/routes.ts:690 server/kaggle/localRunner.ts:62-92 |
| GET /api/kaggle/volcano/profile | real wind-profile sampling for a box | server | server/kaggle/routes.ts:47 |
Capability pages
BSSA14 GMPE · measured 0.008 s compute, 166 ms e2e job
HLL/minmod SWE · measured flat-bed stability + sloped-bed instability
Lava + plume + ash · benchmarks 4/4 PASS measured
Voellmy–Salm · convergence gates PASS measured
Local-inertial SWE · mass closure 0.0000 % measured
Holland + surge + waves + rain + runoff · gates PASS measured
Rothermel + Anderson-13 · calibration PASS measured