BalbiNov2011 computes xsi = (Ml - Md)·(Sd/Sl)·(Deltah/DeltaH), the share of combustion energy spent vaporising the moisture the live fuel carries in excess of the dead fuel. For fuel 1 of tests/runff/fuels.csv, xsi crosses 1 near Ml ≈ 0.8. Past that, (1 - xsi) is negative, so flame temperature T drops below ambient — and R00 ∝ T⁴ turns that back into a positive, growing number.
Measured on dev, standard fuel, still air, flat ground, sweeping Ml with Md = 0.1:
Ml | ROS (m/s) | |
|---|
| 0.1 | 0.0227 | |
| 0.5 | 9.06e-4 | falling correctly |
| 0.8 | 2.34e-8 | minimum |
| 1.0 | 8.16e-5 | shipped default |
| 1.5 | 0.0175 | rising |
| 2.0 | 0.1596 | 7× the bone-dry rate |
Soaking-wet live fuel spreads seven times faster than bone-dry live fuel.
fuels.csv ships Ml = 1.0, which is inside the broken region — so this is not an edge case reachable only by unusual inputs. It is the default.
It is isolated to this one model
I swept the whole family under identical conditions:
| Model | Ml=0.1 | Ml=1.0 | Ml=2.0 | Monotonic? |
|---|
Balbi2015 | 0.02245 | 0.004263 | 0.0001431 | yes |
BalbiNov2011Curv | 0.02245 | 0.004264 | 0.0001431 | yes |
BalbiUnsteady | 0.02245 | 0.004263 | 0.0001431 | yes |
BalbiNov2011 | 0.02273 | 8.161e-05 | 0.1596 | NO — inverts |
Balbi2020 | 0.01428 | 0.01428 | 0.01428 | does not respond to Ml |
BalbiNov2011TMdMl | 0.02273 | 0.02273 | 0.02273 | does not respond to Ml |
Rothermel | 0.02931 | 0.02931 | 0.02931 | does not respond to Ml |
Three siblings that do respond to live moisture agree with each other to four significant figures across the whole range. BalbiNov2011 is the only one that inverts.
The difference is one coefficient.BalbiNov2011 uses Sd/Sl where Balbi2015 uses Sigmal/Sigmad — and Balbi2015 stays monotonic. That is the first thing to check against Santoni et al. (2011).
Worth a second look separately: BalbiNov2011TMdMl is named for Md/Ml yet its output does not move with Ml at all under these conditions.
Relationship to #158
That PR clamps xsi at zero, fixing the other end — dead fuel wetter than live. It deliberately does not clamp at 1, because unlike the lower clamp that would change results at the default fuel values, moving pinned rates of spread and possibly runff output. That is a physics decision, not a bug-fix decision, which is why it is here as its own issue. The numbers above are identical before and after #158.
Options: clamp xsi at 1; revisit the Sd/Sl coefficient; or establish that Ml = 1.0 is out of range for this model and validate inputs against that. Related to the closed #35 and #99.
Drafted by Claude Opus 5 from a codebase audit. Reviewed by a maintainer before filing.
BalbiNov2011computesxsi = (Ml - Md)·(Sd/Sl)·(Deltah/DeltaH), the share of combustion energy spent vaporising the moisture the live fuel carries in excess of the dead fuel. For fuel 1 oftests/runff/fuels.csv,xsicrosses 1 nearMl ≈ 0.8. Past that,(1 - xsi)is negative, so flame temperatureTdrops below ambient — andR00 ∝ T⁴turns that back into a positive, growing number.Measured on
dev, standard fuel, still air, flat ground, sweepingMlwithMd = 0.1:MlSoaking-wet live fuel spreads seven times faster than bone-dry live fuel.
fuels.csvshipsMl = 1.0, which is inside the broken region — so this is not an edge case reachable only by unusual inputs. It is the default.It is isolated to this one model
I swept the whole family under identical conditions:
Ml=0.1Ml=1.0Ml=2.0Balbi2015BalbiNov2011CurvBalbiUnsteadyBalbiNov2011Balbi2020MlBalbiNov2011TMdMlMlRothermelMlThree siblings that do respond to live moisture agree with each other to four significant figures across the whole range.
BalbiNov2011is the only one that inverts.The difference is one coefficient.
BalbiNov2011usesSd/SlwhereBalbi2015usesSigmal/Sigmad— andBalbi2015stays monotonic. That is the first thing to check against Santoni et al. (2011).Worth a second look separately:
BalbiNov2011TMdMlis named forMd/Mlyet its output does not move withMlat all under these conditions.Relationship to #158
That PR clamps
xsiat zero, fixing the other end — dead fuel wetter than live. It deliberately does not clamp at 1, because unlike the lower clamp that would change results at the default fuel values, moving pinned rates of spread and possiblyrunffoutput. That is a physics decision, not a bug-fix decision, which is why it is here as its own issue. The numbers above are identical before and after #158.Options: clamp
xsiat 1; revisit theSd/Slcoefficient; or establish thatMl = 1.0is out of range for this model and validate inputs against that. Related to the closed #35 and #99.Drafted by Claude Opus 5 from a codebase audit. Reviewed by a maintainer before filing.