ERF
Energy Research and Forecasting: An Atmospheric Modeling Code
ERF_TwoStreamCanopyForcing.H File Reference

What the two-stream sweep hands the building faces of the immersed-boundary surface energy balance (erf.ibseb.radiation = two_stream), and how a face reads it. More...

#include <AMReX_Array4.H>
#include <AMReX_Extension.H>
#include <AMReX_GpuQualifiers.H>
#include <AMReX_MultiFab.H>
#include <AMReX_REAL.H>
#include <limits>
Include dependency graph for ERF_TwoStreamCanopyForcing.H:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  TwoStreamCanopyView
 The fields a level's faces read for one step: the beam and the cosine of the zenith the sweep of that step wrote, and that sweep's interface fluxes. All null when the level has not swept this step (the initial report). More...
 
struct  TwoStreamFaceSky
 What one face takes from its column (all W/m^2). More...
 

Functions

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void two_stream_canopy_beam (int i, int j, int kmin, int m_top, const amrex::Array4< const amrex::Real > &scratch, int f_dir_comp, bool sw_on, amrex::Real cos_zenith, amrex::Real cloud_fraction, bool blend, const amrex::Array4< amrex::Real > &beam)
 Write the direct beam on a horizontal surface at the interfaces 0 .. m_top of column (i,j), from the scratch of the evaluation that has just run there, into beam: the clear-sky evaluation's beam as it is, and the cloudy evaluation's blended in with the cloud fraction, by the same expression as the fluxes ((1 - f) clear + f cloudy), so the two round alike in single precision and the shortwave down less the beam is the diffuse light. More...
 
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE int two_stream_canopy_sample (int k, int k0, int dir, int side, amrex::Real &w_up)
 Sample interface of a face and the weight of the one above. A z face takes the interface it lies on: a roof (solid below, side -1) the bottom of its fluid cell (m = k - k0), a ceiling (solid above, side +1, as under an overhang of a building from an STL file) the top of it (m = k - k0 + 1). A wall takes the mean of the two interfaces of its cell (m and m + 1), its mean height. More...
 
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE TwoStreamFaceSky two_stream_face_sky (int i, int j, int k, int k0, int dir, int side, const amrex::Array4< const amrex::Real > &beam, const amrex::Array4< const amrex::Real > &cosz, const amrex::Array4< const amrex::Real > &fluxes)
 The column radiation a face at fluid cell (i,j,k) of direction dir, with its solid on side side, takes: at its sample (two_stream_canopy_sample()), the direct-normal irradiance (the beam over the column's cosine of the zenith), the diffuse light (the shortwave down less the beam, floored at zero against round-off on a transparent column), the longwave down, and the shortwave and longwave up, which the face takes through its view of the ground. More...
 

Detailed Description

What the two-stream sweep hands the building faces of the immersed-boundary surface energy balance (erf.ibseb.radiation = two_stream), and how a face reads it.

The sweep already writes the interface fluxes of every column into ERF's rad_fluxes (RRTMGP's level layout: index k the lower interface of layer k, component 0 SW up, 1 SW down, 2 LW up, 3 LW down, after the clear/cloudy blend). What it does not keep is the direct beam, which only its scratch holds, and the cosine of the zenith it used. On the levels where ERF::init_ibseb() asks for them (TwoStreamRadiation::supply_canopy_forcing()) every sweep also writes:

  • the direct beam on a horizontal surface at the interfaces m = 0 .. m_top of every column, counted from the surface, m_top the highest interface a face of the level reads (a field on the level's grids flattened in z and then given those interfaces, index k = m), blended clear/cloudy like the fluxes;
  • the cosine of the zenith angle, floored at zero (a 2D field). A face reads the column of its fluid cell at its own height (two_stream_canopy_sample()): the downwelling fluxes there are the sun and the sky that reach it (for height-map buildings no building stands above a face in its own column; a face under the overhang of an STL building sees only building in IBFaceSet's view fractions, which take each column as solid up to its top, so its column's fluxes carry no weight), and the upwelling fluxes there are the ground as seen from that height, through the air in between.

Function Documentation

◆ two_stream_canopy_beam()

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void two_stream_canopy_beam ( int  i,
int  j,
int  kmin,
int  m_top,
const amrex::Array4< const amrex::Real > &  scratch,
int  f_dir_comp,
bool  sw_on,
amrex::Real  cos_zenith,
amrex::Real  cloud_fraction,
bool  blend,
const amrex::Array4< amrex::Real > &  beam 
)

Write the direct beam on a horizontal surface at the interfaces 0 .. m_top of column (i,j), from the scratch of the evaluation that has just run there, into beam: the clear-sky evaluation's beam as it is, and the cloudy evaluation's blended in with the cloud fraction, by the same expression as the fluxes ((1 - f) clear + f cloudy), so the two round alike in single precision and the shortwave down less the beam is the diffuse light.

vertical_two_stream_sweep() keeps the Beer-Lambert beam of every interface in its scratch (TwoStreamScratch::F_DIR), but writes it only when the shortwave is on and the sun is up; otherwise the scratch holds the other evaluation's beam or nothing at all, and the beam is zero. Call it right after each evaluation, before the next one overwrites the scratch.

Parameters
scratchthe sweep's scratch, as vertical_two_stream_sweep() takes it
f_dir_compthe scratch component of the beam (TwoStreamScratch::F_DIR)
kminlowest cell of the column (its surface interface)
m_tophighest interface of the beam field, at most the column's top
sw_onwhether the sweep ran its shortwave
cos_zenithcosine of the zenith angle the sweep used (unfloored)
cloud_fractionthe cloud fraction (used only when blend)
blendfalse for the clear-sky evaluation (overwrite), true for the cloudy one
beamthe beam field (component 0, index k = m)
81 {
82  const bool lit = sw_on && (cos_zenith > amrex::Real(0.0));
83  for (int m = 0; m <= m_top; ++m) {
84  const amrex::Real b = lit ? scratch(i, j, kmin + m, f_dir_comp) : amrex::Real(0.0);
85  beam(i, j, m) = blend ? (1.0 - cloud_fraction) * beam(i, j, m) + cloud_fraction * b : b;
86  }
87 }
amrex::Real Real
Definition: ERF_ShocInterface.H:19
Definition: ERF_ConsoleIO.cpp:17

Referenced by TwoStreamRadiation::advance().

Here is the caller graph for this function:

◆ two_stream_canopy_sample()

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE int two_stream_canopy_sample ( int  k,
int  k0,
int  dir,
int  side,
amrex::Real &  w_up 
)

Sample interface of a face and the weight of the one above. A z face takes the interface it lies on: a roof (solid below, side -1) the bottom of its fluid cell (m = k - k0), a ceiling (solid above, side +1, as under an overhang of a building from an STL file) the top of it (m = k - k0 + 1). A wall takes the mean of the two interfaces of its cell (m and m + 1), its mean height.

Parameters
kfluid cell of the face (the level's index)
k0the level's domain bottom
dirface direction (0 x, 1 y, 2 z)
sideside of the fluid cell the solid is on (-1 or +1)
w_upweight of interface m + 1
Returns
the lower sample interface m
105 {
106  w_up = (dir == 2) ? amrex::Real(0.0) : amrex::Real(0.5);
107  return k - k0 + ((dir == 2 && side > 0) ? 1 : 0);
108 }

Referenced by two_stream_face_sky().

Here is the caller graph for this function:

◆ two_stream_face_sky()

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE TwoStreamFaceSky two_stream_face_sky ( int  i,
int  j,
int  k,
int  k0,
int  dir,
int  side,
const amrex::Array4< const amrex::Real > &  beam,
const amrex::Array4< const amrex::Real > &  cosz,
const amrex::Array4< const amrex::Real > &  fluxes 
)

The column radiation a face at fluid cell (i,j,k) of direction dir, with its solid on side side, takes: at its sample (two_stream_canopy_sample()), the direct-normal irradiance (the beam over the column's cosine of the zenith), the diffuse light (the shortwave down less the beam, floored at zero against round-off on a transparent column), the longwave down, and the shortwave and longwave up, which the face takes through its view of the ground.

Parameters
beambeam field (index k = m)
coszcosine of the zenith, floored at zero (2D)
fluxesinterface fluxes in RRTMGP's level layout (absolute k)
137 {
138  amrex::Real w_up = 0.0;
139  const int ms = two_stream_canopy_sample(k, k0, dir, side, w_up);
140  const int mu = ms + ((w_up > amrex::Real(0.0)) ? 1 : 0);
141  const amrex::Real w_lo = amrex::Real(1.0) - w_up;
142  const amrex::Real beam_h = w_lo * beam(i, j, ms) + w_up * beam(i, j, mu);
143  const amrex::Real sw_dn = w_lo * fluxes(i, j, k0 + ms, 1) + w_up * fluxes(i, j, k0 + mu, 1);
145  const amrex::Real cz = cosz(i, j, 0);
146  // Both operands valid in both arms: an optimiser may evaluate the division
147  // before the selection, and 0 / 0 at night would raise the invalid flag.
148  s.dni = (cz > amrex::Real(0.0)) ? beam_h / (cz + std::numeric_limits<amrex::Real>::min()) : amrex::Real(0.0);
149  s.diffuse = (sw_dn - beam_h > amrex::Real(0.0)) ? sw_dn - beam_h : amrex::Real(0.0);
150  s.lw_down = w_lo * fluxes(i, j, k0 + ms, 3) + w_up * fluxes(i, j, k0 + mu, 3);
151  s.sw_up = w_lo * fluxes(i, j, k0 + ms, 0) + w_up * fluxes(i, j, k0 + mu, 0);
152  s.lw_up = w_lo * fluxes(i, j, k0 + ms, 2) + w_up * fluxes(i, j, k0 + mu, 2);
153  return s;
154 }
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE int two_stream_canopy_sample(int k, int k0, int dir, int side, amrex::Real &w_up)
Sample interface of a face and the weight of the one above. A z face takes the interface it lies on: ...
Definition: ERF_TwoStreamCanopyForcing.H:104
@ mu
Definition: ERF_AdvanceMorrison.cpp:92
What one face takes from its column (all W/m^2).
Definition: ERF_TwoStreamCanopyForcing.H:112
amrex::Real sw_up
Shortwave up at the face's height (the ground's reflection, seen from there)
Definition: ERF_TwoStreamCanopyForcing.H:116
amrex::Real diffuse
Diffuse shortwave down at the face's height.
Definition: ERF_TwoStreamCanopyForcing.H:114
amrex::Real lw_up
Longwave up at the face's height (the ground's emission and the air's below)
Definition: ERF_TwoStreamCanopyForcing.H:117
amrex::Real lw_down
Longwave down at the face's height.
Definition: ERF_TwoStreamCanopyForcing.H:115
amrex::Real dni
Direct-normal irradiance at the face's height.
Definition: ERF_TwoStreamCanopyForcing.H:113

Referenced by IBFaceSet::compute_longwave_two_stream(), and IBFaceSet::compute_shortwave_two_stream().

Here is the call graph for this function:
Here is the caller graph for this function: