geeViz.fireLib.behavior

Per-pixel fire behavior — Rothermel surface spread and its consequences.

This is the part of fire modeling Earth Engine is genuinely ideal for. Rothermel’s rate of spread given a fuel bed, slope, wind and moisture is a pure pixel-wise function: no neighbors, no iteration, no state. It maps onto a tile-parallel engine perfectly, at CONUS scale, across as many weather scenarios as you care to run.

The model (Rothermel 1972, INT-115) computes

R = (I_R * xi * (1 + phi_w + phi_s)) / (rho_b * eps * Q_ig)

where I_R is reaction intensity, xi the propagating flux ratio, phi_w and phi_s the wind and slope factors, and the denominator the heat sink. Everything here is in Rothermel’s original English units (tons/acre, ft, ft/min, BTU/lb) because the published coefficients are, and converting the coefficients rather than the inputs is how sign and magnitude errors get in. Conversion to metric happens once, at the edge, in ros_metric().

On accuracy. This is the surface-fire model. It does not include crown fire (see crown_fire_initiation()), spotting, or any fire-atmosphere coupling. Rothermel himself scoped it to a quasi-steady fire spreading through continuous, uniform surface fuel — real fires routinely violate every one of those. Treat the output as a physically grounded index that is well correlated with observed spread, not as a prediction of what a specific fire will do.

Module Attributes

HEAT_CONTENT

Heat content of wood, BTU/lb.

PARTICLE_DENSITY

Oven-dry particle density, lb/ft3.

MINERAL_TOTAL

Total and effective mineral content, fractions.

TONS_ACRE_TO_LB_FT2

tons/acre -> lb/ft2.

FT_MIN_TO_M_S

ft/min -> m/s.

Functions

crown_fire_initiation(fuels, flame_length_ft, *)

Van Wagner crown-fire initiation: does the surface fire torch?

flame_length(ros_ft_min[, i_r, ...])

Byram flame length in feet from rate of spread.

rate_of_spread(fuels, terrain, *, ...[, ...])

Rothermel surface rate of spread, ft/min, as an ee.Image.

ros_metric(ros_ft_min)

Convert rate of spread from ft/min to m/s.

terrain_slope_factor(terrain, beta)

Rothermel slope factor phi_s.

geeViz.fireLib.behavior.HEAT_CONTENT = 8000.0

Heat content of wood, BTU/lb. Rothermel’s standard value; varies little enough between species that per-fuel-model variation is not worth the complexity here.

geeViz.fireLib.behavior.PARTICLE_DENSITY = 32.0

Oven-dry particle density, lb/ft3.

geeViz.fireLib.behavior.MINERAL_TOTAL = 0.0555

Total and effective mineral content, fractions.

geeViz.fireLib.behavior.TONS_ACRE_TO_LB_FT2 = 0.04591368227731864

tons/acre -> lb/ft2. 2000 lb per ton over 43,560 ft2 per acre.

geeViz.fireLib.behavior.FT_MIN_TO_M_S = 0.00508

ft/min -> m/s.

geeViz.fireLib.behavior.rate_of_spread(fuels, terrain, *, wind_speed_20ft, moisture_1h=0.06, moisture_live=1.5, fbfm_band: str = 'FBFM40', wind_adjustment: float = 0.4)[source]

Rothermel surface rate of spread, ft/min, as an ee.Image.

Parameters:
  • fuels – Image carrying the fuel-model band (see landfire_fuels()).

  • terrain – Image carrying slope_tan (see terrain_layers()).

  • wind_speed_20ft – 20-ft wind speed in mi/h, as a number or an ee.Image. GRIDMET’s vs is 10 m in m/s — convert before passing it, or the result is wrong by roughly a factor of two and still looks reasonable.

  • moisture_1h – Dead 1-hour fuel moisture, fraction (0.06 = 6%). GRIDMET ships fm100/fm1000 as percentages.

  • moisture_live – Live fuel moisture, fraction. 1.50 is a typical growing-season value; 0.60 or below is critically dry.

  • fbfm_band – Name of the fuel-model band in fuels.

  • wind_adjustment – Factor converting 20-ft wind to midflame wind. 0.4 is a common sheltered-surface default; unsheltered grass is nearer 0.6 and dense timber nearer 0.1-0.2. This single number moves rate of spread more than almost any other input, which is why it is an explicit argument rather than a constant.

Returns:

ee.Image band ros_ft_min, masked where the fuel model is not in the parameter table and forced to zero on non-burnable models.

geeViz.fireLib.behavior.terrain_slope_factor(terrain, beta)[source]

Rothermel slope factor phi_s.

Separated out because it is the single easiest place to introduce a silent error: the formula takes the tangent of slope, and slope rasters are almost always published in degrees. Passing degrees directly produces a number that is finite, positive, and far too small on steep ground — wrong in the direction that makes a fire look safer than it is.

geeViz.fireLib.behavior.ros_metric(ros_ft_min)[source]

Convert rate of spread from ft/min to m/s.

Kept as an explicit edge conversion. Rothermel’s published coefficients are unit-bearing, so the calculation stays in English units throughout and converts exactly once, here.

geeViz.fireLib.behavior.flame_length(ros_ft_min, i_r=None, *, residence_time_min: float = 0.5)[source]

Byram flame length in feet from rate of spread.

Byram: FL = 0.45 * I^0.46 with fireline intensity I in BTU/ft/s. Intensity is reaction intensity times residence time times spread rate.

Flame length is what most risk products key on – the 4 ft and 8 ft thresholds in Wildfire Risk to Communities are direct suppression interpretations: under 4 ft is generally attackable by hand crews, over 8 ft implies crowning or spotting and effectively rules out direct attack.

geeViz.fireLib.behavior.crown_fire_initiation(fuels, flame_length_ft, *, cbh_band: str = 'CBH', cbh_scale: float = 0.1)[source]

Van Wagner crown-fire initiation: does the surface fire torch?

A surface fire transitions to crown fire when its intensity is sufficient to ignite the canopy base. The controlling geometry is canopy base height — the vertical gap between surface flames and the lowest live crown fuel.

Parameters:

cbh_scale – LANDFIRE stores canopy base height as metres x 10 so it can be an integer raster, so 0.1 converts to metres. Getting this wrong by a factor of ten produces a canopy 10x too high and a landscape that never torches.

Returns:

ee.Image band crown_initiation — 1 where the surface fire is expected to reach the canopy base, 0 otherwise.