Verification

Verification

Each test checks one part of pyFDS-Evac against a value computed without the code under test: a hand calculation, a published table, or FDS’s own output. Everything here is verification (does the code solve its equations correctly?), not validation against observed evacuations.

A test works at one of three levels:

LevelWhat runsWhat it catches
Equationone model function, no simulationa wrong formula or constant
Coupleda full pyFDS-Evac run on a synthetic field, no FDSwrong wiring: the field is not sampled at the agent, or the result does not reach the agent
FDS casea full run on a small FDS case (assets/)wrong reading of FDS output: slice height, units, species names

The tests

Click a test for its page: what it checks, the equation, the setup, the expected value, and the simulated result. Tests without a page yet link to their test file.

ComponentTestLevelWhat it checksStatus
Gas FEDCO dose in a uniform roomFDS caseFED reaches 1 at the hand-calculated time; the fraction of agents incapacitated follows the log-normal threshold (opt-in probabilistic mode)passes: dose and deterministic stop; the probabilistic stop pooled over 10 seeds (1000 agents) stays in the 95 % band (D = 0.023 against 0.043)
Gas FEDFDS FED_FIC caseEquationFED and FIC in the four zones of FDS’s own verification casepasses
Gas FEDS1 corridorCoupledan agent in constant CO stops within one FED update of t*passes
Gas FEDISO 20414 Test 19: incapacitation by toxic gasesFDS casefour gas mixtures separating the CO, CO₂ and O₂ terms: each occupant stops at the next update after the hand-calculated time, as FDS’s own FED device doespasses for CO, CO₂, O₂; HCN, NOₓ, irritants not yet (#257)
Heat FEDHeat dose in a uniform roomFDS caseheat FED at 100, 150 and 200 °C: every agent stops at the update where the hand sum on the FDS temperature reaches 1passes with --heat-clothing unclothed; checks the pipeline, not Eq. 63.44 itself; the default ISO Eq. (9) is an expected row only (#307)
Heat FEDS6 heatCoupledheat incapacitation at t*, cause recorded as heatpasses; checks the wiring of the default ISO Eq. (9), not the law itself
Heat FEDSFPE tablesEquationEq. 63.44 against Table 63.20 (convective rows): within the assumed ±0.5 min rounding of each whole-minute entry, shorter at 100–140 °C; never longer than Table 63.17’s reported dry-air times; the default ISO Eq. (9) recorded at 1.8–3.0 times Table 63.20passes (#219)
Heat FEDHeat endpointsCoupled--heat-endpoint: on the temperature history of SFPE Table 63.21 the tolerance dose reaches 1 in the fourth minute; at 150 °C the fatal dose crosses at the Eq. 63.47 time; endpoint, 205 °C and non-finite flag and unknown humidity reach the outputs; with --heat-clothing unclothed the FED history and manifest match a baseline from main (apart from heat_clothing); without an endpoint the run crosses at ISO Eq. (9)passes
Heat FEDTotal flux (test)Coupled--heat-fed-method total-flux against the hand formula of Eqs. 63.49 and 63.43: dense smoke at 300 °C (tolerance, ε 0.9, h 8) crosses at 5.8 s; clear air at 100 °C (tolerance, ε 0.05, h 8) at 190 s on convection alone; smoke at 200 °C (fatal, ε 0.5, h 8) has a radiant term of 1.17 kW/m², below the 2.5 kW/m² threshold; outputs carry heat_flux_kw_m2 and the methodpasses (#223)
Heat FEDHot layer (test)Coupled--heat-regime layer: head at 120 °C below a 300 °C layer (φ 0.5, ε_L 0.9; layer term 2.52 kW/m², just above the threshold) crosses at the hand time; distinct from the smoke regime and from double counting; layer column in the outputspasses; synthetic fields only; no FDS case runs the layer regime yet (#308); the #224 radiometer decks are FDS-only reference data
Heat FEDINTEGRATED INTENSITY (test)Coupled + FDS caseradiant-only crossing at the hand time (q = 3.98 kW/m², fatal after 159.7 s) and its scaling with f; a committed FDS 6.10.1 case read at the head height against FDS’s own devices; f = 1/4 against the FDS skin gauge in the #224 uniform roompasses; radiometer part skipped without the sciebo data (#221)
Heat FEDRadiant thresholdEquationISO 2.5 kW/m² on the radiant term of each source (gas, layer, U): 2.4 counts as zero, 2.5 counts, a negative term counts as zero, NaN still voids the dose; convection unchanged; heat_flux_kw_m2 stays physical; manifest records the thresholdpasses
Heat FEDRadiant and flame-pass referencesEquationEq. 63.45 against Table 63.21; Eq. 63.43 against Table 63.20’s radiant rows; dose of an agent walking past a flamereference only; they call no pyFDS-Evac code (#223)
Heat FEDHeat radiometer reference decksFDS caseFDS only, no pyFDS-Evac run: where a skin gauge’s incident flux q sits between U/4 and U under a hot layer, in a uniform room and beside a burnerreference data; no run reads it; the uniform room is the expected value of the f = 1/4 check above
Smoke speedS2 corridorCoupledapplied speed factor equals the Frantzich–Nilsson and Fridolf lawspasses
Smoke speedISO 20414 Test 18: walking speed in smokeFDS caseegress time in the ISO corridor at K = 0.5–10 1/m and from FDS: equals the clear-air time scaled by 1/f(K)passes
IrritantsFIC vs FED speedEquationon a short egress FIC slows agents at once while FED stays far below 1passes
Pre-movementDistributionsEquationsampled moments of the gamma, log-normal, Weibull and uniform presets; the constant 10 s default is not checkedpasses (#309)
Slice samplingNearest FDS nodeEquationnode- and cell-centred slices read at the right indexpasses
Slice samplingSlice heightFDS casethe gas FED reads the horizontal slice nearest 1.6 m in a room with CO in three layerspasses
Slice samplingSign legibility slice heightFDS casefdsvismap reads the horizontal extinction slice nearest 1.6 m, never a vertical slice listed first, and the same slice as the smoke samplerpasses
Slice samplingGradient fieldCoupledthe field is sampled at the agent’s current positionmissing (#24)
Sign legibilityUnit testsEquationreading distance, 30 m cap, viewing anglepasses
Sign legibilityS3 visibility gatingCoupleda sign is acquired only when legible through smokemissing (#22)
Cognitive mapFamiliarity: full map vs discovered mapCoupledwhat each agent knows, learns and walks, against sight lines computed from the planfails (tour, convergence): criteria 1–3 and 5 pass; 4 agents skip CP1, which criterion 4 does not allow for; the discovery egress time is not grid-converged (#168, #250)
Cognitive mapS5 staff vs visitorCoupledthe cognitive map is used in the run loopmissing (#23)
RoutingS4 T-junctionCoupledsmoke on one branch makes every agent switch exitpasses
RoutingGolden rerouting decisionsEquationroute costs and decisions unchanged (regression, not verification)passes

Every field is read from the horizontal slice nearest --smoke-slice-height (1.6 m). The FDS-case checks of that rule, per quantity: gas, the slice-height test above; sign legibility, the sign-legibility slice-height test; temperature and U, the committed case of the INTEGRATED INTENSITY test; extinction for walking speed, only the weak check of ISO Test 18, whose slices differ by very little (#259).

Movement itself (walking, collision avoidance, flow through doors) is JuPedSim’s and is not retested here; see Status against ISO 20414.

Running the tests

uv run pytest tests/verification -m "not slow"   # fast suite
uv run pytest tests/verification                  # incl. ensemble checks

Seven rows of the table link tests outside tests/verification, including the CI tests behind ISO Tests 18 and 19. Run them with:

uv run pytest tests/test_heat_radiant_threshold.py tests/test_fic_vs_fed_speed.py \
    tests/test_slice_node_index.py tests/test_visibility.py \
    tests/test_rerouting_golden.py tests/test_smoke_speed.py \
    tests/test_iso_table21_coupled.py tests/test_iso_table22_coupled.py

uv run pytest runs everything. Tests that need the external data store (for example the radiometer decks, $HEAT_RADIOMETER_DATA) are skipped when it is absent.

The FDS cases need their FDS output, which is not in the repository; each test page says where to get it or how to rerun FDS.

Last updated on