ERF
Energy Research and Forecasting: An Atmospheric Modeling Code
ERF_TwoStreamRadiation.H
Go to the documentation of this file.
1 #ifndef ERF_TWO_STREAM_RADIATION_H_
2 #define ERF_TWO_STREAM_RADIATION_H_
3 
4 #include <memory>
5 #include <string>
6 
7 #include <AMReX_BoxArray.H>
8 #include <AMReX_DistributionMapping.H>
9 #include <AMReX_Geometry.H>
10 #include <AMReX_MultiFab.H>
11 #include <AMReX_REAL.H>
12 #include <AMReX_Vector.H>
13 
14 #include <ERF_RadStruct.H>
15 #include <ERF_LandSurface.H>
18 
19 /**
20  * @brief The two-stream radiation model (erf.radiation_model = TwoStream).
21  *
22  * Owns everything the model keeps between steps: the per-level surface
23  * property fields it falls back on when no land-surface model supplies
24  * them, the surface-energy-balance (SEB) fields and force-restore state,
25  * and the domain-mean flux diagnostics of the last column sweep. ERF holds
26  * one instance and calls it only after testing
27  * `solverChoice.rad_type == RadiationType::TwoStream`; every method
28  * here checks the same predicate and returns without acting otherwise.
29  *
30  * Lifecycle:
31  * - resize(nlevs) once at construction (before the inputs are read);
32  * - define_level(lev, radChoice, rdOcp, ba2d, dm, ba, domain, supply_land_forcing)
33  * whenever a level is (re)built;
34  * - advance(...) twice per step: "pre_dycore" runs the column sweep on the
35  * old state and writes the heating rates, "post_dycore" reuses that
36  * sweep's flux diagnostics and advances the SEB state by dt_step;
37  * - write_land_forcing(...) after a sweep, when a land-surface model integrates
38  * on the radiation this model computes (see supply_land_forcing);
39  * - supply_canopy_forcing(...) once, when the building faces of the
40  * immersed-boundary balance take their radiation from the sweep
41  * (erf.ibseb.radiation = two_stream), and canopy_forcing(...) after each sweep;
42  * - write_checkpoint / read_checkpoint for the prognostic surface state.
43  *
44  * The heating-rate MultiFab itself stays in ERF, since RRTMGP writes the
45  * same 2-component (SW, LW) array and the RhoTheta source term and the
46  * plotfile read it without caring which model filled it.
47  */
49 {
50 public:
51  TwoStreamRadiation () = default;
52 
53  /** @brief Size the per-level containers; no allocation happens here. */
54  void resize (int nlevs_max);
55 
56  /** @brief True once a level has been defined with the model selected. */
57  [[nodiscard]] bool active () const {
58  return (m_rad != nullptr) && m_rad->enabled;
59  }
60 
61  /** @brief Read-only view of the per-level prognostic surface-temperature state. */
62  [[nodiscard]] const amrex::MultiFab* prognostic_surface_temperature_state (int lev) const noexcept {
63  return (lev >= 0 && lev < static_cast<int>(m_t_sfc.size()))
64  ? m_t_sfc[lev].get() : nullptr;
65  }
66 
67  /**
68  * @brief Allocate the 2D surface fields of one level on the given
69  * horizontal BoxArray and fill them with the scalar defaults. A no-op
70  * unless rad_choice.rad_type == TwoStream.
71  *
72  * Also enforces the model's one grid requirement: every box of @p ba must
73  * span @p domain in z, because the column sweep applies the
74  * top-of-atmosphere and surface boundary conditions at the ends of a box.
75  * Aborting here means a bad refinement patch is rejected when the level is
76  * built (including on regrid), not at the first radiation call.
77  *
78  * @param lev level
79  * @param rad_choice the model's inputs
80  * @param ba2d horizontal BoxArray the 2D surface fields live on
81  * @param dm distribution mapping shared with the level's state
82  * @param ba the level's 3D BoxArray, checked for the z span
83  * @param domain the level's domain Box
84  * @param supply_land_forcing allocate the downwelling SW, downwelling LW and
85  * cos(zenith) fields the sweep fills for a land-surface model
86  * (SolverChoice::rad_feeds_lsm()); off, the sweep does no
87  * extra work and the fields do not exist
88  */
89  void define_level (int lev,
90  const RadChoice& rad_choice,
92  const amrex::BoxArray& ba2d,
93  const amrex::DistributionMapping& dm,
94  const amrex::BoxArray& ba,
95  const amrex::Box& domain,
96  bool supply_land_forcing = false);
97 
98  /**
99  * @brief One radiation call at one level.
100  *
101  * @param lev level
102  * @param nstep step number, used as the diagnostics row index
103  * @param time time logged with the diagnostics row [s]
104  * @param dt_step step size, used by the SEB Euler update [s]
105  * @param call_site "pre_dycore" (column sweep + diagnostics) or
106  * "post_dycore" (cached diagnostics + SEB update)
107  * @param cons_old old-state conserved variables of this level
108  * @param z_phys_nd nodal heights (layer interfaces), or nullptr on a uniform grid
109  * @param geom geometry of this level
110  * @param lsm land-surface model (queried for per-column fields)
111  * @param radiation_inputs canonical surface-property inputs, in fixed order
112  * @param noahmp_active whether Noah-MP diagnostics may be queried
113  * @param qheating 2-component (SW, LW) heating-rate MultiFab of this
114  * level, written at the pre-dycore call; may be nullptr
115  * @param rad_fluxes 4-component (SW up, SW down, LW up, LW down) interface
116  * fluxes of this level in RRTMGP's level layout (index k
117  * the lower interface of layer k, the top of the
118  * atmosphere in the z-ghost cell above the top layer),
119  * written at the pre-dycore call; may be nullptr
120  * @param t_surf the surface layer's surface temperature, or nullptr;
121  * used as the longwave boundary condition where no
122  * land-surface field exists, as RRTMGP does
123  * @param sfc_sens_flux the conservative heat flux (rho w'theta', z faces)
124  * the zlo surface layer applies to this level, or
125  * nullptr when it applies none; the surface energy
126  * balance's H where no land-surface model supplies one
127  * (see ERF_SEBTurbulentFlux.H)
128  * @param sfc_laten_flux the moisture flux (rho w'qv', z faces) likewise,
129  * for LE; nullptr without a moisture model
130  * @param lat_m per-column latitude [degrees], or nullptr (then
131  * erf.rad_cons_lat); only the WRF/metgrid inits fill it
132  * @param lon_m per-column longitude [degrees], likewise
133  * @param epoch_time seconds since 1970-01-01 00:00 UTC of this call
134  * (start_time + time), the RRTMGP time base; double, as
135  * RRTMGP keeps it, since a float cannot resolve a time
136  * of day at ~1.7e9 s
137  * @param have_datetime true when start_datetime (or a WRF/metgrid start
138  * date) fixed the calendar; without it a dynamic sun
139  * cannot be placed and the call aborts
140  */
141  void advance (int lev,
142  int nstep,
143  amrex::Real time,
144  amrex::Real dt_step,
145  const std::string& call_site,
146  const amrex::MultiFab& cons_old,
147  const amrex::MultiFab* z_phys_nd,
148  const amrex::Geometry& geom,
149  LandSurface& lsm,
150  const amrex::Vector<const amrex::MultiFab*>& radiation_inputs,
151  bool noahmp_active,
152  amrex::MultiFab* qheating,
153  amrex::MultiFab* rad_fluxes,
154  const amrex::MultiFab* t_surf,
155  const amrex::MultiFab* sfc_sens_flux,
156  const amrex::MultiFab* sfc_laten_flux,
157  const amrex::MultiFab* lat_m,
158  const amrex::MultiFab* lon_m,
159  double epoch_time,
160  bool have_datetime);
161 
162  /**
163  * @brief The prognostic surface state of one level, or nullptr when the SEB is
164  * off or the level has not been built.
165  *
166  * Exposed so ERF can average t_sfc and q_sfc down after the finer levels have
167  * advanced. Every level evolves its own copy, and without that transfer the two
168  * estimates of one surface drift apart -- which would give the longwave boundary
169  * condition two different values for the same ground. ERF owns refRatio and the
170  * level geometries; this class does not, and should not grow them for one call.
171  */
172  [[nodiscard]] amrex::MultiFab* seb_t_sfc (int lev) {
173  return (active() && m_rad->seb_enable && lev < m_t_sfc.size()) ? m_t_sfc[lev].get() : nullptr;
174  }
175  [[nodiscard]] amrex::MultiFab* seb_q_sfc (int lev) {
176  return (active() && m_rad->seb_enable && lev < m_q_sfc.size()) ? m_q_sfc[lev].get() : nullptr;
177  }
178 
179  /**
180  * @brief The sensible and latent heat fluxes [W/m^2] the surface energy balance
181  * of one level last used, or nullptr when the SEB is off or the level has not
182  * been built. Read-only: for output.
183  */
184  [[nodiscard]] const amrex::MultiFab* seb_hfx (int lev) const {
185  return (active() && m_rad->seb_enable && lev < m_hfx_sfc.size()) ? m_hfx_sfc[lev].get() : nullptr;
186  }
187  [[nodiscard]] const amrex::MultiFab* seb_lh (int lev) const {
188  return (active() && m_rad->seb_enable && lev < m_lh_sfc.size()) ? m_lh_sfc[lev].get() : nullptr;
189  }
190 
191  /**
192  * @brief What level lev's surface hands the surface layer for its surface mixing ratio
193  * (erf.radiation.seb_surface_layer_uses_moisture), per column, in the components of
194  * erf_surface_moisture::Component: the soil-water factor (seb_moisture_availability
195  * of the current q_s); with erf.radiation.seb_soil_type, the bare-soil resistance and
196  * the relative humidity of its pore air at the skin temperature; and
197  * with erf.radiation.seb_vegetation_type as well, the vegetated fraction and the canopy
198  * resistance without its vapour-deficit factor (from the net shortwave the balance
199  * holds divided by (1 - surface albedo) -- the sweep's with seb_use_radiation_fluxes,
200  * seb_sw_flux_default otherwise -- and the skin temperature). Absent pieces are a
201  * fraction of 0 and resistances of 1e6 s/m. nullptr
202  * when the option is off or the level has not been built. Recomputed on every call,
203  * on the valid cells; the halo is not filled.
204  */
205  [[nodiscard]] const amrex::MultiFab* seb_surface_moisture (int lev);
206 
207  /** @brief True when the force-restore state is being evolved and so needs transferring. */
208  [[nodiscard]] bool seb_prognostic_active () const {
210  }
211 
212  /** @brief True when define_level allocated the land-model forcing fields on @p lev. */
213  [[nodiscard]] bool supplies_land_forcing (int lev) const noexcept {
214  return lev >= 0 && lev < static_cast<int>(m_sw_dn_sfc.size()) && m_sw_dn_sfc[lev] != nullptr;
215  }
216 
217  /**
218  * @brief The surface forcing of the last sweep on @p lev (2D: i,j), or nullptr when
219  * the level does not supply it: total downwelling shortwave [W/m^2], downwelling
220  * longwave [W/m^2] and the cosine of the solar zenith angle floored at zero [1].
221  * lsm_undefined until a sweep has run on the level, so a copy made before one is
222  * caught by the land model's missing-input check instead of reading as zero.
223  */
224  [[nodiscard]] const amrex::MultiFab* land_forcing_sw_dn (int lev) const noexcept {
225  return supplies_land_forcing(lev) ? m_sw_dn_sfc[lev].get() : nullptr;
226  }
227  [[nodiscard]] const amrex::MultiFab* land_forcing_lw_dn (int lev) const noexcept {
228  return supplies_land_forcing(lev) ? m_lw_dn_sfc[lev].get() : nullptr;
229  }
230  [[nodiscard]] const amrex::MultiFab* land_forcing_cos_zenith (int lev) const noexcept {
231  return supplies_land_forcing(lev) ? m_cos_zenith[lev].get() : nullptr;
232  }
233 
234  /**
235  * @brief Copy the surface forcing of the last sweep on @p lev into a land-surface
236  * model's radiation inputs (SurfaceModel's "sw_flux_dn", "lw_flux_dn" and
237  * "cos_zenith_angle" outputs). A null destination is skipped. Each destination
238  * must lie on this level's horizontal grids; see copy_surface_plane. Before the
239  * level's first sweep this copies the lsm_undefined sentinel, not zero.
240  */
241  void write_land_forcing (int lev,
242  amrex::MultiFab* sw_flux_dn,
243  amrex::MultiFab* lw_flux_dn,
244  amrex::MultiFab* cos_zenith_angle) const;
245 
246  /**
247  * @brief Have every later sweep on @p lev write what the building faces need
248  * besides the interface fluxes (erf.ibseb.radiation = two_stream;
249  * ERF_TwoStreamCanopyForcing.H): the direct beam on a horizontal surface at the
250  * interfaces 0 .. @p m_top of each column, counted from the surface, and the
251  * cosine of the zenith. Allocates one field on the level's horizontal grids given
252  * those interfaces in z and one 2D field. Call after define_level(); a later
253  * define_level() of the level (a regrid) drops the request.
254  *
255  * @param lev level, which must have been defined; its sweep asserts that the
256  * columns reach @p m_top
257  * @param m_top highest interface the faces read (IBFaceSet::top_sample_interface()),
258  * in [0, number of cells in z]
259  */
260  void supply_canopy_forcing (int lev, int m_top);
261 
262  /** @brief True when supply_canopy_forcing() was called for @p lev since its last define_level(). */
263  [[nodiscard]] bool supplies_canopy_forcing (int lev) const noexcept {
264  return lev >= 0 && lev < static_cast<int>(m_canopy.size()) && m_canopy[lev] != nullptr;
265  }
266 
267  /**
268  * @brief The beam and the cosine of the zenith of @p lev as the sweep of step
269  * @p nstep wrote them (the view's fluxes are left for the caller, who owns
270  * rad_fluxes), or an empty view when the level does not supply them or has not
271  * swept at that step: the faces must not take a previous step's radiation, nor
272  * the zeros of a level whose radiation came from its parent.
273  */
274  [[nodiscard]] TwoStreamCanopyView canopy_forcing (int lev, int nstep) const noexcept {
276  if (supplies_canopy_forcing(lev) && m_canopy_step[lev] == nstep) {
277  v.beam = m_canopy[lev].get();
278  v.cos_zenith = m_canopy_cosz[lev].get();
279  }
280  return v;
281  }
282 
283  /** @brief Write the prognostic surface state of one level (SEB on). */
284  void write_checkpoint (int lev, const std::string& checkpointname) const;
285 
286  /** @brief Read it back when the checkpoint carries it; else keep defaults. */
287  void read_checkpoint (int lev, const std::string& restart_chkfile);
288 
289  // Orbital elements of the current year (Berger 1978, or the erf.rad_orbital_*
290  // overrides), computed once per year rather than every step, and the
291  // one-time note about an unscaled irradiance. Public so the file-local
292  // solar-state helper and two_stream_sun_date() can fill it.
293  struct OrbitalCache {
294  int year = -9999;
295  double eccen = 0.0;
296  double obliqr = 0.0;
297  double lambm0 = 0.0;
298  double mvelpp = 0.0;
299  bool noted_unscaled = false;
300  };
301 
302 private:
303  // Domain-mean flux diagnostics of the last column sweep, per level, so the
304  // post-dycore call can report them without sweeping again.
305  struct FluxDiag {
306  // False until a column sweep has filled this level's entry. The post-dycore call
307  // reports the cached values rather than sweeping again, and a level whose
308  // pre-dycore sweep was skipped -- the interp-from-coarse-pending path, which
309  // returns before the sweep -- would otherwise report the zero-initialised struct
310  // as though the fluxes really were zero.
311  bool valid = false;
313  amrex::Real SW_TOA = 0.0; // domain-mean incident SW at the top
318  };
319 
320  const RadChoice* m_rad = nullptr;
323 
324  // CSV / console diagnostics writer, one per level, created on that level's
325  // first advance() so its header and duplicate-row state persist across
326  // calls. Per level because every level of a hierarchy reports the same
327  // step, call_site and time, and a shared duplicate guard would suppress
328  // all but the first to report.
329  amrex::Vector<std::unique_ptr<RadiationDiagnostics>> m_diag;
330 
331  // Fallback surface properties when no LSM supplies them (2D: i,j).
332  amrex::Vector<std::unique_ptr<amrex::MultiFab>> m_alb_sw;
333  amrex::Vector<std::unique_ptr<amrex::MultiFab>> m_emiss_lw;
334  amrex::Vector<std::unique_ptr<amrex::MultiFab>> m_t_sfc; // prognostic when the SEB evolves it
335 
336  // Surface-energy-balance fields (2D: i,j), allocated when seb_enable.
337  amrex::Vector<std::unique_ptr<amrex::MultiFab>> m_sw_flux_sfc; // net absorbed shortwave [W/m^2]
338  amrex::Vector<std::unique_ptr<amrex::MultiFab>> m_lw_flux_sfc; // net absorbed longwave [W/m^2]
339  amrex::Vector<std::unique_ptr<amrex::MultiFab>> m_hfx_sfc; // sensible heat flux [W/m^2]
340  amrex::Vector<std::unique_ptr<amrex::MultiFab>> m_lh_sfc; // latent heat flux [W/m^2]
341  amrex::Vector<std::unique_ptr<amrex::MultiFab>> m_grdflx_sfc; // ground heat flux [W/m^2]
342  amrex::Vector<std::unique_ptr<amrex::MultiFab>> m_q_sfc; // surface moisture, prognostic (see RadChoice::seb_q_sfc_default)
343  amrex::Vector<std::unique_ptr<amrex::MultiFab>> m_t_deep; // deep-soil temperature [K]
344  amrex::Vector<std::unique_ptr<amrex::MultiFab>> m_q_deep; // deep-soil moisture q_s restores to
345  amrex::Vector<std::unique_ptr<amrex::MultiFab>> m_moisture; // seb_surface_moisture (seb_surface_layer_uses_moisture)
346 
347  // What the sweep hands to a land-surface model (2D: i,j), allocated when
348  // define_level is asked to supply it. These are the DOWNWELLING fluxes, as opposed to
349  // the net fluxes above that the SEB consumes: a land model applies its own albedo
350  // and emissivity, so they cannot be recovered from the net fields.
351  amrex::Vector<std::unique_ptr<amrex::MultiFab>> m_sw_dn_sfc; // downwelling shortwave at the surface [W/m^2]
352  amrex::Vector<std::unique_ptr<amrex::MultiFab>> m_lw_dn_sfc; // downwelling longwave at the surface [W/m^2]
353  amrex::Vector<std::unique_ptr<amrex::MultiFab>> m_cos_zenith; // cosine of the solar zenith angle, >= 0 [1]
354 
355  // The canopy forcing of the building faces (see supply_canopy_forcing), its top
356  // interface counted from the surface, and the step of the sweep that last wrote it
357  // (-1 before any).
358  amrex::Vector<std::unique_ptr<amrex::MultiFab>> m_canopy; // the beam, interfaces 0 .. m_top
359  amrex::Vector<std::unique_ptr<amrex::MultiFab>> m_canopy_cosz; // cos z, floored at zero (2D)
360  amrex::Vector<int> m_canopy_m;
361  amrex::Vector<int> m_canopy_step;
362 
363  amrex::Vector<FluxDiag> m_flux_diag;
364 };
365 
366 /**
367  * @brief Copy a 2D field (k = 0 only) into the k = 0 plane of a surface-model field.
368  *
369  * Surface-model fields keep their surface values in the k = 0 plane, which may lie in
370  * the field's z ghost region (SLM stores soil layers at k < 0), and carry x/y ghost cells
371  * the source need not have. Only the i,j extent of each destination VALID box is
372  * written, so ghost columns and every other k are left alone. The two fields must share
373  * a horizontal layout: the destination's boxes flattened to k = 0 equal the source's,
374  * on the same DistributionMapping -- which holds for ERF's ba2d and a land model's
375  * data built from the same level grids, and is asserted rather than assumed.
376  */
377 void copy_surface_plane (const amrex::MultiFab& src2d, amrex::MultiFab& dst);
378 
379 /** @brief RRTMGP's reference total solar irradiance [W/m^2], scaled by the date's Earth-Sun distance factor. */
380 inline constexpr amrex::Real two_stream_tsi_reference = 1360.9;
381 
382 /** @brief The calendar sun of the two-stream model at one time (see two_stream_sun_date()). */
384  double calday = 1.0; ///< Day of the year (1 = 1 January), UTC time of day as the fraction
385  double declin = 0.0; ///< Solar declination [rad]
386  double eccf = 1.0; ///< Earth-Sun distance factor (d0/d)^2
387 };
388 
389 /**
390  * @brief The calendar sun of the two-stream model at a UTC epoch time (start_time + t).
391  *
392  * The date as the RRTMGP interface forms it, the orbit of the year (or the
393  * erf.rad_orbital_* overrides) cached in @p orbit, and the declination and distance
394  * factor of ERF_OrbCosZenith.H. The two-stream sweep places its sun from this, with the
395  * column's position, and so does the immersed-boundary balance with
396  * erf.ibseb.sun_mode = two_stream.
397  */
399  double epoch_time);
400 
401 #endif // ERF_TWO_STREAM_RADIATION_H_
constexpr amrex::Real RdoCp
Definition: ERF_Constants.H:53
const Real rdOcp
Definition: ERF_InitCustomPert_ABL.H:72
Radiation model type and control parameters.
Radiation module diagnostic output and CSV logging.
amrex::Real Real
Definition: ERF_ShocInterface.H:19
What the two-stream sweep hands the building faces of the immersed-boundary surface energy balance (e...
constexpr amrex::Real two_stream_tsi_reference
RRTMGP's reference total solar irradiance [W/m^2], scaled by the date's Earth-Sun distance factor.
Definition: ERF_TwoStreamRadiation.H:380
TwoStreamSunDate two_stream_sun_date(const RadChoice &rc, TwoStreamRadiation::OrbitalCache &orbit, double epoch_time)
The calendar sun of the two-stream model at a UTC epoch time (start_time + t).
Definition: ERF_TwoStreamRadiation.cpp:100
void copy_surface_plane(const amrex::MultiFab &src2d, amrex::MultiFab &dst)
Copy a 2D field (k = 0 only) into the k = 0 plane of a surface-model field.
Wrapper class for managing land surface models across AMR levels.
Definition: ERF_LandSurface.H:19
The two-stream radiation model (erf.radiation_model = TwoStream).
Definition: ERF_TwoStreamRadiation.H:49
void write_land_forcing(int lev, amrex::MultiFab *sw_flux_dn, amrex::MultiFab *lw_flux_dn, amrex::MultiFab *cos_zenith_angle) const
Copy the surface forcing of the last sweep on lev into a land-surface model's radiation inputs (Surfa...
Definition: ERF_TwoStreamRadiation.cpp:482
bool supplies_canopy_forcing(int lev) const noexcept
True when supply_canopy_forcing() was called for lev since its last define_level().
Definition: ERF_TwoStreamRadiation.H:263
amrex::Vector< std::unique_ptr< amrex::MultiFab > > m_canopy_cosz
Definition: ERF_TwoStreamRadiation.H:359
bool supplies_land_forcing(int lev) const noexcept
True when define_level allocated the land-model forcing fields on lev.
Definition: ERF_TwoStreamRadiation.H:213
amrex::Vector< std::unique_ptr< amrex::MultiFab > > m_q_sfc
Definition: ERF_TwoStreamRadiation.H:342
const amrex::MultiFab * seb_hfx(int lev) const
The sensible and latent heat fluxes [W/m^2] the surface energy balance of one level last used,...
Definition: ERF_TwoStreamRadiation.H:184
amrex::MultiFab * seb_q_sfc(int lev)
Definition: ERF_TwoStreamRadiation.H:175
TwoStreamRadiation()=default
void read_checkpoint(int lev, const std::string &restart_chkfile)
Read it back when the checkpoint carries it; else keep defaults.
Definition: ERF_TwoStreamRadiation.cpp:516
void define_level(int lev, const RadChoice &rad_choice, amrex::Real rdOcp, const amrex::BoxArray &ba2d, const amrex::DistributionMapping &dm, const amrex::BoxArray &ba, const amrex::Box &domain, bool supply_land_forcing=false)
Allocate the 2D surface fields of one level on the given horizontal BoxArray and fill them with the s...
Definition: ERF_TwoStreamRadiation.cpp:258
void supply_canopy_forcing(int lev, int m_top)
Have every later sweep on lev write what the building faces need besides the interface fluxes (erf....
Definition: ERF_TwoStreamRadiation.cpp:362
amrex::Vector< std::unique_ptr< amrex::MultiFab > > m_canopy
Definition: ERF_TwoStreamRadiation.H:358
amrex::Vector< std::unique_ptr< amrex::MultiFab > > m_grdflx_sfc
Definition: ERF_TwoStreamRadiation.H:341
void write_checkpoint(int lev, const std::string &checkpointname) const
Write the prognostic surface state of one level (SEB on).
Definition: ERF_TwoStreamRadiation.cpp:496
amrex::Vector< std::unique_ptr< amrex::MultiFab > > m_lw_flux_sfc
Definition: ERF_TwoStreamRadiation.H:338
amrex::Vector< std::unique_ptr< amrex::MultiFab > > m_moisture
Definition: ERF_TwoStreamRadiation.H:345
amrex::Vector< std::unique_ptr< amrex::MultiFab > > m_q_deep
Definition: ERF_TwoStreamRadiation.H:344
const amrex::MultiFab * seb_surface_moisture(int lev)
What level lev's surface hands the surface layer for its surface mixing ratio (erf....
Definition: ERF_TwoStreamRadiation.cpp:405
amrex::MultiFab * seb_t_sfc(int lev)
The prognostic surface state of one level, or nullptr when the SEB is off or the level has not been b...
Definition: ERF_TwoStreamRadiation.H:172
amrex::Real m_rdOcp
Definition: ERF_TwoStreamRadiation.H:321
amrex::Vector< FluxDiag > m_flux_diag
Definition: ERF_TwoStreamRadiation.H:363
bool active() const
True once a level has been defined with the model selected.
Definition: ERF_TwoStreamRadiation.H:57
const amrex::MultiFab * seb_lh(int lev) const
Definition: ERF_TwoStreamRadiation.H:187
const amrex::MultiFab * land_forcing_lw_dn(int lev) const noexcept
Definition: ERF_TwoStreamRadiation.H:227
amrex::Vector< std::unique_ptr< amrex::MultiFab > > m_emiss_lw
Definition: ERF_TwoStreamRadiation.H:333
void resize(int nlevs_max)
Size the per-level containers; no allocation happens here.
Definition: ERF_TwoStreamRadiation.cpp:232
amrex::Vector< std::unique_ptr< amrex::MultiFab > > m_t_sfc
Definition: ERF_TwoStreamRadiation.H:334
amrex::Vector< std::unique_ptr< amrex::MultiFab > > m_lw_dn_sfc
Definition: ERF_TwoStreamRadiation.H:352
const amrex::MultiFab * land_forcing_sw_dn(int lev) const noexcept
The surface forcing of the last sweep on lev (2D: i,j), or nullptr when the level does not supply it:...
Definition: ERF_TwoStreamRadiation.H:224
amrex::Vector< std::unique_ptr< amrex::MultiFab > > m_lh_sfc
Definition: ERF_TwoStreamRadiation.H:340
TwoStreamCanopyView canopy_forcing(int lev, int nstep) const noexcept
The beam and the cosine of the zenith of lev as the sweep of step nstep wrote them (the view's fluxes...
Definition: ERF_TwoStreamRadiation.H:274
amrex::Vector< std::unique_ptr< amrex::MultiFab > > m_alb_sw
Definition: ERF_TwoStreamRadiation.H:332
amrex::Vector< std::unique_ptr< amrex::MultiFab > > m_sw_flux_sfc
Definition: ERF_TwoStreamRadiation.H:337
const amrex::MultiFab * prognostic_surface_temperature_state(int lev) const noexcept
Read-only view of the per-level prognostic surface-temperature state.
Definition: ERF_TwoStreamRadiation.H:62
OrbitalCache m_orbit
Definition: ERF_TwoStreamRadiation.H:322
void advance(int lev, int nstep, amrex::Real time, amrex::Real dt_step, const std::string &call_site, const amrex::MultiFab &cons_old, const amrex::MultiFab *z_phys_nd, const amrex::Geometry &geom, LandSurface &lsm, const amrex::Vector< const amrex::MultiFab * > &radiation_inputs, bool noahmp_active, amrex::MultiFab *qheating, amrex::MultiFab *rad_fluxes, const amrex::MultiFab *t_surf, const amrex::MultiFab *sfc_sens_flux, const amrex::MultiFab *sfc_laten_flux, const amrex::MultiFab *lat_m, const amrex::MultiFab *lon_m, double epoch_time, bool have_datetime)
One radiation call at one level.
Definition: ERF_TwoStreamRadiation.cpp:536
amrex::Vector< std::unique_ptr< amrex::MultiFab > > m_t_deep
Definition: ERF_TwoStreamRadiation.H:343
amrex::Vector< std::unique_ptr< RadiationDiagnostics > > m_diag
Definition: ERF_TwoStreamRadiation.H:329
bool seb_prognostic_active() const
True when the force-restore state is being evolved and so needs transferring.
Definition: ERF_TwoStreamRadiation.H:208
amrex::Vector< std::unique_ptr< amrex::MultiFab > > m_sw_dn_sfc
Definition: ERF_TwoStreamRadiation.H:351
const amrex::MultiFab * land_forcing_cos_zenith(int lev) const noexcept
Definition: ERF_TwoStreamRadiation.H:230
const RadChoice * m_rad
Definition: ERF_TwoStreamRadiation.H:320
amrex::Vector< int > m_canopy_step
Definition: ERF_TwoStreamRadiation.H:361
amrex::Vector< std::unique_ptr< amrex::MultiFab > > m_hfx_sfc
Definition: ERF_TwoStreamRadiation.H:339
amrex::Vector< int > m_canopy_m
Definition: ERF_TwoStreamRadiation.H:360
amrex::Vector< std::unique_ptr< amrex::MultiFab > > m_cos_zenith
Definition: ERF_TwoStreamRadiation.H:353
constexpr std::array< amrex::Real, num_veg_params > rc
Definition: ERF_SLM_DefaultParams.H:22
Container holding radiation-related choices and parameters.
Definition: ERF_RadStruct.H:86
bool seb_prognostic_enable
Enable prognostic SEB surface temperature and moisture evolution. When true, integrates SEB residual ...
Definition: ERF_RadStruct.H:550
bool seb_enable
Master switch for simplified SEB infrastructure. When false (default), no SEB MultiFabs are allocated...
Definition: ERF_RadStruct.H:377
bool enabled
True when erf.radiation_model = TwoStream. Set by init_params from the model SolverChoice read; the e...
Definition: ERF_RadStruct.H:92
The fields a level's faces read for one step: the beam and the cosine of the zenith the sweep of that...
Definition: ERF_TwoStreamCanopyForcing.H:45
const amrex::MultiFab * beam
Direct beam on a horizontal surface, interfaces 0 .. m_top [W/m^2].
Definition: ERF_TwoStreamCanopyForcing.H:46
const amrex::MultiFab * cos_zenith
Cosine of the zenith of the sweep, floored at zero (2D) [1].
Definition: ERF_TwoStreamCanopyForcing.H:47
Definition: ERF_TwoStreamRadiation.H:305
amrex::Real LW_net_surface
Definition: ERF_TwoStreamRadiation.H:315
amrex::Real SW_TOA
Definition: ERF_TwoStreamRadiation.H:313
amrex::Real SW_surface
Definition: ERF_TwoStreamRadiation.H:312
amrex::Real heating_rate_max
Definition: ERF_TwoStreamRadiation.H:317
bool valid
Definition: ERF_TwoStreamRadiation.H:311
amrex::Real LW_up_TOA
Definition: ERF_TwoStreamRadiation.H:316
amrex::Real SW_up_TOA
Definition: ERF_TwoStreamRadiation.H:314
Definition: ERF_TwoStreamRadiation.H:293
bool noted_unscaled
Definition: ERF_TwoStreamRadiation.H:299
double obliqr
Definition: ERF_TwoStreamRadiation.H:296
int year
Definition: ERF_TwoStreamRadiation.H:294
double lambm0
Definition: ERF_TwoStreamRadiation.H:297
double mvelpp
Definition: ERF_TwoStreamRadiation.H:298
double eccen
Definition: ERF_TwoStreamRadiation.H:295
The calendar sun of the two-stream model at one time (see two_stream_sun_date()).
Definition: ERF_TwoStreamRadiation.H:383
double eccf
Earth-Sun distance factor (d0/d)^2.
Definition: ERF_TwoStreamRadiation.H:386
double declin
Solar declination [rad].
Definition: ERF_TwoStreamRadiation.H:385
double calday
Day of the year (1 = 1 January), UTC time of day as the fraction.
Definition: ERF_TwoStreamRadiation.H:384