pyFDS-Evac example: ASET-RSET maps after Schröder et al. (2020)
===============================================================

100 people leave a 30 x 10 x 3 m room with one door (or two) while a 60
kW fire fills it with smoke. You run the FDS decks yourself, then the
script that runs 160 evacuations and builds the ASET, RSET and DIFF
maps. Room, door, fire and crowd follow the authors' release,
doi:10.5281/zenodo.3875550. No file of that release is in this zip; the
optional comparison with it (step 6) needs you to download it from
Zenodo.

Page: https://pedestriandynamics.org/pyFDS-Evac/docs/studies/study-schroeder2020/

Run every command from this folder, the folder that holds this
README.txt. The files keep the layout of the pyFDS-Evac repository, so
the commands are the ones on the page, with python instead of uv run
python.

Contents
--------
  README.txt                                     this file
  LICENSE                                        MIT licence of the code
  requirements.txt                               pinned Python packages, from uv.lock
  assets/schroeder2020_room/README.md            what the inputs are and where they come from
  assets/schroeder2020_room/make_decks_rel.py    writes the FDS decks of the rel_* family (release conditions)
  assets/schroeder2020_room/make_configs_rel.py  writes the scenarios and geometry of the rel_* family
  assets/schroeder2020_room/make_decks.py        writes the FDS decks of the hrr060_* family (paper alone)
  assets/schroeder2020_room/make_configs.py      writes the scenarios and geometry of the hrr060_* family
  assets/schroeder2020_room/rel_1door/           one door, 0.2 m grid: FDS deck, scenarios for the pre-movement sweep, geometry
  assets/schroeder2020_room/rel_1door_dx010/     one door, 0.1 m grid: FDS deck, scenarios, geometry
  assets/schroeder2020_room/rel_2door/           two doors, 0.2 m grid: FDS deck and one scenario per seed and version in seeds/
  assets/schroeder2020_room/hrr060_1door/        sensitivity, one door, 0.2 m grid
  assets/schroeder2020_room/hrr060_1door_dx010/  sensitivity, one door, 0.1 m grid
  assets/schroeder2020_room/hrr060_1door_pert/   sensitivity, one door, HRRPUA +0.1 % (FDS deck only)
  assets/schroeder2020_room/hrr060_2door/        sensitivity, two doors, 0.2 m grid
  run.py                                         the pyFDS-Evac command line, which the map script calls for each run
  scripts/docs/schroeder_room_maps.py            runs the evacuations, prints every number of the page, draws the maps
  scripts/docs/study_animations.py               the two animations
  scripts/docs/schroeder_grid_figures.py         the grid figures
  scripts/docs/first_fds_case_figures.py         helpers used by the animation script
  scripts/animate_agents_smoke.py                helpers used by the animation script

Versions
--------
The zip was built from this commit. requirements.txt pins every Python
package to the version in its uv.lock.

  pyFDS-Evac   0.6.1, git commit e1f296725e70051f91d6741b4f4dd50dbee06a42 (2026-10-21)
  Python       >=3.12,<3.15
  jupedsim     1.4.2
  pedpy        1.4.0
  fdsreader    1.11.7
  fdsvismap    0.3.3
  numpy        2.4.4
  shapely      2.1.2
  matplotlib   3.10.8
  pandas       2.3.3
  seaborn      0.13.2
  FDS          FDS-6.10.1-0-g12efa16-release

Run it
------
The commands are for a POSIX shell (Linux, macOS; on Windows, WSL or Git
Bash).

1. Install pyFDS-Evac and the pinned packages:

     python -m venv .venv
     source .venv/bin/activate    # Windows: .venv\Scripts\activate
     pip install -r requirements.txt

2. Copy the three rel_* folders to DATA, a folder outside this one, and
   run FDS in each with 6 MPI processes (22 min, 28 min, and 4 h 14 min
   for the 0.1 m grid):

     DATA=$HOME/schroeder2020-room
     for V in rel_1door rel_2door rel_1door_dx010; do
       mkdir -p "$DATA" && cp -R assets/schroeder2020_room/$V "$DATA/"
       (cd "$DATA/$V" && mpiexec -n 6 fds $V.fds)
     done

3. Install PedPy 1.5.1 for compute_rset_map; it replaces the pinned
   1.4.0:

     pip install "pedpy==1.5.1"

4. Run the 160 evacuations, print the page's numbers and draw the maps
   (about 5 min with 6 workers). RUNS is an empty folder outside this
   one:

     RUNS=$HOME/schroeder2020-runs
     python scripts/docs/schroeder_room_maps.py --data "$DATA" --runs "$RUNS" --family rel

5. Draw the animations (needs ffmpeg) and the grid figures:

     python scripts/docs/study_animations.py schroeder --data "$DATA" --runs "$RUNS" --family rel
     python scripts/docs/schroeder_grid_figures.py --data "$DATA" --cache "$RUNS/cache" --family rel

6. Optional, the comparison with the authors' release: download it from
   https://doi.org/10.5281/zenodo.3875550, unpack it to RELEASE, and run
   step 4 again with --release (the runs are reused):

     python scripts/docs/schroeder_room_maps.py --data "$DATA" --runs "$RUNS" --family rel --release RELEASE

7. Optional, the sensitivity (room rebuilt from the paper alone): FDS on
   the four hrr060_* folders (20 min, 18 min, 4 h 8 min and 15 min),
   then the maps and the grid figures with their own runs folder:

     for V in hrr060_1door hrr060_2door hrr060_1door_dx010 hrr060_1door_pert; do
       cp -R assets/schroeder2020_room/$V "$DATA/"
       (cd "$DATA/$V" && mpiexec -n 6 fds $V.fds)
     done
     python scripts/docs/schroeder_room_maps.py --data "$DATA" --runs "$HOME/schroeder2020-runs-hrr060" --family hrr060
     python scripts/docs/schroeder_grid_figures.py --data "$DATA" --cache "$HOME/schroeder2020-runs-hrr060/cache" --family hrr060

Runtime
-------
  FDS: 1308 s (rel_1door), 1708 s (rel_2door) and 15260 s (rel_1door_dx010) wall clock with 6 MPI processes on an Apple M3 Pro, macOS
  pyFDS-Evac: about 5 min for the 160 runs and the maps, 6 workers

Expected result
---------------
The page shows these lines. They were produced at commit 9c820e0f with
Python 3.12.13 on Apple M3 Pro, macOS, from FDS output of
FDS-6.10.1-0-g12efa16-release.

  | 1door capped 1.00 p/s, pre-movement 0 | 60.5 ± 0.5 | 20.5 ± 0.5 | 100-101 s |
  | 1door capped 1.00 p/s, pre-movement 0, 0.2 m, 1 door | -27 at (29.7, 8.1) | -27 | 6.7 | -112 | -124 | 718/21/0 |
  | 1door capped 1.00 p/s, pre-movement 0, 0.1 m, 1 door | -27 at (29.7, 8.7) | -27 | 6.4 | -107 | -116 | 719/20/0 |
  | 2door capped 1.00 p/s, pre-movement 0, 0.2 m, 2 doors | -40 at (0.3, 8.7) | -40 | 7.4 | -174 | -175 | 722/23/0 |

scripts/docs/schroeder_room_maps.py prints these rows in its Markdown
tables "Agents remaining (pre-movement 0, 10 seeds, mean ± sd)", the
first line, and "DIFF measures, K ≥ 0.23, ∃ rule, ~1 s, pooling: maximum
over n = 10 seeds", the other three: remaining at 40 s and 80 s and the
last one out; min DIFF [s], area with DIFF < 0 [m²] and C [m²s]. They
are the page's headline. The runs behind the page were made at 4a7142f;
re-runs at 449a755d and 9c820e0f, without --release, print the same
values. FDS output from another FDS build or machine can move them
slightly.

Licence
-------
Code (the .py files): MIT, see LICENSE. FDS decks, scenario files and
geometry: CC-BY-4.0, https://creativecommons.org/licenses/by/4.0/.
Attribution: pyFDS-Evac,
https://github.com/PedestrianDynamics/pyFDS-Evac.

pyFDS-Evac is research software, provided without warranty.
