Coming from FDS+Evac

Coming from FDS+Evac

This page is for engineers who have an FDS+Evac input file and want to run the same case in pyFDS-Evac. It maps each FDS+Evac input to its place here, and it lists what has no equivalent. FDS+Evac was removed from FDS in 2021 (FDS commit 6a1d48aa5e); the link above and every evac.f90:NNNN reference in these docs point to its last version before removal, FDS 6.7.6-404-gc9da70d7a, which the 2021 guide describes. Read Limitations before you rely on a result.

pyFDS-Evac is research software, provided without warranty. It is not intended for regulatory or design use.

What carries over and what changes

The fire part of your deck carries over. Remove the evacuation namelists and the evacuation meshes, keep the fire meshes, obstructions, &REAC and &SURF lines, and add the slices pyFDS-Evac reads (What your FDS case must provide). Then run FDS as usual.

The occupants move in a different program. FDS+Evac (Korhonen 2021) computes movement inside the FDS executable, with its own social-force model on 2-D evacuation meshes. In pyFDS-Evac, JuPedSim moves the agents on a continuous walkable polygon. The operational model is chosen in the scenario JSON (model_type, default CollisionFreeSpeedModel).

Smoke is read, not computed alongside. pyFDS-Evac never runs FDS. It reads the slice files of a finished FDS run and samples them at the agents' positions. The coupling is one-way: the fire acts on the occupants, and nothing the occupants do (opening a door, for example) acts on the fire.

A case therefore has three parts: the FDS output directory, a scenario JSON, and a walkable geometry as WKT (well-known text, a plain-text polygon format). uv run python run.py --scenario <json|dir|zip> --fds-dir <fds output> combines them.

Defaults follow FDS+Evac

pyFDS-Evac is an enhancement of FDS+Evac, not a clone. Where a mechanism has a direct FDS+Evac counterpart, the default is the FDS+Evac form, so that a case converted from FDS+Evac behaves as its author expects. Newer or alternative forms stay available as options. Earlier pyFDS-Evac versions used other defaults for eight mechanisms (#157):

MechanismDefault now (= FDS+Evac)Previous pyFDS-Evac defaultTo get the previous behaviour
Sampling height1.6 m, HUMAN_SMOKE_HEIGHT (evac.f90:1138; Guide §8.7)2.0 m--smoke-slice-height 2.0; opts.smoke_slice_height = 2.0, or slice_height_m=2.0 in SmokeSpeedConfig and DefaultFedConfig
Irritant (FIC) slowdownNone; evac.f90 imports only FED (evac.f90:65)On whenever the gas FED is computed--enable-fic-speed; opts.enable_fic_speed = True, or TenabilityConfig(enable_fic_speed=True)
HCN term of the FEDCHCN − (CNO + CNO2), offset 1/220 (function FED in FDS func.f90)CHCN − CNO2, offset 0.0045 (Guide Eq. 14–15)Not available; see the note below
O2 term of the FEDApplied only below 20 % O2 (function FED in FDS func.f90)Applied below 19.5 %--o2-threshold-percent 19.5; opts.o2_threshold_percent = 19.5, or DefaultFedConfig(o2_threshold_percent=19.5)
Pre-movement, when a spawn area sets noneConstant 10 s, PRE_MEAN (evac.f90:1672), with a warning in the log0 s"use_premovement": false in the spawn area’s parameters
Unimpeded walking speed v0, when a spawn area sets none1.25 m/s, VEL_MEAN (evac.f90:1670)1.2 m/s"v0": 1.2 in the spawn area’s parameters
Convective heat doseNone (Guide §1.2)On whenever the output has a TEMPERATURE slice--enable-heat-fed; opts.enable_heat_fed = True
Gas incapacitation thresholdEvery agent stops at FED = 1 (Guide §3.4)Per-agent log-normal draw, median --fed-threshold, σ = 0.94--incapacitation-mode probabilistic; opts.incapacitation_mode = "probabilistic", or TenabilityConfig(incapacitation_mode="probabilistic") (#235)

The CLI flags that change a result are also fields of the web GUI, and the opts attributes are what build_run_kwargs reads, so a script that builds its own options sets them the same way. The changelog lists the same changes.

The HCN term follows the FED as FDS and FDS+Evac compute it. FDS+Evac calls the FED function of FDS, which has subtracted NO + NO2 from HCN, with the offset 0.00454545 (about 1/220), since FDS commit 694e033 (2011); earlier versions had no HCN term. The FDS+Evac Guide’s Eq. 15 subtracts NO2 alone, which no FDS version computed, so pyFDS-Evac follows the code, not the guide’s text, and does not offer the guide’s form as an option. The FDS verification case FED_FIC separates the two forms and is part of the test suite (#159).

What deliberately still differs:

  • Route choice, cognitive maps and sign visibility are enhancements with no one-to-one FDS+Evac counterpart (#157); see Smoke-aware routing.
  • An exit is found by reading its sign, not by seeing the door. FDS+Evac counts a door as visible at any distance if nothing blocks the line of sight. pyFDS-Evac reads a sign only within its reading distance, 30 m by default even in clear air, and less off-axis or in smoke. See Seeing a door vs reading a sign.
  • Known issues: an agent incapacitated during its pre-movement time is released when that time ends (#145).

Where each FDS+Evac input goes

Section numbers refer to the FDS+Evac Technical Reference and User’s Guide (Korhonen 2021). “JSON” means the scenario JSON. Its stage layout (distributions, exits, checkpoints, journeys) is the one the JuPedSim web editor writes, and load_scenario converts the editor’s journeys_v2 routes on load. The pyFDS-Evac web GUI (graphical user interface, app.py) runs uploaded scenarios. It does not edit geometry or stages.

FDS+Evac inputWhat it didIn pyFDS-Evac
Evacuation meshes (&MESH EVACUATION=.TRUE., §8.1)2-D grids for movement, separate from the fire meshesReplaced by one walkable polygon (WKT). scripts/generate_walkable_from_fds.py derives it from the &OBST lines of a deck (see Usage).
EVAC_Z_OFFSET (§8.1)Distance from the mid height of an evacuation mesh down to its floor, which is the reference level for HUMAN_SMOKE_HEIGHTNo equivalent: pyFDS-Evac has no evacuation meshes.
HUMAN_SMOKE_HEIGHT (§8.7)Height above the floor at which smoke and FED are read, default 1.6 m (Guide §8.7 p. 81; VTT W119 p. 61)--smoke-slice-height [m], default 1.6 as in FDS+Evac (2.0 before; pass --smoke-slice-height 2.0 for it), an absolute z in the FDS domain rather than a height above the floor (#157). It selects the extinction, gas and temperature slices closest to it, so the deck must contain an &SLCF PBZ= at that height.
&EVAC (§8.8)Places a group of agents in a rectangleA distributions entry in the JSON: a polygon plus parameters (number, v0, radius, pre-movement, familiarity).
&PERS (§8.7)Agent type: body size, speed, pre-movement, force constantsPer distribution in the JSON: v0 [m/s], radius [m] and the pre-movement keys below. There are no named agent types and no three-circle body; an agent is a circle.
&EVHO (§8.9)Area where no agents are placedNot supported. Draw the distribution polygon so that it excludes the area.
&EXIT (§8.10)Line that removes agentsAn exits entry in the JSON (a polygon). Optional enable_throughput_throttling and max_throughput cap the flow, and an optional sign feeds visibility.
&DOOR (§8.12)Moves agents to another part of the calculationNo door object. A doorway is a gap in the walkable polygon; an intermediate target is a checkpoints entry in a journey.
&ENTR (§8.11)Adds agents at a constant rateFlow spawning on a distribution: use_flow_spawning, flow_start_time, flow_end_time [s].
&CORR (§8.13)One-way corridor or stair between floorsNot supported. pyFDS-Evac is single-floor.
&STRS (§8.15)Whole staircase with its own meshNot supported.
&EVSS (§8.14)Incline with speed factors FAC_V0_UP/DOWN/HORINot supported as an incline. A zones or checkpoints entry with a speed_factor (0 to 3) scales the speed of agents inside a polygon, with no direction dependence.
DET_* and PRE_* (§8.7, §8.8)Detection time plus reaction time, each from a distribution. The default reaction time is a constant PRE_MEAN = 10 s (evac.f90:1672; PRE_EVAC_DIST = 0 is a constant, Guide §8.7), added to the detection time, whose default DET_MEAN is T_BEGIN (:1673); a lone agent starts moving at TDET + TPRE (:9209), a group member at TDET (:9211)One pre-movement delay per agent: use_premovement, premovement_distribution, premovement_param_a, premovement_param_b, premovement_seed. There is no separate detection phase. See the table below.
TDET_SMOKE_DENS (§8.7)Smoke at the agent’s position triggers detectionNot supported. The pre-movement delay does not depend on smoke.
VELOCITY_DIST and speed ranges (§8.7)Unimpeded walking speed distribution; default VEL_MEAN = 1.25 m/s (evac.f90:1670)v0 [m/s], default 1.25 as in FDS+Evac (1.2 before; set v0 per spawn area for it; #157), with v0_distribution = "constant" or "gaussian" and v0_std. These are the keys the run reads from the JSON. desired_speed, desired_speed_distribution and desired_speed_std are aliases accepted only by Scenario.set_agent_params() in Python, which writes the v0 keys; in the JSON they are ignored. Gaussian draws are clipped to 0.1–5.0 m/s. There is no uniform speed distribution.
Smoke-speed reduction (Eq. 11), SMOKE_MIN_SPEED_FACTOR and SMOKE_MIN_SPEEDLinear speed reduction with extinction, floored at SMOKE_MIN_SPEED_FACTOR × v0 (default 0.1). The guide calls SMOKE_MIN_SPEED a factor too, but the code divides it by v0 (evac.f90:8516), so it is a speed in m/sThe default is the same law, Frantzich–Nilsson (the lund option; the linear FDS+Evac law). Its coefficients (alpha, beta, min_speed_factor) are library-level; see What needs Python.
FED, fractional effective dose (§3.4)Purser FED from CO, CO2, O2 (and optional gases), incapacitation at FED ≥ 1. The O2 term is applied only below 20 % O2 (function FED in FDS 6.7.6 func.f90, which FDS+Evac calls). The HCN term in the code (the same FED function) is exp(CCN/43)/220 − 0.00454545 (about 1/220) with CCN = CHCN − (CNO + CNO2); Guide Eq. 14–15 write the offset as 0.0045 and CCN = CHCN − CNO2. The code form has been in FDS since firemodels/fds 694e033 (2011); earlier versions had no HCN term. FDS’s FED_FIC verification case reproduces only with it (0.97402 against the expected 0.97403 at 100 s; 6.17 with NO2 alone). The FDS User Guide was corrected to NO + NO2 in 2016 (903df07); the FDS+Evac Guide and the FDS Verification Guide were not. An agent that reaches FED ≥ 1 stays down for the rest of the runComputed when the output has CO, CO2 and O2 slices; HCN, NOx and irritant slices are added when present. The O2 term is applied below 20 %, as in FDS+Evac; --o2-threshold-percent 19.5 (opts.o2_threshold_percent) gives the previous 19.5 %. The HCN term is the one in the code FDS+Evac ran (CHCN − (CNO + CNO2), offset 1/220), and FED_FIC is reproduced in the test suite (#159). Earlier pyFDS-Evac versions followed Guide Eq. 14–15 (CHCN − CNO2, offset 0.0045); the two differ materially only when NO is present: at 100 ppm HCN, 50 ppm NO and 10 ppm NO2 the CN rate is 0.007 /min now against 0.032 /min before; with no NO the difference is the offset alone, 4.5 × 10⁻⁵ /min. By default every agent stops at FED = 1, as in FDS+Evac. With --incapacitation-mode probabilistic each agent draws its own threshold instead (log-normal, median 1; spread on the FED model page), so about half stop below FED = 1. The heat dose, which FDS+Evac does not have, is deterministic by default and uses the same threshold, as ISO 13571:2012 asks (§5.4). Thresholds are set with --fed-threshold; --heat-fed-threshold sets a separate heat threshold, a departure from ISO. An agent incapacitated while it is still waiting is released when its pre-movement time ends, a known bug (#145).
Convective heatNone: gas temperature and radiation do not act on agents (Guide §1.2)Off by default, as in FDS+Evac. With --enable-heat-fed (opts.enable_heat_fed), a separate heat dose is computed from the TEMPERATURE slice, by default with ISO 13571:2012 Eq. (9) for fully clothed subjects, and kept apart from the gas FED; it incapacitates at the same threshold as the gas dose unless --heat-fed-threshold sets another; before, this happened automatically whenever the output had such a slice. --disable-tenability turns off both stops (#157).
Irritant slowdown (FIC)None: no FIC acts on the agents, since evac.f90 imports only FED from FDS (evac.f90:65). Irritants enter only the FED sum. FDS can write FIC as an output quantity, and the guide tabulates FFIC (Table 2), but neither feeds the agents’ speedOff by default, as in FDS+Evac. --enable-fic-speed (opts.enable_fic_speed) turns on speed × max(0.3, 1 − 0.7 · FIC) whenever the gas FED is computed; before, it was on by default. The rule is a pyFDS-Evac assumption with no known source (#147, #157).
FED activity levelInput accepts rest, light work or heavy work, but the dose is always computed for light work (evac.f90:16086–16088)Same as FDS+Evac 6.7.6: light work only (FDS+Evac reads the input but does not use it). See issue #135.
KNOWN_DOOR_NAMES, KNOWN_DOOR_PROBS (§8.8)Which exits an agent knows, with a probability per exit. An exit not listed is known only if its &EXIT or &DOOR line sets KNOWN_DOOR, which defaults to .FALSE. (evac.f90:2291, :2733), so by default agents rely on the exits they can seefamiliarity on a distribution: "full", "discovery", or one probability in [0, 1] applied to every exit. The default is "full": every agent knows every exit. The FDS+Evac default is closer to "discovery". entrance names one exit, reachable from the spawn area, that the agents know from the start. A probability per exit is not supported; see issue #136.
Door visibility (Is_Visible_Door)A door is visible when the line of sight from the agent to the door centre is not blocked (or, for an XB door, to its centre from the correct side). There is no range limit, no contrast and no angle factorA sign is legible when \(A \cdot U \cdot \min(C/\bar K, V_{\max}) \ge L\) (see Wayfinding). \(V_{\max}\) = 30 m by default (--max-sign-distance, or "max_distance" per sign), so a door farther than 30 m is not found by sight even in clear air. See below.
Door selection with smoke (FED_DOOR_CRIT)Ranks doors as smoke-free by FED or visibility. For a door in view, the smoke is the mean over the cells of the straight line to the door; for a door not in view, See_door stops at the first wall and uses only the smoke in the agent’s own cell, with the L1 distance (evac.f90:15762–15765, :15803–15806; Guide §3.6). Smoke beyond a wall is never counted, and smoke along the way to a door out of view is ignoredRoute choice is a different model, configured in the JSON routing block and switched on by default (--enable-rerouting). See Smoke-aware routing.
Queueing in door selection (FAC_DOOR_QUEUE)On by default (1.3 persons/m/s, evac.f90:1568). Within Change_Target_Door the estimated queueing time ranks only the first preference tier, the doors that are both known and visible (:16592); the parameter also switches on the Nash iteration of the initial exit choice (:7071) and enters the queue estimates in EVACUATE_HUMANS (:9364)Off by default: w_queue = 0 in the JSON routing block. When set, it counts all agents targeting an exit, not a local queue.
TAU (TAU_MEAN etc., §8.7)Relaxation time of the social-force modelNo equivalent. Movement parameters belong to the JuPedSim model named in model_type.

Seeing a door vs reading a sign

Two plan views of the same hall with one exit and an obstacle. Left, FDS+Evac: every cell with an unblocked line of sight to the door sees it, at any distance. Right, pyFDS-Evac: only cells inside the 30 m reading circle and outside the obstacle’s shadow read the sign

A 60 × 30 m hall with one exit and a 3 × 8 m obstacle; the door centre and the sign are the same point. Left: a re-implementation of FDS+Evac’s door test, See_door (evac.f90:15682–15813), which marches the cells of the see-or-not mesh along the segment to the door centre and fails at the first solid wall face, at any distance; smoke along the way is averaged, not blocking. That mesh is a slab at HUMAN_SMOKE_HEIGHT ± EVAC_DELTA_SEE (0.29 m, :1137; Guide §1.3.5), so the obstacle here is taken to reach eye height: a low obstruction, or one marked HIDDEN, does not block the sight line in FDS+Evac. Right: the cells from which pyFDS-Evac’s visibility model reads the sign, for an omni-directional sign (C = 3) in clear air with the default 30 m reading distance (dashed circle, drawn faintly on the left for reference). Both need a clear line of sight, so the obstacle casts the same shadow; the only difference is range. Agent 1 (12 m, in view) sees the exit in both; agent 2 (45 m, in view) sees the door in FDS+Evac but cannot read the sign; agent 3 (23 m, behind the obstacle) sees neither. A directional sign shrinks the right-hand region further by the angle factor, and smoke shrinks it again.

Consequences for a deck carried over from FDS+Evac:

  • In a space wider than 30 m, an agent that does not know an exit (a discovery agent, or one whose familiarity draw missed it) learns it only once it comes within reading distance of its sign. Egress times of such agents are longer than FDS+Evac’s in large, open spaces.
  • Off-axis, the reading distance shrinks with the angle factor \(A\): in clear air a sign is legible up to \(A \cdot V_{\max}\). An omni-directional sign (no alpha) has \(A = 1\).
  • Smoke shortens it further, to \(A \cdot C/\bar K\) once \(C/\bar K < V_{\max}\). FDS+Evac’s door visibility ignores smoke; smoke acts only in its door ranking.
  • To model a sign that is read from farther away (a larger or illuminated sign), set its "max_distance". To approximate FDS+Evac’s unlimited range, raise --max-sign-distance above the largest distance in the deck.
  • Agents with familiarity "full", the default, know every exit and are unaffected.

Pre-movement parameters

The two parameters mean different things for each distribution, so FDS+Evac values cannot be copied across unchanged. The delay is in seconds.

premovement_distributionpremovement_param_apremovement_param_bPreset (a, b)
gamma (default)shapescale [s]1.291, 103.901
lognormalmean of ln(t)standard deviation of ln(t)4.586, 0.967
weibullscale [s]shape139.285, 1.195
uniformlower bound [s]upper bound [s]0.0, 60.0
constantdelay [s]unused10.0, -

The gamma, log-normal and Weibull presets are the fits for office buildings (Business Cluster 1: 11 evacuations, 10 of them drills, 4–14 floors, R² 0.55–0.57) in Lovreglio et al. (2019), Table 3, with the log-normal a taken from the 2019 corrigendum (doi:10.1016/j.firesaf.2018.12.009; doi:10.1016/j.firesaf.2019.102829). The uniform preset is RiMEA’s “speedy evacuation” sensitivity scenario, not data. For other occupancies, set both parameters from the matching table of that paper.

The presets are used when use_premovement is true and premovement_param_a or premovement_param_b is missing; both parameters must be given for either to take effect (constant needs only premovement_param_a). A spawn area that sets none of these keys gets the FDS+Evac default, a constant 10 s after T_BEGIN (PRE_MEAN; #157), and the run logs a warning, since the FDS+Evac guide advises against relying on defaults. With use_premovement false, agents start moving at t = 0, as every spawn area without pre-movement keys did before. When premovement_seed is null, the draws are seeded from the run seed, so they repeat under a fixed --seed.

While an agent waits, its walking speed is not reduced by the smoke around it. It starts at its full clear-air speed when it is released. Its toxic dose does accumulate while it waits.

What is lost

Some FDS+Evac features have no counterpart. The social-force movement model with its three-circle body, and its dedicated counterflow algorithm, are replaced by the JuPedSim model you choose. Floors, stairs, &EVHO holes, smoke-triggered detection and per-exit known-door probabilities are not supported. Each is described on the Limitations page. The FED activity level is the same as in FDS+Evac 6.7.6: light work only (FDS+Evac reads the input but does not use it).

What needs Python

Some parameters cannot be set from the CLI or the scenario JSON. The smoke-speed parameters are the main case. speed_law ("lund" or "fridolf"), alpha, beta, min_speed_factor, visibility_factor_c and the fridolf_* constants are fields of SmokeSpeedConfig, and run.py and the web GUI build that object with its defaults. A run started from either one uses the Frantzich–Nilsson law with the defaults listed on the smoke-speed model page.

To change them, build a SmokeSpeedModel yourself and pass it to run_scenario() from Python.

The JSON routing block accepts keys with the same names (alpha, beta, min_speed_factor). They set the speed factor used to estimate travel time when a route is priced. Changing them changes what routes cost, not how fast agents walk.

Before you convert

  • Read What your FDS case must provide and add the slices it lists: extinction coefficient, CO, CO2, O2 and TEMPERATURE, with the &REAC yields that produce the gases.
  • Put the slices at the height you will pass to --smoke-slice-height.
  • Check that the building fits on one floor. Stairs and several floors are not supported. generate_walkable_from_fds.py treats stair treads and risers as floor, so a staircase in the deck becomes flat floor walked at full speed.
  • Check the walkable polygon it produces (--plot, --report). The script decides what blocks from the CAD layer name in the comment after each &OBST, so a deck without such comments needs checking by hand.
  • Translate pre-movement into one delay per agent (table above). Detection and reaction are no longer separate.
  • Decide what each group knows (familiarity, entrance).
  • Run FDS, then uv run python run.py --scenario <json> --fds-dir <dir> --inspect-fds to list the quantities pyFDS-Evac finds.
  • Read the warnings of the first run. A missing gas slice switches FED off and the run still finishes, with no FED in the result: metrics has no fed_max (Outputs).
  • Read Limitations and the verification status.

Words that changed meaning

Terminology.

  • tau is an optical depth here: the mean extinction coefficient along a route times its length, τ = Kave · L (dimensionless). It is not the relaxation time TAU of FDS+Evac. The routing key tau_max is an optical depth (default on the routing model page).
  • Stage is a JuPedSim target: a distribution, a checkpoint or an exit. Journeys are sequences of stages.
  • Gate has two meanings, and only two. The route-cost gate (routing.cost_model = "gate", the default) refuses routes whose optical depth is too high. Sight gating decides whether an agent can read a sign, and so which exits enter its cognitive map. The dose is not a gate: when it reaches the agent’s threshold, the agent stops.
  • FIC, Purser’s fractional irritant concentration, which slows agents when --enable-fic-speed is given, is related to, but not the same as, the FEC (fractional effective concentration) of ISO 13571, which uses different denominators.
  • Cognitive map is the graph of stages an agent knows. It is not meant in the psychological sense.

References

Korhonen, T. (2021). Fire Dynamics Simulator with Evacuation: FDS+Evac. Technical Reference and User’s Guide (FDS 6.7.6, Evac 2.6.0). VTT Technical Research Centre of Finland.

Last updated on