Metadata-Version: 2.4
Name: pycfast
Version: 0.2.2
Summary: Python interface for building, running, and analyzing CFAST fire simulation models
Project-URL: Homepage, https://github.com/bewygs/pycfast
Project-URL: Documentation, https://pycfast.org
Project-URL: Repository, https://github.com/bewygs/pycfast
Project-URL: Issues, https://github.com/bewygs/pycfast/issues
Project-URL: Changelog, https://github.com/bewygs/pycfast/blob/main/CHANGELOG.md
Author-email: WYGAS Benoît <97663334+bewygs@users.noreply.github.com>
Maintainer-email: WYGAS Benoît <97663334+bewygs@users.noreply.github.com>
License: MIT License
        
        Copyright (c) 2025 Benoît WYGAS — Orano.
        
        Permission is hereby granted, free of charge, to any person obtaining a copy
        of this software and associated documentation files (the "Software"), to deal
        in the Software without restriction, including without limitation the rights
        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        copies of the Software, and to permit persons to whom the Software is
        furnished to do so, subject to the following conditions:
        
        The above copyright notice and this permission notice shall be included in all
        copies or substantial portions of the Software.
        
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
        SOFTWARE.
License-File: LICENSE
Keywords: cfast,engineering,fire,fire-safety,modeling,simulation
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: Microsoft :: Windows
Classifier: Operating System :: POSIX
Classifier: Operating System :: Unix
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Scientific/Engineering :: Physics
Requires-Python: >=3.10
Requires-Dist: f90nml>=1.4.5
Requires-Dist: pandas>=2.0.0
Provides-Extra: all
Requires-Dist: bokeh>=3.8.0; extra == 'all'
Requires-Dist: coverage>=7.13.4; extra == 'all'
Requires-Dist: dask>=2025.7.0; extra == 'all'
Requires-Dist: distributed>=2025.7.0; extra == 'all'
Requires-Dist: ipython>=8.38.0; extra == 'all'
Requires-Dist: jupyter>=1.1.1; extra == 'all'
Requires-Dist: linkify-it-py>=2.0.3; extra == 'all'
Requires-Dist: matplotlib>=3.10.5; extra == 'all'
Requires-Dist: mypy>=1.19.1; extra == 'all'
Requires-Dist: myst-parser>=4.0.1; extra == 'all'
Requires-Dist: nbsphinx>=0.9.7; extra == 'all'
Requires-Dist: numpydoc>=1.9.0; extra == 'all'
Requires-Dist: pandas-stubs>=2.3.3.260113; extra == 'all'
Requires-Dist: pre-commit>=4.3.0; extra == 'all'
Requires-Dist: pydata-sphinx-theme>=0.16.1; extra == 'all'
Requires-Dist: pytest-cov>=7.0.0; extra == 'all'
Requires-Dist: pytest>=8.4.2; extra == 'all'
Requires-Dist: ruff>=0.15.1; extra == 'all'
Requires-Dist: salib>=1.5.1; extra == 'all'
Requires-Dist: scikit-learn>=1.7.1; extra == 'all'
Requires-Dist: scipy>=1.15.3; extra == 'all'
Requires-Dist: seaborn>=0.13.2; extra == 'all'
Requires-Dist: sphinx-autodoc-typehints>=3.0.1; extra == 'all'
Requires-Dist: sphinx-copybutton>=0.5.2; extra == 'all'
Requires-Dist: sphinx-design>=0.6.1; extra == 'all'
Requires-Dist: sphinx-gallery>=0.16; extra == 'all'
Requires-Dist: sphinx-sitemap>=2.9.0; extra == 'all'
Requires-Dist: sphinx>=5.0; extra == 'all'
Requires-Dist: torch>=2.8.0; extra == 'all'
Provides-Extra: dev
Requires-Dist: coverage>=7.13.4; extra == 'dev'
Requires-Dist: mypy>=1.19.1; extra == 'dev'
Requires-Dist: pandas-stubs>=2.3.3.260113; extra == 'dev'
Requires-Dist: pre-commit>=4.3.0; extra == 'dev'
Requires-Dist: pytest-cov>=7.0.0; extra == 'dev'
Requires-Dist: pytest>=8.4.2; extra == 'dev'
Requires-Dist: ruff>=0.15.1; extra == 'dev'
Provides-Extra: docs
Requires-Dist: bokeh>=3.8.0; extra == 'docs'
Requires-Dist: dask>=2025.7.0; extra == 'docs'
Requires-Dist: distributed>=2025.7.0; extra == 'docs'
Requires-Dist: ipython>=8.38.0; extra == 'docs'
Requires-Dist: jupyter>=1.1.1; extra == 'docs'
Requires-Dist: linkify-it-py>=2.0.3; extra == 'docs'
Requires-Dist: matplotlib>=3.10.5; extra == 'docs'
Requires-Dist: myst-parser>=4.0.1; extra == 'docs'
Requires-Dist: nbsphinx>=0.9.7; extra == 'docs'
Requires-Dist: numpydoc>=1.9.0; extra == 'docs'
Requires-Dist: pydata-sphinx-theme>=0.16.1; extra == 'docs'
Requires-Dist: salib>=1.5.1; extra == 'docs'
Requires-Dist: scikit-learn>=1.7.1; extra == 'docs'
Requires-Dist: scipy>=1.15.3; extra == 'docs'
Requires-Dist: seaborn>=0.13.2; extra == 'docs'
Requires-Dist: sphinx-autodoc-typehints>=3.0.1; extra == 'docs'
Requires-Dist: sphinx-copybutton>=0.5.2; extra == 'docs'
Requires-Dist: sphinx-design>=0.6.1; extra == 'docs'
Requires-Dist: sphinx-gallery>=0.16; extra == 'docs'
Requires-Dist: sphinx-sitemap>=2.9.0; extra == 'docs'
Requires-Dist: sphinx>=5.0; extra == 'docs'
Requires-Dist: torch>=2.8.0; extra == 'docs'
Provides-Extra: examples
Requires-Dist: bokeh>=3.8.0; extra == 'examples'
Requires-Dist: dask>=2025.7.0; extra == 'examples'
Requires-Dist: distributed>=2025.7.0; extra == 'examples'
Requires-Dist: jupyter>=1.1.1; extra == 'examples'
Requires-Dist: matplotlib>=3.10.5; extra == 'examples'
Requires-Dist: salib>=1.5.1; extra == 'examples'
Requires-Dist: scikit-learn>=1.7.1; extra == 'examples'
Requires-Dist: scipy>=1.15.3; extra == 'examples'
Requires-Dist: seaborn>=0.13.2; extra == 'examples'
Requires-Dist: torch>=2.8.0; extra == 'examples'
Description-Content-Type: text/markdown

# PyCFAST

[![CI Status](https://github.com/bewygs/pycfast/actions/workflows/test.yml/badge.svg)](https://github.com/bewygs/pycfast/actions/workflows/test.yml)
[![Docs](https://github.com/bewygs/pycfast/actions/workflows/docs.yml/badge.svg)](https://pycfast.org/index.html)
[![pre-commit.ci status](https://results.pre-commit.ci/badge/github/bewygs/pycfast/main.svg)](https://results.pre-commit.ci/latest/github/bewygs/pycfast/main)
[![uv](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/uv/main/assets/badge/v0.json)](https://github.com/astral-sh/uv)
[![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)
[![MyPy Checked](https://img.shields.io/badge/mypy-checked-blue)](https://github.com/python/mypy)
[![PyPI - Python Version](https://img.shields.io/pypi/pyversions/pycfast)](https://pypi.org/project/pycfast/)
[![Conda Version](https://img.shields.io/conda/vn/conda-forge/pycfast.svg)](https://anaconda.org/conda-forge/pycfast)
[![codecov](https://codecov.io/gh/bewygs/pycfast/graph/badge.svg?token=B39Q5PHMU3)](https://codecov.io/gh/bewygs/pycfast)
[![License: MIT](https://img.shields.io/badge/license-MIT-yellow.svg)](https://github.com/bewygs/pycfast/blob/main/LICENSE)
[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.18703351.svg)](https://doi.org/10.5281/zenodo.18703351)


**PyCFAST** is a Python interface for the [**Consolidated Fire and Smoke Transport (CFAST)**](https://pages.nist.gov/cfast/) fire simulation software. Its primary goal is to **automate CFAST calculations**, run parametric studies, sensitivity analyses, data generation, or optimization loops that would be impractical through the graphical interface (CEdit). It also provides a convenient way to create CFAST input files, execute simulations, and analyze results using the versatility and extensive ecosystem of Python.

## From CEdit GUI to Python

PyCFAST can be seen as an alternative to the CFAST graphical interface, CEdit. It exposes Python objects that integrate naturally into your Python workflow. Instead of relying on modifying input files through the GUI, you define and manipulate CFAST models programmatically.

<table>
<tr>
<td align="center"><strong>CEdit (GUI)</strong></td>
<td align="center"><strong>PyCFAST (Python)</strong></td>
</tr>
<tr>
<td><img src="docs/source/_static/images/cedit-compartments-tab.png" alt="CEdit Compartment Tab" width="400"></td>
<td>

```python
from pycfast import Compartment

room = Compartment(
    id="Comp 1",
    width=10.0,
    depth=10.0,
    height=10.0,
    ceiling_mat_id="Gypboard",
    wall_mat_id="Gypboard",
    floor_mat_id="Gypboard",
)

```

</td>
</tr>
</table>


## Example Usage

This minimal model runs with just a title and one compartment with default values:

```python
from pycfast import CFASTModel, Compartment, SimulationEnvironment

model = CFASTModel(
    simulation_environment=SimulationEnvironment(title="My Simulation"),
    compartments=[Compartment()],
    # you can also add: fires, wall_vents, ceiling_floor_vents, mechanical_vents, ...
    file_name="my_simulation.in",
)
model.summary()
model.save()
```

For a full model with all components:

```python
from pycfast import (
    CeilingFloorVent,
    CFASTModel,
    Compartment,
    Fire,
    Material,
    MechanicalVent,
    SimulationEnvironment,
    WallVent,
)

model = CFASTModel(
    simulation_environment=SimulationEnvironment(...),
    material_properties=[Material(...)],
    compartments=[Compartment(...)],
    wall_vents=[WallVent(...)],
    ceiling_floor_vents=[CeilingFloorVent(...)],
    mechanical_vents=[MechanicalVent(...)],
    fires=[Fire(...)],
    file_name="test_simulation.in",
)
```

Or you can import your existing model from a CFAST input file:

```python
from pycfast.parsers import parse_cfast_file

model = parse_cfast_file("existing_model.in")
```

Then you can run the model and obtain results as pandas DataFrames:

```python
results = model.run()
# results is a dict of pandas DataFrames
# Available keys: compartments, devices, masses, vents, walls, zone

results["compartments"].head()
#   Time    ULT_1   LLT_1   HGT_1  VOL_1  PRS_1  ...
# 0  0.0    20.00   20.00    5.00   0.01    0.0   ...
# 1  1.0    20.83   20.00    5.00   0.10    0.0   ...

results["devices"].head()
#   Time  TRGGAST_1  TRGSURT_1  TRGINT_1  TRGFLXI_1  ...
# 0  0.0      20.0       20.0      20.0       0.0    ...
# 1  1.0      20.0       20.0      20.0       0.38   ...
```


**Note:** When importing an existing model, ensure that all component names (such as TITLE, MATERIAL, ID, etc.) use **only alphanumeric characters**. Avoid **special characters** like quotes and slashes, as these may cause parsing issues and will be automatically sanitized where possible.

You can also inspect the model using text-based methods:

```python
print(model.summary())   # text summary to stdout
model.save()      # writes the CFAST input file to disk
model.view_cfast_input_file()  # view the generated input file
```

Check out the [examples](https://pycfast.org/examples.html) for more usage scenarios.

## Installation

PyCFAST requires **Python 3.10 or later** *and* a working installation of **[CFAST](https://pages.nist.gov/cfast/) itself**. It is fully [tested on verification input files](https://github.com/bewygs/pycfast/tree/main/tests/verification_tests) and [validation input files](https://github.com/bewygs/pycfast/tree/main/tests/validation_tests) from CFAST version **7.7.0** to version **7.7.7**. Versions below **7.7.0** might work but are not guaranteed to be fully compatible.

### CFAST Installation

CFAST is developed and distributed by NIST, independently of PyCFAST. Download and install it from the [NIST CFAST website](https://pages.nist.gov/cfast/) or the [CFAST GitHub repository](https://github.com/firemodels/cfast), then ensure `cfast` is available in your PATH.

- **Windows**: download and run the official installer for the version you want from the [CFAST releases page](https://github.com/firemodels/cfast/releases) (look for the `.exe` asset, e.g. `CFAST-X.Y.Z_SMV-A.B.C.exe`), which installs the `cfast` executable for you.

- **Linux / macOS**: NIST does not publish pre-built binaries for these platforms, so CFAST must be compiled from source with a Fortran compiler (`gfortran`). See the [Compiling CFAST wiki page](https://github.com/firemodels/cfast/wiki/Compiling-CFAST) for full details:

    ```bash
    # 1. Install a Fortran compiler
    sudo apt-get install gfortran        # Debian/Ubuntu
    # sudo dnf install gcc-gfortran      # Fedora/RHEL
    # brew install gcc                   # macOS

    # 2. Clone the CFAST source, pinned to the release tag you want (see the releases page above)
    git clone --depth 1 --branch <CFAST_TAG> https://github.com/firemodels/cfast.git
    cd cfast/Build/CFAST/gnu_linux       # macOS: cd cfast/Build/CFAST/gnu_osx

    # 3. Build the executable
    chmod +x make_cfast.sh
    ./make_cfast.sh

    # 4. Install it on your PATH
    sudo cp cfast7_linux /usr/local/bin/cfast   # macOS: cfast7_osx instead of cfast7_linux
    sudo chmod +x /usr/local/bin/cfast
    ```

    Notes:
    - CFAST versions below 7.7.5 do not reliably build on Linux with modern `gfortran` (see [#32](https://github.com/bewygs/pycfast/issues/32)).
    - The macOS build was manually verified to work but is not covered by PyCFAST's CI.
    - If the build fails, the compiler and flags for each platform target are defined in `Build/CFAST/makefile`. Adjust them there to match your machine.

### Pip or Conda

PyCFAST can be installed from [PyPI](https://pypi.org/project/pycfast) or [conda-forge](https://anaconda.org/conda-forge/pycfast):

```bash
pip install pycfast
```

```bash
conda install -c conda-forge pycfast
```

### Source

To install PyCFAST from source, clone the repository and install the required dependencies:

```bash
git clone https://github.com/bewygs/pycfast.git
cd pycfast
python -m pip install .
```

### Configuring the CFAST Executable

If CFAST is installed in a non-standard location, you can manually specify the path with these methods:

- From an environment variable ``CFAST``:

    ```bash
    export CFAST="/path/to/your/cfast/executable"  # Linux/MacOS
    set CFAST="C:\path\to\your\cfast\executable"  # Windows (cmd)
    $env:CFAST="C:\path\to\your\cfast\executable"  # Windows (PowerShell)
    ```

- From Python code when defining the ``CFASTModel``:

    ```python
    from pycfast import CFASTModel

    # set custom CFAST executable path via environment variable
    import os
    os.environ['CFAST'] = "/path/to/your/cfast/executable"

    # Or directly when defining CFASTModel
    model = CFASTModel(
            ...,
            cfast_exe="/path/to/your/cfast/executable"
        )
    ```

## Documentation

Full documentation, including the API reference and examples, is available online: [PyCFAST Documentation](https://pycfast.org/index.html)

## Contributing

We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) for more information.

## References

If you use PyCFAST in your projects, please consider citing the following:

```bib
@software{wygas_2026_pycfast,
  author    = {Wygas, Benoît},
  title     = {PyCFAST},
  year      = {2026},
  publisher = {Zenodo},
  doi       = {10.5281/zenodo.18703351},
  url       = {https://doi.org/10.5281/zenodo.18703351}
}
```

## Acknowledgments

This Python package was developed with the support of [**Orano**](https://www.orano.group/).

<a href="https://www.orano.group/">
  <picture>
    <source media="(prefers-color-scheme: dark)" srcset="docs/source/_static/orano-logo-dark.svg">
    <img src="docs/source/_static/orano-logo.svg" alt="Orano logo" width="150" >
  </picture>
</a>

PyCFAST is built on top of the work of the CFAST development team at the [National Institute of Standards and Technology (NIST)](https://www.nist.gov/). We acknowledge their ongoing efforts in maintaining and improving the CFAST fire modeling software.
