Regression Tests
The regtest/ directory contains a comprehensive suite of regression tests that exercise
individual features and capabilities of the wildfire level-set solver. Each test is
self-contained — it ships with an inputs.i configuration file and any required data files.
Running the Tests
Run a single test from the repository root:
cd regtest/basic_levelset
../../build/levelset inputs.i
Run all regression tests with CTest (after building):
cd build
ctest -L regtest --output-on-failure
# Or use the custom target
make regtest
# Run a specific test by name
ctest -R rothermel_fuel --output-on-failure
Build requirements vary by test; see the per-test sections below.
Test Descriptions
basic_levelset
Purpose: Verifies fundamental level-set advection with a constant velocity field.
The spherical initial condition is advected without distortion for 100 steps on a 64³ grid. Successful completion confirms that:
The WENO5-Z + RK3 advection kernel compiles and runs.
Reinitialization keeps \(|\nabla\phi| \approx 1\).
Plotfile output is written correctly.
Build: Default 3D build.
farsite_ellipse
Purpose: Verifies the FARSITE elliptical expansion model (Richards 1990).
A box (line) ignition expands under a constant wind field using fixed Richards coefficients (\(a = 1.0\), \(b = 0.4\), \(c = 0.2\)) and a fixed length-to-width ratio of 3.0. Confirms that the fire perimeter forms an ellipse with the expected elongation.
Build: Default 3D build.
rothermel_fuel
Purpose: Tests fire spread with NFFL fuel model FM1 (Short Grass).
The Rothermel (1972) model is evaluated with a standard fuel database entry, 6 % fuel moisture, and a moderate constant wind. Confirms that the Rothermel ROS field is computed for every cell and that different fuel models produce different spread rates.
Build: Default 3D build. Change rothermel.fuel_model to test FM1–FM13 or any
Scott & Burgan 40 code.
cheney_gould_grassfire
Purpose: Tests the Cheney & Gould (1995/1998) empirical grassland fire spread model.
A spherical ignition on a flat 1 km × 1 km domain is propagated at 10 m/s wind (36 km/h) with 8 % dead fuel moisture and full curing (\(CF = 1\)). The expected head-fire ROS is ≈ 2.69 m/s from the piecewise formula:
Confirms that the Cheney–Gould model produces an asymmetric elliptical perimeter.
Build: Default 3D build.
terrain_wind
Purpose: Tests external terrain (Gaussian hill) and a spatially-varying wind field (2D only).
A 1000 m × 1000 m domain contains a Gaussian hill with σ = 150 m and peak elevation 100 m. The wind CSV has a base speed of 5 m/s with up to 50 % speed-up over the crest. Confirms:
Terrain slopes are correctly computed from an XYZ elevation file.
IDW interpolation of wind from the CSV to the AMReX grid works.
The fire accelerates upslope and over the crest.
Build: 2D build (-DLEVELSET_DIM_2D=ON).
anderson_lw
Purpose: Tests dynamic L/W ratio calculation based on wind speed (Anderson 1983).
The Anderson formula is evaluated at ≈ 10 mph wind (expected L/W ≈ 2.5) and the resulting ellipse coefficients \(a\), \(b\), \(c\) are applied to the FARSITE propagation.
Build: Default 3D build.
reinitialization
Purpose: Tests aggressive level-set reinitialization to maintain the signed-distance property.
Reinitialization is run every 5 steps for 30 iterations. Confirms that \(|\nabla\phi|\) remains close to 1.0 after prolonged advection.
Build: Default 3D build.
ellipse_sdf
Purpose: Tests the elliptical SDF initial condition.
An ellipsoidal initial fire region (semi-axes \(r_x = 0.25\), \(r_y = 0.15\), \(r_z = 0.10\)) is advected at constant velocity. Confirms that the elliptical SDF is constructed correctly and that shape is preserved under advection.
Build: Default 3D build.
eb_implicit
Purpose: Tests embedded boundary (EB) implicit function initial conditions.
An EB-defined ellipsoid is used as the initial fire region. Confirms that the AMReX EB infrastructure can initialise \(\phi\) from implicit-function geometries (sphere, ellipsoid, cylinder, plane).
Build: EB build recommended (-DLEVELSET_ENABLE_EB=ON).
firebrand_spotting
Purpose: Tests the probability-based stochastic firebrand spotting model.
Firebrands are generated probabilistically from the fire front, with landing distances sampled
from a log-normal distribution. Confirms that spot ignitions appear ahead of the fire perimeter
and that diagnostic fields (spot_prob, spot_count, spot_dist, spot_active) are
written to every plotfile.
Build: Default 3D build.
albini_spotting
Purpose: Tests the Albini (1983) physics-based firebrand spotting model.
The Albini model lofts firebrands using:
and then integrates a 2-D horizontal trajectory through the wind field. Confirms that the
lofting height, landing distance, and diagnostic fields (albini_Hz, albini_count,
albini_dist, albini_active) are computed and written correctly.
Build: CPU or GPU builds (GPU-safe: trajectory runs on the host; device data is synchronized and copied to host-pinned memory before computation, then written back to device).
albini_spotting_3d_wind
Purpose: Tests the Albini spotting model driven by 3-D wind data from a massconsistent_amr plotfile.
A synthetic AMReX plotfile is generated by generate_plt_wind.py (an 8×8×4
grid with uniform u = 5 m/s, v = 0.5 m/s wind). The reader in
src/plt_wind_reader.H loads the plotfile as flat 1-D GPU arrays of
(x, y, z, u, v, w), computes a height-averaged 2-D wind, and bilinearly
interpolates onto the fire-model grid for trajectory integration.
Requires Python 3 to generate the synthetic plt file (handled automatically by CTest as a fixture setup step).
Build: CPU or GPU builds (GPU-safe).
ember_cascade_flux
Purpose: Tests the flux-based ember cascade model (ember_cascade_flux.H)
driven by a synthetic 3-D wind plotfile.
Physical scenario: a chaparral ignition (FM4, 7 % moisture) on a 600 m × 600 m
domain burns under a 6 m/s westerly wind. generate_plt_wind.py creates a
synthetic plt wind directory (8×8×4 grid, u = 6 m/s, v = 1 m/s) that the
model reads via plt_wind_reader.H.
The test confirms that:
The Albini (1983) plume height is computed per fire-front cell.
The Gaussian landing-flux field is non-zero downwind of the fire.
The plotfile variables
ember_cascade_fluxandember_cascade_ignitionare written to every output step.The model produces spot-fire ignitions (
ember_cascade_ignition> 0) after the fire front reaches sufficient intensity.
Requires Python 3 for the setup step (same pattern as albini_spotting_3d_wind).
Build: CPU or GPU builds (GPU-safe).
crown_initiation
Purpose: Tests Van Wagner (1977) crown fire initiation.
The model checks whether the Byram fireline intensity exceeds the critical threshold:
Cells where crown fire initiates are classified as passive (1) or active (2) depending on
whether the ROS exceeds the critical active-crown threshold. Confirms that crown_fraction
and crown_activity fields are written to plotfiles.
Build: Default 3D build.
bulk_fuel_consumption
Purpose: Tests post-frontal bulk fuel consumption modelling.
The exponential consumption model:
is applied to cells inside the fire perimeter. Confirms that the fuel_consumption field
increases monotonically with time behind the fire front.
Build: Default 3D build.
3d_sphere
Purpose: Tests full 3D fire spread simulation.
A sphere initial condition is propagated using the Rothermel model in a 48³ cell 3D domain with a 3D wind vector and an upslope terrain. Confirms that the 3D FARSITE elliptical expansion and terrain effects work in three dimensions.
Build: Default 3D build. Visualise results with ParaView or VisIt.
terrain_wind_preprocess
Purpose: Integration test for the wrf_wind_reader.py preprocessing tool.
Generates a terrain XYZ file and a wind CSV using the Python tool, then runs the solver with those files. Confirms that the WRF wind extraction and IDW interpolation pipeline produces valid inputs for the C++ solver.
Build: 2D build. Requires Python 3 with netCDF4, numpy, pyproj.
time_dependent_wind
Purpose: Tests time-varying wind fields (2D only).
Sequential wind CSV snapshots are loaded and linearly interpolated at each time step. Confirms
that use_time_dependent_wind = 1 correctly advances through the wind time series.
Build: 2D build (-DLEVELSET_DIM_2D=ON).
balbi_viegas_heatflux
Purpose: Tests the Balbi (2009) model together with Viegas eruptive-fire diagnostics and the heat-flux-driven wind correction.
Confirms that fire_spread_model = balbi, viegas.enable = 1, and
heat_flux.enable_upward = 1 all interoperate correctly.
Build: Default 3D build.
windninja_ridge_canyon
Purpose: Tests the WindNinja ridge/canyon empirical speed-up (Option 7).
A Gaussian hill terrain is combined with wind_terrain.model = windninja_ridge_canyon.
Confirms that wind is accelerated on the upslope face and channelled in canyon geometry.
Build: 2D build.
terrain_gradient_correction
Purpose: Verifies that the level-set gradient \(|\nabla\phi|\) is computed on the terrain surface when a terrain file is present.
When terrain slopes are non-zero, godunov_norm_grad_phi replaces the flat grid
spacings with terrain arc-length spacings:
where \(s_x = \partial z/\partial x\) and \(s_y = \partial z/\partial y\).
The test uses a steep Gaussian hill (\(H = 200\) m, \(\sigma = 100\) m) where
the slope magnitude at the inflection ring reaches \(\approx 1.21\) (50°), giving an
effective spacing factor of \(\sqrt{1 + 1.21^2} \approx 1.57\). A level-set run
(propagation_method = levelset) exercises the corrected WENO3 Godunov gradient across
the full hill profile. Confirms that the solver completes 100 steps without NaN/Inf and
writes 4 plotfiles.
Build: 2D build (-DLEVELSET_DIM_2D=ON).
landfire_farsite
Purpose: Integration test for FARSITE with a real (or synthetic) LANDFIRE landscape.
The setup script regtest/landfire_farsite/create_landscape.py attempts to download
LANDFIRE data; if offline, a synthetic Southern California chaparral landscape is generated as
a fallback. FARSITE elliptical spread with Anderson dynamic L/W ratio is then run on the
landscape.
Build: Default 3D build. Requires Python 3 with
pip install requests rasterio numpy pyproj elevation.
gaussian_hill_wind_solver (Deprecated)
Deprecated since version The: mass-consistent wind solver has been moved to src/deprecated/ and is no longer
built. This regression test is retained for historical reference only.
Purpose: Validated the terrain-following mass-consistent wind solver (wind_solver
executable) over a Gaussian hill terrain.
A 10 × 10 × 10 cell Cartesian grid (dx = dy = dz = 30 m) covers a 300 m × 300 m × 300 m domain. The terrain is a Gaussian hill with peak elevation 50 m centred at (150, 150) m (σ = 60 m). A 10 m/s westerly reference wind at z_ref = 10 m with roughness length z₀ = 0.1 m is applied.
Successful completion confirmed that:
The log-law profile initialisation runs without error.
The AMReX MLMG (
MLABecLaplacian) solver converges to the requested tolerance.The maximum divergence after correction is substantially smaller than before.
An AMReX plotfile
plt_wind_gaussianis written.
Build: This test is no longer active (wind solver deprecated).
Build Configurations Summary
Compatible tests |
Build |
CMake flags |
|---|---|---|
All except |
3D (default) |
|
|
2D |
|
|
3D + EB |
|
|
CPU or GPU |
GPU-safe: synchronizes device, runs host-side trajectory |
Adding a New Regression Test
Create
regtest/<test_name>/directory.Add
inputs.iwith the test parameters.Add a
README.mddocumenting expected behavior.Register in
CMakeLists.txtso CTest discovers it.Add a description to the main
regtest/README.mdand to this page.
New Feature Regression Tests
The following tests were added with the 2025 feature update. All use UTM Zone 11N, Southern California coordinates (reference: 330000 E, 3775000 N — Malibu / Santa Monica Mountains area).
fmc_seasonal (crown_fire/)
Purpose: Tests the FMC seasonal phenological schedule.
The foliar moisture content (FMC) used by the Van Wagner (1977) crown fire initiation model is updated each timestep from a built-in parametric curve representing Southern California chaparral phenology (green-up in spring, peak in summer, curing in autumn).
Key parameters:
fmc_schedule.enable = 1
fmc_schedule.use_farsite_curve = 1
fmc_schedule.start_doy = 200 # mid-July (summer peak)
Confirms that crown.FMC changes each timestep and that crown fire behaviour
responds to the seasonal FMC change.
precip_wetting (moisture/)
Purpose: Tests precipitation-driven dead fuel moisture wetting.
Dead fuel moisture evolves under a constant light rain rate (2 mm/hr). The exponential wetting model drives 1-hr fuel moisture towards saturation (120%) with a 1-hr time constant, and 10-hr fuel with a 2-hr time constant.
Key parameters:
diurnal_moisture.enable = 1
diurnal_moisture.precip_rain_rate_mm_hr = 2.0
diurnal_moisture.M_sat = 1.20
Confirms that rothermel.M_d1 increases over time and fire spread rate
decreases as fuel becomes wetter.
polygon_ignition (ignition/)
Purpose: Tests closed-polygon fire ignition rasterisation.
An irregular 8-vertex polygon (~20 m × 18 m) is rasterised into the level-set
field using the winding-number algorithm. The interior is set to phi < 0
(burned) and the exterior to the Euclidean signed distance.
Key parameters:
source_type = polygon
fire_polygon_file = ignition_polygon.csv
Confirms that the rasterised initial perimeter closely follows the input polygon vertices and that the signed-distance function is correct inside and outside.
polyline_ignition (ignition/)
Purpose: Tests polyline (line fire) ignition rasterisation.
A 6-vertex east-west polyline is rasterised with a 6 m half-width, creating an initial line-fire ignition zone. Wind drives the fire northward from the ignition line.
Key parameters:
source_type = polyline
fire_polygon_file = ignition_line.csv
polyline_width = 6.0
wind_dir_schedule (wind/)
Purpose: Tests the compact wind direction / speed schedule.
Wind starts at 270° (westerly) at 3 m/s and backs to 180° (southerly) at 5 m/s
over 2 hours. The schedule is read from a three-column CSV
(time_s, speed_ms, dir_deg).
Key parameters:
wind_dir_schedule_file = wind_schedule.csv
Confirms that the wind vector changes direction and magnitude at each timestep, and that the fire footprint reflects the wind rotation.
waf_andrews (wind/)
Purpose: Tests the Andrews (2018) logarithmic Wind Adjustment Factor (WAF) together with the Maximum Effective Wind Speed (MEWS) cap.
The WAF converts the 20-ft reference wind to midflame height using Albini & Baughman (1979):
For FM4 chaparral (\(h = 6\) ft): WAF ≈ 0.36; the 5 m/s ambient wind is reduced to ≈ 1.8 m/s at midflame height.
Key parameters:
rothermel.use_waf = 1
rothermel.waf_formula = andrews
rothermel.use_wind_limit = 1
Confirms that the solver runs with waf_formula = "andrews" and that fire
spread is slower than without WAF, consistent with midflame wind sheltering.
Build: 2D build (-DLEVELSET_DIM_2D=ON).
waf_behaviorplus (wind/)
Purpose: Tests the BehavePlus linear Wind Adjustment Factor for open and shrub fuel models.
The BehavePlus linear formula:
gives WAF = 0.648 for FM4 (\(h = 72\) in). Compare with the Andrews logarithmic formula (WAF ≈ 0.36 for the same fuel): the BehavePlus formula produces higher midflame wind and therefore faster ROS for deep fuel beds.
Key parameters:
rothermel.use_waf = 1
rothermel.waf_formula = behaviorplus
rothermel.waf_canopy_alpha = 1.5
rothermel.use_wind_limit = 1
Confirms that the solver runs with waf_formula = "behaviorplus", that the
WAF value is computed from the linear formula, and that the fire spread rate
is higher than the waf_andrews test for the same ambient wind.
Build: 2D build (-DLEVELSET_DIM_2D=ON).
scott_reinhardt_indices (diagnostics/)
Purpose: Tests the Scott & Reinhardt (2001) TI/CI diagnostic outputs.
A strong 8 m/s wind and low canopy base height (2.5 m) create active crown fire
conditions. The plotfile torching_ratio and crowning_ratio fields
(ecology components 4 and 5) should be ≥ 1.0 in the active fire zone.
These dimensionless ratios are zero for surface fire, cross 1.0 when torching begins, and exceed 1.0 again for active crown fire, giving an easily interpreted diagnostic layer without inverting the Rothermel wind function.
Sub-folder Organisation
Starting from the 2025 release all regression tests reside in named sub-folders grouped by physical category:
All tests use UTM Zone 11N, Southern California reference coordinates (330 000 E, 3 775 000 N).