ERF
Energy Research and Forecasting: An Atmospheric Modeling Code
ERF_FireEngineTemplate.H
Go to the documentation of this file.
1 #ifndef ERF_FIRE_ENGINE_TEMPLATE_H
2 #define ERF_FIRE_ENGINE_TEMPLATE_H
3 
4 #include <ERF_FireEngine.H>
5 
6 /**
7  * @file ERF_FireEngineTemplate.H
8  * @brief A starting point for a new fire engine: declarations only
9  *
10  * This class declares every FireEngine method a new fire model provides and
11  * says what ERF hands it and expects back. Nothing here has a body, no input
12  * selects it and nothing creates one, so it adds no code to ERF. The stand-in
13  * engine of the FireCoupler unit tests (Tests/Unit/Fire/ERF_GTestFireCoupler.cpp)
14  * is the smallest engine that works.
15  *
16  * To start a new engine:
17  * 1. Copy this file into the new model's engine directory (outside ERF),
18  * rename the class and the include guard, and write the bodies in a .cpp
19  * file there. Delete the
20  * declarations of the optional methods the engine does not provide (their
21  * defaults in FireEngine then apply); a declaration left without a body
22  * fails to link.
23  * 2. Read the model's inputs under its own prefix (fire.<engine>.* is
24  * recommended), so they never mix with the coupling's keys
25  * (FireCouplingParams, erf.fire.*) or another engine's.
26  * 3. Register the engine in that .cpp, at namespace scope:
27  * ERF_REGISTER_FIRE_ENGINE(MyEngine, "my_fire")
28  * (ERF_FireEngineRegistry.H), and give the engine directory a
29  * Make.package (GNU make, FIRE_HOME) and an ERFFireEngine.cmake defining
30  * erf_fire_engine_add(target) (CMake, ERF_FIRE_ENGINE_DIRS).
31  * Tests/FireEngineExample is a complete engine directory to copy.
32  * 4. Run the FireCoupler unit tests with the new engine in place of their
33  * stand-in, and a restart of a coupled run against a straight run: the
34  * atmosphere and fire plotfiles must agree at zero tolerance.
35  *
36  * What the coupling layer already does for every engine: it builds the fire
37  * grid over erf.fire.anchor_level, hands the engine the atmosphere's state
38  * each step, averages the engine's fluxes onto the atmospheric columns, holds
39  * them one step, injects heat, vapour and smoke, and saves those lagged fluxes
40  * in the checkpoint. An engine owns only its fire physics and its own state.
41  *
42  * The call order is the one documented on FireEngine (ERF_FireEngine.H).
43  * ERF_FireCoupler.cpp checks at compile time that this class declares every
44  * method FireEngine requires (the pure virtual ones), and override checks the
45  * signature of every method declared here. The optional methods are listed by
46  * hand: a new optional method in FireEngine is added here too.
47  */
49 {
50 public:
51  /// The name erf.fire.engine selects this engine by, for example "my_fire".
52  const char* name () const override;
53 
54  /**
55  * Check the engine's own inputs against the ERF configuration, once at
56  * start-up, before the fire grid is built. Abort naming the input on
57  * anything the engine cannot run (a missing fuel file, a time step its
58  * front tracking cannot take, a grid ratio it does not support).
59  */
60  void verify_prerequisites (const ERF& erf, int lev) override;
61 
62  /**
63  * Allocate the engine's fields on the fire grid fg (fg.ba, fg.dm, fg.geom;
64  * fg.atm_lo is the fire region's corner in the level's index space) and
65  * set the initial fire: fuels, terrain slope, ignition. surface_layer is
66  * never null; ERF passes z_phys_nd_atm too.
67  */
68  void initialize (const ERF& erf,
69  int lev,
70  const FireGrid& fg,
72  const amrex::MultiFab* z_phys_nd_atm) override;
73 
74  /**
75  * Called after initialize(), once the run's end is known: anything that
76  * depends on stop_time or max_step (output schedules, a check that the
77  * ignition happens before the run ends). On a restart, read_checkpoint()
78  * comes after this.
79  */
80  void start_run (amrex::Real stop_time, int max_step, int steps_per_coarse_step) override; // optional
81 
82  /**
83  * Advance the fire over one step of the fire grid's level (forcing.dt from
84  * forcing.time). forcing holds the face velocities, the cell-centre
85  * heights, the lowest cell's temperature and humidity, and the surface
86  * rain if wants_surface_precip() is true; sample them onto the fire grid
87  * here and keep no pointer to them after this call.
88  */
89  void advance (const FireForcing& forcing) override;
90 
91  /**
92  * Point fluxes.sensible (and fluxes.latent, if the fuel releases water) at
93  * the heat flux into the air on the fire grid [W/m2], positive upward,
94  * averaged over exactly [forcing.time, forcing.time + forcing.dt] of the
95  * last advance() (sum over any substeps, divided by forcing.dt); leave a
96  * pointer nullptr for none. A vapour mass flux becomes a latent flux by
97  * multiplying by L_v (ERF_Constants.H). The fields must stay valid until the next
98  * advance(). Called only when the coupling injects heat or smoke.
99  */
100  void fill_fluxes (FireFluxes& fluxes) override;
101 
102  /**
103  * Heat released per kilogram of fuel burned [J/kg], matching the sensible
104  * flux last handed over; the coupling divides by it to get the fuel burnt
105  * that the smoke emission factor applies to.
106  */
107  amrex::Real smoke_heat_per_kg () const override;
108 
109  /// Optional, false unless declared: true if advance() needs forcing.precip_accum_k0.
110  bool wants_surface_precip () const override;
111 
112  /// Optional, true unless declared: false if the engine reads nothing from the
113  /// surface layer, so it may run over any bottom boundary.
114  bool needs_surface_layer () const override;
115 
116  /**
117  * Optional, nullptr unless declared: for erf.fire.heat_open_fraction, the
118  * fraction of each atmospheric column open to the air [0-1] and the mean
119  * roof height of the rest [m], on the level's k = 0 slabs with one ghost cell.
120  */
121  const amrex::MultiFab* heat_open_fraction_atm () const override;
122  const amrex::MultiFab* roof_height_atm () const override;
123 
124  /**
125  * Optional (the default writes nothing and the engine cannot restart).
126  * Write everything the engine carries from one step to the next under
127  * checkpointname/Level_<lev>/ (lev the fire grid's level). The coupling
128  * writes its lagged fluxes after this; use names that do not start with
129  * FireQ.
130  */
131  void write_checkpoint (const std::string& checkpointname) const override;
132 
133  /**
134  * Optional (the default stops the run, saying restart is not supported).
135  * Read back what write_checkpoint() wrote, on a restart, after start_run()
136  * and before the first step; step is the fire grid level's step count at
137  * the checkpoint. Abort if the checkpoint's fire grid is not this run's.
138  */
139  void read_checkpoint (const std::string& restart_chkfile, int max_level, int step) override;
140 
141  /// Optional (the default writes nothing): the engine's plotfile of the fire grid,
142  /// named plotfile_prefix plus the step.
143  void write_plotfile (const std::string& plotfile_prefix, amrex::Real time, int step) const override;
144 
145  /**
146  * Optional, none unless declared: the fire fields the ERF plotfile can
147  * carry (names starting with "fire_", listed in erf.plot_vars_*), known
148  * from the inputs alone (asked before initialize()), and each field on the
149  * fire grid; the coupler writes its column means at k = 0.
150  */
151  std::vector<std::string> plot_var_names () const override;
152  const amrex::MultiFab* plot_var (const std::string& name) const override;
153 
154  /// Optional, -1 unless declared: area burned so far [m2], printed with erf.fire.fire_debug.
155  amrex::Real burned_area () const override;
156 
157  /**
158  * Optional, nullptr (or 0) unless declared: what other surface models read
159  * from the fire (a dust or smoke source model, for example). A level set negative where burned;
160  * the wind (u, v) the engine sampled at reference_wind_height() above
161  * ground; and the heat released before any split into sensible and latent.
162  */
163  const amrex::MultiFab* level_set () const override;
164  const amrex::MultiFab* reference_wind () const override;
166  const amrex::MultiFab* heat_release () const override;
167 };
168 
169 #endif
The interface between the fire coupling and a fire engine.
@ surface_layer
amrex::Real Real
Definition: ERF_ShocInterface.H:19
Definition: ERF_FireEngineTemplate.H:49
void write_checkpoint(const std::string &checkpointname) const override
amrex::Real smoke_heat_per_kg() const override
void read_checkpoint(const std::string &restart_chkfile, int max_level, int step) override
const amrex::MultiFab * heat_release() const override
const char * name() const override
The name erf.fire.engine selects this engine by, for example "my_fire".
const amrex::MultiFab * heat_open_fraction_atm() const override
amrex::Real burned_area() const override
Optional, -1 unless declared: area burned so far [m2], printed with erf.fire.fire_debug.
const amrex::MultiFab * level_set() const override
const amrex::MultiFab * roof_height_atm() const override
bool needs_surface_layer() const override
void fill_fluxes(FireFluxes &fluxes) override
void advance(const FireForcing &forcing) override
void write_plotfile(const std::string &plotfile_prefix, amrex::Real time, int step) const override
void initialize(const ERF &erf, int lev, const FireGrid &fg, const SurfaceLayer *surface_layer, const amrex::MultiFab *z_phys_nd_atm) override
const amrex::MultiFab * reference_wind() const override
Wind (u, v) [m/s] the engine sampled at reference_wind_height() on the fire grid; nullptr if none.
bool wants_surface_precip() const override
Optional, false unless declared: true if advance() needs forcing.precip_accum_k0.
void verify_prerequisites(const ERF &erf, int lev) override
std::vector< std::string > plot_var_names() const override
amrex::Real reference_wind_height() const override
Height above ground [m] of reference_wind().
void start_run(amrex::Real stop_time, int max_step, int steps_per_coarse_step) override
const amrex::MultiFab * plot_var(const std::string &name) const override
The field plot_var_names() lists as name, on the fire grid.
A fire engine behind the shared coupling layer.
Definition: ERF_FireEngine.H:132
Definition: ERF_SurfaceLayer.H:60
Definition: ERF_InterpolationUtils.H:15
@ fg
Definition: ERF_AdvanceMorrison.cpp:111
The fluxes a fire engine hands to the atmosphere after its step.
Definition: ERF_FireEngine.H:99
The atmospheric state a fire engine reads at the start of its step.
Definition: ERF_FireEngine.H:67
2D horizontal fire computational grid
Definition: ERF_FireGrid.H:29