ERF
Energy Research and Forecasting: An Atmospheric Modeling Code
ERF_BuoyancyUtils.H
Go to the documentation of this file.
1 #ifndef ERF_BUOYANCY_UTILS_H_
2 #define ERF_BUOYANCY_UTILS_H_
3 
4 #include <ERF_EOS.H>
5 #include <ERF_Constants.H>
6 
7 AMREX_GPU_DEVICE
8 AMREX_FORCE_INLINE
10 buoyancy_dry_anelastic (int& i, int& j, int& k,
11  amrex::Real const& grav_gpu,
12  const amrex::Array4<const amrex::Real>& r0_arr,
13  const amrex::Array4<const amrex::Real>& th0_arr,
14  const amrex::Array4<const amrex::Real>& cell_data)
15 {
16  // Note: this is the same term as the moist anelastic buoyancy when qv = qc = qt = 0
17  amrex::Real theta_d_hi = cell_data(i,j,k ,RhoTheta_comp)/cell_data(i,j,k ,Rho_comp);
18  amrex::Real theta_d_lo = cell_data(i,j,k-1,RhoTheta_comp)/cell_data(i,j,k-1,Rho_comp);
19 
20  amrex::Real theta_d_wface = amrex::Real(0.5) * (theta_d_lo + theta_d_hi);
21  amrex::Real theta_d0_wface = amrex::Real(0.5) * (th0_arr(i,j,k) + th0_arr(i,j,k-1));
22  amrex::Real rho0_wface = amrex::Real(0.5) * (r0_arr(i,j,k) + r0_arr(i,j,k-1));
23 
24  return (-rho0_wface * grav_gpu * (theta_d_wface - theta_d0_wface) / theta_d0_wface);
25 }
26 
27 AMREX_GPU_DEVICE
28 AMREX_FORCE_INLINE
30 buoyancy_moist_anelastic (int& i, int& j, int& k,
31  amrex::Real const& grav_gpu,
32  amrex::Real const& rv_over_rd,
33  const amrex::Array4<const amrex::Real>& r0_arr,
34  const amrex::Array4<const amrex::Real>& th0_arr,
35  const amrex::Array4<const amrex::Real>& qv0_arr,
36  const amrex::Array4<const amrex::Real>& cell_data,
37  const amrex::Array4<const amrex::Real>& qt_arr)
38 {
39  amrex::Real Fact = (1.0 - rv_over_rd); // = -0.61
40 
41  amrex::Real th_d_hi = cell_data(i,j,k ,RhoTheta_comp)/cell_data(i,j,k ,Rho_comp);
42  amrex::Real th_d_lo = cell_data(i,j,k-1,RhoTheta_comp)/cell_data(i,j,k-1,Rho_comp);
43 
44  amrex::Real qv_hi = cell_data(i,j,k ,RhoQ1_comp) /cell_data(i,j,k ,Rho_comp);
45  amrex::Real qv_lo = cell_data(i,j,k-1,RhoQ1_comp) /cell_data(i,j,k-1,Rho_comp);
46 
47  amrex::Real qt_hi = qt_arr(i,j,k ) - qv_hi;
48  amrex::Real th_v_hi = th_d_hi * (1.0 - Fact*qt_hi - rv_over_rd*qt_hi);
49 
50  amrex::Real qt_lo = qt_arr(i,j,k-1) - qv_lo;
51  amrex::Real th_v_lo = th_d_lo * (1.0 - Fact*qt_lo - rv_over_rd*qt_lo);
52 
53  amrex::Real th_v0_hi = th0_arr(i,j,k ) * (1.0 - Fact*qv0_arr(i,j,k ));
54  amrex::Real th_v0_lo = th0_arr(i,j,k-1) * (1.0 - Fact*qv0_arr(i,j,k-1));
55 
56  amrex::Real qv0_hi = qv0_arr(i,j,k );
57  amrex::Real qv0_lo = qv0_arr(i,j,k-1);
58 
59  amrex::Real q_hi = (qv_hi-qv0_hi) - qt_hi + (th_v_hi - th_v0_hi) / th_v0_hi;
60  amrex::Real q_lo = (qv_lo-qv0_lo) - qt_lo + (th_v_lo - th_v0_lo) / th_v0_lo;
61 
62  amrex::Real qavg = amrex::Real(0.5) * (q_hi + q_lo);
63 
64  amrex::Real r0avg = amrex::Real(0.5) * (r0_arr(i,j,k) + r0_arr(i,j,k-1));
65 
66  return (-r0avg * grav_gpu * qavg);
67 }
68 
69 AMREX_GPU_DEVICE
70 AMREX_FORCE_INLINE
72 buoyancy_rhopert (int& i, int& j, int& k,
73  amrex::Real const& grav_gpu,
74  const amrex::Array4<const amrex::Real>& r0_arr,
75  const amrex::Array4<const amrex::Real>& cell_data,
76  const amrex::Array4<const amrex::Real>& qt_arr)
77 {
78  amrex::Real rhop_hi = cell_data(i,j,k ,Rho_comp) * (1.0 + qt_arr(i,j,k ))- r0_arr(i,j,k );
79  amrex::Real rhop_lo = cell_data(i,j,k-1,Rho_comp) * (1.0 + qt_arr(i,j,k-1))- r0_arr(i,j,k-1);
80  return( grav_gpu * amrex::Real(0.5) * ( rhop_hi + rhop_lo ) );
81 }
82 
83 AMREX_GPU_DEVICE
84 AMREX_FORCE_INLINE
86 buoyancy_rhopert_eb (int& i, int& j, int& k,
87  amrex::Real const& grav_gpu,
88  const amrex::Array4<const amrex::Real>& r0_arr,
89  const amrex::Array4<const amrex::Real>& cell_data,
90  const amrex::Array4<const amrex::Real>& qt_arr,
91  amrex::Array4<amrex::EBCellFlag const> const& flag)
92 {
93  amrex::Real buoyancy = 0.0;
94  if (flag(i,j,k).isRegular()) {
95  amrex::Real rhop_hi = cell_data(i,j,k ,Rho_comp) * (1.0 + qt_arr(i,j,k ))- r0_arr(i,j,k );
96  amrex::Real rhop_lo = cell_data(i,j,k-1,Rho_comp) * (1.0 + qt_arr(i,j,k-1))- r0_arr(i,j,k-1);
97  buoyancy = grav_gpu * amrex::Real(0.5) * ( rhop_hi + rhop_lo );
98  } else if (flag(i,j,k).isSingleValued()) {
99  if (flag(i,j,k-1).isCovered()) {
100  amrex::Real rhop_hihi = cell_data(i,j,k+1,Rho_comp) * (1.0 + qt_arr(i,j,k+1))- r0_arr(i,j,k+1);
101  amrex::Real rhop_hi = cell_data(i,j,k ,Rho_comp) * (1.0 + qt_arr(i,j,k ))- r0_arr(i,j,k );
102  buoyancy = grav_gpu * 0.5 * ( 3.0 * rhop_hi - rhop_hihi );
103  // buoyancy = grav_gpu * rhop_hi;
104  } else if (flag(i,j,k).isCovered()) {
105  amrex::Real rhop_lo = cell_data(i,j,k-1,Rho_comp) * (1.0 + qt_arr(i,j,k-1))- r0_arr(i,j,k-1);
106  amrex::Real rhop_lolo = cell_data(i,j,k-2,Rho_comp) * (1.0 + qt_arr(i,j,k-2))- r0_arr(i,j,k-2);
107  buoyancy = grav_gpu * 0.5 * ( 3.0 * rhop_lo - rhop_lolo );
108  // buoyancy = grav_gpu * rhop_lo;
109  } else {
110  amrex::Real rhop_hi = cell_data(i,j,k ,Rho_comp) * (1.0 + qt_arr(i,j,k ))- r0_arr(i,j,k );
111  amrex::Real rhop_lo = cell_data(i,j,k-1,Rho_comp) * (1.0 + qt_arr(i,j,k-1))- r0_arr(i,j,k-1);
112  buoyancy = grav_gpu * amrex::Real(0.5) * ( rhop_hi + rhop_lo );
113  }
114  }
115  return buoyancy;
116 }
117 
118 AMREX_GPU_DEVICE
119 AMREX_FORCE_INLINE
121 buoyancy_dry_Tpert (int& i, int& j, int& k,
122  amrex::Real const& grav_gpu,
123  amrex::Real const& rd_over_cp,
124  const amrex::Array4<const amrex::Real>& r0_arr,
125  const amrex::Array4<const amrex::Real>& p0_arr,
126  const amrex::Array4<const amrex::Real>& th0_arr,
127  const amrex::Array4<const amrex::Real>& cell_data)
128 {
129  amrex::Real t0_hi = getTgivenPandTh(p0_arr(i,j,k), th0_arr(i,j,k), rd_over_cp);
130  amrex::Real t_hi = getTgivenRandRTh(cell_data(i,j,k ,Rho_comp), cell_data(i,j,k ,RhoTheta_comp));
131 
132  amrex::Real t0_lo = getTgivenPandTh(p0_arr(i,j,k-1), th0_arr(i,j,k-1), rd_over_cp);
133  amrex::Real t_lo = getTgivenRandRTh(cell_data(i,j,k-1,Rho_comp), cell_data(i,j,k-1,RhoTheta_comp));
134 
135  amrex::Real tprime_hi = (t_hi-t0_hi)/t0_hi;
136  amrex::Real tprime_lo = (t_lo-t0_lo)/t0_lo;
137 
138  amrex::Real tp_avg = amrex::Real(0.5) * (tprime_hi + tprime_lo);
139  amrex::Real r0_avg = amrex::Real(0.5) * (r0_arr(i,j,k) + r0_arr(i,j,k-1));
140 
141  return ( -r0_avg * grav_gpu * tp_avg);
142 }
143 
144 AMREX_GPU_DEVICE
145 AMREX_FORCE_INLINE
147 buoyancy_dry_Thpert (int& i, int& j, int& k,
148  amrex::Real const& grav_gpu,
149  const amrex::Array4<const amrex::Real>& r0_arr,
150  const amrex::Array4<const amrex::Real>& th0_arr,
151  const amrex::Array4<const amrex::Real>& cell_prim)
152 {
153  amrex::Real thetaprime_hi = (cell_prim(i,j,k ,PrimTheta_comp) - th0_arr(i,j,k )) / th0_arr(i,j,k );
154  amrex::Real thetaprime_lo = (cell_prim(i,j,k-1,PrimTheta_comp) - th0_arr(i,j,k-1)) / th0_arr(i,j,k-1);
155 
156  amrex::Real thp_avg = amrex::Real(0.5) * (thetaprime_hi + thetaprime_lo);
157  amrex::Real r0_avg = amrex::Real(0.5) * (r0_arr(i,j,k) + r0_arr(i,j,k-1));
158 
159  return ( -r0_avg * grav_gpu * thp_avg);
160 }
161 
162 AMREX_GPU_DEVICE
163 AMREX_FORCE_INLINE
165 buoyancy_moist_Tpert (int& i, int& j, int& k,
166  const int& n_qstate,
167  amrex::Real const& grav_gpu,
168  amrex::Real const& rd_over_cp,
169  const amrex::Array4<const amrex::Real>& r0_arr,
170  const amrex::Array4<const amrex::Real>& th0_arr,
171  const amrex::Array4<const amrex::Real>& qv0_arr,
172  const amrex::Array4<const amrex::Real>& p0_arr,
173  const amrex::Array4<const amrex::Real>& cell_prim,
174  const amrex::Array4<const amrex::Real>& cell_data,
175  const amrex::Array4<const amrex::Real>& qt_arr)
176 {
177  amrex::Real qv_hi = (n_qstate >= 1) ? cell_prim(i,j,k ,PrimQ1_comp) : 0.0;
178  amrex::Real qv_lo = (n_qstate >= 1) ? cell_prim(i,j,k-1,PrimQ1_comp) : 0.0;
179 
180  amrex::Real t0_hi = getTgivenPandTh(p0_arr(i,j,k ), th0_arr(i,j,k ), rd_over_cp);
181  amrex::Real t0_lo = getTgivenPandTh(p0_arr(i,j,k-1), th0_arr(i,j,k-1), rd_over_cp);
182 
183  amrex::Real dt_hi = getTgivenRandRTh(cell_data(i,j,k ,Rho_comp), cell_data(i,j,k ,RhoTheta_comp), qv_hi) - t0_hi;
184  amrex::Real dt_lo = getTgivenRandRTh(cell_data(i,j,k-1,Rho_comp), cell_data(i,j,k-1,RhoTheta_comp), qv_lo) - t0_lo;
185 
186  amrex::Real qv0_hi = qv0_arr(i,j,k );
187  amrex::Real qv0_lo = qv0_arr(i,j,k-1);
188 
189  amrex::Real q_hi = amrex::Real(0.61) * (qv_hi-qv0_hi) - (qt_arr(i,j,k )-qv_hi) + dt_hi/t0_hi;
190  amrex::Real q_lo = amrex::Real(0.61) * (qv_lo-qv0_lo) - (qt_arr(i,j,k-1)-qv_lo) + dt_lo/t0_lo;
191 
192  amrex::Real qavg = amrex::Real(0.5) * (q_hi + q_lo);
193 
194  amrex::Real r0avg = amrex::Real(0.5) * (r0_arr(i,j,k) + r0_arr(i,j,k-1));
195 
196  return ( -r0avg * grav_gpu * qavg);
197 }
198 
199 AMREX_GPU_DEVICE
200 AMREX_FORCE_INLINE
202 buoyancy_moist_Thpert (int& i, int& j, int& k,
203  const int& n_qstate,
204  amrex::Real const& grav_gpu,
205  const amrex::Array4<const amrex::Real>& r0_arr,
206  const amrex::Array4<const amrex::Real>& th0_arr,
207  const amrex::Array4<const amrex::Real>& qv0_arr,
208  const amrex::Array4<const amrex::Real>& cell_prim,
209  const amrex::Array4<const amrex::Real>& qt_arr)
210 {
211  amrex::Real qv_hi = (n_qstate >= 1) ? cell_prim(i,j,k ,PrimQ1_comp) : 0.0;
212  amrex::Real qv_lo = (n_qstate >= 1) ? cell_prim(i,j,k-1,PrimQ1_comp) : 0.0;
213 
214  amrex::Real qt_hi = qt_arr(i,j,k ) - qv_hi;
215  amrex::Real qt_lo = qt_arr(i,j,k-1) - qv_lo;
216 
217  amrex::Real dth_hi = cell_prim(i,j,k ,PrimTheta_comp) - th0_arr(i,j,k );
218  amrex::Real dth_lo = cell_prim(i,j,k-1,PrimTheta_comp) - th0_arr(i,j,k-1);
219 
220  amrex::Real qv0_hi = qv0_arr(i,j,k );
221  amrex::Real qv0_lo = qv0_arr(i,j,k-1);
222 
223  amrex::Real q_hi = amrex::Real(0.61) * (qv_hi-qv0_hi) - qt_hi + dth_hi/th0_arr(i,j,k );
224  amrex::Real q_lo = amrex::Real(0.61) * (qv_lo-qv0_lo) - qt_lo + dth_lo/th0_arr(i,j,k-1);
225 
226  amrex::Real qavg = amrex::Real(0.5) * (q_hi + q_lo);
227 
228  amrex::Real r0avg = amrex::Real(0.5) * (r0_arr(i,j,k) + r0_arr(i,j,k-1));
229 
230  return ( -r0avg * grav_gpu * qavg);
231 }
232 
233 // **************************************************************************************
234 // Routines below this line are not currently used
235 // **************************************************************************************
236 
237 AMREX_GPU_DEVICE
238 AMREX_FORCE_INLINE
240 buoyancy_dry_anelastic_T (int& i, int& j, int& k,
241  amrex::Real const& grav_gpu,
242  amrex::Real const& rd_over_cp,
243  const amrex::Array4<const amrex::Real>& r0_arr,
244  const amrex::Array4<const amrex::Real>& p0_arr,
245  const amrex::Array4<const amrex::Real>& cell_data)
246 {
247  amrex::Real rt0_hi = getRhoThetagivenP(p0_arr(i,j,k));
248  amrex::Real t0_hi = getTgivenPandTh(p0_arr(i,j,k), rt0_hi/r0_arr(i,j,k), rd_over_cp);
249  amrex::Real t_hi = getTgivenPandTh(p0_arr(i,j,k), cell_data(i,j,k,RhoTheta_comp)/r0_arr(i,j,k), rd_over_cp);
250  amrex::Real q_hi = (t_hi-t0_hi)/t0_hi;
251 
252  amrex::Real rt0_lo = getRhoThetagivenP(p0_arr(i,j,k-1));
253  amrex::Real t0_lo = getTgivenPandTh(p0_arr(i,j,k-1), rt0_lo/r0_arr(i,j,k-1), rd_over_cp);
254  amrex::Real t_lo = getTgivenPandTh(p0_arr(i,j,k-1), cell_data(i,j,k-1,RhoTheta_comp)/r0_arr(i,j,k-1), rd_over_cp);
255  amrex::Real q_lo = (t_lo-t0_lo)/t0_lo;
256 
257  amrex::Real r0_q_avg = amrex::Real(0.5) * (r0_arr(i,j,k) * q_hi + r0_arr(i,j,k-1) * q_lo);
258  return (-r0_q_avg * grav_gpu);
259 }
260 
261 #endif
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real buoyancy_moist_anelastic(int &i, int &j, int &k, amrex::Real const &grav_gpu, amrex::Real const &rv_over_rd, const amrex::Array4< const amrex::Real > &r0_arr, const amrex::Array4< const amrex::Real > &th0_arr, const amrex::Array4< const amrex::Real > &qv0_arr, const amrex::Array4< const amrex::Real > &cell_data, const amrex::Array4< const amrex::Real > &qt_arr)
Definition: ERF_BuoyancyUtils.H:30
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real buoyancy_moist_Tpert(int &i, int &j, int &k, const int &n_qstate, amrex::Real const &grav_gpu, amrex::Real const &rd_over_cp, const amrex::Array4< const amrex::Real > &r0_arr, const amrex::Array4< const amrex::Real > &th0_arr, const amrex::Array4< const amrex::Real > &qv0_arr, const amrex::Array4< const amrex::Real > &p0_arr, const amrex::Array4< const amrex::Real > &cell_prim, const amrex::Array4< const amrex::Real > &cell_data, const amrex::Array4< const amrex::Real > &qt_arr)
Definition: ERF_BuoyancyUtils.H:165
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real buoyancy_moist_Thpert(int &i, int &j, int &k, const int &n_qstate, amrex::Real const &grav_gpu, const amrex::Array4< const amrex::Real > &r0_arr, const amrex::Array4< const amrex::Real > &th0_arr, const amrex::Array4< const amrex::Real > &qv0_arr, const amrex::Array4< const amrex::Real > &cell_prim, const amrex::Array4< const amrex::Real > &qt_arr)
Definition: ERF_BuoyancyUtils.H:202
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real buoyancy_dry_anelastic(int &i, int &j, int &k, amrex::Real const &grav_gpu, const amrex::Array4< const amrex::Real > &r0_arr, const amrex::Array4< const amrex::Real > &th0_arr, const amrex::Array4< const amrex::Real > &cell_data)
Definition: ERF_BuoyancyUtils.H:10
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real buoyancy_dry_Thpert(int &i, int &j, int &k, amrex::Real const &grav_gpu, const amrex::Array4< const amrex::Real > &r0_arr, const amrex::Array4< const amrex::Real > &th0_arr, const amrex::Array4< const amrex::Real > &cell_prim)
Definition: ERF_BuoyancyUtils.H:147
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real buoyancy_rhopert_eb(int &i, int &j, int &k, amrex::Real const &grav_gpu, const amrex::Array4< const amrex::Real > &r0_arr, const amrex::Array4< const amrex::Real > &cell_data, const amrex::Array4< const amrex::Real > &qt_arr, amrex::Array4< amrex::EBCellFlag const > const &flag)
Definition: ERF_BuoyancyUtils.H:86
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real buoyancy_dry_Tpert(int &i, int &j, int &k, amrex::Real const &grav_gpu, amrex::Real const &rd_over_cp, const amrex::Array4< const amrex::Real > &r0_arr, const amrex::Array4< const amrex::Real > &p0_arr, const amrex::Array4< const amrex::Real > &th0_arr, const amrex::Array4< const amrex::Real > &cell_data)
Definition: ERF_BuoyancyUtils.H:121
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real buoyancy_dry_anelastic_T(int &i, int &j, int &k, amrex::Real const &grav_gpu, amrex::Real const &rd_over_cp, const amrex::Array4< const amrex::Real > &r0_arr, const amrex::Array4< const amrex::Real > &p0_arr, const amrex::Array4< const amrex::Real > &cell_data)
Definition: ERF_BuoyancyUtils.H:240
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real buoyancy_rhopert(int &i, int &j, int &k, amrex::Real const &grav_gpu, const amrex::Array4< const amrex::Real > &r0_arr, const amrex::Array4< const amrex::Real > &cell_data, const amrex::Array4< const amrex::Real > &qt_arr)
Definition: ERF_BuoyancyUtils.H:72
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 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 getTgivenPandTh(const amrex::Real P, const amrex::Real th, const amrex::Real rdOcp)
Definition: ERF_EOS.H:32
#define PrimQ1_comp
Definition: ERF_IndexDefines.H:53
#define Rho_comp
Definition: ERF_IndexDefines.H:36
#define RhoTheta_comp
Definition: ERF_IndexDefines.H:37
#define PrimTheta_comp
Definition: ERF_IndexDefines.H:50
#define RhoQ1_comp
Definition: ERF_IndexDefines.H:42
amrex::Real Real
Definition: ERF_ShocInterface.H:16