ERF
Energy Research and Forecasting: An Atmospheric Modeling Code
ERF_TerminalVelocity.H
Go to the documentation of this file.
1 #ifndef TERMINALVELOCITY_H
2 #define TERMINALVELOCITY_H
3 
4 #include <cmath>
5 #include <AMReX_Gpu.H>
6 #include "ERF_Constants.H"
7 
8 template <typename RT /*!< real-type */>
10 {
11  RT m_rho_w; /*!< density of water */
12 
13  /*! \brief Compute viscosity coefficient - Pruppacher & Klett, 1997*/
14  AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
15  auto viscCoeff( const RT a_T /*!< temperature [K] */ ) const noexcept
16  {
17  RT T_degC = a_T - RT(273.15); // [K] -> [deg Celsius]
18  RT viscosity = RT(0.0);
19  if (T_degC >= RT(0)) {
20  viscosity = (RT(1.7180) + RT(4.9e-3)*T_degC) * RT(1.0e-4);
21  } else {
22  viscosity = ( RT(1.7180) + RT(4.9e-3)*T_degC
23  - RT(1.2e-5)*T_degC*T_degC ) * RT(1.0e-4);
24  }
25  return viscosity;
26  }
27 
28  /*! \brief Terminal velocity - Rogers & Yau, 1989 */
29  AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
30  RT RogersYau( const RT a_r) const noexcept
31  {
32  static const RT k1 = RT(1.233e8); // m^{-1} s^{-1}
33  return (k1 * a_r * a_r);
34  }
35 
36  /*! \brief Terminal velocity - Atlas & Ulbrich, 1977 */
37  AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
38  RT AtlasUlbrich( const RT a_r) const noexcept
39  {
40  static const RT a = RT(3.778);
41  static const RT b = RT(0.67);
42  RT D = RT(2)*a_r*RT(1000); // meter -> mm
43  return a*(std::exp(b*std::log(D)));
44  }
45 
46  /* The following code is adapted from SCALE-SDM:
47  * Copyright (c) 2012-2014, Team SCALE, All rights reserved. */
48  /*! \brief Terminal velocity - cloud/rain droplets
49  Shima et al., 2009, "The super-droplet method for the numerical simulation of clouds and
50  precipitation: A particle-based and probabilistic microphysics model coupled with a non-
51  hydrostatic model." Quart. J. Roy. Meteorol. Soc., 135: 1307-1320
52  https://github.com/Shima-Lab/SCALE-SDM_BOMEX_Sato2018/blob/master/contrib/SDM/sdm_motion.f90 */
53  AMREX_GPU_HOST_DEVICE
54  RT CloudRainShima ( const RT a_r, /*!< radius */
55  const RT a_rho, /*!< density */
56  const RT a_P, /*!< pressure */
57  const RT a_T /*!< temperature */) const noexcept
58  {
59  RT lb4l = RT(6.62E-6); // base length[cm] for mean free path of air molecules
60  RT visb4l = RT(1.818E-4); // base dynamic viscosity[g/(cm*s)] for mean free path of air molecules
61  RT pb4l = RT(1013.25); // base pressure[hPa] for mean free path of air molecules
62  RT tb4l = RT(293.15); // base temperature[20C] for mean free path of air molecules
63 
64  RT P_hPa = a_P / RT(100.0); // [Pa] -> [hPa]
65  RT diameter_cm = RT(2.0)*a_r*RT(100.0); // [m] -> [cm]
66  RT rho_mat_cgs = m_rho_w/RT(1000.0); // [kg/m^3] -> [g/cm^3]
67  RT rho_air_cgs = a_rho/RT(1000.0); // [kg/m^3] -> [g/cm^3]
68  RT grav_cgs = CONST_GRAV * RT(100); // [m/s^2] -> [cm/s^2]
69 
70  RT gxdrow = grav_cgs * ( rho_mat_cgs - rho_air_cgs );
71 
72  RT viscosity = viscCoeff(a_T);
73 
74  RT v_terminal = RT(0.0);
75  if (diameter_cm < RT(1.9e-3)) {
76  // small cloud droplets
77  RT sd_l = lb4l * (viscosity/visb4l) * (pb4l/P_hPa) * std::sqrt(a_T/tb4l);
78  RT c1 = gxdrow / (RT(18.0)*viscosity);
79  RT csc = RT(1.0) + RT(2.510) * (sd_l/diameter_cm);
80  v_terminal = c1 * csc * diameter_cm * diameter_cm;
81  } else if (diameter_cm < RT(1.07e-1)) {
82  // large cloud droplets and small raindrops
83  RT sd_l = lb4l * (viscosity/visb4l) * (pb4l/P_hPa) * std::sqrt(a_T/tb4l);
84  RT c2 = rho_air_cgs * (RT(4.0)*gxdrow)/(RT(three)*viscosity*viscosity);
85  RT nda = c2 * diameter_cm * diameter_cm * diameter_cm;
86  RT csc = RT(1.0) + RT(2.510) * ( sd_l / diameter_cm );
87  RT nre = csc * std::exp(vz_b_x(std::log(nda)));
88  v_terminal = (viscosity*nre)/(rho_air_cgs*diameter_cm);
89  } else {
90  // large raindrops
91  RT tau = RT(1.0) - a_T/RT(647.0960);
92  RT sigma = RT(0.2358) * std::exp( RT(1.2560)*std::log(tau) )
93  * ( RT(1.0) - RT(0.6250)*tau );
94  if( a_T<RT(267.5) ) {
95  tau = std::tanh( (a_T-RT(243.9))/RT(35.35) );
96  sigma = sigma - RT(2.854E-3) * tau + RT(1.666E-3);
97  }
98  sigma = sigma * RT(1.E+3); // N/m => g/s^2
99  RT c3 = (RT(4.0)*gxdrow)/(RT(three)*sigma);
100  RT bond = c3 * diameter_cm * diameter_cm;
101  RT npp = (rho_air_cgs*rho_air_cgs) * (sigma*sigma*sigma)
102  / (gxdrow*viscosity*viscosity*viscosity*viscosity);
103  npp = std::exp( std::log(npp)/RT(6.0) );
104  RT nre = npp * std::exp(vz_c_x(std::log(bond*npp)));
105  v_terminal = (viscosity*nre)/(rho_air_cgs*diameter_cm);
106  }
107 
108  v_terminal /= RT(100.0); // [cm/s] -> [m/s]
109  return v_terminal;
110  }
111 
112  /* The following code is adapted from SCALE-SDM:
113  * Copyright (c) 2012-2014, Team SCALE, All rights reserved. */
114  /*! \brief Compute vz_b(x) */
115  AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
116  RT vz_b_x ( const RT a_x /*!< x */) const noexcept
117  {
118  RT x1 = a_x;
119  RT x2 = x1 * x1;
120  RT x3 = x1 * x2;
121  RT y = - RT(0.318657E+1)
122  + RT(0.9926960) * x1
123  - RT(0.153193E-2) * x2
124  - RT(0.987059E-3) * x3
125  - RT(0.578878e-3) * x2*x2
126  + RT(0.855176E-4) * x3*x2
127  - RT(0.327815E-5) * x3*x3;
128  return y;
129  }
130 
131  /*! \brief Compute vc_b(x) */
132  AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
133  RT vz_c_x ( const RT a_x /*!< x */) const noexcept
134  {
135  RT x1 = a_x;
136  RT x2 = x1 * x1;
137  RT x3 = x1 * x2;
138  RT y = - RT(0.500015E+1)
139  + RT(0.523778E+1) * x1
140  - RT(0.204914E+1) * x2
141  + RT(0.47529400) * x3
142  - RT(0.542819E-1) * x2*x2
143  + RT(0.238449E-2) * x3*x2;
144  return y;
145  }
146 
147 };
148 
149 #endif
constexpr amrex::Real three
Definition: ERF_Constants.H:9
constexpr amrex::Real CONST_GRAV
Definition: ERF_Constants.H:32
amrex::Real sigma
Definition: ERF_InitCustomPert_DataAssimilation_ISV.H:11
real(c_double), parameter c2
Definition: ERF_module_model_constants.F90:35
real(c_double), private k1
Definition: ERF_module_mp_morr_two_moment.F90:213
real(c_double), private c1
Definition: ERF_module_mp_morr_two_moment.F90:212
Definition: ERF_TerminalVelocity.H:10
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE RT vz_b_x(const RT a_x) const noexcept
Compute vz_b(x)
Definition: ERF_TerminalVelocity.H:116
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE RT RogersYau(const RT a_r) const noexcept
Terminal velocity - Rogers & Yau, 1989.
Definition: ERF_TerminalVelocity.H:30
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE RT vz_c_x(const RT a_x) const noexcept
Compute vc_b(x)
Definition: ERF_TerminalVelocity.H:133
RT m_rho_w
Definition: ERF_TerminalVelocity.H:11
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE auto viscCoeff(const RT a_T) const noexcept
Compute viscosity coefficient - Pruppacher & Klett, 1997.
Definition: ERF_TerminalVelocity.H:15
AMREX_GPU_HOST_DEVICE RT CloudRainShima(const RT a_r, const RT a_rho, const RT a_P, const RT a_T) const noexcept
Terminal velocity - cloud/rain droplets Shima et al., 2009, "The super-droplet method for the numeric...
Definition: ERF_TerminalVelocity.H:54
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE RT AtlasUlbrich(const RT a_r) const noexcept
Terminal velocity - Atlas & Ulbrich, 1977.
Definition: ERF_TerminalVelocity.H:38