ERF
Energy Research and Forecasting: An Atmospheric Modeling Code
ERF_HSEUtils.H
Go to the documentation of this file.
1 #ifndef ERF_HSEUTIL_H_
2 #define ERF_HSEUTIL_H_
3 
5 #include "ERF_Constants.H"
6 #include "ERF_EOS.H"
7 
8 /**
9  * Utility functions for calculating a hydrostatic equilibrium (HSE) base state
10 */
11 
12 namespace HSEutils
13 {
14  using namespace amrex;
15 
16  // to control Newton iterations in init_isentropic_hse*
17  const int MAX_ITER = 10;
18  const amrex::Real TOL = Real(1.e-8);
19 
20  /**
21  * Function to calculate the hydrostatic density and pressure
22  * from Newton-Raphson iterations
23  *
24  * @param[in] m_tol iteration tolerance
25  * @param[in] RdOCp Rd/Cp
26  * @param[out] dz change in vertical height
27  * @param[out] g magnitude of gravity
28  * @param[in] C sum of known terms in HSE balance
29  * @param[in] T theta at the current cell center
30  * @param[in] qt total moisture (non-precip and precip)
31  * @param[in] qv water vapor
32  * @param[in] P pressure at cell center
33  * @param[in] rd dry density at cell center
34  * @param[in] F starting residual of non-linear eq
35  */
36  AMREX_GPU_HOST_DEVICE
37  AMREX_FORCE_INLINE
38  void
39  Newton_Raphson_hse (const Real& m_tol,
40  const Real& RdOCp,
41  const Real& dz,
42  const Real& g,
43  const Real& C,
44  const Real& Th,
45  const Real& qt,
46  const Real& qv,
47  Real& P,
48  Real& rd,
49  Real& F)
50  {
51  int iter=0;
52  int max_iter=20;
53  Real eps = Real(1.e-6);
54  Real ieps = Real(1.e6);
55  while (std::abs(F)>m_tol && iter<max_iter) {
56  // Compute change in pressure
57  Real hi = getRhogivenThetaPress(Th, P + eps, RdOCp, qv);
58  Real lo = getRhogivenThetaPress(Th, P - eps, RdOCp, qv);
59  Real dFdp = one + fourth*ieps*(hi - lo)*g*dz;
60  P -= F/dFdp;
61  if (P < Real(1.e3)) amrex::Warning("P < 1000 [Pa]; Domain height may be too large...");
63 
64  // Diagnose density and residual
65  rd = getRhogivenThetaPress(Th, P, RdOCp, qv);
67  Real r_tot = rd * (one + qt);
68  F = P + myhalf*r_tot*g*dz + C;
69  ++iter;
70  }
71  if (iter>=max_iter) {
72  AMREX_DEVICE_PRINTF("WARNING: HSE Newton iterations did not converge to tolerance!\n%s", "");
73  AMREX_DEVICE_PRINTF("HSE Newton tol: %e %e\n",F,m_tol);
74  }
75  }
76 
77 
78  /**
79  * Function to calculate the hydrostatic density and pressure
80  *
81  * @param[in] r_sfc surface density
82  * @param[in] theta surface potential temperature
83  * @param[out] r hydrostatically balanced density profile
84  * @param[out] p hydrostatically balanced pressure profile
85  * @param[in] dz vertical grid spacing (constant)
86  * @param[in] prob_lo_z surface height
87  * @param[in] khi z-index corresponding to the big end of the domain
88  */
89  AMREX_GPU_HOST_DEVICE
90  AMREX_FORCE_INLINE
91  void
93  const amrex::Real& theta,
94  amrex::Real* r,
95  amrex::Real* p,
96  const amrex::Real& dz,
97  const int klo, const int khi)
98  {
99  int kstart;
100 
101  // r_sfc / p_0 are the density / pressure at klo
102 
103  // Initial guess
104  Real myhalf_dz = myhalf*dz;
105  r[klo] = r_sfc;
106  p[klo] = p_0 - myhalf_dz * r[klo] * CONST_GRAV;
107 
108  if (klo == 0)
109  {
110  kstart = 1;
111 
112  // We do a Newton iteration to satisfy the EOS & HSE (with constant theta)
113  bool converged_hse = false;
114  Real p_hse;
115  Real p_eos;
116 
117  for (int iter = 0; iter < MAX_ITER && !converged_hse; iter++)
118  {
119  p_hse = p_0 - myhalf_dz * r[klo] * CONST_GRAV;
120  p_eos = getPgivenRTh(r[klo]*theta);
121 
122  Real A = p_hse - p_eos;
123 
124  Real dpdr = getdPdRgivenConstantTheta(r[klo],theta);
125 
126  Real drho = A / (dpdr + myhalf_dz * CONST_GRAV);
127 
128  r[klo] = r[klo] + drho;
129  p[klo] = getPgivenRTh(r[klo]*theta);
130 
131  if (std::abs(drho) < TOL)
132  {
133  converged_hse = true;
134  break;
135  }
136  }
137 
138  // if (!converged_hse) amrex::Print() << "DOING ITERATIONS AT K = " << klo << std::endl;
139  // if (!converged_hse) amrex::Error("Didn't converge the iterations in init");
140  } else {
141  kstart = klo; // because we need to solve for r[klo] here; r[klo-1] is what was passed in r_sfc
142  r[klo-1] = r_sfc; // r_sfc is really the interpolated density in the ghost cell in this case
143  p[klo-1] = getPgivenRTh(r[klo-1]*theta);
144  }
145 
146  // To get values at k > 0 we do a Newton iteration to satisfy the EOS (with constant theta) and
147  for (int k = kstart; k <= khi; k++)
148  {
149  // To get values at k > 0 we do a Newton iteration to satisfy the EOS (with constant theta) and
150  // to discretely satisfy HSE -- here we assume spatial_order = 2 -- we can generalize this later if needed
151  bool converged_hse = false;
152 
153  r[k] = r[k-1];
154 
155  Real p_eos = getPgivenRTh(r[k]*theta);
156  Real p_hse;
157 
158  for (int iter = 0; iter < MAX_ITER && !converged_hse; iter++)
159  {
160  Real r_avg = myhalf * (r[k-1]+r[k]);
161  p_hse = p[k-1] - dz * r_avg * CONST_GRAV;
162  p_eos = getPgivenRTh(r[k]*theta);
163 
164  Real A = p_hse - p_eos;
165 
166  Real dpdr = getdPdRgivenConstantTheta(r[k],theta);
167  // Gamma * p_0 * std::pow( (R_d * theta / p_0), Gamma) * std::pow(r[k], Gamma-one) ;
168 
169  Real drho = A / (dpdr + dz * CONST_GRAV);
170 
171  r[k] = r[k] + drho;
172  p[k] = getPgivenRTh(r[k]*theta);
173 
174  if (std::abs(drho) < TOL * r[k-1])
175  {
176  converged_hse = true;
177  // amrex::Print() << " converged " << std::endl;
178  break;
179  }
180  }
181 
182  // if (!converged_hse) amrex::Print() << "DOING ITERATIONS AT K = " << k << std::endl;
183  // if (!converged_hse) amrex::Error("Didn't converge the iterations in init");
184  }
185  r[khi+1] = r[khi];
186  }
187 
188 
189  /**
190  * Function to calculate the hydrostatic density and pressure over terrain
191  *
192  * @param[in] i x-index
193  * @param[in] j y-index
194  * @param[in] r_sfc surface density
195  * @param[in] theta surface potential temperature
196  * @param[out] r hydrostatically balanced density profile
197  * @param[out] p hydrostatically balanced pressure profile
198  * @param[in] z_cc cell-center heights
199  * @param[in] khi z-index corresponding to the big end of the domain
200  */
201  AMREX_GPU_HOST_DEVICE
202  AMREX_FORCE_INLINE
203  void
205  int j,
206  const amrex::Real& r_sfc,
207  const amrex::Real& theta,
208  amrex::Real* r,
209  amrex::Real* p,
210  const amrex::Array4<amrex::Real const> z_cc,
211  const int& klo, const int& khi)
212 {
213  int kstart;
214 
215  if (klo == 0) {
216  //
217  // r_sfc / p_0 are the density / pressure at the surface
218  //
219  // Initial guess
220  int k0 = 0;
221 
222  // Where we start the lower iteration
223  kstart = 1;
224 
225  Real myhalf_dz = z_cc(i,j,k0);
226  r[k0] = r_sfc;
227  p[k0] = p_0 - myhalf_dz * r[k0] * CONST_GRAV;
228  {
229  // We do a Newton iteration to satisfy the EOS & HSE (with constant theta)
230  bool converged_hse = false;
231  Real p_hse;
232  Real p_eos;
233 
234  for (int iter = 0; iter < MAX_ITER && !converged_hse; iter++)
235  {
236  p_hse = p_0 - myhalf_dz * r[k0] * CONST_GRAV;
237  p_eos = getPgivenRTh(r[k0]*theta);
238 
239  Real A = p_hse - p_eos;
240 
241  Real dpdr = getdPdRgivenConstantTheta(r[k0],theta);
242 
243  Real drho = A / (dpdr + myhalf_dz * CONST_GRAV);
244 
245  r[k0] = r[k0] + drho;
246  p[k0] = getPgivenRTh(r[k0]*theta);
247 
248  if (std::abs(drho) < TOL)
249  {
250  converged_hse = true;
251  break;
252  }
253  }
254 
255  //if (!converged_hse) amrex::Print() << "DOING ITERATIONS AT K = " << k0 << std::endl;
256  //if (!converged_hse) amrex::Error("Didn't converge the iterations in init");
257  }
258  } else {
259  kstart = klo; // because we need to solve for r[klo] here; r[klo-1] is what was passed in r_sfc
260  r[klo-1] = r_sfc; // r_sfc is really the interpolated density in the ghost cell in this case
261  p[klo-1] = getPgivenRTh(r[klo-1]*theta);
262  }
263 
264  // To get values at k > 0 we do a Newton iteration to satisfy the EOS (with constant theta) and
265  for (int k = kstart; k <= khi; k++)
266  {
267  // To get values at k > 0 we do a Newton iteration to satisfy the EOS (with constant theta) and
268  // to discretely satisfy HSE -- here we assume spatial_order = 2 -- we can generalize this later if needed
269  bool converged_hse = false;
270 
271  Real dz_loc = (z_cc(i,j,k) - z_cc(i,j,k-1));
272 
273  r[k] = r[k-1];
274 
275  Real p_eos = getPgivenRTh(r[k]*theta);
276  Real p_hse;
277 
278  for (int iter = 0; iter < MAX_ITER && !converged_hse; iter++)
279  {
280  p_hse = p[k-1] - dz_loc * myhalf * (r[k-1]+r[k]) * CONST_GRAV;
281  p_eos = getPgivenRTh(r[k]*theta);
282 
283  Real A = p_hse - p_eos;
284 
285  Real dpdr = getdPdRgivenConstantTheta(r[k],theta);
286 
287  Real drho = A / (dpdr + dz_loc * CONST_GRAV);
288 
289  r[k] = r[k] + drho;
290  p[k] = getPgivenRTh(r[k]*theta);
291 
292  if (std::abs(drho) < TOL * r[k-1])
293  {
294  converged_hse = true;
295  //amrex::Print() << " converged " << std::endl;
296  break;
297  }
298  }
299 
300  // if (!converged_hse) amrex::Print() << "DOING ITERATIONS AT K = " << k << std::endl;
301  // if (!converged_hse) amrex::Error("Didn't converge the iterations in init");
302  }
303 }
304 
305 AMREX_FORCE_INLINE
306 AMREX_GPU_HOST_DEVICE
308 {
309  Real p_s = erf_esatw(T_b,use_empirical);
310  return p_s * Real(100.0);
311 }
312 
313 AMREX_FORCE_INLINE
314 AMREX_GPU_HOST_DEVICE
315 Real compute_relative_humidity (const Real p_b, const Real T_b, const bool use_empirical,
316  const int which_zone, const Real scaled_height)
317 {
318  if (which_zone > 0) {
319  if (which_zone == 1) { // z <= height
321  Real q_s = Rd_on_Rv*p_s/(p_b - p_s);
322  return Real(0.014)/q_s;
323  } else if (which_zone == 2) { // z > height and z <= z_tr; scaled_height = z/z_tr
324  return one - Real(0.75)*std::pow(scaled_height,Real(1.25));
325  } else { // z > z_tr
326  return fourth;
327  }
328  } else {
329  return one;
330  }
331 }
332 
333 AMREX_FORCE_INLINE
334 AMREX_GPU_HOST_DEVICE
335 Real vapor_mixing_ratio (const Real p_b, const Real T_b, const Real RH, const bool use_empirical,
336  int which_zone)
337 {
339  Real p_v = compute_vapor_pressure(p_s, RH);
340  Real q_v = Rd_on_Rv*p_v/(p_b - p_v);
341 
342  if (which_zone == 1) { // z <= height
343  return Real(0.014);
344  } else {
345  return q_v;
346  }
347 }
348 
349 AMREX_FORCE_INLINE
350 AMREX_GPU_HOST_DEVICE
351 Real compute_F_for_temp(const Real T_b, const Real p_b, const Real q_t, const Real eq_pot_temp,
352  const bool use_empirical, const int which_zone, const Real scaled_height)
353 {
354  Real fac = Cp_d + Cp_l*q_t;
355  Real RH = compute_relative_humidity(p_b, T_b, use_empirical, which_zone, scaled_height);
356  Real q_v = vapor_mixing_ratio(p_b, T_b, RH, use_empirical, which_zone);
358  Real p_v = compute_vapor_pressure(p_s, RH);
359  return eq_pot_temp - T_b*std::pow((p_b - p_v)/p_0, -R_d/fac)*std::exp(L_v*q_v/(fac*T_b));
360 }
361 
362 AMREX_FORCE_INLINE
363 AMREX_GPU_HOST_DEVICE
364 Real compute_temperature (const Real p_b, const Real q_t, const Real eq_pot_temp, const bool use_empirical,
365  const int which_zone, const Real scaled_height)
366 {
367  Real T_b = Real(200.0), delta_T; // Initial guess
368  for (int iter=0; iter<20; iter++)
369  {
370  Real F = compute_F_for_temp(T_b , p_b, q_t, eq_pot_temp, use_empirical, which_zone, scaled_height);
371  Real F_plus_dF = compute_F_for_temp(T_b+Real(1e-10), p_b, q_t, eq_pot_temp, use_empirical, which_zone, scaled_height);
372  Real F_prime = (F_plus_dF - F)/Real(1e-10);
373  delta_T = -F/F_prime;
374  T_b = T_b + delta_T;
375  }
376 
377  if(std::fabs(delta_T) > 1e-8){
378  amrex::Abort("Newton Raphson for temperature could not converge");
379  }
380 
381  return T_b;
382 }
383 
384 AMREX_FORCE_INLINE
385 AMREX_GPU_HOST_DEVICE
387 {
388  Real T_dp, gamma, T;
389  T = T_b - Real(273.15);
390 
391  Real b = Real(18.678), c = Real(257.14), d = Real(234.5);
392  gamma = std::log(RH*std::exp((b - T/d)*T/(c + T)));
393 
394  T_dp = c*gamma/(b - gamma);
395 
396  return T_dp;
397 }
398 
399 AMREX_FORCE_INLINE
400 AMREX_GPU_HOST_DEVICE
401 Real compute_theta (const Real scaled_height, const Real theta_0,
402  const Real theta_tr, const Real z_tr, const Real T_tr)
403 {
404  if(scaled_height <= one) {
405  return theta_0 + (theta_tr - theta_0)*std::pow(scaled_height,Real(1.25));
406  } else {
407  return theta_tr*std::exp(CONST_GRAV/(Cp_d*T_tr)*z_tr*(scaled_height - one));
408  }
409 }
410 
411 AMREX_FORCE_INLINE
412 AMREX_GPU_HOST_DEVICE
413 void compute_rho (const Real& pressure, Real& theta, Real& rho, Real& q_v, Real& T_dp, Real& T_b,
414  const Real q_t, const Real eq_pot_temp, const bool use_empirical, const int which_zone,
415  const Real scaled_height, const bool T_from_theta,
416  const Real theta_0, const Real theta_tr, const Real z_tr, const Real T_tr)
417 {
418 
419  if (T_from_theta) {
420  theta = compute_theta(scaled_height, theta_0, theta_tr, z_tr, T_tr);
421  T_b = getTgivenPandTh(pressure, theta, (R_d/Cp_d));
422  } else {
423  T_b = compute_temperature(pressure, q_t, eq_pot_temp, use_empirical, which_zone, scaled_height);
424  theta = getThgivenTandP(T_b, pressure, (R_d/Cp_d));
425  }
426 
427  Real RH = compute_relative_humidity(pressure, T_b, use_empirical, which_zone, scaled_height);
428 
429  q_v = vapor_mixing_ratio(pressure, T_b, RH, use_empirical, which_zone);
430 
431  rho = getRhogivenTandPress(T_b, pressure, q_v);
432 
433  if (T_from_theta) {
434  rho *= (one + q_v);
435  } else {
436  rho *= (one + q_t);
437  }
438 
439  T_dp = compute_dewpoint_temperature(T_b, RH);
440 }
441 
442 AMREX_FORCE_INLINE
443 AMREX_GPU_HOST_DEVICE
444 Real compute_F (const Real& p_k, const Real& p_k_minus_1, Real &theta_k, Real& rho_k, Real& q_v_k,
445  Real& T_dp, Real& T_b, const Real& dz, const Real& rho_k_minus_1, const Real q_t,
446  const Real eq_pot_temp, const bool use_empirical,
447  const int which_zone, const Real scaled_height, const bool T_from_theta,
448  const Real theta_0, const Real theta_tr, const Real z_tr, const Real T_tr)
449 {
450  Real F;
451 
452  compute_rho(p_k, theta_k, rho_k, q_v_k, T_dp, T_b, q_t, eq_pot_temp, use_empirical, which_zone, scaled_height,
453  T_from_theta, theta_0, theta_tr, z_tr, T_tr);
454 
455  if(rho_k_minus_1 == amrex::Real(0)) // This loop is for the first point above the ground
456  {
457  F = p_k - p_k_minus_1 + rho_k*CONST_GRAV*dz/two;
458  }
459  else
460  {
461  F = p_k - p_k_minus_1 + myhalf * (rho_k + rho_k_minus_1)*CONST_GRAV*dz;
462  }
463 
464  return F;
465 }
466 
467 AMREX_FORCE_INLINE
468 AMREX_GPU_HOST_DEVICE
469 Real compute_p_k (Real &p_k, const Real p_k_minus_1, Real &theta_k, Real& rho_k, Real& q_v_k,
470  Real& T_dp, Real& T_b, const Real dz, const Real rho_k_minus_1, const Real q_t,
471  const Real eq_pot_temp, const bool use_empirical,
472  const int which_zone, const Real scaled_height, const bool T_from_theta,
473  const Real theta_0, const Real theta_tr, const Real z_tr, const Real T_tr)
474 {
475  Real delta_p_k;
476 
477 #ifdef AMREX_USE_FLOAT
478  Real eps = Real(1e-6);
479  Real tol = Real(1e-8);
480 #else
481  Real eps = Real(1e-10);
482  Real tol = Real(1e-8);
483 #endif
484 
485  for(int iter=0; iter<20; iter++)
486  {
487  Real F = compute_F(p_k , p_k_minus_1, theta_k, rho_k, q_v_k, T_dp, T_b, dz, rho_k_minus_1,
488  q_t, eq_pot_temp, use_empirical, which_zone, scaled_height, T_from_theta,
490  Real F_plus_dF = compute_F(p_k+eps, p_k_minus_1, theta_k, rho_k, q_v_k, T_dp, T_b, dz, rho_k_minus_1,
491  q_t, eq_pot_temp, use_empirical, which_zone, scaled_height, T_from_theta,
493  Real F_prime = (F_plus_dF - F)/eps;
494  delta_p_k = -F/F_prime;
495  p_k = p_k + delta_p_k;
496  }
497 
498  if (std::fabs(delta_p_k) > tol) {
499  amrex::Abort("Newton Raphson for pressure could not converge");
500  }
501 
502  return p_k;
503 }
504 
505 AMREX_FORCE_INLINE
506 AMREX_GPU_HOST_DEVICE
507 void
509  const Real& dz, const int& khi, const Real q_t,
510  const Real eq_pot_temp, const bool use_empirical,
511  const bool T_from_theta = false,
512  const Real z_tr_1 = -one, const Real z_tr_2 = -one,
513  const Real theta_0 = amrex::Real(0), const Real theta_tr = amrex::Real(0), const Real T_tr = amrex::Real(0))
514 {
515  Real T_b, T_dp;
516 
517  int which_zone = -1;
518  Real scaled_height = amrex::Real(0);
519 
520  // Compute the quantities at z = myhalf*dz (first cell center)
521  p[0] = p_0;
522  if (z_tr_1 > amrex::Real(0)) {
523  Real z = myhalf * dz;
524  if (z <= z_tr_1) {
525  which_zone = 1;
526  } else if (z <= z_tr_2) {
527  which_zone = 2;
528  } else {
529  which_zone = 3;
530  }
531  scaled_height = z/z_tr_2;
532  }
533 
534  compute_p_k(p[0], p_0, theta[0], r[0], q_v[0], T_dp, T_b, dz, amrex::Real(0), q_t, eq_pot_temp,
535  use_empirical, which_zone, scaled_height, T_from_theta,
536  theta_0, theta_tr, z_tr_2, T_tr);
537 
538  for (int k=1; k<=khi; k++)
539  {
540  p[k] = p[k-1];
541 
542  if (z_tr_1 > amrex::Real(0)) {
543  Real z = (k+myhalf) * dz;
544  if (z <= z_tr_1) {
545  which_zone = 1;
546  } else if (z <= z_tr_2) {
547  which_zone = 2;
548  } else {
549  which_zone = 3;
550  }
551  scaled_height = z/z_tr_2;
552  }
553 
554  compute_p_k(p[k], p[k-1], theta[k], r[k], q_v[k], T_dp, T_b, dz, r[k-1], q_t, eq_pot_temp,
555  use_empirical, which_zone, scaled_height, T_from_theta,
556  theta_0, theta_tr, z_tr_2, T_tr);
557  }
558 
559  r[khi+1] = r[khi];
560 }
561 
562 } // namespace
563 
564 #endif
constexpr amrex::Real Cp_d
Definition: ERF_Constants.H:23
constexpr amrex::Real Rd_on_Rv
Definition: ERF_Constants.H:98
constexpr amrex::Real two
Definition: ERF_Constants.H:8
constexpr amrex::Real one
Definition: ERF_Constants.H:7
constexpr amrex::Real fourth
Definition: ERF_Constants.H:12
constexpr amrex::Real myhalf
Definition: ERF_Constants.H:11
constexpr amrex::Real p_0
Definition: ERF_Constants.H:29
constexpr amrex::Real CONST_GRAV
Definition: ERF_Constants.H:32
constexpr amrex::Real Cp_l
Definition: ERF_Constants.H:25
constexpr amrex::Real R_d
Definition: ERF_Constants.H:21
constexpr amrex::Real L_v
Definition: ERF_Constants.H:27
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real getdPdRgivenConstantTheta(const amrex::Real rho, const amrex::Real theta, const amrex::Real qv=amrex::Real(0))
Definition: ERF_EOS.H:127
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=amrex::Real(0))
Definition: ERF_EOS.H:96
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 getRhogivenTandPress(const amrex::Real T, const amrex::Real p, const amrex::Real qv=amrex::Real(0))
Definition: ERF_EOS.H:113
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 getPgivenRTh(const amrex::Real rhotheta, const amrex::Real qv=amrex::Real(0))
Definition: ERF_EOS.H:81
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
const int khi
Definition: ERF_InitCustomPert_Bubble.H:21
Real T
Definition: ERF_InitCustomPert_Bubble.H:105
AMREX_ALWAYS_ASSERT(bx.length()[2]==khi+1)
RH
Definition: ERF_InitCustomPert_Bubble.H:107
rho
Definition: ERF_InitCustomPert_Bubble.H:106
const Real dz
Definition: ERF_InitCustomPert_Bubble.H:25
amrex::Real gamma
Definition: ERF_InitCustomPert_DataAssimilation_ISV.H:9
Real eq_pot_temp
Definition: ERF_InitCustomPert_MultiSpeciesBubble.H:23
bool use_empirical
Definition: ERF_InitCustomPert_MultiSpeciesBubble.H:25
Real T_tr
Definition: ERF_InitCustomPert_SquallLine.H:43
Real q_t
Definition: ERF_InitCustomPert_SquallLine.H:24
Real theta_tr
Definition: ERF_InitCustomPert_SquallLine.H:47
Real theta_0
Definition: ERF_InitCustomPert_SquallLine.H:46
Real z_tr
Definition: ERF_InitCustomPert_SquallLine.H:36
Real * p
Definition: ERF_InitCustomPert_SquallLine.H:61
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real erf_esatw(amrex::Real t, bool use_empirical=false)
Definition: ERF_MicrophysicsUtils.H:123
amrex::Real Real
Definition: ERF_ShocInterface.H:19
Definition: ERF_HSEUtils.H:13
AMREX_FORCE_INLINE AMREX_GPU_HOST_DEVICE void compute_rho(const Real &pressure, Real &theta, Real &rho, Real &q_v, Real &T_dp, Real &T_b, const Real q_t, const Real eq_pot_temp, const bool use_empirical, const int which_zone, const Real scaled_height, const bool T_from_theta, const Real theta_0, const Real theta_tr, const Real z_tr, const Real T_tr)
Definition: ERF_HSEUtils.H:413
AMREX_FORCE_INLINE AMREX_GPU_HOST_DEVICE Real compute_p_k(Real &p_k, const Real p_k_minus_1, Real &theta_k, Real &rho_k, Real &q_v_k, Real &T_dp, Real &T_b, const Real dz, const Real rho_k_minus_1, const Real q_t, const Real eq_pot_temp, const bool use_empirical, const int which_zone, const Real scaled_height, const bool T_from_theta, const Real theta_0, const Real theta_tr, const Real z_tr, const Real T_tr)
Definition: ERF_HSEUtils.H:469
const int MAX_ITER
Definition: ERF_HSEUtils.H:17
AMREX_FORCE_INLINE AMREX_GPU_HOST_DEVICE Real compute_dewpoint_temperature(const Real T_b, const Real RH)
Definition: ERF_HSEUtils.H:386
AMREX_FORCE_INLINE AMREX_GPU_HOST_DEVICE Real vapor_mixing_ratio(const Real p_b, const Real T_b, const Real RH, const bool use_empirical, int which_zone)
Definition: ERF_HSEUtils.H:335
AMREX_FORCE_INLINE AMREX_GPU_HOST_DEVICE Real compute_saturation_pressure(const Real T_b, const bool use_empirical)
Definition: ERF_HSEUtils.H:307
AMREX_FORCE_INLINE AMREX_GPU_HOST_DEVICE void init_isentropic_hse_no_terrain(Real *theta, Real *r, Real *p, Real *q_v, const Real &dz, const int &khi, const Real q_t, const Real eq_pot_temp, const bool use_empirical, const bool T_from_theta=false, const Real z_tr_1=-one, const Real z_tr_2=-one, const Real theta_0=amrex::Real(0), const Real theta_tr=amrex::Real(0), const Real T_tr=amrex::Real(0))
Definition: ERF_HSEUtils.H:508
AMREX_FORCE_INLINE AMREX_GPU_HOST_DEVICE Real compute_temperature(const Real p_b, const Real q_t, const Real eq_pot_temp, const bool use_empirical, const int which_zone, const Real scaled_height)
Definition: ERF_HSEUtils.H:364
AMREX_FORCE_INLINE AMREX_GPU_HOST_DEVICE Real compute_relative_humidity(const Real p_b, const Real T_b, const bool use_empirical, const int which_zone, const Real scaled_height)
Definition: ERF_HSEUtils.H:315
AMREX_FORCE_INLINE AMREX_GPU_HOST_DEVICE Real compute_F(const Real &p_k, const Real &p_k_minus_1, Real &theta_k, Real &rho_k, Real &q_v_k, Real &T_dp, Real &T_b, const Real &dz, const Real &rho_k_minus_1, const Real q_t, const Real eq_pot_temp, const bool use_empirical, const int which_zone, const Real scaled_height, const bool T_from_theta, const Real theta_0, const Real theta_tr, const Real z_tr, const Real T_tr)
Definition: ERF_HSEUtils.H:444
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void Newton_Raphson_hse(const Real &m_tol, const Real &RdOCp, const Real &dz, const Real &g, const Real &C, const Real &Th, const Real &qt, const Real &qv, Real &P, Real &rd, Real &F)
Definition: ERF_HSEUtils.H:39
AMREX_FORCE_INLINE AMREX_GPU_HOST_DEVICE Real compute_F_for_temp(const Real T_b, const Real p_b, const Real q_t, const Real eq_pot_temp, const bool use_empirical, const int which_zone, const Real scaled_height)
Definition: ERF_HSEUtils.H:351
const amrex::Real TOL
Definition: ERF_HSEUtils.H:18
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void init_isentropic_hse_terrain(int i, int j, const amrex::Real &r_sfc, const amrex::Real &theta, amrex::Real *r, amrex::Real *p, const amrex::Array4< amrex::Real const > z_cc, const int &klo, const int &khi)
Definition: ERF_HSEUtils.H:204
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void init_isentropic_hse(const amrex::Real &r_sfc, const amrex::Real &theta, amrex::Real *r, amrex::Real *p, const amrex::Real &dz, const int klo, const int khi)
Definition: ERF_HSEUtils.H:92
AMREX_FORCE_INLINE AMREX_GPU_HOST_DEVICE Real compute_theta(const Real scaled_height, const Real theta_0, const Real theta_tr, const Real z_tr, const Real T_tr)
Definition: ERF_HSEUtils.H:401
@ theta
Definition: ERF_MM5.H:20
@ P
Definition: ERF_IndexDefines.H:148
@ qt
Definition: ERF_Kessler.H:27
@ qv
Definition: ERF_Kessler.H:28
Definition: ERF_ConsoleIO.cpp:12
real(c_double), parameter g
Definition: ERF_module_model_constants.F90:19