Fuel Moisture

Fuel moisture enters every rate-of-spread model through the moisture damping of the reaction intensity and, for Balbi, through the energy needed to bring the fuel to ignition. FLARE carries five moisture classes per fire cell in fire_fuel_mc: dead 1-hour, 10-hour and 100-hour fuels, and live herbaceous and live woody fuels. The dead classes can be held fixed or advanced with the atmosphere; how the live classes move with them is set by erf.fire.moisture_live_model.

Static moisture

With erf.fire.moisture_dynamic = false the dead classes stay at erf.fire.moisture_1hr, erf.fire.moisture_10hr and erf.fire.moisture_100hr (fractions of dry mass, defaults 0.08, 0.08 and 0.10) for the whole run, and the live classes at erf.fire.moisture_live (default 0.60). This is the configuration the canonical rate-of-spread tests use.

Dynamic dead-fuel moisture

With erf.fire.moisture_dynamic = true (the default in the parameter struct, so a deck that does not set it gets the dynamic model) each dead class in every fire cell follows the time-lag equation of Nelson (2000), advanced by forward Euler once per atmospheric step:

\[M_{n+1} = M_n + \Delta t\,\Bigl[\frac{M_e - M_n}{\tau\, f_T} + P\Bigr],\]

with \(\Delta t\) in hours, \(\tau\) the class time lag of 1, 10 or 100 hours, and the result clamped to \([0.01, 0.40]\).

Equilibrium moisture \(M_e\) comes from a wetting (adsorption) curve \(E_w\) and a drying (desorption) curve \(E_d\), chosen by erf.fire.emc_model:

  • "legacy" (default): fourth-degree polynomials in the relative humidity fraction \(H\), \(E_w = 0.0323 + 0.281 H + 0.409 H^2 - 1.356 H^3 + 1.660 H^4\) and \(E_d = 0.0580 + 0.199 H + 0.625 H^2 - 1.183 H^3 + 1.057 H^4\), each clamped to \([0, 0.35]\), with \(H\) clamped to \([0.01, 0.99]\) and no temperature dependence. They were ported from wildfire_levelset with an attribution to Nelson (2000), which does not contain them: Nelson fits Hart’s (1977) isotherm to Blackmarr’s (1971) adsorption and desorption data and averages the two into one isotherm. The constant and linear terms are those of Simard’s (1968) equation for RH below 10 % (RH and EMC in percent, temperature in °F) applied to fractions; no source is known for the rest. The curves run 60-80 % above the published ones between 10 and 60 % RH, cross near 66 % RH and both reach the 0.35 cap above 70 %.

  • "van_wagner": the drying and wetting equilibrium moisture of the Canadian Fine Fuel Moisture Code (Van Wagner and Pickett, 1985; Van Wagner, 1987, eqs. 2a-2b; Viney, 1991, eqs. 7-8), the pair WRF-SFIRE uses (Mandel et al., 2014). With \(h\) the relative humidity in percent and \(T\) the temperature in °C, in percent of dry mass,

    \[ \begin{align}\begin{aligned}E_d = 0.942\, h^{0.679} + 11\, e^{(h-100)/10} + 0.18\,(21.1 - T)\,(1 - e^{-0.115 h}),\\E_w = 0.618\, h^{0.753} + 10\, e^{(h-100)/10} + 0.18\,(21.1 - T)\,(1 - e^{-0.115 h}),\end{aligned}\end{align} \]

    divided by 100 and floored at zero; \(h\) is clamped to \([0, 100]\). (WRF-SFIRE’s module_fr_sfire_phys.F writes the exponential terms as 0.4994e-4*exp(0.1*H) and 0.4540e-4*exp(0.1*H), a tenth of \(11 e^{-10}\) and \(10 e^{-10}\); ERF follows the published form, as the cffdrs R package does.)

At 20 °C the two choices give:

RH [%]

legacy \(E_w\)

legacy \(E_d\)

van_wagner \(E_w\)

van_wagner \(E_d\)

0 (dry air)

0.035

0.060

0.000

0.000

10

0.063

0.083

0.036

0.046

20

0.097

0.115

0.061

0.074

40

0.166

0.189

0.102

0.118

60

0.270

0.284

0.139

0.156

80

0.350

0.350

0.183

0.202

95

0.350

0.350

0.253

0.276

A deck without an atmospheric moisture model hands the fuel zero relative humidity: the legacy curves clamp it to 1 % and hold the dead classes near 0.035-0.060, while van_wagner lets them dry to the 0.01 floor. Exec/RegTests/FireEmcModel runs both choices in dry air and at about 40 % RH, and the unit test ERF_GTestFuelMoistureEMC checks the curves against the published equations and the long-time equilibrium of both update models.

The curve is chosen by sorption hysteresis, as in the WRF-SFIRE dead-fuel model (Vejmelka et al. 2016): a fuel wetter than \(E_d\) dries toward it, a fuel drier than \(E_w\) wets toward it, and a fuel between the two does not change (\(M_e = M_n\), so only rain moves it). Nelson (2000) draws the same line, desorption when the fuel is wetter than its equilibrium and adsorption when it is drier. Where the legacy polynomials cross (66-70 % relative humidity) the band is taken between the lower and the upper value. In constant dry air a fuel starting at \(M_0 > E_d\) therefore follows \(M(t) = E_d + (M_0 - E_d)\,e^{-t/(\tau f_T)}\), which the unit test ERF_GTestFuelMoisture and the verification case Exec/CanonicalTests/Fire/Verification/Moisture_Relaxation check.

Note

Until September 2026 the choice was reversed: a fuel above the adsorption curve relaxed toward it and one below the desorption curve toward that, so a drying fuel headed for the lower curve and was then held at the upper one, and a fuel drier than both wetted toward the upper one. Runs with dynamic moisture made before the fix differ from runs made after it.

Temperature correction. The time lag is scaled by \(f_T = \exp(-0.015\,(T - 20^\circ\mathrm{C}))\), clamped to \([0.5, 2]\), so warm fuel responds faster.

Precipitation. A rain rate \(r\) [mm/h] adds a wetting term \(P = 0.01\, r\) per hour once the rate reaches 0.1 mm/h (the stick model holds its surface shell at erf.fire.stick.rain_surface_moisture instead); where the rate comes from is set by erf.fire.precip_source (Rain source).

The drivers are the air temperature (the potential temperature times the Exner function of the cell’s pressure, the same conversion the relative humidity uses) and relative humidity of the lowest atmospheric cell, sampled onto the fire grid each step and also written as fire_surface_temp_K and fire_surface_rh. Moisture is advanced before the rate of spread is evaluated, so the spread responds within the same step. The Rothermel, Balbi and Cheney-Gould coefficients are rebuilt each step from the domain-average moisture; Balbi can instead take the per-cell value with erf.fire.balbi.use_cell_moisture, and the BEHAVE path uses the per-cell dead classes and the live classes through its dynamic live-to-dead herbaceous transfer, whose moisture window is erf.fire.behave.dynamic_transfer_lo and _hi (BEHAVE Multi-Class Rothermel).

Rain source

erf.fire.precip_source chooses where the rain that wets the dead classes comes from:

  • "uniform" (the default): erf.fire.precip_rate_mm_hr on every fire cell for the whole run, as before this option existed (0 by default, so no rain).

  • "atmosphere": the rain of each atmospheric column. Every Eulerian microphysics scheme with precipitation keeps a cumulative surface accumulator per column (Kessler’s rain_accum, the rain, snow and graupel accumulations of SAM, Morrison, WSM6 and WDM6), exposed in kg/m² of liquid water. One kg/m² is one millimetre of depth, so after the microphysics of each step the fire layer takes the accumulation of every column of its level, subtracts the accumulation it saw at the end of its previous step and divides by the step to get the rate,

    \[r = \frac{A(t + \Delta t) - A(t)}{\Delta t}\, 3600 \quad [\mathrm{mm/h}],\]

    clamped at zero if the accumulator was reset. Every fire cell of a column takes its column’s rate, the same map that hands the fuel its temperature and humidity, so the rain is piecewise constant on atmospheric columns. A fresh start measures from zero, where every scheme starts its accumulators; a restart brings the previous accumulation back from the checkpoint (FirePrecipAccumPrev), and a checkpoint written without it gives the first restarted step no rain and starts the reference from that step. The rate is a step average over the step just taken, while the temperature and humidity are the pre-step values.

    The source is checked at start-up: the run stops, naming erf.moisture_model, if the scheme provides no accumulators (None, Kessler_NoRain, SatAdj, MoistNoCondensation); if erf.fire.moisture_dynamic is false; or if a positive erf.fire.precip_rate_mm_hr is set as well, since the rain has one source and the two are not added.

With dynamic moisture and either source the rate of every fire cell is written as fire_precip_mm_hr in the fire plotfile, and its maximum over the fire grid as the last column, precip_max_mm_hr, of the statistics CSV (Fire Diagnostics and Output); a uniform rate of zero writes neither.

Exec/RegTests/FirePrecipSource runs a passive grass fire under Kessler rain from a cold column of air with the three settings side by side: the atmosphere’s rain wets the 1-hour class under the raining columns only, the uniform rate wets it everywhere, the fire-grid rate equals the change of rain_accum over the last step to round-off, and a restart reproduces the straight run exactly. The unit test ERF_GTestFirePrecip checks the rate conversion, the species sum without double counting, the rolling snapshot and the map onto the fire grid. Not modelled: canopy interception, the storage and evaporation of water on the fuel surface, and any distinction between rain and the liquid-water equivalent of snow, graupel and hail.

Live moisture

With dynamic moisture the live herbaceous and live woody classes follow erf.fire.moisture_live_model:

  • "legacy" (the default, so existing runs reproduce) passes each live class through the dead-fuel update above with the 100-hour lag and no rain, then bounds it to \([0.30, 2.50]\). The dead-fuel update clamps its input to \([0.01, 0.40]\) and relaxes toward the dead-fuel equilibrium of erf.fire.emc_model, so a live moisture above 0.40 (the default erf.fire.moisture_live is 0.60) drops to 0.40 or below on the first step, even in saturated air, and then decays toward the 0.30 bound over tens of hours. This is not a live-moisture model; it is kept for backward compatibility.

  • "fixed" holds the live classes at erf.fire.moisture_live. A restart takes them from the inputs, not from the checkpoint, so it can change the value, and a checkpoint written by a "legacy" run or an older build does not bring back its clamped live moisture. Live moisture follows the plant’s water status over days to weeks, not the air over the length of a fire run, so this is the recommended setting.

The live classes reach only the BEHAVE model, per cell or as the domain average that the directional level-set path builds its state from: through the live moisture damping and through the transfer of live herbaceous load to the dead class, which grows as the live herbaceous moisture falls. With "legacy" that average is clamped to \([0.30, 2.50]\); with "fixed" it is not, so a erf.fire.moisture_live outside that range reaches both paths. A fuel without a live load (Anderson model 1, for example) is unaffected. Rothermel, Balbi and the Scott-Burgan curing transfer read erf.fire.moisture_live directly. Exec/RegTests/FireLiveMoisture runs the two settings side by side, and ERF_GTestFuelMoistureLive checks both updates.

Stick model

erf.fire.moisture_model = "stick" (default "timelag") replaces the single time constant with the diffusion of moisture through a cylindrical fuel particle, the framework of Nelson (2000): for each dead class in every fire cell,

\[\frac{\partial M}{\partial t} = \frac{1}{r}\frac{\partial}{\partial r} \Bigl(r D \frac{\partial M}{\partial r}\Bigr), \qquad 0 < r < R_c,\]

on erf.fire.stick.n_shells shells (default 6), advanced implicitly, with the surface held at the air’s equilibrium moisture (the same adsorption/desorption hysteresis, applied to the surface shell) or at erf.fire.stick.rain_surface_moisture (0.35) while it rains. The diffusivity is set so that the slowest radial mode has the class’s time lag, \(D_c = R_c^2 / (\lambda_1^2 \tau_c)\) with \(\lambda_1 = 2.405\) the first zero of \(J_0\), scaled by the temperature factor above and by erf.fire.stick.diffusivity_scale; the radii erf.fire.stick.radius_cm default to 0.15, 0.635 and 2.5 cm (the 10-h value is the standard stick). The class moisture the rate-of-spread models see is the volume average of the shells, so the long-time response equals the time-lag model’s while the short-time response is diffusive: the surface follows the air within minutes and the core lags by hours, which is the diurnal shape Nelson measured. The shells are carried in fire_stick_mc and checkpointed. Not reproduced from Nelson: his species constants for the diffusivity, bound-water isotherm and surface exchange, and the solar heating of the stick. Exec/RegTests/FireStickMoisture checks the plumbing and the restart, and the unit test ERF_GTestFuelMoistureStick the relaxation, the calibrated lag, the surface-before-core ordering and the rain condition.

Moisture of extinction

Every Anderson fuel model carries a moisture of extinction \(M_x\), the dead moisture at which spread stops. The Rothermel and BEHAVE kernels use the fuel model’s tabulated value in the moisture damping coefficient, and Balbi zeroes its rate at and above that value when erf.fire.balbi.use_moisture_extinction is set. A surface-area-to-volume dependent estimate,

\[M_x = 0.12 + 0.28\, (\sigma / 1739)^{-0.3},\]

clamped to \([0.12, 0.45]\), is evaluated per cell from the load-weighted \(\sigma\) of the local fuel and held in the field fire_mext. It is presently diagnostic: the kernels still read the tabulated value.

Limitations

  • Moisture is uniform within a fire cell and there is no fuel-bed depth profile.

  • Rain wets the fuel through the wetting term only: no canopy interception, no surface water storage or evaporation, and frozen precipitation counts as its liquid-water equivalent.

  • There is no live-moisture model: the live classes are held ("fixed") or carried through the dead-fuel update ("legacy"). Curing of the live herbaceous load is available to the Balbi 2020 form through erf.fire.balbi.herb_curing.

  • The forward Euler step is accurate while the atmospheric step is much shorter than the shortest time lag (one hour), which holds for every practical ERF step.

References

  • Nelson, R. M. (2000). Prediction of diurnal change in 10-h fuel stick moisture content. Canadian Journal of Forest Research, 30, 1071-1087.

  • Van Wagner, C. E. (1972). Equilibrium moisture contents of some fine forest fuels in eastern Canada. Canadian Forestry Service Information Report PS-X-36.

  • Van Wagner, C. E., and Pickett, T. L. (1985). Equations and FORTRAN program for the Canadian Forest Fire Weather Index System. Canadian Forestry Service, Forestry Technical Report 33.

  • Vejmelka, M., Kochanski, A. K., and Mandel, J. (2016). Data assimilation of dead fuel moisture observations from remote automated weather stations. International Journal of Wildland Fire, 25, 558-568.

  • Van Wagner, C. E. (1987). Development and structure of the Canadian Forest Fire Weather Index System. Canadian Forestry Service, Forestry Technical Report 35.

  • Viney, N. R. (1991). A review of fine fuel moisture modelling. International Journal of Wildland Fire, 1(4), 215-234.

  • Simard, A. J. (1968). The moisture content of forest fuels. Part III: moisture content variations of fast responding fuels below the fibre saturation point. Canadian Forest Service Information Report FF-X-16.

  • Mandel, J., et al. (2014). Recent advances and applications of WRF-SFIRE. Natural Hazards and Earth System Sciences, 14, 2829-2845.

  • Rothermel, R. C. (1972). A mathematical model for predicting fire spread in wildland fuels. USDA Forest Service Research Paper INT-115.

  • Anderson, H. E. (1970). Forest fuel ignitability. Fire Technology, 6(4), 312-319.