ERF
Energy Research and Forecasting: An Atmospheric Modeling Code
ERF_EOS.H
Go to the documentation of this file.
1 #ifndef ERF_EOS_H_
2 #define ERF_EOS_H_
3 #include <ERF_Constants.H>
4 #include <AMReX.H>
5 #include <AMReX_IntVect.H>
6 #include <AMReX_MFIter.H>
7 #include <cmath>
8 
9 /**
10  * Function to return potential temperature given pressure and temperature
11  *
12  * @params[in ] P pressure
13  * @params[in ] T temperature
14  * @params[in ] rdOcp ratio of R_d to c_p
15  * @params[ out] potential temperature
16 */
17 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
18 amrex::Real getThgivenPandT(const amrex::Real T, const amrex::Real P, const amrex::Real rdOcp)
19 {
20  return T * std::pow(p_0/P, rdOcp);
21 }
22 
23 /**
24  * Function to return temperature given pressure and potential temperature
25  *
26  * @params[in ] P pressure
27  * @params[in ] th potential temperature
28  * @params[in ] rdOcp ratio of R_d to c_p
29  * @params[ out] temperature
30 */
31 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
32 amrex::Real getTgivenPandTh(const amrex::Real P, const amrex::Real th, const amrex::Real rdOcp)
33 {
34  return th / std::pow(p_0/P, rdOcp);
35 }
36 
37 /**
38  * Function to return temperature given density and potential temperature
39  *
40  * @params[in ] rho density
41  * @params[in ] rhotheta (density times potential temperature)
42  * @params[in ] qv water vapor
43  * @params[ out] temperature
44 */
45 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
46 amrex::Real getTgivenRandRTh(const amrex::Real rho, const amrex::Real rhotheta, const amrex::Real qv=0.0)
47 {
48  // rho and rhotheta are dry values. We should be using moist value of theta when using moisture
49  // theta_m = theta * (1 + R_v/R_d*qv)
50  amrex::Real p_loc = p_0 * std::pow(R_d * rhotheta * (1.0 + R_v/R_d*qv) * ip_0, Gamma);
51 
52  // p = rho_d * R_d * T_v (not T)
53  // T_v = T * (1 + R_v/R_d*qv)
54  return p_loc / (R_d * rho * (1.0 + R_v/R_d*qv) );
55 }
56 
57 /**
58  * Function to return potential temperature given density and temperature
59  *
60  * @params[in ] rho density
61  * @params[in ] T temperature
62  * @params[in ] rdOcp ratio of R_d to c_p
63  * @params[in ] qv water vapor
64  * @params[ out] potential temperature
65 */
66 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
67 amrex::Real getThgivenRandT(const amrex::Real rho, const amrex::Real T, const amrex::Real rdOcp, const amrex::Real qv=0.0)
68 {
69  // p = rho_d * R_d * T_moist
70  amrex::Real p_loc = rho * R_d * T * (1.0 + R_v/R_d*qv);
71 
72  // theta_d = T * (p0/p)^(R_d/C_p)
73  return T * std::pow((p_0/p_loc),rdOcp);
74 }
75 
76 /**
77  * Function to return pressure given density times theta
78  *
79  * @params[in ] rhotheta density times potential temperature
80  * @params[in ] qv water vapor
81  * @params[ out] pressure
82 */
83 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
84 amrex::Real getPgivenRTh(const amrex::Real rhotheta, const amrex::Real qv = 0.)
85 {
86  return p_0 * std::pow(R_d * rhotheta * ( amrex::Real(1.0) + (R_v/R_d)*qv) * ip_0, Gamma);
87 }
88 
89 /**
90  * Function to return density given theta and pressure
91  *
92  * @params[in ] theta potential temperature
93  * @params[in ] p pressure
94  * @params[in ] rdOcp ratio of R_d to c_p
95  * @params[in ] qv water vapor
96  * @params[ out] density
97 */
98 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
99 amrex::Real getRhogivenThetaPress (const amrex::Real th, const amrex::Real p, const amrex::Real rdOcp, const amrex::Real qv=0.0)
100 {
101  // We should be using moist value of theta when using moisture
102  // theta_m = theta * (1 + R_v/R_d*qv)
103  return std::pow(p_0, rdOcp) * std::pow(p, iGamma) / (R_d * th * (amrex::Real(1.0) + R_v/R_d*qv) );
104 }
105 
106 /**
107  * Function to return density given temperature and pressure
108  *
109  * @params[in ] theta potential temperature
110  * @params[in ] p pressure
111  * @params[in ] rdOcp ratio of R_d to c_p
112  * @params[in ] qv water vapor
113  * @params[ out] density
114 */
115 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
116 amrex::Real getRhogivenTandPress (const amrex::Real T, const amrex::Real p, const amrex::Real qv=0.0)
117 {
118  return p / ( R_d * T * (amrex::Real(1.0) + (R_v/R_d)*qv) );
119 }
120 
121 /**
122  * Function to return dP/drho at constant theta
123  *
124  * @params[in ] rho density
125  * @params[in ] theta potential temperature
126  * @params[in ] qv water vapor
127  * @params[ out] pressure
128 */
129 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
130 amrex::Real getdPdRgivenConstantTheta(const amrex::Real rho, const amrex::Real theta, const amrex::Real qv=0.0)
131 {
132  // We should be using moist value of theta when using moisture
133  // theta_m = theta * (1 + R_v/R_d*qv)
134  return Gamma * p_0 * std::pow( (R_d * theta * (amrex::Real(1.0) + R_v/R_d*qv) * ip_0), Gamma) * std::pow(rho, Gamma-1.0) ;
135 }
136 
137 /**
138  * Function to return the Exner function pi given pressure
139  * @params[in ] p pressure
140  * @params[in ] rdOcp ratio of R_d to c_p
141  * @params[ out] Exner function
142 */
143 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
144 amrex::Real getExnergivenP(const amrex::Real P, const amrex::Real rdOcp)
145 {
146  // Exner function pi in terms of P
147  return std::pow(P * ip_0, rdOcp);
148 }
149 
150 /**
151  * Function to return the Exner function pi given density times potential temperature
152  *
153  * @params[in ] rhotheta density times potential temperature
154  * @params[in ] rdOcp ratio of R_d to c_p
155  * @params[in ] qv water vapor
156  * @params[ out] Exner function
157 */
158 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
159 amrex::Real getExnergivenRTh(const amrex::Real rhotheta, const amrex::Real rdOcp, const amrex::Real qv=0.0 )
160 {
161  // Exner function pi in terms of (rho theta)
162  // We should be using moist value of theta when using moisture
163  // theta_m = theta * (1 + R_v/R_d*qv)
164  return std::pow(R_d * rhotheta * (1.0 + R_v/R_d*qv) * ip_0, Gamma * rdOcp);
165 }
166 
167 /**
168  * Function to return (rho theta) given pressure
169  *
170  * @params[in ] p pressure
171  * @params[in ] qv water vapor
172  * @params[ out] density times potential temperature
173 */
174 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
175 amrex::Real getRhoThetagivenP(const amrex::Real p, const amrex::Real qv=0.0)
176 {
177  // diagnostic relation for the full pressure
178  // see https://erf.readthedocs.io/en/latest/theory/NavierStokesEquations.html
179  // For cases with moisture, theta = theta_m / (1 + R_v/R_d*qv)
180  return std::pow(p*std::pow(p_0, Gamma-1), iGamma) * iR_d / (1.0 + R_v/R_d*qv) ;
181 }
182 
183 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
184 amrex::Real compute_vapor_pressure (const amrex::Real p_s, const amrex::Real RH)
185 {
186  return p_s*RH;
187 }
188 
189 #endif
190 
constexpr amrex::Real R_v
Definition: ERF_Constants.H:11
constexpr amrex::Real iR_d
Definition: ERF_Constants.H:25
constexpr amrex::Real ip_0
Definition: ERF_Constants.H:24
constexpr amrex::Real p_0
Definition: ERF_Constants.H:18
constexpr amrex::Real iGamma
Definition: ERF_Constants.H:26
constexpr amrex::Real R_d
Definition: ERF_Constants.H:10
constexpr amrex::Real Gamma
Definition: ERF_Constants.H:19
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real getPgivenRTh(const amrex::Real rhotheta, const amrex::Real qv=0.)
Definition: ERF_EOS.H:84
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real getExnergivenRTh(const amrex::Real rhotheta, const amrex::Real rdOcp, const amrex::Real qv=0.0)
Definition: ERF_EOS.H:159
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real compute_vapor_pressure(const amrex::Real p_s, const amrex::Real RH)
Definition: ERF_EOS.H:184
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real getRhoThetagivenP(const amrex::Real p, const amrex::Real qv=0.0)
Definition: ERF_EOS.H:175
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real getRhogivenThetaPress(const amrex::Real th, const amrex::Real p, const amrex::Real rdOcp, const amrex::Real qv=0.0)
Definition: ERF_EOS.H:99
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real getTgivenRandRTh(const amrex::Real rho, const amrex::Real rhotheta, const amrex::Real qv=0.0)
Definition: ERF_EOS.H:46
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real getdPdRgivenConstantTheta(const amrex::Real rho, const amrex::Real theta, const amrex::Real qv=0.0)
Definition: ERF_EOS.H:130
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real getExnergivenP(const amrex::Real P, const amrex::Real rdOcp)
Definition: ERF_EOS.H:144
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real getThgivenPandT(const amrex::Real T, const amrex::Real P, const amrex::Real rdOcp)
Definition: ERF_EOS.H:18
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real getThgivenRandT(const amrex::Real rho, const amrex::Real T, const amrex::Real rdOcp, const amrex::Real qv=0.0)
Definition: ERF_EOS.H:67
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real getRhogivenTandPress(const amrex::Real T, const amrex::Real p, const amrex::Real qv=0.0)
Definition: ERF_EOS.H:116
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real getTgivenPandTh(const amrex::Real P, const amrex::Real th, const amrex::Real rdOcp)
Definition: ERF_EOS.H:32
@ theta
Definition: ERF_MM5.H:20
@ rho
Definition: ERF_Kessler.H:30
@ qv
Definition: ERF_Kessler.H:36
@ T
Definition: ERF_IndexDefines.H:99