Skip to content
Back to skills

ELMFIRE

ASecurity

**Package**: `wildfire-elmfire` v1.0.0 **Model**: ELMFIRE 2025.1002 **Created by**: Knowledge Dissection Toolkit **Last updated**: 2026-03-26 **Stats**: 4 tools | 5 skill documents | 20 diagnostic triplets | ~1,500 lines of validated Python **Validation status**: `tutorial_validated` (Tutorial 01 — Constant Wind) ---

  • 200 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added September 11, 2026
testingpythongoshellbashdockerawsdebugginggitapiperformance

Works with

  • cli
  • api

Security analysis

A100/100

Pro scans all 19 files and shows the line behind each finding

Scanned September 11, 2026

npx -y skills add lzwei196/KISS---Knowledge-Infrastructure-for-Scientific-Simulation --skill ELMFIRE --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of ELMFIRE?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for ELMFIRE
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/lzwei196-elmfire/badge)](https://www.skillsdirectory.com/skills/lzwei196-elmfire)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
> **MANDATORY EXECUTION POLICY** — READ BEFORE PROCEEDING
>
> You MUST run the **actual model binary or package** described in this document.
> If the model fails to import, compile, or execute, you MUST:
> 1. Check `diagnostics/triplets.yaml` for a matching error pattern
> 2. Try the fix suggested in the triplet's `remedy` section
> 3. If still failing, report the error to the user with full details
>
> You MUST NOT substitute a simplified Python formula, regression equation,
> or hand-coded approximation in place of the real model.
>
>
> Before starting, run: `python preflight_check.py` (in this KI directory)
> to verify that the model binary/package and required data are available.
>
> **DEBUGGING PROTOCOL** — When something goes wrong, follow this order:
> 1. **Check triplets** — `diagnostics/triplets.yaml` may already cover this error
> 2. **Read official docs** — The model's own documentation for expected formats/units
> 3. **Find working examples** — Check `outputs/` or the model's shipped test data
> 4. **Fix the tool** — With knowledge of what "correct" looks like
>
> Do NOT write custom debug scripts. The answers are in the docs and examples.

<!-- KI-MAP:BEGIN (projected by generate_skill_map.py — edit the KI, not this table) -->
## KI map — what to read, and when

| when you need | read | why |
|---|---|---|
| FIRST, always | `preflight_check.py` | run it (`python preflight_check.py`): proves env/binary/data are usable and emits a machine-readable `PREFLIGHT_REPORT=` line. Do not debug a run that never had a healthy environment. |
| to run the pipeline stages | `tools/` (4 tools) | the executable pipeline. Read each tool's argparse (`--help`) before composing a command; SKILL.md's stage table says which tool serves which stage. |
| on ANY error, before debugging | `diagnostics/triplets.yaml` (20 entries) | symptom → diagnosis → remedy for this model's known failure modes. Check here FIRST; the answer usually exists. Never renumber or rewrite entries. |
| to know what an output IS | `dag.yaml` | the model's identity: every output's medium, units, `validation_rank` (1 = the headline variable) and observability. Scoring and obs-binding read THIS — when asked 'what does this model predict', the dag is the answer, not a guess. |
| when building inputs / parsing outputs | `docs/format_spec.yaml` | exact I/O shapes + `known_issues`, projected from dag + triplets. Regenerate with `ki_tools_common/generate_format_spec.py` after changing either — never hand-edit. |
| to judge a run's skill | `docs/validation_convention.yaml` | how this model's field judges it validated: per-`dag_variable` metrics, directions and CITED pass-bands. A run is graded against these, not against intuition. |
| for claims and thresholds | `docs/gathered_papers.json` (19 papers) + `docs/papers_index.md` | the literature this KI is judged by; each entry's `text_path` is fetched full text in the central paper cache. `role: benchmark` marks the model's own skill paper. |
| for a machine-readable summary | `knowledge_infrastructure.yaml` | the manifest (package, pipeline, validation tier, counts) — projected by `ki_tools_common/generate_ki_manifest.py`; regenerate after structural changes, never hand-edit. |

*Projected 2026-08-17 from the KI's actual contents — 8 components present. Refresh: `python3 ki_tools_common/generate_skill_map.py --ki_dir <this KI>`.*
<!-- KI-MAP:END -->

<!-- KI-TOOL-INDEX:BEGIN (projected by generate_skill_map.py — the discoverability contract: every public tool, exact path; PURPOSE stays human-authored elsewhere) -->
### Executable tool index (projected — complete by construction)

Every public tool in this KI, by exact path. What each is FOR lives in the
human-written Tool Inventory above; `--help` on any of these prints its arguments.

| tool (exact path) | invocation |
|---|---|
| `tools/convert_landscape_to_elmfire.py` | `KISSPATH_PYTHON_ENV/bin/python {KI}/tools/convert_landscape_to_elmfire.py --help` |
| `tools/convert_weather_to_elmfire.py` | `KISSPATH_PYTHON_ENV/bin/python {KI}/tools/convert_weather_to_elmfire.py --help` |
| `tools/parse_elmfire_output.py` | `KISSPATH_PYTHON_ENV/bin/python {KI}/tools/parse_elmfire_output.py --help` |
| `tools/run_elmfire.py` | `KISSPATH_PYTHON_ENV/bin/python {KI}/tools/run_elmfire.py --help` |

*4 public tools; `_`-prefixed helpers and packaging files excluded.*
<!-- KI-TOOL-INDEX:END -->

# ELMFIRE (Eulerian Level Set Model of FIRE Spread) — Knowledge Infrastructure

**Package**: `wildfire-elmfire` v1.0.0
**Model**: ELMFIRE 2025.1002
**Created by**: Knowledge Dissection Toolkit
**Last updated**: 2026-03-26
**Stats**: 4 tools | 5 skill documents | 20 diagnostic triplets | ~1,500 lines of validated Python
**Validation status**: `tutorial_validated` (Tutorial 01 — Constant Wind)

---

## Data Preparation

### Forcing data

**Data Sources**: Use `from ki_tools_common.load_forcing import load_daily_forcing` for CMFD/MSWX/NASA POWER.

**Data Validation Reference**: See `data_ki/CMFD/SKILL.md` for weather forcing documentation.
See `data_ki/MTBS/SKILL.md` for fire perimeter observations.


## Overview

This knowledge infrastructure enables autonomous wildfire spread simulation using ELMFIRE on any landscape, **without manual data preparation**. The 4 validated tools replace the standard shell-script workflow with a Python pipeline that generates GeoTIFF inputs, configures Fortran namelists, executes the model, and parses outputs.

**What ELMFIRE does**: 2D Eulerian level-set wildfire spread model. Simulates:
- Fire perimeter propagation (level-set equations on raster grid)
- Surface fire spread (Rothermel model with 304 fuel models)
- Crown fire initiation and spread (Van Wagner / Cruz-Alexander)
- Ember transport and spot fire ignition (UMD physics-based model)
- Fire behavior metrics: rate of spread, flame length, fireline intensity
- Monte Carlo burn probability (hundreds of ensemble members)
- Smoke emissions and PM2.5 yield (optional)
- Suppression / initial attack modeling (optional)

**Key difference from other wildfire models**: ELMFIRE is grid-based (Eulerian), not perimeter-tracking (Lagrangian like FARSITE). It uses level-set methods for robust topology changes (merging fires, islands) and scales efficiently with MPI parallelism.

**Reference**: Lautenberger, C. (2013). Wildland fire modeling with an Eulerian level set method and automated calibration. *Fire Safety Journal*, 62, 289–298. https://doi.org/10.1016/j.firesaf.2013.08.014

---

## Installation

### Binary

```
ELMFIRE:      build/linux/bin/elmfire_2025.1002
Post:         build/linux/bin/elmfire_post_2025.1002
Platform:     Linux x86-64, MPI-parallel (OpenMPI)
Source:       github.com/lautenberger/elmfire
```

### Build from source

```bash
cd build/linux
./make_gnu.sh   # Produces 6 binaries in bin/
```

### Dependencies

```
gfortran >= 9, libopenmpi-dev, openmpi-bin
gdal-bin (gdal_calc.py, gdalwarp, gdal_translate, gdal_contour, gdalinfo)
jq, bc, csvkit, pigz
Python 3: google-api-python-client, grpcio, python-dateutil (for CloudFire)
```

### Docker

```bash
docker build -t elmfire .
docker-compose up
```

### Quick test

```bash
cd tutorials/01-constant-wind
./01-run.sh
# Produces: outputs/time_of_arrival*.tif, spread_rate*.tif, flin*.tif
```

---

## Pipeline (7 stages)

| # | Stage | Tool(s) | Description |
|---|-------|---------|-------------|
| 1 | Landscape data | `convert_landscape_to_elmfire.py` | Fuel, topography, canopy GeoTIFFs |
| 2 | Weather forcing | `convert_weather_to_elmfire.py` | Wind speed/dir, fuel moisture GeoTIFFs |
| 3 | Ignition setup | (in namelist) | Point coords, CSV file, or probability mask |
| 4 | Namelist config | `convert_weather_to_elmfire.py` | Generate elmfire.data (Fortran namelist) |
| 5 | Execution | `run_elmfire.py` | Preflight checks → mpirun → output validation |
| 6 | Post-processing | `elmfire_post` binary | Ensemble aggregation, burn probability |
| 7 | Output analysis | `parse_elmfire_output.py` | Extract CSV time series, compute metrics |

---

## Unit Trap Table (CRITICAL — silent errors if wrong)

These are the most dangerous unit mismatches in ELMFIRE. Getting any of these wrong produces plausible but incorrect results with **no error message**.

| Variable | ELMFIRE expects | Common source | Trap | Symptom |
|----------|----------------|---------------|------|---------|
| Wind speed | **mph at 20 ft** | m/s at 10 m | ×2.237 for m/s→mph, ×1.15 for 10m→20ft | Fire too slow (m/s) or too fast (knots) |
| Wind direction | **degrees, met convention** (direction FROM) | math convention (direction TO) | Add 180° if "to" convention | Fire spreads opposite to observed |
| Dead fuel moisture (M1,M10,M100) | **percent** (e.g., 5.0) | fraction (0.05) | ×100 if fraction | No fire (fraction) or instant crown fire (wrong %) |
| Live fuel moisture (MLH,MLW) | **percent** (e.g., 60.0) | fraction (0.60) | ×100 if fraction | Fire too intense or nonexistent |
| Slope | **degrees** (0–90) | percent rise or radians | Convert: degrees = atan(rise/100)×180/π | Wild spread rates on steep terrain |
| Aspect | **degrees** (0=N, 90=E, 180=S) | 0=E mathematical | Rotate: aspect_geo = 90 - aspect_math | Wrong solar heating, affects diurnal |
| Canopy base height | **meters ×10** (integer) | meters | Multiply by 10 when CBH_TIMES_10=.TRUE. | Crown fire threshold wrong |
| Canopy bulk density | **kg/m³ ×100** (integer) | kg/m³ | Multiply by 100 when CBD_TIMES_100=.TRUE. | Crown fire intensity wrong |
| Canopy cover | **percent** (0–100) | fraction (0–1) | ×100 if CC_IN_PERCENT=.TRUE. | No crown fire (fraction treated as %) |
| Canopy height | **meters ×10** (integer) | meters | Multiply by 10 when CH_TIMES_10=.TRUE. | WAF calculation wrong |
| Domain coordinates | **UTM meters** | lat/lon degrees | Must reproject to UTM zone EPSG | Tiny domain or domain in wrong location |
| Simulation time | **seconds** | hours or minutes | ×3600 for hours | Fire stops too early |
| DTDUMP | **seconds** | hours | ×3600 | No output or too many files |
| Cell size | **meters** | feet or km | 1 km = 1000 m | Resolution completely wrong |
| Fireline intensity output | **kW/m** | BTU/ft/s | ×3.46 from BTU/ft/s | Misinterpret severity |
| Spread rate output | **ft/min** | m/s or chains/hr | ×0.3048/60 to m/s | Misinterpret ROS values |
| Flame length output | **feet** | meters | ×0.3048 to meters | Misinterpret for suppression thresholds |

---

## Input File Reference

### Namelist file (elmfire.data)

Fortran 90 namelist format with 10 groups:

```fortran
&INPUTS
FUELS_AND_TOPOGRAPHY_DIRECTORY = './inputs'
ASP_FILENAME  = 'asp'       ! Aspect (degrees, 0=N)
SLP_FILENAME  = 'slp'       ! Slope (degrees)
DEM_FILENAME  = 'dem'       ! Elevation (meters)
FBFM_FILENAME = 'fbfm40'    ! Fuel model code (FBFM40, 0-303)
ADJ_FILENAME  = 'adj'       ! Spread rate adjustment factor (-)
PHI_FILENAME  = 'phi'       ! Level set initial field (1.0=unburned)
CBD_FILENAME  = 'cbd'       ! Canopy bulk density (100*kg/m³)
CBH_FILENAME  = 'cbh'       ! Canopy base height (10*m)
CC_FILENAME   = 'cc'        ! Canopy cover (percent)
CH_FILENAME   = 'ch'        ! Canopy height (10*m)
WEATHER_DIRECTORY = './inputs'
WS_FILENAME   = 'ws'        ! Wind speed (mph at 20ft)
WD_FILENAME   = 'wd'        ! Wind direction (degrees, met convention)
M1_FILENAME   = 'm1'        ! 1-hr dead fuel moisture (percent)
M10_FILENAME  = 'm10'       ! 10-hr dead fuel moisture (percent)
M100_FILENAME = 'm100'      ! 100-hr dead fuel moisture (percent)
LH_MOISTURE_CONTENT = 30.0  ! Live herbaceous moisture (percent)
LW_MOISTURE_CONTENT = 60.0  ! Live woody moisture (percent)
DT_METEOROLOGY = 3600.0     ! Weather update interval (seconds)
/

&OUTPUTS
OUTPUTS_DIRECTORY    = './outputs'
DTDUMP               = 3600.   ! Output interval (seconds)
DUMP_FLIN            = .TRUE.  ! Fireline intensity
DUMP_SPREAD_RATE     = .TRUE.  ! Rate of spread
DUMP_TIME_OF_ARRIVAL = .TRUE.  ! Fire arrival time
DUMP_FLAME_LENGTH    = .FALSE. ! Flame length
DUMP_CROWN_FIRE      = .FALSE. ! Crown fire flag
DUMP_FIRE_SIZE_STATS = .TRUE.  ! Cumulative area CSV
CONVERT_TO_GEOTIFF   = .TRUE.  ! Auto-convert BIL to GeoTIFF
/

&COMPUTATIONAL_DOMAIN
A_SRS = 'EPSG: 32610'                    ! Spatial reference (UTM zone)
COMPUTATIONAL_DOMAIN_CELLSIZE = 30.0      ! Cell size (meters)
COMPUTATIONAL_DOMAIN_XLLCORNER = -6000.0  ! Lower-left X (UTM meters)
COMPUTATIONAL_DOMAIN_YLLCORNER = -6000.0  ! Lower-left Y (UTM meters)
/

&TIME_CONTROL
SIMULATION_DT    = 30.0     ! Time step (seconds, adaptive)
SIMULATION_DTMAX = 600.0    ! Max time step (seconds)
SIMULATION_TSTOP = 21600.0  ! End time (seconds)
TARGET_CFL       = 0.4      ! CFL stability number
/

&SIMULATOR
NUM_IGNITIONS = 1
X_IGN(1) = 0.0       ! Ignition UTM easting (meters)
Y_IGN(1) = 3000.0    ! Ignition UTM northing (meters)
T_IGN(1) = 0.0       ! Ignition time (seconds from start)
/

&MISCELLANEOUS
PATH_TO_GDAL = '/usr/bin'
SCRATCH      = './scratch'
/
```

### Input raster format

- **Format**: GeoTIFF (`.tif`) or ENVI BIL (`.bil` + `.hdr`)
- **Data types**: Float32 for continuous, Int16 for categorical
- **NODATA**: -9999
- **CRS**: Must match `A_SRS` in namelist (typically UTM)
- **Resolution**: Must match `COMPUTATIONAL_DOMAIN_CELLSIZE`
- **Extent**: Must cover computational domain
- **Bands**: Single-band per time step, or multi-band with DT_METEOROLOGY interval

### Fuel models

304 models from `fuel_models.csv`:
- 0: Non-burnable
- 1–13: Original 13 NFFL models (Anderson 1982)
- 101–189: FBFM40 expanded set (Scott & Burgan 2005)
  - GR1–GR9 (101–109): Grass
  - GS1–GS4 (121–124): Grass-shrub
  - SH1–SH9 (141–149): Shrub
  - TU1–TU5 (161–165): Timber-understory
  - TL1–TL9 (181–189): Timber litter
  - SB1–SB4 (201–204): Slash-blowdown

---

## Output File Reference

### GeoTIFF outputs (in OUTPUTS_DIRECTORY)

| File pattern | Variable | Units | Type |
|---|---|---|---|
| `time_of_arrival_*.tif` | Fire arrival time | seconds | Float32 |
| `spread_rate_*.tif` | Rate of spread | ft/min | Float32 |
| `flin_*.tif` | Fireline intensity | kW/m | Float32 |
| `flame_length_*.tif` | Flame length | feet | Float32 |
| `crown_fire_*.tif` | Crown fire flag | 0/1 | Int16 |
| `velocity_*.tif` | Spread velocity | ft/min | Float32 |
| `hourly_isochrones.shp` | Fire contours | polygon | Shapefile |

### Fire size statistics CSV

```csv
Case,Ensemble_Member,Time(sec),Area(acres),Area(hectares),Perimeter(feet),Perimeter(meters)
1,1,0.0,0.0,0.0,0.0,0.0
1,1,3600.0,125.4,50.8,2341.2,714.0
```

### Postprocessing outputs (from elmfire_post)

- `burn_probability.tif` — fraction of ensemble members that burned each pixel
- `time_of_arrival_pNN.tif` — Nth percentile arrival time
- `fire_size_percentiles.csv` — ensemble fire size distribution

---

## 6. Output Description (sourced from dag.yaml)

The dag is the source of truth for observable outputs. If this section ever disagrees with
`dag.yaml`, the dag wins.

**Headline output** (`validation_rank: 1`):

> `fire_size` — Cumulative burned area (and perimeter) time series per case. (acres (and hectares))

| Output variable (dag `var`) | Dag unit | Dag description / supplied dag fact |
|---|---|---|
| `fire_size` | acres (and hectares) | Cumulative burned area (and perimeter) time series per case. |
| `time_of_arrival` | See `dag.yaml` | Listed as an additional dag output. |
| `spread_rate` | See `dag.yaml` | Listed as an additional dag output. |
| `fireline_intensity` | See `dag.yaml` | Listed as an additional dag output. |
| `flame_length` | See `dag.yaml` | Listed as an additional dag output. |
| `crown_fire` | See `dag.yaml` | Listed as an additional dag output. |
| `burn_probability` | See `dag.yaml` | Listed as an additional dag output. |

The dag output list is: `fire_size`, `time_of_arrival`, `spread_rate`,
`fireline_intensity`, `flame_length`, `crown_fire`, and `burn_probability`.

---

## 8. Unit Conversion and Unit Table

This table restates the pipeline's unit-sensitive conversions and output units already
documented in this KI body. Use `docs/format_spec.yaml` for exact machine-readable shapes.

### Input conversion table

| Variable | Source unit / common source | ELMFIRE unit | Conversion or rule |
|---|---|---|---|
| Wind speed | m/s at 10 m | mph at 20 ft | ×2.237 for m/s→mph; ×1.15 for 10m→20ft |
| Wind direction | math convention, direction TO | degrees, meteorological convention, direction FROM | Add 180° if using "to" convention |
| Dead fuel moisture (`M1`, `M10`, `M100`) | fraction, e.g. 0.05 | percent, e.g. 5.0 | ×100 if source is fraction |
| Live fuel moisture (`MLH`, `MLW`) | fraction, e.g. 0.60 | percent, e.g. 60.0 | ×100 if source is fraction |
| Slope | percent rise or radians | degrees, 0–90 | degrees = atan(rise/100)×180/π |
| Aspect | 0=E mathematical | degrees, 0=N, 90=E, 180=S | aspect_geo = 90 - aspect_math |
| Canopy base height | meters | meters ×10 integer | Multiply by 10 when `CBH_TIMES_10=.TRUE.` |
| Canopy bulk density | kg/m³ | kg/m³ ×100 integer | Multiply by 100 when `CBD_TIMES_100=.TRUE.` |
| Canopy cover | fraction, 0–1 | percent, 0–100 | ×100 if `CC_IN_PERCENT=.TRUE.` |
| Canopy height | meters | meters ×10 integer | Multiply by 10 when `CH_TIMES_10=.TRUE.` |
| Domain coordinates | lat/lon degrees | UTM meters | Reproject to the UTM zone used by `A_SRS` |
| Simulation time | hours or minutes | seconds | ×3600 for hours |
| `DTDUMP` | hours | seconds | ×3600 |
| Cell size | feet or km | meters | 1 km = 1000 m |

### Output unit table

| Output variable | Unit |
|---|---|
| `fire_size` | acres (and hectares) |
| `time_of_arrival` | seconds |
| `spread_rate` | ft/min |
| `fireline_intensity` | kW/m |
| `flame_length` | feet |
| `crown_fire` | 0/1 |
| `burn_probability` | fraction of ensemble members that burned each pixel |

### Output interpretation conversions

| Output variable | ELMFIRE output unit | Common comparison unit | Conversion |
|---|---|---|---|
| `fireline_intensity` | kW/m | BTU/ft/s | ×3.46 from BTU/ft/s |
| `spread_rate` | ft/min | m/s | ×0.3048/60 to m/s |
| `flame_length` | feet | meters | ×0.3048 to meters |

---

## 11. Validated Results

### Current validation status

| Property | Value |
|---|---|
| Validation status | `tutorial_validated` |
| Validated tutorial | Tutorial 01 — Constant Wind |
| Headline dag output | `fire_size` |
| Headline dag output unit | acres (and hectares) |
| Headline dag output description | Cumulative burned area (and perimeter) time series per case. |
| Body validation campaign | pending |

### Performance metrics — judged against convention bars

`docs/validation_convention.yaml` is the source of truth for metric direction and pass-bands.
Null bands in the convention are written here as "no cited threshold"; no substitute thresholds
are inferred.

No cited convention bar for the rank-1 dag output `fire_size` is stated in the supplied KI
facts for this edit. Do not use another variable's bar as a proxy for `fire_size`.

| Dag variable | Metric | Direction | Satisfactory band | Good band | Very good band | Citation key |
|---|---|---|---|---|---|---|
| `time_of_arrival` | `sorensen` | maximize | 0.4 (`giannaros2020`) | 0.6 (`giannaros2020`) | 0.8 (`giannaros2020`) | `giannaros2020` |
| `spread_rate` | `absolute_percent_error` | minimize | 35.0 (`gale2025`) | no cited threshold (`gale2025`) | no cited threshold (`gale2025`) | `gale2025` |

### Data replacement tracking

| Component | Source | Status | Notes |
|---|---|---|---|
| Landscape data | `convert_landscape_to_elmfire.py` | Pipeline available | Fuel, topography, and canopy GeoTIFFs |
| Weather forcing | `convert_weather_to_elmfire.py` | Pipeline available | Wind speed, wind direction, and fuel moisture GeoTIFFs |
| Execution | `run_elmfire.py` | Pipeline available | Preflight checks, `mpirun`, and output validation |
| Output parsing | `parse_elmfire_output.py` | Pipeline available | CSV time series and metrics JSON |
| Body validation campaign | KI body | pending | Keep numeric achieved metrics out of this section until produced by the real model run |

---

## Tool Reference

| Tool | Purpose | Inputs | Outputs |
|------|---------|--------|---------|
| `convert_landscape_to_elmfire.py` | Generate terrain/fuel/canopy GeoTIFFs | LANDFIRE rasters or raw DEMs | slope, aspect, fbfm, canopy TIFs |
| `convert_weather_to_elmfire.py` | Generate weather GeoTIFFs + namelist | RAWS/HRRR/gridded weather | ws, wd, m1, m10, m100 TIFs + elmfire.data |
| `run_elmfire.py` | Execute ELMFIRE with preflight checks | elmfire.data + input TIFs | All output TIFs + fire_size_stats.csv |
| `parse_elmfire_output.py` | Extract results to CSV, compute metrics | Output TIFs + fire_size_stats.csv | Summary CSV + metrics JSON |

---

## Common Execution Patterns

### Single deterministic fire

```bash
# 1. Prepare inputs
python convert_landscape_to_elmfire.py --dem dem.tif --fuel fbfm40.tif --out ./inputs
python convert_weather_to_elmfire.py --ws 15 --wd 0 --m1 3 --m10 4 --m100 5 --out ./inputs

# 2. Run
python run_elmfire.py --namelist ./inputs/elmfire.data --np 4

# 3. Parse
python parse_elmfire_output.py --outputs_dir ./outputs --out results.csv
```

### Monte Carlo burn probability

```bash
# Set NUM_ENSEMBLE_MEMBERS = 100 and RANDOM_IGNITIONS = .TRUE.
python run_elmfire.py --namelist ./inputs/elmfire.data --np 16
# Post-process
elmfire_post_2025.1002 ./outputs/elmfire_post.data
```

### Docker execution

```bash
docker run -v $(pwd)/inputs:/elmfire/inputs \
           -v $(pwd)/outputs:/elmfire/outputs \
           elmfire mpirun -np 4 elmfire_2025.1002 /elmfire/inputs/elmfire.data
```

---

## Verification Checklist

Before any ELMFIRE run, verify:

1. **CRS consistency**: All rasters and namelist `A_SRS` must use the same UTM zone
2. **Resolution match**: All rasters must have the same cell size as `COMPUTATIONAL_DOMAIN_CELLSIZE`
3. **Extent coverage**: Rasters must fully cover the computational domain
4. **Wind speed units**: Must be mph at 20 ft above vegetation (not m/s, not 10 m)
5. **Moisture units**: Must be percent (3.0 = 3%), not fraction (0.03)
6. **Canopy multipliers**: CBD ×100, CBH ×10, CH ×10 when integer flags are set
7. **Fuel model codes**: Must be valid FBFM40 codes (check against fuel_models.csv)
8. **NODATA**: Must be -9999 in all rasters
9. **Ignition location**: Must fall within domain and on a burnable fuel pixel
10. **Time units**: SIMULATION_TSTOP, DTDUMP, DT_METEOROLOGY all in seconds

Files in this skill

  • SKILL.md22.1 KB
  • dag.yaml28.9 KB
  • diagnostics/triplets.yaml23.7 KB
  • docs/01_landscape_preparation.md4.9 KB
  • docs/02_weather_forcing.md4.8 KB
  • docs/03_namelist_configuration.md6.5 KB
  • docs/04_execution.md4.7 KB
  • docs/05_output_analysis.md5.7 KB
  • docs/REFERENCES.md2.1 KB
  • docs/format_spec.yaml25.7 KB
  • docs/papers.json5.8 KB
  • docs/validation_convention.yaml16.3 KB
  • knowledge_infrastructure.yaml2.9 KB
  • preflight_check.py5.9 KB
  • tools/convert_landscape_to_elmfire.py10.2 KB
  • tools/convert_weather_to_elmfire.py10.8 KB
  • tools/parse_elmfire_output.py10.2 KB
  • tools/run_elmfire.py9 KB
  • workflow/workflow.md1.4 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…