ERF
Energy Research and Forecasting: An Atmospheric Modeling Code
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
ERF_RRTMGP_Utils.H
Go to the documentation of this file.
1 #ifndef ERF_RRTMGP_UTILS_H
2 #define ERF_RRTMGP_UTILS_H
3 
4 #include "rrtmgp_const.h"
5 
6 #include "ERF_Constants.H"
7 
8 namespace rrtmgp {
9 
10 template<class View1, class View2, class View3, class View4, class View5>
11 void
12 mixing_ratio_to_cloud_mass (View1 const& mixing_ratio ,
13  View2 const& cloud_fraction,
14  View3 const& rho ,
15  View4 const& dz ,
16  View5 const& cloud_mass)
17 {
18  const int ncol = mixing_ratio.extent(0);
19  const int nlay = mixing_ratio.extent(1);
20  Kokkos::parallel_for(Kokkos::MDRangePolicy<Kokkos::Rank<2>>({0, 0}, {ncol, nlay}),
21  KOKKOS_LAMBDA (int icol, int ilay)
22  {
23  // Compute in-cloud mixing ratio (mixing ratio of the cloudy part of the layer)
24  // NOTE: these thresholds (from E3SM) seem arbitrary, but included here for consistency
25  // This limits in-cloud mixing ratio to 0.005 kg/kg. According to note in cloud_diagnostics
26  // in EAM, this is consistent with limits in MG2. Is this true for P3?
27  if (cloud_fraction(icol,ilay) > 0) {
28  // Compute layer-integrated cloud mass (per unit area)
29  auto incloud_mixing_ratio = std::min(mixing_ratio(icol,ilay) /
30  std::max(0.0001, cloud_fraction(icol,ilay)), 0.005);
31  cloud_mass(icol,ilay) = incloud_mixing_ratio * rho(icol,ilay) * dz(icol,ilay);
32  } else {
33  cloud_mass(icol,ilay) = 0;
34  }
35  });
36 }
37 
38 // 1D limiting
39 template<typename InT, typename OutT, typename T>
40 void
41 limit_to_bounds_1d (InT const& arr_in,
42  T const lower ,
43  T const upper ,
44  OutT& arr_out)
45 {
46  Kokkos::parallel_for(arr_out.size(), KOKKOS_LAMBDA(int i)
47  {
48  arr_out(i) = std::min(std::max(arr_in(i), lower), upper);
49  });
50 }
51 
52 // 2D limiting
53 template<typename InT, typename OutT, typename T>
54 void
55 limit_to_bounds_2d (InT const& arr_in,
56  T const lower ,
57  T const upper ,
58  OutT& arr_out)
59 {
60  const int ex0 = (int) arr_out.extent(0);
61  const int ex1 = (int) arr_out.extent(1);
62  Kokkos::parallel_for(Kokkos::MDRangePolicy<Kokkos::Rank<2>>({0, 0}, {ex0, ex1}),
63  KOKKOS_LAMBDA (int i, int j)
64  {
65  arr_out(i, j) = std::min(std::max(arr_in(i, j), lower), upper);
66  });
67 }
68 
69 // Provide a routine to compute heating due to radiative fluxes. This is
70 // computed as net flux into a layer, converted to a heating rate. It is
71 // the responsibility of the user to ensure fields are passed with the
72 // proper units. I.e., pressure at level interfaces should be in Pa,
73 // fluxes in W m-2, Cpair in J kg-1 K-1, gravit in m s-2. This will give
74 // heating in units of K s-1.
75 // TODO: we should probably update this to use the pseudo-density pdel instead
76 // of approximating pdel by differencing the level interface pressures.
77 // We are leaving this for the time being for consistency with SCREAMv0,
78 // from which this code was directly ported.
79 template<class View1, class View2, class View3, class View4, class View5>
80 void
81 compute_heating_rate (View1 const& flux_up,
82  View2 const& flux_dn,
83  View3 const& rho ,
84  View4 const& dz ,
85  View5& heating_rate)
86 {
87  const int ncol = (int)flux_up.extent(0);
88  const int nlay = (int)flux_up.extent(1)-1;
89  Kokkos::parallel_for(Kokkos::MDRangePolicy<Kokkos::Rank<2>>({0, 0}, {ncol, nlay}),
90  KOKKOS_LAMBDA (int icol, int ilay)
91  {
92  heating_rate(icol,ilay) = ( flux_up(icol,ilay+1) - flux_up(icol,ilay)
93  - flux_dn(icol,ilay+1) + flux_dn(icol,ilay) )
94  / ( -rho(icol,ilay) * dz(icol,ilay) * Cp_d );
95  });
96 }
97 
98 
99 inline
100 bool
101 radiation_do (const int irad,
102  const int nstep)
103 {
104  // If irad == 0, then never do radiation;
105  // Otherwise, we always call radiation at the first step,
106  // and afterwards we do radiation if the timestep is divisible
107  // by irad
108  if (irad == 0) {
109  return false;
110  } else {
111  return ( (nstep == 0) || (nstep % irad == 0) );
112  }
113 }
114 
115 
116 }// namespace rrtmgp
117 #endif
constexpr amrex::Real Cp_d
Definition: ERF_Constants.H:12
@ rho
Definition: ERF_Kessler.H:22
@ T
Definition: ERF_IndexDefines.H:110
Definition: ERF_RRTMGP_Interface.cpp:16
bool radiation_do(const int irad, const int nstep)
Definition: ERF_RRTMGP_Utils.H:101
void limit_to_bounds_2d(InT const &arr_in, T const lower, T const upper, OutT &arr_out)
Definition: ERF_RRTMGP_Utils.H:55
void mixing_ratio_to_cloud_mass(View1 const &mixing_ratio, View2 const &cloud_fraction, View3 const &rho, View4 const &dz, View5 const &cloud_mass)
Definition: ERF_RRTMGP_Utils.H:12
void compute_heating_rate(View1 const &flux_up, View2 const &flux_dn, View3 const &rho, View4 const &dz, View5 &heating_rate)
Definition: ERF_RRTMGP_Utils.H:81
void limit_to_bounds_1d(InT const &arr_in, T const lower, T const upper, OutT &arr_out)
Definition: ERF_RRTMGP_Utils.H:41