Scenario assets
Scenario assets
This page is for maintainers: what each tracked scenario proves, and which test checks it. To run a scenario, see Usage.
Scenario definitions are stored in assets/.
assets/README.md indexes the folders and the file
conventions; what each one proves, and where that proof is checked, is below.
- ISO-table21: ISO 20414:2020 Table 21 (Test 18, reduced visibility vs
walking speed) — corridor 2 m x 100 m, one occupant at 1,25 m/s, constant
extinction. See the asset README for the
clause-by-clause comparison, including the two places we deviate. Proves the smoke speed reduction law is applied correctly end to end:
test_iso_table21_constant_extinction_matches_expected_time_ratioruns the scenario clear and then under aConstantExtinctionFieldat five extinction coefficients (0.5, 1.0, 3.0, 7.5, 10.0 /m), asserting the ratio of evacuation times matches1 / speed_factor_from_extinction(k)within 8% and that every recordedspeed_factorequals the expected one exactly. Doubles as the standard small fixture intest_progress_callback.py,test_webapp.pyandtest_fed.py, which use it for its size rather than its ISO provenance. - ISO-table22: ISO 20414:2020 Table 22 (Test 19, occupant
incapacitation by fire/smoke) — room 10 m x 10 m x 3 m, one occupant held
still by ISO’s prescribed pre-evacuation time above 10 000 000 s. See
the asset README. The gas field is stubbed, so
it verifies the accumulator, not the FDS coupling; the coupled four-case
version is
iso_table22_coupled. One agent withv0forced to 0 in a fixed gas concentration; config and geometry only, no deck. Proves the runtime FED accumulator agrees with the closed form:test_iso_table22_stationary_runtime_matches_analytic_threshold_timetakes the analytic FED=1.0 time fromtime_to_fed_threshold_s()and asserts the observed crossing lands within one timestep of it, thatfed_max >= 1.0, and that the agent does not evacuate. Holding the gas inputs constant is deliberate; this tests the accumulator, not the gas sampling. Also backs the FED history throttling test. - t_junction: T-corridor FDS scenario with cable fire, two exits (A open, B smoke-accumulating),
200 visitors spawning in the branch; used for visibility-aware routing and cognitive
map verification. Includes
config_full.jsonandconfig_discovery.jsonfor familiarity-tier comparison. The rerouting mechanism itself is verified by scenario S4 intests/verification/test_s4_tjunction_reroute.py(control arm and null-field control both record zero switches; smoke forces every agent B→A and never the reverse; reroute latency stays within the configured interval; switch count is reproducible under a fixed seed). Note that S4 builds its own T-corridor viaharness.t_junction_scenario()with a synthetic smoke field rather than loading this asset, so the mechanism is covered but the deck and config here are not exercised by the suite. This config uses flow spawning deliberately: under by-number placement an agent’s route-eval source node is its assigned exit, which makes rerouting degenerate (issue #21). - fed_incap_co_2000ppm / fed_incap_co_4000ppm / fed_incap_co_8000ppm:
FED accumulation and probabilistic-incapacitation verification against a
hand-calculated reference (
fed_hand_calc.py), at three constant CO concentrations (2000/4000/8000 ppm) in a sealed, spatially uniform room — removing gas-transport physics as a variable isolates the FED/incapacitation pipeline logic. 100 non-evacuating agents circling a rectangular path, FDS domain split across 4 MPI meshes to confirm gas data is consistent at mesh boundaries. All three concentrations currently match the hand-calc’s FED=1.0 crossing time to <0.5% (2000 ppm: 782.4 s hand-calc vs 786 s simulated; 4000 ppm: 382.3 s vs 384 s; 8000 ppm: 186.6 s vs 187 s). Verified by running the cases and comparing, not by a test intests/. (See the FDS input pitfalls on the FED page for the conflicting-&INITpitfall this suite surfaced.) Full writeup:docs/testing-homogeneous.md. - Cognitive Map Memory: 4x32 m corridor with a side alcove, 20
discoveryagents. The side exit’s sign faces west and is legible only fromy ∈ [12.3, 27.8]on the centreline on the 0.25 m grid ([12.5, 27.5]analytically under the 30 m cap) — a window that falls out ofview_angle * max_vis >= distancerather than being tuned, and thatbuild_geometry.pyrecomputes and asserts. Proves the cognitive map does the one thing a visibility query cannot: remember. The side exit is unknown at spawn, enters the map on crossingy=12, and is still there aty=30where the sign is long unreadable. Persistence is the load-bearing claim — delete the expansion rules and acquisition still appears to work for any agent starting inside the window. A third test closes the loop to routing: a remembered-but-illegible exit must still be routable.scripts/generate_cognitive_map_states.pyrenders the three states (unknown / legible now / remembered, the hatched exit being the memory made visible) from liverank_routesprobes. The agent takes the side exit fromy = 14to24and the end exit fromy = 26(the two are equally far aty ≈ 25.4); walking back toy = 10with its map, it takes the side exit where it took the end exit on the way up. In the full run each agent switches once,E_end → E_sideat t = 5–20 s, and egress takes 22.3 s. Checked bytests/test_cognitive_map_memory.py, which pins the probe outcomes. - FIC vs FED Speed: 4x50 m sealed corridor, 30 agents, one exit. The gas is
prescribed by a single
&INIT(CO at 2000 ppm, acrolein at 10 ppm) rather than burned, so concentration is constant in space and time and the only variable across runs is which tenability rules are enabled — set from the command line (--disable-tenability,--fic-alpha 0, or--enable-fic-speed; the FIC slowdown is off by default, as in FDS+Evac). Separates the two rules by timescale: FED is a cumulative dose with a threshold and does nothing below it (0.079 /min here, so 13 minutes to reach FED = 1, against a ~33 s egress), while FIC responds instantaneously (FIC = 0.5, speed factor 0.65, so ~51 s). The prediction is stated in the asset README before running and is falsifiable: if FED materially slows an agent over a minute of exposure, the model or the reasoning is wrong. A control test records that acrolein is not only an irritant — it also sits in FED’s Fractional Lethal Dose sum, so removing it takes 100% of the speed penalty but only 3% of the dose rate, and that asymmetry is what makes the two rules separable. Also pins the O2 hypoxia term against the published closed form (Fire Safety Journal, surrogate-gases paper, Eq. 9) rather than against our own docs. Checked bytests/test_fic_vs_fed_speed.py. - Exit Visibility Alpha: 4x30 m corridor, 40
discoveryagents, two exits. The two configs differ in exactly one value — the viewing bearing (alpha) of the near exit’s sign — so any difference in exit choice is attributable to sign orientation and nothing else. Proves that legibility decides cognitive-map membership, and membership decides the exit: atalpha=0both exits enter the map and agents take the nearer one; atalpha=180the near exit never enters the map and agents walk 10 m further to the only exit they know about, even though distance favours the near one by more than 2:1. The near exit is absent, not rejected — a stronger claim, since a rejected route still appears in the ranking and the all-rejected fallback can reinstate it. Checked bytests/test_exit_visibility_alpha.py, which needs no FDS output: it reimplements fdsvismap’s clear-air rule (view_angle * max_vis >= distance) so the test exercises the routing decision rather than the third-party solver. A companion test pins that afull-familiarity agent ignores the bearing entirely — signs are wayfinding information and bind only where knowledge is incomplete. The folder README documents the visibility ceiling (30 m by default) that makes a sign illegible at any bearing, and how much tighter it becomes once smoke is present (c / K̄, so 6 m atc=3,K̄=0.5). - Familiarity Test Full / Familiarity Test Discovery:
SocialForceModelscenario on a hand-drawn maze-like floor plan (20x18 m, 0.1 m walls, 1.2 m doors throughout, generated parametrically by each folder’sbuild_geometry.py), differing only in the spawn distribution’sfamiliarityvalue. A matching fire deck lives atassets/familiarity_test_full/familiarity_test.fds(real combustion via&REAC, not a prescribed&INIT; walls mirror the walkable geometry exactly so smoke propagates through the same doorways agents use). These two configs use the legacyjourneys/transitionsshape directly (the web editor’sjourneys_v2format is auto-migrated to this shape byload_scenario, but was hand-converted here to add the extra edge below). The maze’s start room is one open box that connects directly to the checkpoint outside the exit door (jps-checkpoints_0 → jps-checkpoints_3), completely bypassing the scripted checkpoint tour through the rest of the maze — a real ~39% shorter route (32 m vs 52 m) that’s declared as an extra graph edge (taggedjourney_id: "shortcut"intransitions, invisible to the static spawn-time journey) for the rerouting/cognitive-map system to find. Run with--enable-rerouting(no--fds-dir/vis-cache needed — divergence here is pure-distance, not smoke-driven) to see it:fullagents know the whole graph immediately and are assigned the shortcut at spawn;discoveryagents start knowing only the spawn’s declared neighbor and explore the nearest known-but-unvisited doorway at each step — which for this maze’s geometry happens to coincide with the original scripted tour the whole way, so they end up taking the long route without ever finding the shortcut. Verified:fullevacuates in 34.5 s vsdiscovery’s 68.1 s (both 20/20 evacuated; see the results table indocs/testing-familiarity.md).
Last updated on