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
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
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
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  return p_loc / (R_d * rho * (1.0 + R_v/R_d*qv));
52 }
53 
54 /**
55  * Function to return potential temperature given density and temperature
56  *
57  * @params[in ] rho density
58  * @params[in ] T temperature
59  * @params[in ] rdOcp ratio of R_d to c_p
60  * @params[in ] qv water vapor
61  * @params[ out] potential temperature
62 */
63 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
65 {
66  // p = rho_d * R_d * T_moist
67  amrex::Real p_loc = rho * R_d * T * (1.0 + R_v/R_d*qv);
68 
69  // theta_d = T * (p0/p)^(R_d/C_p)
70  return T * std::pow((p_0/p_loc),rdOcp);
71 }
72 
73 /**
74  * Function to return pressure given density times theta
75  *
76  * @params[in ] rhotheta density times potential temperature
77  * @params[in ] qv water vapor
78  * @params[ out] pressure
79 */
80 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
81 amrex::Real getPgivenRTh(const amrex::Real rhotheta, const amrex::Real qv = 0.)
82 {
83  return p_0 * std::pow(R_d * rhotheta * ( amrex::Real(1.0) + (R_v/R_d)*qv) * ip_0, Gamma);
84 }
85 
86 /**
87  * Function to return density given theta and pressure
88  *
89  * @params[in ] theta potential temperature
90  * @params[in ] p pressure
91  * @params[in ] rdOcp ratio of R_d to c_p
92  * @params[in ] qv water vapor
93  * @params[ out] density
94 */
95 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
97 {
98  // We should be using moist value of theta when using moisture
99  // theta_m = theta * (1 + R_v/R_d*qv)
100  return std::pow(p_0, rdOcp) * std::pow(p, iGamma) / (R_d * th * (amrex::Real(1.0) + R_v/R_d*qv) );
101 }
102 
103 /**
104  * Function to return density given temperature and pressure
105  *
106  * @params[in ] theta potential temperature
107  * @params[in ] p pressure
108  * @params[in ] rdOcp ratio of R_d to c_p
109  * @params[in ] qv water vapor
110  * @params[ out] density
111 */
112 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
114 {
115  return p / ( R_d * T * (amrex::Real(1.0) + (R_v/R_d)*qv) );
116 }
117 
118 /**
119  * Function to return dP/drho at constant theta
120  *
121  * @params[in ] rho density
122  * @params[in ] theta potential temperature
123  * @params[in ] qv water vapor
124  * @params[ out] pressure
125 */
126 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
128 {
129  // We should be using moist value of theta when using moisture
130  // theta_m = theta * (1 + R_v/R_d*qv)
131  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) ;
132 }
133 
134 /**
135  * Function to return the Exner function pi given pressure
136  * @params[in ] p pressure
137  * @params[in ] rdOcp ratio of R_d to c_p
138  * @params[ out] Exner function
139 */
140 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
142 {
143  // Exner function pi in terms of P
144  return std::pow(P * ip_0, rdOcp);
145 }
146 
147 /**
148  * Function to return the Exner function pi given density times potential temperature
149  *
150  * @params[in ] rhotheta density times potential temperature
151  * @params[in ] rdOcp ratio of R_d to c_p
152  * @params[in ] qv water vapor
153  * @params[ out] Exner function
154 */
155 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
156 amrex::Real getExnergivenRTh(const amrex::Real rhotheta, const amrex::Real rdOcp, const amrex::Real qv=0.0 )
157 {
158  // Exner function pi in terms of (rho theta)
159  // We should be using moist value of theta when using moisture
160  // theta_m = theta * (1 + R_v/R_d*qv)
161  return std::pow(R_d * rhotheta * (1.0 + R_v/R_d*qv) * ip_0, Gamma * rdOcp);
162 }
163 
164 /**
165  * Function to return (rho theta) given pressure
166  *
167  * @params[in ] p pressure
168  * @params[in ] qv water vapor
169  * @params[ out] density times potential temperature
170 */
171 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
173 {
174  // diagnostic relation for the full pressure
175  // see https://erf.readthedocs.io/en/latest/theory/NavierStokesEquations.html
176  // For cases with moisture, theta = theta_m / (1 + R_v/R_d*qv)
177  return std::pow(p*std::pow(p_0, Gamma-1), iGamma) * iR_d / (1.0 + R_v/R_d*qv) ;
178 }
179 
180 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
182 {
183  return p_s*RH;
184 }
185 
186 #endif
187 
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:81
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:156
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:181
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real getRhoThetagivenP(const amrex::Real p, const amrex::Real qv=0.0)
Definition: ERF_EOS.H:172
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:96
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 getThgivenTandP(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 getdPdRgivenConstantTheta(const amrex::Real rho, const amrex::Real theta, const amrex::Real qv=0.0)
Definition: ERF_EOS.H:127
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real getExnergivenP(const amrex::Real P, const amrex::Real rdOcp)
Definition: ERF_EOS.H:141
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:64
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:113
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
amrex::Real Real
Definition: ERF_ShocInterface.H:16
@ theta
Definition: ERF_MM5.H:20
@ rho
Definition: ERF_Kessler.H:22
@ qv
Definition: ERF_Kessler.H:28
@ T
Definition: ERF_IndexDefines.H:110