pyFDS-Evac example: ISO 20414 Test 18: walking speed in smoke
=============================================================

One occupant walks a 100 m corridor at constant extinction coefficients
and at K read from an FDS slice; 16 runs check the speed-factor law and
the egress times against hand values. You run the small FDS deck
yourself (about 10 s).

Page: https://pedestriandynamics.org/pyFDS-Evac/verification/iso-test-18/

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
  run.py                                              the pyFDS-Evac command line
  scripts/verification/iso_test_18_figures.py         prints the page's table, checks the pass criteria, draws the figures
  assets/ISO-table21/config.json                      JuPedSim scenario, constant K (social force model)
  assets/ISO-table21/geometry.wkt                     walkable area
  assets/ISO-table21/ISO-table21.fds                  template deck with a fire; the test does not run it
  assets/ISO-table21/README.md                        what the constant-K scenario is
  assets/iso_table21_coupled/iso_table21_coupled.fds  FDS deck of the smoky corridor
  assets/iso_table21_coupled/config.json              JuPedSim scenario, K from FDS (collision-free speed model)
  assets/iso_table21_coupled/geometry.wkt             walkable area
  assets/iso_table21_coupled/build_geometry.py        writes the coupled deck, scenario and geometry
  assets/iso_table21_coupled/README.md                what the coupled case is and where it comes from

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. Run FDS on the coupled deck, one process (about 10 s):

     mkdir -p assets/iso_table21_coupled/fds
     cp assets/iso_table21_coupled/iso_table21_coupled.fds assets/iso_table21_coupled/fds/
     (cd assets/iso_table21_coupled/fds && fds iso_table21_coupled.fds)

3. Run the 16 cases and the figure script (about 45 s). OUT is a folder
   of your choice:

     OUT=$HOME/iso-test-18
     run() {  # name scenario [extra options]
       name=$1 scen=$2; shift 2
       mkdir -p $OUT/evac/$name
       python run.py --scenario $scen --seed 420 --smoke-update-interval 0.1 \
         --no-enable-rerouting --disable-tenability "$@" \
         --output-sqlite $OUT/evac/$name/run.sqlite \
         --output-smoke-history $OUT/evac/$name/smoke_history.csv > $OUT/evac/$name/run.log
     }
     for v in 1.25 1 0.75 0.5 0.25; do
       d=$OUT/scenarios/v0_$v; mkdir -p $d; cp assets/ISO-table21/geometry.wkt $d/
       python -c "import json,sys; c=json.load(open('assets/ISO-table21/config.json')); \
     c['config']['simulation_settings']['simulationParams']['max_simulation_time']=600; \
     [d['parameters'].update(v0=float(sys.argv[1])) for d in c['distributions'].values()]; \
     json.dump(c, open(sys.argv[2]+'/config.json','w'), indent=2)" $v $d
     done
     run clear $OUT/scenarios/v0_1.25
     for K in 0.5 1 3 7.5 10; do run K$K $OUT/scenarios/v0_1.25 --constant-extinction $K; done
     for v in 1 0.75 0.5 0.25; do
       run v0_${v}_clear $OUT/scenarios/v0_$v
       run v0_${v}_K1 $OUT/scenarios/v0_$v --constant-extinction 1
     done
     cp -R assets/iso_table21_coupled/fds $OUT/fds
     run coupled_clear assets/iso_table21_coupled/config.json
     run coupled_fds assets/iso_table21_coupled/config.json --fds-dir $OUT/fds
     python scripts/verification/iso_test_18_figures.py --data $OUT

Runtime
-------
  FDS: 10 s wall clock, one process, on an Apple M3 Pro, macOS
  pyFDS-Evac: about 45 s for the 16 runs and the figures

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.

  run                K    v0    f hand  t_clear  t_smoke   t_pred    diff    tol      1/f    ratio   err % f rec-hand walk/fv0-1
  K10          10.0000  1.25  0.192635    79.24   408.91  408.913 -0.0035 0.0357  5.19118  5.16040  -0.593   -2.8e-17   -9.6e-06
  coupled_fds   0.9955  1.25  0.919626    78.44    85.30   85.296 +0.0045 0.0209  1.08740  1.08746  +0.005   -2.7e-07   -5.8e-09
  pass criteria: all met

scripts/verification/iso_test_18_figures.py prints the page's Result
table, one line per run. Above are its header, its rows K10 and
coupled_fds, and the verdict line; t_clear, t_smoke and t_pred are in
seconds. The runs behind the page were made at 8fc26b1; re-runs at
449a755d and 9c820e0f print the same table. The script exits with an
error if a pass criterion fails.

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.
