.. Copied from erf-model/FLARE Docs/sphinx_doc/theory/fire_output.rst at 39e777bcc by .. tools/sync_flare_docs.py. Edit the page in FLARE, then rerun the script. .. role:: cpp(code) :language: c++ .. _sec:FireOutput: Fire Diagnostics and Output =========================== Flame diagnostics ----------------- Computed every fire step on burned cells (:math:`\phi < 0`) and zero elsewhere: - **Byram fireline intensity** :math:`I_B = h\, w_0\, R` [kW/m], with :math:`h` the heat content [kJ/kg], :math:`w_0` the fuel load the front consumes [kg/m²] (the cell's initial load) and :math:`R` the rate of spread, on burning cells; it is zero once the cell's remaining load falls below 1 % of :math:`w_0` (burned out). It drives ember lofting, crown-fire initiation and the flame diagnostics below. :math:`w_0` is the whole load, dead and live, so on heavy fuels the intensity is above Byram's :math:`I_R t_r R / 60` of the flaming front alone (BehavePlus): for Anderson 10 the 100-h class is 0.23 lb/ft² of the 0.55 lb/ft² load, so the crown criterion and ember launch trigger more readily there than BehavePlus would. Until October 2026 it was :math:`h\,(w_0 - w)\, R`, zero on the cell the front had just reached and largest far behind it; that form is kept as the plotfile variable ``fire_heat_release``. - **Thomas flame length** :math:`L = 0.0775\, I_B^{0.46}` [m]. - **Flame temperature**, by :cpp:`erf.fire.flame_temp_method`: ``"byram_radiant"`` (default) :math:`T = T_a + 800\,(I_B/1000)^{0.25}`; ``"mcalpine_heat"``, the adiabatic estimate of McAlpine and Xanthopoulos (1989) from the heat content and moisture, clipped to :math:`T_a + 100 < T < 1500` K; ``"nelson_emissivity"``, the Stefan-Boltzmann inversion :math:`T = (1000\, I_B / (\sigma \epsilon))^{0.25}` with :math:`\epsilon = 0.9`. :math:`T_a` is :cpp:`erf.fire.flame_temp_T_amb`. - **Flame tilt** from vertical, :math:`\arctan(U / v_b)` in degrees, from the effective wind speed and a buoyancy velocity built from the intensity, flame length and radiant flux with :cpp:`erf.fire.flame_tilt_rho_air` and :cpp:`erf.fire.flame_tilt_T_amb`. Off unless :cpp:`erf.fire.compute_flame_tilt` is set; a diagnostic only. Fire plotfiles -------------- The fire grid has its own plotfile stream, separate from the atmospheric plotfiles, written to ``erf.fire.plot_file`` (default ``plt_fire_``) every ``erf.fire.plot_int`` steps or every ``erf.fire.plot_per`` seconds. Each is a single-level AMReX plotfile on the fire grid, whose domain is the region the fire grid covers (the refined region when the fire runs on a finer level), with a small JSON sidecar giving the grid ratio, the atmospheric level of the fire grid and the variable count. Variables appear in this fixed order; the optional blocks are present only when their feature is on: .. list-table:: :widths: 30 12 58 :header-rows: 1 * - Variable - Unit - Present when * - ``fire_phi`` - - - always * - ``fire_ros`` - m/s - always * - ``fire_wind_eff_u``, ``fire_wind_eff_v`` - m/s - always * - ``fire_wind_ref_u``, ``fire_wind_ref_v`` - m/s - always * - ``fire_extract_z`` - m - always * - ``fire_slope_x``, ``fire_slope_y`` - - - always * - ``fire_fuel_mc_1hr``, ``fire_fuel_mc_10hr``, ``fire_fuel_mc_100hr`` - fraction - always * - ``fire_surface_temp_K``, ``fire_surface_rh`` - K, 0-1 - always * - ``fire_heat_flux`` - W/m² - always * - ``fire_fuel_load`` - kg/m² - always * - ``fire_fireline_intensity``, ``fire_flame_length`` - kW/m, m - always * - ``fire_arrival_time`` - s - always * - ``fire_heat_release`` - kW/m - always (:math:`h\,(w_0 - w)\, R`, the intensity's form before 2026-10) * - ``fire_fuel_mc_lh``, ``fire_fuel_mc_lw`` - fraction - live moisture components present (BEHAVE path) * - ``fire_lofting_height``, ``fire_spot_brand_count``, ``fire_spot_max_dist``, ``fire_spot_active`` - m, -, m, - - ``erf.fire.spotting.enable`` * - ``fire_flame_tilt`` - deg - ``erf.fire.compute_flame_tilt`` (crown fire on or off) * - ``fire_crown_active``, ``fire_crown_load``, ``fire_crown_fraction_burned`` - -, kg/m², - - ``erf.fire.crown.enable`` * - ``fire_flame_temp`` - K - ``erf.fire.crown.enable`` * - ``fire_fuel_model_code`` - - - a spatial fuel map is loaded * - ``fire_ros_model_weight`` - 0-1 - ``erf.fire.ros_model = hybrid`` * - ``fire_structure_height`` - m - ``erf.fire.structures.enable`` or the hybrid ``structure`` selector * - ``fire_nonburnable`` - 0/1 - structures, ``fuel_map.nonburnable_codes``, ``firebreak.use_mask`` or ``suppression.enable`` configured * - ``fire_structure_id``, ``fire_heat_load``, ``fire_peak_intensity``, ``fire_ember_landings`` - -, J/m², kW/m, - - ``erf.fire.exposure.enable`` (see below) * - ``fire_structure_state``, ``fire_structure_ignition_time``, ``fire_structure_rad_flux`` - -, s, W/m² - ``erf.fire.structures.ignition.enable`` (:doc:`wui_structure_ignition`) * - ``fire_precip_mm_hr`` - mm/hr - dynamic dead-fuel moisture with ``erf.fire.precip_source = atmosphere`` or a positive ``erf.fire.precip_rate_mm_hr`` * - ``fire_suppression_mask`` - -1/0/1 - ``erf.fire.suppression.enable``; 1 suppressed this step, -1 a line cell that failed its hold test * - ``fire_ros_factor`` - 0-1 - ``erf.fire.suppression.enable``; the drop multiplier on the rate of spread, 1 outside drops * - ``fire_line_progress`` - - - ``erf.fire.suppression.enable``; ordinal of the line a built cell belongs to, 0 elsewhere Fire statistics CSV ------------------- When :cpp:`erf.fire.write_fire_stats_csv` is true (default) one line per fire step is appended to :cpp:`erf.fire.fire_stats_csv_file` (default ``fire_stats.csv``) with the columns ``step, time_s, burned_area_ha, perimeter_km, active_front_cells, head_ros_ms, major_axis_m, minor_axis_m, heat_flux_max_Wm2, spot_fires_this_step, max_spot_dist_m, edge_band_cells, edge_contact_time_s, precip_max_mm_hr``. Burned area and perimeter come from the arrival-time field, the head rate is the maximum rate of spread over burning cells, and the axes are those of the burned region's bounding ellipse. The spotting columns are zero unless spotting is on. The last two are the boundary guard of :ref:`sec:FireGridEdge`: the number of burning cells within :cpp:`erf.fire.boundary_guard_cells` of a non-periodic edge of the fire grid on this step, and the time the fire first entered that band, :math:`-1` until it does. Both are zero and :math:`-1` with :cpp:`erf.fire.boundary_guard_action = "none"`. Arrival-time probes ------------------- :cpp:`erf.fire.probes = x1 y1 x2 y2 ...` [m] lists points at which the arrival time is reported. Each probe prints one line, ``[FIRE PROBE] n x= y= cell=(i,j) arrival_time_s=``, on the fire step its cell first burns, and nothing afterwards; a probe outside the domain is reported once and ignored. The obstacle regression suite uses these to tabulate arrival at building faces. Structure exposure ------------------ With :cpp:`erf.fire.exposure.enable` (which needs :cpp:`erf.fire.structures.enable`) the fire layer reports what each building experienced. At initialisation the points of the structure heightmap above :cpp:`erf.fire.structures.min_height` are grouped into connected footprints (4-connected on the file's grid, numbered in scan order) and each fire cell takes the id of its nearest point, the same sampling as the mask, so ``fire_structure_id`` is nonzero exactly where the mask holds a structure. Three accumulators run on the fire grid: the heat load :math:`\int Q\,dt` [J/m²] of every cell, the running maximum of the Byram fireline intensity [kW/m], and the number of embers that landed on each masked cell (brands the spotting model drops there instead of igniting). Every :cpp:`erf.fire.exposure.interval` fire steps one line per structure is appended to :cpp:`erf.fire.exposure.file` (default ``fire_exposure.csv``), evaluated over the *wall band*: the burnable cells within :cpp:`erf.fire.exposure.ring` fire cells of the footprint (a cell between two footprints counts for both). The columns are ``time_s, structure_id, x_m, y_m, height_m, footprint_cells, wall_cells, wall_burned_frac, t_first_s, t_last_s, residence_s, peak_intensity_kWm, heat_load_mean_MJm2, heat_load_max_MJm2, embers``: the footprint centroid and sampled height, the size of the footprint and of its band, the fraction of the band burned, the earliest and latest arrival of the front in the band and their difference (how long the front spent passing the structure; both are -1 until it arrives), the largest peak intensity in the band, the mean and largest heat load there in MJ/m², and the embers on the footprint. The first time a structure's band burns a line ``[FIRE EXPOSURE] structure n x= y= reached_at_s=`` is printed, and every row set ends with a summary of how many structures have been reached and the largest peak intensity and heat load among them. A restarted run appends to an existing file and writes the header only into a new one. The four fields are added to the fire plotfile as ``fire_structure_id``, ``fire_heat_load``, ``fire_peak_intensity`` and ``fire_ember_landings``, and the three accumulators are checkpointed as ``FireHeatLoad``, ``FirePeakIntensity`` and ``FireEmberLandings``. The heat load is the fire's own release at the ground next to the wall, not a radiant flux onto the wall; a view-factor model of the wall flux from the flame length and tilt of the band cells is the natural next step. ``Exec/RegTests/FireExposure`` runs the obstacle scenario with and without immersed-forcing buildings and with spotting, and ``FireRestart`` checks that the CSV resumes exactly. With :cpp:`erf.fire.structures.ignition.enable` the structures ignite from these accumulators, burn and load their neighbours (:ref:`sec:WUIStructureIgnition`). The CSV then gains ``state, t_ignition_s, cause, structure_flux_Wm2, incident_flux_max_Wm2`` (the columns are absent when the option is off), the plotfile ``fire_structure_state``, ``fire_structure_ignition_time`` and ``fire_structure_rad_flux``, and the checkpoint ``FireStructureState``. Models in use ------------- Every run prints, once at start-up and before the first step, the model or option it uses for each piece of fire physics, whatever :cpp:`erf.fire.fire_debug` says: the rate-of-spread model and its options, the front propagation and its directional options, the wind (interpolation, height, sampling, wind adjustment factor, terrain factors), the fuel, burnout and moisture models, the coupling to the atmosphere, the flame temperature, and whether acceleration, spotting, crown fire, threshold ignition, smoke, structures and suppression are on, with the ignition sources. Each line gives the ``erf.fire`` key, the value the run uses, and whether the inputs set it or it is the default; a value the code forced says so. An excerpt:: [FIRE] Models (erf.fire key = value; set in the inputs, or the default): [FIRE] Rate of spread ros_model = rothermel (set) [FIRE] Rothermel reaction velocity reaction_velocity_formula = albini (default) [FIRE] midflame wind limit use_wind_limit = true (default) [FIRE] wind limit form wind_limit = rothermel (default) [FIRE] Front propagation propagation_method = levelset (set) An option is listed only when it acts in the run: a model's own options only when that model is in use (the Cheney-Gould pasture with ``ros_model = cheney_gould``, the level-set gradient with ``propagation_method = levelset``), the heat-injection options only when heat reaches the atmosphere, the wind interpolation only when the wind is not prescribed. Debug output ------------ :cpp:`erf.fire.fire_debug` prints, every step, the wind extraction range, the rate-of-spread maximum and mean over burning cells, the number of subcycles, the count of active fire cells, the flux and intensity maxima, and, where relevant, the hybrid weight summary and the coupling tendency check. The regression scripts parse these lines, so their formats are stable. Checkpoint and restart ---------------------- The atmospheric checkpoint carries the fire state: fields under the ``Level_`` directory of the level the fire grid refines, and the text files ``FireState`` and ``FireSuppression`` at the top of the checkpoint. The fire engine writes its own fields and the coupling layer (:ref:`sec:FireCoupling`) writes the lagged flux buffers ``FireQAtmPrev`` and ``FireQLatAtmPrev`` that the next step injects. The native engine writes: * always: ``FirePhi``, ``FireArrivalTime``, ``FireHeatFlux``, ``FireFlameLength``, ``FireFuelLoad``, ``FireFuelMC``, ``FireDispAccum``, ``FireCrownFractionBurned`` and the text file ``FireState`` (the step and level-set subcycle counters, the heat-flux partition factor, the boundary guard's contact time and reach flag, the start of the next ignition window, the anchor level and the corner of the fire region, and the already reported probes and structures); * with crown fire, ``FireCrownActive``, ``FireCrownLoad`` and ``FireCrownRosActive``; with the stick moisture model, ``FireStickMC``; with :cpp:`erf.fire.precip_source = atmosphere`, ``FirePrecipAccumPrev``; with exposure, ``FireHeatLoad``, ``FirePeakIntensity`` and ``FireEmberLandings``; with structure ignition, ``FireStructureState``; with spotting, ``FireAlbiniData``; with the temporal acceleration model, ``FireAccelState``; * with suppression, the four fields ``FireSuppressionMask``, ``FireSuppressionFactor``, ``FireSuppressionProgress`` and ``FireSuppressionFailed`` with the action state in ``FireSuppression`` (:ref:`sec:FireSuppression`). On restart the fire engine is initialised from the inputs first, so a spatial fuel map, firebreaks, a hybrid weight, a structure mask or a suppression action file must still be available, and the checkpointed fields are then read over the initial ones: the engine's first, then the lagged fluxes. A field missing from an older checkpoint keeps its initial value, and a checkpoint that holds the fire on another level or region than the run's aborts. Diagnostics not in these lists are recomputed on the first step. A fire run restarts on the level-0 boxes it was written with: a restart that re-makes them (:cpp:`erf.regrid_level_0_on_restart`, or more ranks than the checkpoint has level-0 boxes) stops with a message saying so. References ---------- - Byram, G. M. (1959). Combustion of forest fuels. In: Forest Fire: Control and Use, McGraw-Hill, 61-89. - Thomas, P. H. (1963). The size of flames from natural fires. Ninth Symposium (International) on Combustion, 844-859. - McAlpine, R. S. and Xanthopoulos, G. (1989). Predicted vs. observed fire spread rates in Ponderosa pine fuel beds. Proceedings of the 10th Conference on Fire and Forest Meteorology. - Nelson, R. M. (1980). Flame characteristics for fires in southern fuels. USDA Forest Service Research Paper SE-205.