Route choice in smoke after Schröder et al. (2015)
Schröder et al. (2015) let agents in an assembly hall choose between two doors and two exits while smoke from a fire in a neighbouring room spreads. We build their geometry, add our own growing fire, and run pyFDS-Evac’s own smoke-aware routing on it with 200 agents and 10 seeds per case:
- Exit and door shares. How the default
gaterouter and theadditiverouter change them in a growing fire, against a smoke-blind crowd. - Door choice by movement start. Why, under
gate, the door an agent takes depends mainly on when it starts moving. - What the router sees. It reads the smoke along the whole route at 1.6 m, including smoke that will arrive later. Schröder’s sensor reads the smoke present in the agent’s room along straight lines at 2.8 m. This difference in perception scope is #125.
Download the files for this page (100 kB zip)
scripts/docs/schroeder2015_route.py and
scripts/docs/schroeder2015_fire_figures.py print every number and draw
every figure on this page; scripts/docs/study_animations.py draws the
animation. The page reports research software applied to
one scenario and gives no design or safety verdict.The result in brief
Main fire a047_pvc_h40, mean of 10 seeds. The no-fire and smoke-blind
arms are identical, so the smoke-blind arm is the reference:
| Arm | Exit-E share | ΔE against smoke-blind (95 % CI) | Door split |
|---|---|---|---|
| no fire = smoke-blind | 0.520 | 0 | boundary at y = 12.54 ± 0.13 m (per seed) |
gate | 0.702 | +0.182 (+0.140, +0.224) | no boundary in metres (valid in 1 of 10 seeds); Δy > 0 in 10 of 10 seeds (post hoc sign test, p = 0.002) |
additive | 0.504 | −0.016 (−0.025, −0.007), below 0.048 | Δy = −0.08 m (−0.38, +0.22), not resolved; a valid boundary in 10 of 10 seeds |
Δy is the boundary minus the clear-air boundary of the same seed. A positive Δy moves the boundary toward door B, so more agents use door A. A change in the E share counts if it exceeds 2 × SD of the smoke-blind shares, 0.048. A shift in Δy counts as resolved if its 95 % CI excludes zero.
- Gate sends more agents through door A to exit E than clear air does: E share 0.702 against 0.520.
- (Post hoc) Gate’s door choice follows mainly when an agent starts moving. The door-B share is 0.04 for agents starting at 30–120 s and 0.74 for those starting at 150–300 s. In clear air it is about 0.5 throughout.
- The cause is a hall-wide re-path at 45 s and a wave of fallbacks after the first routes are refused. The path search reads the smoke present at decision time, while the route’s τ reads the smoke each point will have when the agent gets there. From 129–132 s every route is refused for the first agents, and the fallback sends most of them to exit F, by door A or door B.
- Additive does not resolve a shift on the main fire. Its Δy is
−0.08 m (95 % CI −0.38, +0.22) and its ΔE of −0.016 is below the 0.048
threshold, so it fails the E-share criterion. On
a047_pvc_h35the shift is +0.28 m (+0.02, +0.53), resolved by a narrow margin, with ΔE +0.011, also below 0.048. Ona012_pvc_h30it is +2.02 m (+1.61, +2.43) with ΔE +0.087. The earlier version of this study reported a resolved main-fire shift of −0.90 m. - This is a rerun with a changed fuel. The decks now use
ΔHc 10,300 kJ/kg instead of 16,400
(#796).
The differences from the earlier version of this study combine the fuel
change with the code changes between
c619a046(pyFDS-Evac 0.4.0) and01a30348(0.6.1). For the additive shift on the main fire the fuel alone accounts for the change; see Earlier version. - Heat and the 400 s cap. Heat entered neither routing nor
tenability. Up to 9 late-starting agents per run on the main fire (up
to 12 on
a047_pvc_h35) were still walking at 400 s.
The building

Tags: [P] published in the paper, [D] digitised from Schröder et al. (2015), Figs. 2–3 and 6 (±0.5–1 m), [A] assumed here.
| Item | Value | Tag |
|---|---|---|
| Room 1, hall | x 0–10.5, y 0–24 m; interior x 0.2–10.6 m (10.4 m, on the 0.2 m grid) | [D] / [A] |
| Room 2, corridor | x −5–0, y −10–35 m; exits E (bottom) and F (top), 2 m wide at x −3.6 to −1.6 m | [D] / [A] |
| Room 3 | y 24–31 m; x not given in the source, taken as the hall’s width | [D] / [A] |
| Doors | all 2 m wide. A at y 0.6–2.6, B at y 20.6–22.6, D at y 26.6–28.6, C at x 4.4–6.4 m; snapped to the 0.2 m grid; 2 m high in FDS | [P] width / [A] |
| Floor | 554 m² meshed in FDS; 545 m² inside the walls; 471 m² walkable | computed |
Departures from the source.
- Room 3 and doors C and D are not walkable and not in the stage graph. They stand in for Schröder’s room-to-corridor sensor. In FDS, C and D are open.
- Doors A and B are waypoints, E and F are exits. Each exit has a 0.8 m deep passage, so agents enter it before they are removed (#349).
- The waypoint split is 50/50 at A and at B, because the engine needs an explicit split where a waypoint has two exits. Route ranking picks each agent’s exit. In clear air nobody crosses over: only A→E and B→F occur.
- Agents start uniformly in the hall, 0.3 m from the walls. Model CFSM,
radius 0.15 m, familiarity
full. - FDS 6.10.1 is used. Schröder used FDS 6.1.2.
The fire
The paper publishes no fire: burner, heat release rate, fuel, soot yield, grid, ceiling height and end time are all unstated. Our fire was set from design-fire practice before any routing run. One of nine variants was then chosen against a smoke target, also before any routing run. That choice was made on a sweep with the earlier fuel, 16,400 kJ/kg. The decks were then changed to 10,300 kJ/kg (#796) and not scored again.
| Item | Main fire a047_pvc_h40 | a047_pvc_h35 | a012_pvc_h30 | Source |
|---|---|---|---|---|
| Growth | t², α = 0.047 kW/s² (fast) | same | α = 0.012 kW/s² (medium) | SFPE Handbook, 6th ed., Ch. 3, Table 3.5 |
| Cap | 1.5 MW: HRRPUA 250 kW/m² on a 3 × 2 m burner centred in Room 3 (x 4–7, y 26.6–28.6 m) | same | same | HRRPUA after DIN EN 1991-1-2/NA, via Schröder (2017), p. 74; cap [A] |
| Cap reached at | 178.6 s | 178.6 s | 353.6 s | computed (TAU_Q) |
| Fuel | PVC: soot yield 0.172, CO yield 0.063 kg/kg, ΔHc 10,300 kJ/kg | same | same | Yields from the FDS User’s Guide PVC example, on which Schröder (2017), Table 4.5, p. 75, is based; heat of combustion from the consistent set of Osburg et al. (2025), Table 2, which matches the reaction’s oxygen use at 13.1 MJ/kg O₂. Up to 0.6.1 the decks used 16,400 kJ/kg, the heat of complete combustion of SFPE Table A.39 (#796) |
| Ceiling | 4.0 m | 3.5 m | 3.0 m | [A]; the paper extracts smoke up to 3.0 m (Table 2, p. 334), so its ceiling is above 3 m |
| Grid, time | 0.2 m (dz 0.1944 m at 3.5 m), 480 s, slices every 1 s | same | same | [A] |
Smoke is written at 1.6 m (routing, walking speed and gas dose), and at 2.0 and 2.8 m for comparison. With the 3.5 m ceiling FDS places these at 1.56, 1.94 and 2.72 m; pyFDS-Evac takes the nearest slice and logs the height mismatch.
How the main fire was chosen
Steps 2 to 5 below, the nine-variant table and the smoke-entry figure describe a sweep run with the earlier fuel, HEAT_OF_COMBUSTION 16,400 kJ/kg. The routing runs on this page use 10,300 kJ/kg; the sweep was not repeated, so its scores and K values do not describe the decks routed here.

- The target was fixed first. It is our reading of the paper’s Fig. 6c (p. 335, the 2.8 m extraction at 165 s, printed without a colour scale): Room 3 and the upper corridor opaque (K ≥ 2.3 1/m), the lower corridor clear (K ≤ 0.23), the lower hall at K 0.7–1.4, the upper hall clear (K ≤ 0.23 [A]).
- Nine runs on the 0.2 m grid (16,400 kJ/kg for the PVC variants): α ∈ {0.012, 0.047} × {PVC, PUR} ×
ceiling ∈ {3.0, 4.0} m, plus the central case
a047_pvc_h35. Each is scored by S, the mean over five regions of the share of nodes that meet the target. - No automatic pick was plausible. The best score, 0.60 for
a012_pvc_h30, equals that of a field with smoke only in Room 3. No variant beats that null field.a012_pvc_h30also reverses the hall pattern: median K 2.0 1/m in the upper hall against 0.99 in the lower. - Smoke enters the hall through door C and piles up at the far, door-A end (details below). Whether the 2.8 m slice shows the lower hall darker depends on how far below the ceiling it sits.
- The maintainer chose
a047_pvc_h40by visual match to Fig. 6c. It is the only variant with the lower hall darker than the upper (median K 1.5 against 0.51 1/m) and an opaque upper corridor (87 % of nodes). It differs from Fig. 6c in four ways: the corridor toward E is smokier (median K 0.94 against ≤ 0.23); the lower hall is patchier and darker; some smoke sits at the top of the hall near C; and its score is 0.48 against the best 0.60.
The comparison fires are a012_pvc_h30 (best score, reversed hall
pattern) and a047_pvc_h35 (the central design fire, smoke almost
everywhere). The fire was chosen against the smoke target only; no route
outcome was known.
The scores of all nine variants (16,400 kJ/kg PVC fuel)

| Variant | S (165 s) | S (160–170 s) | Room 3 | Upper corridor | Lower corridor | Lower hall | Upper hall | Median K: upper corridor / lower corridor / lower hall / upper hall |
|---|---|---|---|---|---|---|---|---|
| a047_pvc_h30 | 0.40 | 0.40 | 1.00 | 1.00 | 0.00 | 0.00 | 0.00 | 8.4 / 4.2 / 4.9 / 6.7 |
| a047_pvc_h35 | 0.40 | 0.40 | 1.00 | 0.98 | 0.00 | 0.00 | 0.00 | 4.7 / 1.6 / 2.8 / 2.4 |
| a047_pvc_h40 | 0.48 | 0.46 | 1.00 | 0.87 | 0.08 | 0.40 | 0.08 | 3.5 / 0.94 / 1.5 / 0.51 |
| a047_pur_h30 | 0.41 | 0.38 | 1.00 | 0.59 | 0.00 | 0.49 | 0.00 | 2.4 / 1.3 / 1.4 / 1.9 |
| a047_pur_h40 | 0.40 | 0.41 | 1.00 | 0.02 | 0.30 | 0.09 | 0.62 | 0.97 / 0.28 / 0.44 / 0.2 |
| a012_pvc_h30 | 0.60 | 0.62 | 1.00 | 0.43 | 1.00 | 0.59 | 0.00 | 2.3 / 0 / 0.99 / 2 |
| a012_pvc_h40 | 0.55 | 0.55 | 1.00 | 0.02 | 1.00 | 0.00 | 0.73 | 0.4 / 0 / 0.0066 / 0.14 |
| a012_pur_h30 | 0.24 | 0.23 | 0.19 | 0.00 | 1.00 | 0.00 | 0.00 | 0.64 / 0 / 0.26 / 0.55 |
| a012_pur_h40 | 0.39 | 0.39 | 0.00 | 0.00 | 1.00 | 0.00 | 0.95 | 0.087 / 0 / 0.0012 / 0.04 |
Region columns are the share of nodes meeting the target; K is in 1/m. Regions are inset by one cell; the corridor beside the hall is not scored. PVC rows: ΔHc 16,400 kJ/kg (the routed decks use 10,300). PUR: soot yield 0.056, CO yield 0.122 kg/kg, ΔHc 18,770 kJ/kg (Schröder 2017, Table 4.4 and p. 74). The score uses one LES frame; the thresholds are a reading of a greyscale image.
Where the smoke enters the hall (post hoc, 16,400 kJ/kg sweep)

The decks have no velocity output and no device in door C, so the flow direction is inferred from the order in which the device trees first exceed K = 0.23 1/m. No flux is measured.
- Entry through door C. On the 2.8 m slice the front starts at C and moves toward y = 0.
- Doors A and B are outlets. The hall side of door A is reached 7–20 s before the corridor side in 9 of 9 variants; door B shows the same order in 8 of 9.
- Pile-up at the A end. For the fast PVC fires at 165 s the layer is 1.1–1.3 m deep from C to mid-hall and 2.7–3.3 m deep at the A end.
- So the upper/lower pattern at 2.8 m depends on the slice depth below the ceiling (H − 2.8 m) against the depth of the jet near C. With a 4.0 m ceiling and α = 0.047 the slice lies just below the jet near C and inside the pile-up at the A end.
The crowd and the routers
- 200 agents in the hall [P], placed uniformly at t = 0 [A].
- Walking speed v₀ ~ N(1.0, 0.2) m/s [P], clipped by the engine to 0.1–5.0 m/s.
- Pre-movement with mean 120 s and SD 60 s [P]: Weibull, scale 135.49 s, shape 2.101. The source uses N(120, 60) s, which pyFDS-Evac does not offer.
- Four arms, seeds 1–10 each: no fire; smoke-blind (
--smoke-blind);gate;additivewithw_smoke1.0, the engine default. The cost model is set explicitly in each scenario; at the time a misspelt name selected the additive model (#305). - Routing settings:
anticipate: true,foresight_horizon_sat its default (no limit),base_speed_m_per_s1.0. Routes are re-evaluated every 1 s, also during pre-movement. - Smoke height 1.6 m for routing, speed and gas dose. Schröder’s example extracts at 2.8 m.
- Tenability: gas FED on, heat FED off (both engine defaults).
- Horizon: 400 s against the FDS end of 480 s.
The routing model and the gate in detail explain each setting.
Which pre-movement distribution
pyFDS-Evac offers gamma, lognormal, Weibull, uniform and constant
pre-movement (pyfds_evac/core/premovement_distributions.py). N(120, 60) s
puts 2.3 % of agents below 0 s, so the reference is N(120, 60) truncated at
0. Each family is matched to mean 120 s and SD 60 s:
| Family (engine parameters a, b) | KS distance | W1 [s] | 99th percentile [s] | P(t > 300 s) |
|---|---|---|---|---|
| Weibull 135.49, 2.101 | 0.056 | 6.1 | 280 | 0.005 |
| gamma 4, 30 | 0.079 | 9.1 | 301 | 0.010 |
| uniform 16.1, 223.9 | 0.076 | 9.4 | 222 | 0.000 |
| lognormal 4.676, 0.472 | 0.105 | 12.6 | 322 | 0.015 |
| reference, N(120, 60) truncated at 0 | 260 | 0.001 |
Set both premovement_param_a and premovement_param_b. With only one
set, the engine silently uses its preset.
Results
Exit shares and flows

| Fire | Arm | E share | ΔE against smoke-blind (95 % CI) | Doors A / B | Routes AE / AF / BE / BF |
|---|---|---|---|---|---|
| a047_pvc_h40 | smoke-blind | 0.520 | 0 | 104 / 96 | 104.0 / 0.0 / 0.0 / 96.0 |
| a047_pvc_h40 | gate | 0.702 | +0.182 (+0.140, +0.224) | 154 / 45 | 140.1 / 13.9 / 0.2 / 44.9 |
| a047_pvc_h40 | additive | 0.504 | −0.016 (−0.025, −0.007), below 0.048 | 103 / 96 | 100.7 / 2.4 / 0.0 / 96.2 |
| a047_pvc_h35 | gate | 0.791 | +0.271 (+0.244, +0.298) | 158 / 41 | 157.8 / 0.0 / 0.3 / 40.5 |
| a047_pvc_h35 | additive | 0.531 | +0.011 (+0.003, +0.019), below 0.048 | 106 / 93 | 106.1 / 0.0 / 0.0 / 92.7 |
| a012_pvc_h30 | gate | 0.918 | +0.398 (+0.374, +0.422) | 183 / 17 | 183.1 / 0.0 / 0.4 / 16.3 |
| a012_pvc_h30 | additive | 0.607 | +0.087 (+0.073, +0.100) | 121 / 79 | 121.2 / 0.0 / 0.0 / 78.6 |
Mean of 10 seeds. The smoke-blind arm is the same on every fire. A + B and the route counts fall short of 200 by the agents still walking at 400 s (up to 9 per run on the main fire). The curves in the figure end at the cumulative count at 400 s, so E reads 139 there against 140.3 (AE + BE) in the table.
Door choice follows movement start (gate)

This measure was added after the first results were seen (post hoc). Under
gate, an agent’s door is predicted better by when it starts moving
than by where it starts: area under the ROC curve 0.82 against 0.74, and
McFadden R² 0.23 against 0.12 (0.40 for both together). Position also
carries information. Under additive, start position is the better predictor (AUC 0.96).
Door predictors for all fires
| Fire | Arm | AUC start y | AUC start time | R² start y | R² start time | R² both |
|---|---|---|---|---|---|---|
| a047_pvc_h40 | no fire | 1.00 | 0.50 | 0.99 | 0.00 | 0.99 |
| a047_pvc_h40 | gate | 0.74 | 0.82 | 0.12 | 0.23 | 0.40 |
| a047_pvc_h40 | additive | 0.96 | 0.56 | 0.62 | 0.01 | 0.66 |
| a047_pvc_h35 | gate | 0.76 | 0.83 | 0.14 | 0.23 | 0.43 |
| a047_pvc_h35 | additive | 0.96 | 0.55 | 0.61 | 0.01 | 0.64 |
| a012_pvc_h30 | gate | 0.81 | 0.47 | 0.18 | 0.01 | 0.18 |
| a012_pvc_h30 | additive | 0.97 | 0.41 | 0.67 | 0.01 | 0.71 |
Logistic models of door B, seeds pooled. An AUC below 0.5 means later starters use door B less.
Smoke-blind and gate, animated

Main fire a047_pvc_h40, seed 5, 0–398 s at 16 times real time. Left
smoke-blind, right gate; both arms have the same agents, start positions
and start times. Seed 5 has 152 agents through door A under gate; the
median of the 10 seeds is 152.5. Background: K at 1.6 m, the slice that routing,
walking speed and gas dose use. Open rings: agents in pre-movement. Dots:
walking agents, coloured and sized by their speed factor. Regenerated by
scripts/docs/study_animations.py.
What to watch for:
- 45–145 s. Under
gatealmost every agent that starts walking heads for door A, also from the upper hall. Smoke-blind splits the hall at about y = 12.5 m. By 146 s, 112 agents have passed door A undergateagainst 64 for smoke-blind. - From about 130 s. The first agents find every route refused (129–132 s
over the 10 seeds), as smoke at 1.6 m reaches the door-A end of the hall.
Under
gate, 6 agents pass door B before 145 s (the last at 65.3 s) and 40 from 152.2 s on. Those 40 all go to F through the smoky upper corridor, where their dots grow and turn red. - The end. Smoke-blind’s last agent leaves at 381.8 s, gate’s at
360.7 s. At 400 s nobody is inside under smoke-blind; under
gatefour agents bound for F are, with movement starts at 262–361 s.
The route figure below shows the 2.8 m slice for comparison with the paper. The animation shows 1.6 m, the slice that routing and walking speed use.
Why: a hall-wide re-path and a fallback wave
Five facts of the gate code explain the pattern
(pyfds_evac/core/route_graph.py):
- The path search weights each edge by
k_avg·L + 1e-6·L(GatePolicy.edge_weight), so length only breaks ties: any trace of smoke on the shorter path sends the search onto a smoke-free path of any length. - The search starts where the agent stands (#451): the walk to each door is the first leg, charged the smoke on that walk. The smoke in the hall is nearly uniform at these times, so almost every hall agent gets the same door for a given exit.
- The search uses the smoke present at decision time
(
_generate_candidates). The τ of each candidate is read point by point at the time the agent would reach that point, counted from where the agent stands (_measure_route, #650); see the routing model. - Routes are ranked by τ first (
GatePolicy.order_key). An exit switch needs the rival’s τ to be lower by more than 6 × 0.1 = 0.6 (_tau_band). A route is refused above τ = 6 for the current exit and 4.8 for a rival exit (RouteCostConfig; the rival budget of 4.8 held when this study was run; the margin was removed in 0.6.0, #187). τ = 6 comes from the original FDS+Evac. - Two refused routes: the lower τ decides, with a 20 % margin; a switch straight back is blocked for 10 s (#458).
The 45 s re-path happens at the same second in all 10 seeds; the later events vary between seeds:
| Time | Event |
|---|---|
| 45 s | Exit F re-paths via door A. Trace smoke on hall→B→F (router τ 0.10) makes the smoke-free path via A win, at 45.1 m against 24.5 m. E via A (23.5 m) is now more than 10 % shorter in time than F via A, so agents bound for F switch to E (_clears_exit_anchor): 209 exit changes at 45 s over 10 seeds, all logged shorter_path (#92). No route was refused. |
| 45–129 s | Almost every hall agent heads for A→E. 0.2 B→E agents per seed pass door B, at 71–87 s. |
| 129–132 s | Every route is refused for the first hall agents: their route τ, read at the time they would reach each point, passes 6 as smoke piles up at the door-A end, earlier than the median curves in the figure below. The fallback keeps the current route until a rival’s τ is more than 20 % lower. |
| after the first refusals | Fallback wave: 878 fallback switches over 10 seeds. Old route to new route: A→E to A→F 311, A→E to B→F 212, B→E to B→F 183, A→F to A→E 166, B→F to A→E 6; in all 878 the new route has the lower τ. 706 of them lead to exit F, by door A or door B. |
| 158–175 s | Exit E re-paths via door B (158–175 s over seeds; the mechanism analysis starts from the first pass at 165 s), but B→E is already refused (router τ 51.10–62.44, median per pass, at 165–170 s; A→E 26.80 one pass earlier), so almost nobody turns from A to B→E. Same-exit re-paths (better_path) number 4.6 per seed. |
Between two refused routes the 20 % margin and, at that revision, the 10 s return lockout applied (the lockout was removed in #187).

τ is read point by point at the time the agent would reach each point. A route appears only while the path search offers it for its exit to at least one agent.
The pre-registered mechanism was refuted; its direction held. Before the runs we predicted that B→E would carry more τ than A→E and so move the boundary toward door B. Under gate the door split did move toward B (Δy > 0 in 10 of 10 seeds), and from 130 s B→E does carry more τ than A→E (τ figure), but that comparison does not move the agents: almost nobody takes B→E (0.2 per seed). The shift toward door A comes from the 45 s re-path of exit F, and the later door-B users reach F by the fallback. Additive had no registered direction; on the main fire it now fails criterion 2, which it passed in the earlier version (see Earlier version below).
Reroutes per seed, main fire
| Arm | Switches | Agents | By reason |
|---|---|---|---|
| gate | 182.4 | 116.2 | 69.7 shorter_path, 87.8 fallback, 20.3 smoke_reroute, 4.6 better_path (same exit, new path) |
| additive | 92.3 | 43.0 | 61.4 smoke_reroute, 25.2 shorter_path, 5.7 better_path |
Mean per seed. Since 0.5.0 each exit change is labelled by its cause (#92).
The additive boundary

Under gate, door B is not a monotone function of start y, so a boundary
fitted in metres is not meaningful: its CI lies inside the hall in 1 of the
10 seeds on the main fire. Gate is therefore reported by its E share, its
sign count and the door share by start. Under additive every seed has a
valid boundary; the shift is −0.08 m (−0.38, +0.22) on the main fire, not
resolved (7 of 10 seeds negative, 3 positive).
Additive charges length in both path and exit ranking and keeps the
spatial split; on the main fire it does not move it measurably.
The comparison fires
| Fire | Gate ΔE | Gate sign count | Gate re-path times | Additive Δy (95 % CI) | Additive ΔE |
|---|---|---|---|---|---|
| a047_pvc_h40 (main) | +0.182 | Δy > 0 in 10 of 10; valid boundary in 1 | 45 / 158–175 s; every route refused from 129–132 s | −0.08 m (−0.38, +0.22), not resolved; 7 of 10 negative | −0.016, below 0.048 |
| a047_pvc_h35 | +0.271 | 10 of 10; valid in 0 | 43–44 / 160–180 s; every route refused from 121–126 s | +0.28 m (+0.02, +0.53), resolved; 8 of 10 positive | +0.011, below 0.048 |
| a012_pvc_h30 | +0.398 | 10 of 10; valid in 0 | F via A 57 s; every route refused 167–170 s; E via B 225–359 s | +2.02 m (+1.61, +2.43); 10 of 10 positive | +0.087, above 0.048 |
a047_pvc_h35repeats the main-fire order of events: F via A at 43–44 s, every route refused from 121–126 s, E via B at 160–180 s.a012_pvc_h30reaches the gate’s sign by another route. Most agents take A→E (E share 0.918). Of its 16.7 door-B users per seed, 53 % started before the 57 s re-path; the fallback, from 167–170 s, sends later starters to door B before E re-paths via B at 225–359 s. Start time does not predict door B (AUC 0.47).h35andh40differ only in ceiling height. The evidence is two growth rates and three smoke fields, not three independent fires.- Additive’s shift is not resolved on the main fire
a047_pvc_h40. It is resolved and positive ona047_pvc_h35(marginal) anda012_pvc_h30.h35andh40differ only in ceiling, so the two results are not read as a ceiling effect. Its mechanism was not analysed (#848).
Routes of one seed, main fire

The background is the 2.8 m slice at 165 s, for display only. Routing used the 1.6 m slice.
How far to trust the numbers
Pre-registration. The criteria were fixed before the boundary and E-share statistics were computed. This is stated, but cannot be checked. The E-share threshold (0.048) was set after the seed-1 exit counts were seen (114, 137 and 99 via E for smoke-blind, gate and additive, in the first runs of the earlier version), and those counts already gave its sign. The sign test, the door share by start, the predictor table and the boundary validity count are post hoc.
Earlier version. This page was rerun with the 10,300 kJ/kg fuel (#796), 30 runs per fire. The differences from the earlier version of this study combine the fuel change with the code changes between
c619a046(pyFDS-Evac 0.4.0) and01a30348(0.6.1). The threshold 0.048 was recomputed from the new smoke-blind shares and is unchanged. For the additive arm on the main fire the two are separated (#848): smoke-blind and additive, 10 seeds each, at01a30348on the FDS output of the 16,400 kJ/kg deck give Δy −0.90 m (−1.16, −0.64) and ΔE −0.07, the earlier version’s values, against −0.08 m (−0.38, +0.22) and −0.02 with 10,300 kJ/kg. The shift collapsed with the fuel, not the code. With 10,300 kJ/kg more upper-hall agents switch from F to E between 60 and 150 s (25.3 against 10.9 switches per seed), while the later switches from E to F grow less (36.1 against 31.8), so the net move toward door B halves. Smoke-blind equals clear air in both sets, so Δy has the same reference. Runs and script:p848_old16400_01a30348/in the study data. The gate arm and the comparison fires were not separated.Clear air. Smoke-blind runs are identical to no fire on all three fires. Start positions are the same in every arm, so the comparisons are paired by seed. The deck’s radius is 0.15 m, so 0.5.0 (#408, stage reach from the agent’s own radius) moves the clear-air walks: against the runs of
2a94a8da, every agent keeps its exit, but exit times differ by up to 22.3 s. The E share (0.520), the door counts (104 / 96) and the boundary are unchanged. The clear-air boundary, 12.54 m per seed (12.56 m pooled), lies −0.05 m from the shortest-path boundary at 12.60 m. Before the fix of #350 and #401 the difference was +1.50 m. The clear-air slope comes from perfectly separated data and is not an estimate.Still walking at 400 s. No run raised the FDS horizon error (#356), but the 400 s cap leaves some agents walking:
Fire gate, per run (total in 10 runs) additive a047_pvc_h40 2–9 (49) 2–9 (49) a047_pvc_h35 6–12 (83) 6–12 (82) a012_pvc_h30 0–3 (16) 0–3 (15) They are late starters (movement start 112–361 s, median 274 s; 220 of 294 at 250 s or later) walking at a speed factor of 0.10. None is stalled: each walked at least 0.47 m in the last 30 s.
Gas. The largest gas FED of any agent in any run is 0.117; nobody is incapacitated by gas.
Heat. Heat FED was off in all 90 fire-arm runs, so heat entered neither routing nor tenability, and “nobody incapacitated” covers gas only. A post hoc estimate samples the FDS temperature at 1.6 m at the agents’ positions every 1 s. On the main fire, agents meet up to 167 °C, and 23.1 (gate) and 24.8 (additive) per run on average go above 60 °C. The convective dose peaks at 0.050 clothed and 0.149 unclothed, with the constants of
pyfds_evac/core/fed.py. The unclothed law is Purser and McAllister (2026), Eq. 70.42, p. 2318; it is somewhat unconservative at higher temperatures, so the unclothed dose at 167 °C may be underestimated. The clothed constants have not been checked against ISO 13571. Radiant heat was not assessed.One LES realisation per fire, on the 0.2 m grid only.
What this does not show
- The study uses the geometry of Schröder et al. (2015) with our own fire, crowd and router. Their results are neither reproduced, calibrated nor validated.
- The sensor settings behind the paper’s route patterns (Fig. 6d, extraction height, grid, time step and frisk) are unpublished, so its route choice cannot be set against ours. The counts of its Fig. 7 are one sensitivity sample.
- pyFDS-Evac has neither Schröder’s sensor (Eq. 4), his edge factor (Eq. 5), frisk, nor his obstruction test (routing model).
- The router reads the smoke along the whole route at 1.6 m, including smoke that will arrive later. Agents could not see that smoke (#125).
- The gate’s τ = 6 comes from FDS+Evac. Schröder’s factor 2 and frisk are chosen, not fitted (p. 332). The page ranks neither rule above the other.
- The door-choice pattern is a property of the model: a lexicographic τ rule with present-time path search from each agent’s position. No occupant behaviour was observed.
- The gate split has no boundary in metres (valid in 1 of 10 seeds on the main fire, 0 of 10 on the other fires). It is reported by its E share, its sign count and the door share by start.
- The predicted direction held; the pre-registered mechanism did not.
- The additive result on the main fire changed with the fuel and the code (Δy −0.08 m, not resolved). The page does not claim the fuel caused it.
- The sweep that chose the main fire was not rerun with the 10,300 kJ/kg fuel (#796).
Reproduce
The inputs are in assets/schroeder2015_route/. Run every command from
the repository root, or from the unpacked zip with python instead of
uv run python. DATA is a folder outside the repository.
FDS, 6 MPI processes per deck:
for F in a047_pvc_h40 a047_pvc_h35 a012_pvc_h30; do mkdir -p "$DATA/$F" && cp assets/schroeder2015_route/$F/$F.fds "$DATA/$F/" (cd "$DATA/$F" && mpiexec -n 6 fds $F.fds) doneEvacuation, four arms on the main fire and three on each comparison fire, seeds 1–10. One seed of each arm on the main fire:
C=assets/schroeder2015_route/evac uv run python run.py --scenario $C/config_gate.json --seed 1 # no fire uv run python run.py --scenario $C/config_gate.json --seed 1 --fds-dir "$DATA/a047_pvc_h40" --smoke-blind uv run python run.py --scenario $C/config_gate.json --seed 1 --fds-dir "$DATA/a047_pvc_h40" # gate uv run python run.py --scenario $C/config_additive.json --seed 1 --fds-dir "$DATA/a047_pvc_h40" # additiveassets/schroeder2015_route/run_p1.shruns every seed and adds--output-route-history,--output-exit-history,--output-fed-historyand--output-route-cost-history. A run with agents still walking at the 400 s cap is incomplete, andrun.pyexits with status 2 (Exit status); the script counts such a run as done. It exits non-zero if any run fails. For all seeds at once:PY="uv run python" bash assets/schroeder2015_route/run_p1.sh \ "$DATA/a047_pvc_h40" "$DATA/p1_a047_pvc_h40" 6 --with-nofire PY="uv run python" bash assets/schroeder2015_route/run_p1.sh \ "$DATA/a047_pvc_h35" "$DATA/p1_a047_pvc_h35" 6 PY="uv run python" bash assets/schroeder2015_route/run_p1.sh \ "$DATA/a012_pvc_h30" "$DATA/p1_a012_pvc_h30" 6Numbers and figures:
uv run python scripts/docs/schroeder2015_route.py --data "$DATA"It prints the evacuation numbers on this page as Markdown tables then this summary, then writes the figures:
main fire, exit-E share: no fire 0.520, gate 0.702, additive 0.504 main fire, additive dy: -0.08 m (-0.38, +0.22) main fire, gate door-B share: 0.04 for starts 30-120 s, 0.74 for starts 150-300 sAnimation of smoke-blind and gate, about 1 min. It needs
ffmpegfor the colour reduction; without it the GIF is larger:uv run python scripts/docs/study_animations.py schroeder2015 --data "$DATA"It prints the seed and the numbers of the caption, then writes the GIF:
- gate door-A counts {1: 158, 2: 147, 3: 149, 4: 165, 5: 152, 6: 152, 7: 158, 8: 149, 9: 157, 10: 153}; seed 5 (152, median 152.5) - sb: routes {'AE': 104, 'BF': 96}; at 146 s through door A 64; door B before 145 s 65 (last at 142.4 s), from 145 s 31 (first at 145.9 s); last out 381.8 s; still inside at 400 s: 0 - gate: routes {'AE': 142, 'BF': 46, 'AF': 10, '-F': 2}; at 146 s through door A 112; door B before 145 s 6 (last at 65.3 s), from 145 s 40 (first at 152.2 s); last out 360.7 s; still inside at 400 s: 4 (movement start [276.3, 311.3, 361.4, 262.5] s, exit F) wrote site/static/images/studies/schroeder2015/agents_smoke_gate.gif (2.1 MB, 200 frames)Fire choice, optional: it needs all nine fires. Write the decks with
uv run python assets/schroeder2015_route/make_decks.py "$DATA", run each with FDS as in step 1 (about 6 h for the six further decks), thenuv run python scripts/docs/schroeder2015_fire_figures.py --data "$DATA".
Provenance. The evacuation runs on this page were made at 01a30348
(branch decks/796-pvc-heat-of-combustion, pyFDS-Evac 0.6.1, jupedsim
1.4.2, fdsreader 1.14.0, fdsvismap 0.3.3, Python 3.13.4) by steps 2–4
above (seeds 1–10): 30 runs per fire (no fire, smoke-blind, gate,
additive). Each run’s manifest records git_dirty: false and
agent_seeding: spawn-key-blake2b-v2. The no-fire arm reproduces the
clear-air run, and the smoke-blind arm is identical to no fire on all three
fires. The FDS 6.10.1 decks use the Osburg et al. (2025) PVC set and ran
with FDS-6.10.1-0-g12efa16-release on JURECA. The earlier version of
this page was made at c619a046 (pyFDS-Evac 0.4.0) with 16,400 kJ/kg; its
differences from this one combine the fuel change with the code changes
between the two commits; for the additive shift on the main fire the fuel
alone accounts for them (see Earlier version above). The clear-air arms
of 9c820e0f, 2a94a8da and 828ae8c3 gave the same E share, door counts
and boundary; their trajectories differ (see Clear air above).
Limits and open issues
The scenario and the fire.
- One 0.2 m grid; a 0.1 m check waits until the case is frozen.
- One LES realisation per fire; the fire choice scores one frame, with the earlier 16,400 kJ/kg fuel, and was not repeated after #796.
- The fire is ours, and its differences from Fig. 6c are listed above. Two one-factor tests are deferred, possibly to a later run on JURECA: door C closed, and a 4.6 m ceiling.
- Heat FED was off; radiant heat was not assessed (#81).
- Up to 9 agents per run (main fire) and 12 (
a047_pvc_h35) are still walking at 400 s.
Engine behaviour seen here.
- The path search uses present-time smoke (routing model).
- One path per exit (#185).
- Perception scope (#125).
- Anticipation horizon (#356).
Open design questions.
- Present-time path search against anticipated τ: the τ of a route is read at the agent’s arrival time at each point (#650), the path search at decision time.
- The 1e-6·L length floor lets the path search react to τ of order 1e-4; the gate page discusses the floor.
Not done yet. A dose-aware or perceived-smoke arm for the late B→F route through the opaque upper corridor.
The paper’s unpublished inputs (its fire deck, the settings behind Fig. 6d, later code versions of the factor 2) are not used. The study uses published sources only.
Sources
Sources
- Schröder, B., Haensel, D., Chraibi, M., Arnold, L., Seyfried, A., & Andresen, E. (2015). Knowledge- and perception-based route choice modelling in case of fire. Proceedings of the 6th International Symposium on Human Behaviour in Fire, Cambridge, UK, 28–30 September 2015, pp. 327–338. Interscience Communications. ISBN 978-0-9933933-0-3. juser.fz-juelich.de/record/255940. Room 3 and the fire in it p. 329; the 2.80 m extraction height p. 330; Eq. 4 p. 331; Eq. 5, the factor 2 and frisk p. 332; Table 2 p. 334; Fig. 6 p. 335; doors 2 m wide and the hall’s smoke “lower as well as more homogenous and delayed” than the corridor toward F p. 336.
- Schröder, B. (2017). Multivariate methods for life safety analysis in case of fire. Dissertation, Bergische Universität Wuppertal (2016). Schriften des Forschungszentrums Jülich, IAS Series 34. ISBN 978-3-95806-254-2. urn:nbn:de:0001-2017081810. Fire in Room 3 p. 55; Fig. 3.9 p. 57; HRRPUA p. 74; Table 4.4 p. 74; Table 4.5 p. 75.
- Fleischmann, C., & Wade, C. (2026). Fire scenarios. SFPE Handbook of Fire Protection Engineering, 6th ed., Ch. 3, Table 3.5. doi:10.1007/978-3-031-59212-6_3
- DIN EN 1991-1-2/NA, for the HRRPUA of 250 kW/m², through Schröder (2017), p. 74. Paraphrased.
- McGrattan, K. et al. Fire Dynamics Simulator User’s Guide, sixth edition, NIST SP 1019, section “Fuels not compatible with simple chemistry” (PVC example; yields only).
- Osburg, M., Jäger, G., Schröder, B., & Börger, K. (2025). Quantifizierung der Ruß- und Schadstofffreisetzung bei Brandsimulationen. 71. vfdb-Jahresfachtagung. Table 2 (PVC set balanced to 13.1 MJ/kg of oxygen). doi:10.5281/zenodo.15522181
- Purser, D. A., & McAllister, J. L. (2026). Assessment of hazards to occupants from smoke, toxic gases, and heat. SFPE Handbook of Fire Protection Engineering, 6th ed., Ch. 70, Eq. 70.42, p. 2318 (the running text refers to it as Eq. 70.38). doi:10.1007/978-3-031-59212-6_70
- The original FDS+Evac, for τ = 6.
- Code:
pyfds_evac/core/route_graph.py(GatePolicy.edge_weight,GatePolicy.order_key,_tau_band,_generate_candidates,_measure_route,_clears_exit_anchor,_decide_exit_change,RouteCostConfig),pyfds_evac/core/premovement_distributions.py,pyfds_evac/core/fed.py.
What next
- Routing model: how pyFDS-Evac prices routes in smoke.
- The gate in detail.
- Wayfinding: what agents know and see.
- ASET-RSET maps after Schröder et al. (2020).
- Design fires.
- Perception scope: #125.
pyFDS-Evac is research software, provided without warranty.