Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 97 additions & 1 deletion crates/python_api/docs/api/sfpe-handbook.rst
Original file line number Diff line number Diff line change
Expand Up @@ -137,4 +137,100 @@ Equation 50.20 - Visibility Through Smoke (Percent Obscuration)
.. automodule:: ofire.sfpe_handbook.chapter_50.equation_50_20
:members:
:undoc-members:
:show-inheritance:
:show-inheritance:

Chapter 59
----------

.. automodule:: ofire.sfpe_handbook.chapter_59
:members:
:undoc-members:
:show-inheritance:

Equation 59.5 - Pedestrian Travel Speed
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

.. automodule:: ofire.sfpe_handbook.chapter_59.equation_59_5
:members:
:undoc-members:
:show-inheritance:

Equation 59.6 - Specific Flow of Evacuating Persons
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

.. automodule:: ofire.sfpe_handbook.chapter_59.equation_59_6
:members:
:undoc-members:
:show-inheritance:

Equation 59.7 - Combined Specific Flow
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

.. automodule:: ofire.sfpe_handbook.chapter_59.equation_59_7
:members:
:undoc-members:
:show-inheritance:

Equation 59.8 - Flow Rate of Persons
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

.. automodule:: ofire.sfpe_handbook.chapter_59.equation_59_8
:members:
:undoc-members:
:show-inheritance:

Equation 59.9 - Combined Flow Rate
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

.. automodule:: ofire.sfpe_handbook.chapter_59.equation_59_9
:members:
:undoc-members:
:show-inheritance:

Equation 59.10 - Time for Passage
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

.. automodule:: ofire.sfpe_handbook.chapter_59.equation_59_10
:members:
:undoc-members:
:show-inheritance:

Equation 59.11 - Combined Time for Passage
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

.. automodule:: ofire.sfpe_handbook.chapter_59.equation_59_11
:members:
:undoc-members:
:show-inheritance:

Equation 59.12 - Specific Flow at Transition Point
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

.. automodule:: ofire.sfpe_handbook.chapter_59.equation_59_12
:members:
:undoc-members:
:show-inheritance:

Equation 59.13 - Specific Flow with Two Incoming Flows
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

.. automodule:: ofire.sfpe_handbook.chapter_59.equation_59_13
:members:
:undoc-members:
:show-inheritance:

Equation 59.15 - Evacuation Time (Congestion Dominated)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

.. automodule:: ofire.sfpe_handbook.chapter_59.equation_59_15
:members:
:undoc-members:
:show-inheritance:

Equation 59.16 - Evacuation Time (No Congestion)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

.. automodule:: ofire.sfpe_handbook.chapter_59.equation_59_16
:members:
:undoc-members:
:show-inheritance:
2 changes: 2 additions & 0 deletions crates/python_api/src/sfpe_handbook.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
pub mod chapter_14;
pub mod chapter_50;
pub mod chapter_59;

use pyo3::prelude::*;
use pyo3::wrap_pymodule;
Expand All @@ -14,5 +15,6 @@ use pyo3::wrap_pymodule;
pub fn sfpe_handbook(m: &Bound<'_, PyModule>) -> PyResult<()> {
m.add_wrapped(wrap_pymodule!(chapter_14::chapter_14))?;
m.add_wrapped(wrap_pymodule!(chapter_50::chapter_50))?;
m.add_wrapped(wrap_pymodule!(chapter_59::chapter_59))?;
Ok(())
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,4 @@ fn stairwell_temperature(t_0: f64, eta: f64, t_b: f64) -> PyResult<f64> {
pub fn equation_50_17(m: &Bound<'_, PyModule>) -> PyResult<()> {
m.add_function(wrap_pyfunction!(stairwell_temperature, m)?)?;
Ok(())
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,4 @@ fn visibility(k: f64, l: f64, lambda: f64) -> PyResult<f64> {
pub fn equation_50_20(m: &Bound<'_, PyModule>) -> PyResult<()> {
m.add_function(wrap_pyfunction!(visibility, m)?)?;
Ok(())
}
}
30 changes: 30 additions & 0 deletions crates/python_api/src/sfpe_handbook/chapter_59.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
pub mod equation_59_10;
pub mod equation_59_11;
pub mod equation_59_12;
pub mod equation_59_13;
pub mod equation_59_15;
pub mod equation_59_16;
pub mod equation_59_5;
pub mod equation_59_6;
pub mod equation_59_7;
pub mod equation_59_8;
pub mod equation_59_9;

use pyo3::prelude::*;
use pyo3::wrap_pymodule;

#[pymodule]
pub fn chapter_59(m: &Bound<'_, PyModule>) -> PyResult<()> {
m.add_wrapped(wrap_pymodule!(equation_59_5::equation_59_5))?;
m.add_wrapped(wrap_pymodule!(equation_59_6::equation_59_6))?;
m.add_wrapped(wrap_pymodule!(equation_59_7::equation_59_7))?;
m.add_wrapped(wrap_pymodule!(equation_59_8::equation_59_8))?;
m.add_wrapped(wrap_pymodule!(equation_59_9::equation_59_9))?;
m.add_wrapped(wrap_pymodule!(equation_59_10::equation_59_10))?;
m.add_wrapped(wrap_pymodule!(equation_59_11::equation_59_11))?;
m.add_wrapped(wrap_pymodule!(equation_59_12::equation_59_12))?;
m.add_wrapped(wrap_pymodule!(equation_59_13::equation_59_13))?;
m.add_wrapped(wrap_pymodule!(equation_59_15::equation_59_15))?;
m.add_wrapped(wrap_pymodule!(equation_59_16::equation_59_16))?;
Ok(())
}
43 changes: 43 additions & 0 deletions crates/python_api/src/sfpe_handbook/chapter_59/equation_59_10.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
use pyo3::prelude::*;

use openfire::sfpe_handbook::chapter_59::equation_59_10 as rust_equation_59_10;

#[pyfunction]
/// Calculates the time for passage (Equation 59.10).
///
/// The time for passage is the time for a group of persons to pass a point
/// in an exit route.
///
/// .. math::
///
/// t_p = \frac{P}{F_c}
///
/// where:
///
/// - :math:`t_p` is the time for passage (minutes or seconds)
/// - :math:`P` is the population size (persons)
/// - :math:`F_c` is the calculated flow (persons/min or persons/s)
///
/// The units of tp depend on the units of Fc: tp is in minutes when Fc is in
/// persons/min; tp is in seconds when Fc is in persons/s.
///
/// Args:
/// p (float): Population size (persons)
/// fc (float): Calculated flow (persons/min or persons/s)
///
/// Returns:
/// float: Time for passage tp (minutes or seconds depending on Fc units)
///
/// Example:
/// >>> import ofire
/// >>> result = ofire.sfpe_handbook.chapter_59.equation_59_10.time_for_passage(100.0, 20.0)
/// >>> print(f"{result:.1f} minutes")
fn time_for_passage(p: f64, fc: f64) -> PyResult<f64> {
Ok(rust_equation_59_10::time_for_passage(p, fc))
}

#[pymodule]
pub fn equation_59_10(m: &Bound<'_, PyModule>) -> PyResult<()> {
m.add_function(pyo3::wrap_pyfunction!(time_for_passage, m)?)?;
Ok(())
}
50 changes: 50 additions & 0 deletions crates/python_api/src/sfpe_handbook/chapter_59/equation_59_11.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
use pyo3::prelude::*;

use openfire::sfpe_handbook::chapter_59::equation_59_11 as rust_equation_59_11;

#[pyfunction]
/// Calculates the time for passage combining Equations 59.9 and 59.10 (Equation 59.11).
///
/// This equation combines the calculated flow equation (59.9) with the time for
/// passage equation (59.10) to express time directly in terms of the fundamental
/// parameters.
///
/// .. math::
///
/// t_p = \frac{P}{(1 - aD) \cdot k \cdot D \cdot W_e}
///
/// where:
///
/// - :math:`t_p` is the time for passage (minutes or seconds)
/// - :math:`P` is the population size (persons)
/// - :math:`a` is constant (0.266 for SI, 2.86 for imperial)
/// - :math:`D` is the population density (persons per unit area)
/// - :math:`k` is the constant from Table 59.2
/// - :math:`W_e` is the effective width of the component (ft or m)
///
/// tp is in minutes when k = k1 (from Table 59.2), D is in persons/ft², and We is in ft.
/// tp is in seconds when k = k2 (from Table 59.2), D is in persons/m², and We is in m.
///
/// Args:
/// p (float): Population size (persons)
/// a (float): Unit constant (0.266 for SI units, 2.86 for imperial units)
/// d (float): Population density (persons/m² or persons/ft²)
/// k (float): Constant from Table 59.2
/// we (float): Effective width of the component being traversed (ft or m)
///
/// Returns:
/// float: Time for passage tp (minutes or seconds depending on units)
///
/// Example:
/// >>> import ofire
/// >>> result = ofire.sfpe_handbook.chapter_59.equation_59_11.time_for_passage(100.0, 0.266, 0.5, 1.40, 1.2)
/// >>> print(f"{result:.1f} seconds")
fn time_for_passage(p: f64, a: f64, d: f64, k: f64, we: f64) -> PyResult<f64> {
Ok(rust_equation_59_11::time_for_passage(p, a, d, k, we))
}

#[pymodule]
pub fn equation_59_11(m: &Bound<'_, PyModule>) -> PyResult<()> {
m.add_function(pyo3::wrap_pyfunction!(time_for_passage, m)?)?;
Ok(())
}
43 changes: 43 additions & 0 deletions crates/python_api/src/sfpe_handbook/chapter_59/equation_59_12.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
use pyo3::prelude::*;

use openfire::sfpe_handbook::chapter_59::equation_59_12 as rust_equation_59_12;

#[pyfunction]
/// Calculates the specific flow departing from a transition point (Equation 59.12).
///
/// For cases involving one flow into and one flow out of a transition point,
/// this equation determines the specific flow of the route departing from
/// the transition point.
///
/// .. math::
///
/// F_{s(out)} = \frac{F_{s(in)} \cdot W_{e(in)}}{W_{e(out)}}
///
/// where:
///
/// - :math:`F_{s(out)}` is the specific flow departing from transition point (persons/min/ft or persons/s/m)
/// - :math:`F_{s(in)}` is the specific flow arriving at transition point (persons/min/ft or persons/s/m)
/// - :math:`W_{e(in)}` is the effective width prior to transition point (ft or m)
/// - :math:`W_{e(out)}` is the effective width after passing transition point (ft or m)
///
/// Args:
/// fs_in (float): Specific flow arriving at transition point (persons/min/ft or persons/s/m)
/// we_in (float): Effective width prior to transition point (ft or m)
/// we_out (float): Effective width after passing transition point (ft or m)
///
/// Returns:
/// float: Specific flow departing from transition point Fs(out) (persons/min/ft or persons/s/m)
///
/// Example:
/// >>> import ofire
/// >>> result = ofire.sfpe_handbook.chapter_59.equation_59_12.specific_flow_out(1.0, 2.0, 1.0)
/// >>> print(f"{result:.1f} persons/s/m")
fn specific_flow_out(fs_in: f64, we_in: f64, we_out: f64) -> PyResult<f64> {
Ok(rust_equation_59_12::specific_flow_out(fs_in, we_in, we_out))
}

#[pymodule]
pub fn equation_59_12(m: &Bound<'_, PyModule>) -> PyResult<()> {
m.add_function(pyo3::wrap_pyfunction!(specific_flow_out, m)?)?;
Ok(())
}
55 changes: 55 additions & 0 deletions crates/python_api/src/sfpe_handbook/chapter_59/equation_59_13.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
use pyo3::prelude::*;

use openfire::sfpe_handbook::chapter_59::equation_59_13 as rust_equation_59_13;

#[pyfunction]
/// Calculates the specific flow departing from a transition point with two incoming flows (Equation 59.13).
///
/// For cases involving two incoming flows and one outflow from a transition point,
/// such as that which occurs with the merger of a flow down a stair and the
/// entering flow at a floor.
///
/// .. math::
///
/// F_{s(out)} = \frac{F_{s(in1)} \cdot W_{e(in1)} + F_{s(in2)} \cdot W_{e(in2)}}{W_{e(out)}}
///
/// where:
///
/// - :math:`F_{s(out)}` is the specific flow departing from transition point (persons/min/ft or persons/s/m)
/// - :math:`F_{s(in1)}` is the specific flow of first incoming stream (persons/min/ft or persons/s/m)
/// - :math:`W_{e(in1)}` is the effective width of first incoming stream (ft or m)
/// - :math:`F_{s(in2)}` is the specific flow of second incoming stream (persons/min/ft or persons/s/m)
/// - :math:`W_{e(in2)}` is the effective width of second incoming stream (ft or m)
/// - :math:`W_{e(out)}` is the effective width after passing transition point (ft or m)
///
/// Args:
/// fs_in1 (float): Specific flow of first incoming stream (persons/min/ft or persons/s/m)
/// we_in1 (float): Effective width of first incoming stream (ft or m)
/// fs_in2 (float): Specific flow of second incoming stream (persons/min/ft or persons/s/m)
/// we_in2 (float): Effective width of second incoming stream (ft or m)
/// we_out (float): Effective width after passing transition point (ft or m)
///
/// Returns:
/// float: Specific flow departing from transition point Fs(out) (persons/min/ft or persons/s/m)
///
/// Example:
/// >>> import ofire
/// >>> result = ofire.sfpe_handbook.chapter_59.equation_59_13.specific_flow_out_two_inflows(1.0, 1.0, 1.0, 1.0, 2.0)
/// >>> print(f"{result:.1f} persons/s/m")
fn specific_flow_out_two_inflows(
fs_in1: f64,
we_in1: f64,
fs_in2: f64,
we_in2: f64,
we_out: f64,
) -> PyResult<f64> {
Ok(rust_equation_59_13::specific_flow_out_two_inflows(
fs_in1, we_in1, fs_in2, we_in2, we_out,
))
}

#[pymodule]
pub fn equation_59_13(m: &Bound<'_, PyModule>) -> PyResult<()> {
m.add_function(pyo3::wrap_pyfunction!(specific_flow_out_two_inflows, m)?)?;
Ok(())
}
Loading
Loading