ERF
Energy Research and Forecasting: An Atmospheric Modeling Code
ERF_StormDiagnostics.H
Go to the documentation of this file.
1 #ifndef ERF_STORM_DIAGNOSTICS_H_
2 #define ERF_STORM_DIAGNOSTICS_H_
3 
4 #include "ERF_DataStruct.H"
5 
6 /**
7  * Routines to compute strom diagnostics
8  */
9 
10 
11 AMREX_GPU_HOST_DEVICE
12 AMREX_FORCE_INLINE
14  amrex::Real qra, amrex::Real qsn, amrex::Real qgr,
15  int in0r, int in0s, int in0g, int iliqskin)
16 {
17  using namespace amrex;
18 
19  // Negative mixing ratios contribute nothing; the fractional powers below would give NaN
20  qra = std::max(qra, Real(0.0));
21  qsn = std::max(qsn, Real(0.0));
22  qgr = std::max(qgr, Real(0.0));
23 
24  // ----------------------------------------------------------------
25  // Constants
26  // ----------------------------------------------------------------
27  constexpr amrex::Real pi = Real(3.14159265358979323846);
28  constexpr amrex::Real rhowat = Real(1000.0); // liquid water density [kg/m^3]
29  constexpr amrex::Real rho_r = Real(1000.0); // rain
30  constexpr amrex::Real rho_s = Real(100.0); // snow
31  constexpr amrex::Real rho_g = Real(400.0); // graupel
32  constexpr amrex::Real celkel = Real(273.15); // 0°C in Kelvin
33  constexpr amrex::Real alpha = Real(0.224);
34  constexpr amrex::Real gamma_seven = Real(720.0);
35 
36  // Constant intercepts
37  constexpr amrex::Real rn0_r = Real(8.e6);
38  constexpr amrex::Real rn0_s = Real(2.e7);
39  constexpr amrex::Real rn0_g = Real(4.e6);
40 
41  // Variable intercept constants
42  constexpr amrex::Real r1 = Real(1.e-15);
43  constexpr amrex::Real ron2 = Real(1.e10);
44  constexpr amrex::Real gon = Real(5.e7);
45  constexpr amrex::Real ron_min = Real(8.e6);
46  constexpr amrex::Real ron_qr0 = Real(1.0e-4);
47  constexpr amrex::Real ron_delqr0 = fourth * ron_qr0;
48  constexpr amrex::Real ron_const1r = (ron2 - ron_min) * Real(0.5);
49  constexpr amrex::Real ron_const2r = (ron2 + ron_min) * Real(0.5);
50 
51  // Precompute factors
52  const amrex::Real factor_r = gamma_seven * Real(1.e18) * std::pow(one / (pi * rho_r), Real(1.75));
53  const amrex::Real factor_s = gamma_seven * Real(1.e18) * std::pow(one / (pi * rho_s), Real(1.75))
54  * std::pow(rho_s / rhowat, two) * alpha;
55  const amrex::Real factor_g = gamma_seven * Real(1.e18) * std::pow(one / (pi * rho_g), Real(1.75))
56  * std::pow(rho_g / rhowat, two) * alpha;
57 
58  // ----------------------------------------------------------------
59  // Adjust for bright band (liquid skin on frozen particles)
60  // ----------------------------------------------------------------
61  amrex::Real factorb_s = factor_s;
62  amrex::Real factorb_g = factor_g;
63  if (iliqskin == 1 && tmk > celkel) {
64  factorb_s = factor_s / alpha;
65  factorb_g = factor_g / alpha;
66  }
67 
68  // ----------------------------------------------------------------
69  // Variable intercepts
70  // ----------------------------------------------------------------
71  amrex::Real sonv = rn0_s;
72  if (in0s == 1) { // Thompson for snow
73  amrex::Real temp_c = std::min(-Real(0.001), tmk - celkel);
74  sonv = std::min(Real(2.0e8), Real(2.0e6) * std::exp(-Real(0.12) * temp_c));
75  }
76 
77  amrex::Real gonv = rn0_g;
78  if (in0g == 1) { // Thompson for graupel
79  if (qgr > r1) {
80  gonv = Real(2.38) * std::pow(pi * rho_g / (rho_air * qgr), Real(0.92));
81  gonv = std::max(Real(1.e4), std::min(gonv, gon));
82  }
83  }
84 
85  amrex::Real ronv = rn0_r;
86  if (in0r == 1) { // Thompson for rain
87  ronv = ron2;
88  if (qra > r1) {
89  ronv = ron_const1r * std::tanh((ron_qr0 - qra) / ron_delqr0) + ron_const2r;
90  }
91  }
92 
93  // ----------------------------------------------------------------
94  // Equivalent reflectivity factor Z_e [mm^6 m^-3]
95  // ----------------------------------------------------------------
96  amrex::Real z_e = factor_r * std::pow(rho_air * qra, Real(1.75)) / std::pow(ronv, Real(0.75))
97  + factorb_s * std::pow(rho_air * qsn, Real(1.75)) / std::pow(sonv, Real(0.75))
98  + factorb_g * std::pow(rho_air * qgr, Real(1.75)) / std::pow(gonv, Real(0.75));
99 
100  // Clamp small values
101  z_e = std::max(z_e, Real(0.01));
102 
103  // ----------------------------------------------------------------
104  // Convert to dBZ
105  // ----------------------------------------------------------------
106  return Real(10.0) * std::log10(z_e);
107 }
108 #endif
constexpr amrex::Real two
Definition: ERF_NumericalConstants.H:38
constexpr amrex::Real one
Definition: ERF_NumericalConstants.H:37
constexpr amrex::Real fourth
Definition: ERF_NumericalConstants.H:42
amrex::Real Real
Definition: ERF_ShocInterface.H:19
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real compute_max_reflectivity_dbz(amrex::Real rho_air, amrex::Real tmk, amrex::Real qra, amrex::Real qsn, amrex::Real qgr, int in0r, int in0s, int in0g, int iliqskin)
Definition: ERF_StormDiagnostics.H:13
@ alpha
Definition: ERF_SLM.H:151
Definition: ERF_ConsoleIO.cpp:17
real(c_double), parameter, private pi
Definition: ERF_module_mp_morr_two_moment.F90:100