ERF
Energy Research and Forecasting: An Atmospheric Modeling Code
ERF_MoistUtils.H
Go to the documentation of this file.
1 #ifndef ERF_MOISTUTILS_H_
2 #define ERF_MOISTUTILS_H_
3 
4 #include "ERF_EOS.H"
7 #include "ERF_Constants.H"
8 
9 // =============================================================================
10 // MOIST TURBULENCE FUNCTIONS
11 // =============================================================================
12 
13 /**
14  * Extract moisture variables and partition into liquid/ice phases
15  */
16 AMREX_GPU_DEVICE
17 AMREX_FORCE_INLINE
18 void GetMoistureVars (int i, int j, int k,
19  const amrex::Array4<amrex::Real const>& cell_data,
20  amrex::Real& qv,
21  amrex::Real& qc_liquid,
22  amrex::Real& qc_ice,
23  const MoistureComponentIndices& moisture_indices)
24 {
25  qv = zero; qc_liquid = zero; qc_ice = zero;
26 
27  // Water vapor
28  if (moisture_indices.qv >= 0) {
29  qv = cell_data(i,j,k,moisture_indices.qv)/cell_data(i,j,k,Rho_comp);
30  }
31 
32  // Cloud liquid water
33  if (moisture_indices.qc >= 0) {
34  qc_liquid = cell_data(i,j,k,moisture_indices.qc)/cell_data(i,j,k,Rho_comp);
35  }
36 
37  // Cloud ice (only if separate ice species exists)
38  if (moisture_indices.qi >= 0) {
39  qc_ice = cell_data(i,j,k,moisture_indices.qi)/cell_data(i,j,k,Rho_comp);
40  }
41  // No temperature-based partitioning - respect the microphysics scheme's decisions
42 
43  // Add precipitating species
44  if (moisture_indices.qr >= 0) { // Rain (always liquid)
45  qc_liquid += cell_data(i,j,k,moisture_indices.qr)/cell_data(i,j,k,Rho_comp);
46  }
47  if (moisture_indices.qs >= 0) { // Snow (always ice)
48  qc_ice += cell_data(i,j,k,moisture_indices.qs)/cell_data(i,j,k,Rho_comp);
49  }
50  if (moisture_indices.qg >= 0) { // Graupel (always ice)
51  qc_ice += cell_data(i,j,k,moisture_indices.qg)/cell_data(i,j,k,Rho_comp);
52  }
53 }
54 
55 /**
56  * Extract water vapor and the cloud condensate alone: cloud liquid qc and cloud ice qi, without
57  * the precipitating species (rain, snow, graupel) that GetMoistureVars adds in
58  */
59 AMREX_GPU_DEVICE
60 AMREX_FORCE_INLINE
61 void GetCloudMoistureVars (int i, int j, int k,
62  const amrex::Array4<amrex::Real const>& cell_data,
63  amrex::Real& qv,
64  amrex::Real& qc_liquid,
65  amrex::Real& qc_ice,
66  const MoistureComponentIndices& moisture_indices)
67 {
68  const amrex::Real rho = cell_data(i,j,k,Rho_comp);
69  qv = (moisture_indices.qv >= 0) ? cell_data(i,j,k,moisture_indices.qv) / rho : zero;
70  qc_liquid = (moisture_indices.qc >= 0) ? cell_data(i,j,k,moisture_indices.qc) / rho : zero;
71  qc_ice = (moisture_indices.qi >= 0) ? cell_data(i,j,k,moisture_indices.qi) / rho : zero;
72 }
73 
74 /**
75  * Compute virtual potential temperature with moisture loading effects
76  */
77 AMREX_GPU_DEVICE
78 AMREX_FORCE_INLINE
80  const amrex::Real& qv,
81  const amrex::Real& qc_liquid,
82  const amrex::Real& qc_ice)
83 {
84  amrex::Real qc_total = qc_liquid + qc_ice;
85  return theta * (one + epsv * qv - qc_total);
86 }
87 
88 /**
89  * Wrapper around ComputeVirtualPotentialTemperature
90  */
91 AMREX_GPU_DEVICE
92 AMREX_FORCE_INLINE
93 amrex::Real GetThetav (const int& i, const int& j, const int& k,
94  const amrex::Array4<amrex::Real const>& cell_data,
95  const MoistureComponentIndices& moisture_indices)
96 {
97  amrex::Real theta = cell_data(i, j, k, RhoTheta_comp) / cell_data(i, j, k, Rho_comp);
98 
100  GetMoistureVars(i, j, k, cell_data, qv, qcl, qci, moisture_indices);
101 
103 }
104 
105 /**
106  * Compute linearized liquid-ice water potential temperature,
107  * theta_l = theta - (theta / T) (L_v q_c + L_s q_i) / c_p
108  * from the cloud liquid q_c and cloud ice q_i (WRF's thlix in YSU)
109  */
110 AMREX_GPU_DEVICE
111 AMREX_FORCE_INLINE
113  const amrex::Real& T,
114  const amrex::Real& qc_liquid,
115  const amrex::Real& qc_ice)
116 {
117  return theta - (theta / T) * (L_v * qc_liquid + lsub * qc_ice) / Cp_d;
118 }
119 
120 /**
121  * Wrapper around ComputeLiquidWaterPotentialTemperature. theta_l is the variable conserved under
122  * reversible condensation, so it uses the cloud condensate only: precipitation falls out of the
123  * parcel and does not enter the latent-heat term (erf-model/ERF#4892)
124  */
125 AMREX_GPU_DEVICE
126 AMREX_FORCE_INLINE
127 amrex::Real GetThetal (const int& i, const int& j, const int& k,
128  const amrex::Array4<amrex::Real const>& cell_data,
129  const MoistureComponentIndices& moisture_indices)
130 {
131  amrex::Real qv, qcl, qci;
132  GetCloudMoistureVars(i, j, k, cell_data, qv, qcl, qci, moisture_indices);
133 
134  amrex::Real theta = cell_data(i, j, k, RhoTheta_comp) / cell_data(i, j, k, Rho_comp);
135 
136  amrex::Real T = getTgivenRandRTh(cell_data(i, j, k, Rho_comp),
137  cell_data(i, j, k, RhoTheta_comp),
138  qv);
139 
141 }
142 
143 #endif
constexpr amrex::Real epsv
Definition: ERF_Constants.H:56
constexpr amrex::Real Cp_d
Definition: ERF_Constants.H:51
constexpr amrex::Real L_v
Definition: ERF_Constants.H:67
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real getTgivenRandRTh(const amrex::Real rho, const amrex::Real rhotheta, const amrex::Real qv=amrex::Real(0))
Definition: ERF_EOS.H:46
#define Rho_comp
Definition: ERF_IndexDefines.H:53
#define RhoTheta_comp
Definition: ERF_IndexDefines.H:54
Physical constants and tuning parameters used only by the moisture and cloud-physics code.
constexpr amrex::Real lsub
Definition: ERF_MicrophysicsConstants.H:111
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real GetThetav(const int &i, const int &j, const int &k, const amrex::Array4< amrex::Real const > &cell_data, const MoistureComponentIndices &moisture_indices)
Definition: ERF_MoistUtils.H:93
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real ComputeVirtualPotentialTemperature(const amrex::Real &theta, const amrex::Real &qv, const amrex::Real &qc_liquid, const amrex::Real &qc_ice)
Definition: ERF_MoistUtils.H:79
AMREX_GPU_DEVICE AMREX_FORCE_INLINE void GetMoistureVars(int i, int j, int k, const amrex::Array4< amrex::Real const > &cell_data, amrex::Real &qv, amrex::Real &qc_liquid, amrex::Real &qc_ice, const MoistureComponentIndices &moisture_indices)
Definition: ERF_MoistUtils.H:18
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real ComputeLiquidWaterPotentialTemperature(const amrex::Real &theta, const amrex::Real &T, const amrex::Real &qc_liquid, const amrex::Real &qc_ice)
Definition: ERF_MoistUtils.H:112
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real GetThetal(const int &i, const int &j, const int &k, const amrex::Array4< amrex::Real const > &cell_data, const MoistureComponentIndices &moisture_indices)
Definition: ERF_MoistUtils.H:127
AMREX_GPU_DEVICE AMREX_FORCE_INLINE void GetCloudMoistureVars(int i, int j, int k, const amrex::Array4< amrex::Real const > &cell_data, amrex::Real &qv, amrex::Real &qc_liquid, amrex::Real &qc_ice, const MoistureComponentIndices &moisture_indices)
Definition: ERF_MoistUtils.H:61
constexpr amrex::Real one
Definition: ERF_NumericalConstants.H:37
constexpr amrex::Real zero
Definition: ERF_NumericalConstants.H:36
amrex::Real Real
Definition: ERF_ShocInterface.H:19
@ qcl
Definition: ERF_Kessler.H:32
@ rho
Definition: ERF_Kessler.H:25
@ theta
Definition: ERF_Kessler.H:26
@ qv
Definition: ERF_Kessler.H:31
@ qci
Definition: ERF_Morrison.H:39
@ T
Definition: ERF_IndexDefines.H:168
The moisture data carried by the active microphysics scheme.
Definition: ERF_DataStruct.H:251
int qs
snow
Definition: ERF_DataStruct.H:266
int qr
rain
Definition: ERF_DataStruct.H:265
int qi
cloud ice
Definition: ERF_DataStruct.H:264
int qv
water vapor
Definition: ERF_DataStruct.H:262
int qc
cloud liquid water
Definition: ERF_DataStruct.H:263
int qg
graupel
Definition: ERF_DataStruct.H:267