ERF
Energy Research and Forecasting: An Atmospheric Modeling Code
ERF_SEBTurbulentFlux.H
Go to the documentation of this file.
1 #ifndef ERF_SEB_TURBULENT_FLUX_H_
2 #define ERF_SEB_TURBULENT_FLUX_H_
3 
4 /**
5  * @file ERF_SEBTurbulentFlux.H
6  * @brief Where the simplified surface energy balance takes its sensible (H) and
7  * latent (LE) heat fluxes from.
8  *
9  * The force-restore update removes H + LE from the ground. The air above receives
10  * the flux the lower surface layer applies, which it computes from the same skin
11  * temperature. Unless the two are the same flux the ground never loses what the
12  * air gains, so by default the balance takes the surface layer's flux.
13  *
14  * Precedence, per field, per level and per cell:
15  * 1. a land-surface model field of that name ("hfx" or "lh") where it holds a
16  * valid value (is_valid_lsm_value: finite and below the lsm_undefined
17  * placeholder a land model leaves in cells it does not process);
18  * 2. the surface layer's applied flux, with seb_turbulent_flux_source =
19  * surface_layer and the flux field allocated: a zlo surface layer with any
20  * diffusion or closure, not on EB terrain; the latent flux only with a
21  * moisture model. An adiabatic surface layer has the field and a zero flux,
22  * so H (or LE) is then 0, and ERF warns at start-up if the scalar default it
23  * replaces is nonzero;
24  * 3. the scalar default (seb_hfx_default or seb_lh_default).
25  *
26  * The surface-layer flux is the conservative flux on the lowest z face (rho
27  * w'theta' and rho w'qv'), converted to W/m^2 by the same helpers as the
28  * sensible_heat_flux and latent_heat_flux 2D outputs, so the two cannot
29  * disagree. Positive is away from the surface, as in the balance.
30  */
31 
32 #include <AMReX_MultiFab.H>
33 #include <AMReX_REAL.H>
34 
35 #include <ERF_RadStruct.H>
36 
37 /** @brief Which of the three sources a field was filled from. */
39 
40 /** @brief The turbulent flux being filled: selects the unit conversion. */
42 
43 /**
44  * @brief The precedence rule: land-surface field, then surface layer, then default.
45  *
46  * @param[in] land_surface_field_present a land-surface model exposes the field
47  * @param[in] source erf.radiation.seb_turbulent_flux_source
48  * @param[in] surface_layer_flux_present the surface layer applies this flux
49  */
50 [[nodiscard]] inline SEBFluxOrigin
51 select_seb_flux_origin (bool land_surface_field_present,
52  SEBTurbulentFluxSource source,
53  bool surface_layer_flux_present) noexcept
54 {
55  if (land_surface_field_present) { return SEBFluxOrigin::LandSurface; }
56  if (source == SEBTurbulentFluxSource::SurfaceLayer && surface_layer_flux_present) {
58  }
60 }
61 
62 /**
63  * @brief Fill the SEB's H or LE [W/m^2] on the valid cells of seb_flux.
64  *
65  * The selected values go to the valid cells; the halo always holds the fallback.
66  * The force-restore update, the residual diagnostic and the seb_hfx/seb_lh outputs
67  * read valid cells only. A consumer that needs neighbouring values in the halo must
68  * fill it first (FillBoundary).
69  *
70  * @param[out] seb_flux 2D SEB field (k = 0), laid out like the level's state
71  * @param[in] kind sensible or latent
72  * @param[in] land_surface_field land-surface field of that name, or nullptr; cells
73  * holding no valid value take the next source
74  * @param[in] surface_layer_flux conservative z-face flux the surface layer applies
75  * (rho w'theta' or rho w'qv'), or nullptr
76  * @param[in] surface_k z index of the surface face in surface_layer_flux
77  * @param[in] source erf.radiation.seb_turbulent_flux_source
78  * @param[in] fallback the scalar default [W/m^2]
79  * @return the highest-precedence source the field was filled from (cells of a
80  * land-surface field without a valid value take the next one)
81  */
83 fill_seb_turbulent_flux (amrex::MultiFab& seb_flux,
84  SEBTurbulentFlux kind,
85  const amrex::MultiFab* land_surface_field,
86  const amrex::MultiFab* surface_layer_flux,
87  int surface_k,
88  SEBTurbulentFluxSource source,
89  amrex::Real fallback);
90 
91 
92 /**
93  * @brief Fill one 2D surface-energy-balance input from land-surface model fields,
94  * cell by cell.
95  *
96  * Each valid cell of seb_field is set to scale * field + add_field where both
97  * values are valid land-surface values (is_valid_lsm_value), and to fallback
98  * elsewhere. A land model leaves the lsm_undefined placeholder in cells it does
99  * not process (Noah-MP: open water and sea ice) and everywhere before its first
100  * step, which runs after the first radiation call; those cells take the scalar
101  * default rather than the placeholder. The halo always holds the fallback; only
102  * valid cells take land-surface values.
103  *
104  * @param[out] seb_field 2D SEB field (k = 0), laid out like the land-surface fields
105  * @param[in] field land-surface field, or nullptr
106  * @param[in] fallback the scalar default
107  * @param[in] scale factor on field (Noah-MP's fira is positive upward; the
108  * balance wants the absorbed flux, so -1)
109  * @param[in] add_field second land-surface field added on top, or nullptr
110  * (Noah-MP splits the absorbed shortwave into sav and sag)
111  */
112 void
113 fill_seb_field_from_land_surface (amrex::MultiFab& seb_field,
114  const amrex::MultiFab* field,
115  amrex::Real fallback,
116  amrex::Real scale = amrex::Real(1.0),
117  const amrex::MultiFab* add_field = nullptr);
118 
119 #endif
Radiation model type and control parameters.
void fill_seb_field_from_land_surface(amrex::MultiFab &seb_field, const amrex::MultiFab *field, amrex::Real fallback, amrex::Real scale=amrex::Real(1.0), const amrex::MultiFab *add_field=nullptr)
Fill one 2D surface-energy-balance input from land-surface model fields, cell by cell.
SEBFluxOrigin select_seb_flux_origin(bool land_surface_field_present, SEBTurbulentFluxSource source, bool surface_layer_flux_present) noexcept
The precedence rule: land-surface field, then surface layer, then default.
Definition: ERF_SEBTurbulentFlux.H:51
SEBFluxOrigin
Which of the three sources a field was filled from.
Definition: ERF_SEBTurbulentFlux.H:38
SEBFluxOrigin fill_seb_turbulent_flux(amrex::MultiFab &seb_flux, SEBTurbulentFlux kind, const amrex::MultiFab *land_surface_field, const amrex::MultiFab *surface_layer_flux, int surface_k, SEBTurbulentFluxSource source, amrex::Real fallback)
Fill the SEB's H or LE [W/m^2] on the valid cells of seb_flux.
SEBTurbulentFlux
The turbulent flux being filled: selects the unit conversion.
Definition: ERF_SEBTurbulentFlux.H:41
amrex::Real Real
Definition: ERF_ShocInterface.H:19