14 using namespace amrex;
59 Real dFdp = 1.0 + 0.25*ieps*(hi - lo)*
g*dz;
61 if (P < 1.0e3) amrex::Warning(
"P < 1000 [Pa]; Domain height may be too large...");
67 Real r_tot = rd * (1. +
qt);
68 F = P + 0.5*r_tot*
g*dz + C;
71 while (std::abs(F)>m_tol && iter<max_iter);
73 AMREX_DEVICE_PRINTF(
"WARNING: HSE Newton iterations did not converge to tolerance!\n%s",
"");
74 AMREX_DEVICE_PRINTF(
"HSE Newton tol: %e %e\n",F,m_tol);
98 const int klo,
const int khi)
105 Real half_dz = 0.5*dz;
114 bool converged_hse =
false;
118 for (
int iter = 0; iter <
MAX_ITER && !converged_hse; iter++)
123 Real A = p_hse - p_eos;
132 if (std::abs(drho) <
TOL)
134 converged_hse =
true;
148 for (
int k = kstart; k <=
khi; k++)
152 bool converged_hse =
false;
159 for (
int iter = 0; iter <
MAX_ITER && !converged_hse; iter++)
161 Real r_avg = 0.5 * (r[k-1]+r[k]);
165 Real A = p_hse - p_eos;
175 if (std::abs(drho) <
TOL * r[k-1])
177 converged_hse =
true;
202 AMREX_GPU_HOST_DEVICE
211 const amrex::Array4<amrex::Real const> z_cc,
212 const int&
klo,
const int&
khi)
226 Real half_dz = z_cc(i,j,k0);
231 bool converged_hse =
false;
235 for (
int iter = 0; iter <
MAX_ITER && !converged_hse; iter++)
240 Real A = p_hse - p_eos;
246 r[k0] = r[k0] + drho;
249 if (std::abs(drho) <
TOL)
251 converged_hse =
true;
266 for (
int k = kstart; k <=
khi; k++)
270 bool converged_hse =
false;
272 Real dz_loc = (z_cc(i,j,k) - z_cc(i,j,k-1));
279 for (
int iter = 0; iter <
MAX_ITER && !converged_hse; iter++)
281 p_hse = p[k-1] - dz_loc * 0.5 * (r[k-1]+r[k]) *
CONST_GRAV;
284 Real A = p_hse - p_eos;
293 if (std::abs(drho) <
TOL * r[k-1])
295 converged_hse =
true;
307 AMREX_GPU_HOST_DEVICE
311 if (!use_empirical) p_s *= 100.0;
316 AMREX_GPU_HOST_DEVICE
318 const int which_zone,
const Real scaled_height)
320 if (which_zone > 0) {
321 if (which_zone == 1) {
325 }
else if (which_zone == 2) {
326 return 1.0 - 0.75*std::pow(scaled_height,1.25);
336 AMREX_GPU_HOST_DEVICE
344 if (which_zone == 1) {
352 AMREX_GPU_HOST_DEVICE
354 const bool use_empirical,
const int which_zone,
const Real scaled_height)
361 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));
365 AMREX_GPU_HOST_DEVICE
367 const int which_zone,
const Real scaled_height)
369 Real T_b = 200.0, delta_T;
370 for (
int iter=0; iter<20; iter++)
373 Real F_plus_dF =
compute_F_for_temp(T_b+1e-10, p_b, q_t, eq_pot_temp, use_empirical, which_zone, scaled_height);
374 Real F_prime = (F_plus_dF - F)/1e-10;
375 delta_T = -F/F_prime;
379 if(std::fabs(delta_T) > 1e-8){
380 amrex::Abort(
"Newton Raphson for temperature could not converge");
387 AMREX_GPU_HOST_DEVICE
393 Real b = 18.678, c = 257.14, d = 234.5;
394 gamma = log(RH*exp((b -
T/d)*
T/(c +
T)));
402 AMREX_GPU_HOST_DEVICE
406 if(scaled_height <= 1.0) {
407 return theta_0 + (theta_tr - theta_0)*std::pow(scaled_height,1.25);
409 return theta_tr*exp(
CONST_GRAV/(
Cp_d*T_tr)*z_tr*(scaled_height - 1.0));
414 AMREX_GPU_HOST_DEVICE
416 const Real q_t,
const Real eq_pot_temp,
const bool use_empirical,
const int which_zone,
417 const Real scaled_height,
const bool T_from_theta,
425 T_b =
compute_temperature(pressure, q_t, eq_pot_temp, use_empirical, which_zone, scaled_height);
445 AMREX_GPU_HOST_DEVICE
448 const Real eq_pot_temp,
const bool use_empirical,
449 const int which_zone,
const Real scaled_height,
const bool T_from_theta,
454 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,
455 T_from_theta, theta_0, theta_tr, z_tr, T_tr);
457 if(rho_k_minus_1 == 0.0)
459 F = p_k - p_k_minus_1 + rho_k*
CONST_GRAV*dz/2.0;
463 F = p_k - p_k_minus_1 + 0.5 * (rho_k + rho_k_minus_1)*
CONST_GRAV*dz;
470 AMREX_GPU_HOST_DEVICE
473 const Real eq_pot_temp,
const bool use_empirical,
474 const int which_zone,
const Real scaled_height,
const bool T_from_theta,
480 for(
int iter=0; iter<20; iter++)
482 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,
483 q_t, eq_pot_temp, use_empirical, which_zone, scaled_height, T_from_theta,
484 theta_0, theta_tr, z_tr, T_tr);
485 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,
486 q_t, eq_pot_temp, use_empirical, which_zone, scaled_height, T_from_theta,
487 theta_0, theta_tr, z_tr, T_tr);
488 Real F_prime = (F_plus_dF - F)/eps;
489 delta_p_k = -F/F_prime;
490 p_k = p_k + delta_p_k;
494 if (std::fabs(delta_p_k) > 1e-8) {
495 amrex::Abort(
"Newton Raphson for pressure could not converge");
502 AMREX_GPU_HOST_DEVICE
506 const Real eq_pot_temp,
const bool use_empirical,
507 const bool T_from_theta =
false,
508 const Real z_tr_1 = -1.,
const Real z_tr_2 = -1.,
509 const Real theta_0 = 0.,
const Real theta_tr = 0.,
const Real T_tr = 0.)
514 Real scaled_height = 0.;
522 }
else if (
z <= z_tr_2) {
527 scaled_height =
z/z_tr_2;
530 compute_p_k(p[0],
p_0,
theta[0], r[0], q_v[0], T_dp, T_b, dz, 0.0, q_t, eq_pot_temp,
531 use_empirical, which_zone, scaled_height, T_from_theta,
532 theta_0, theta_tr, z_tr_2, T_tr);
534 for (
int k=1; k<=
khi; k++)
539 Real z = (k+0.5) * dz;
542 }
else if (
z <= z_tr_2) {
547 scaled_height =
z/z_tr_2;
550 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,
551 use_empirical, which_zone, scaled_height, T_from_theta,
552 theta_0, theta_tr, z_tr_2, T_tr);
constexpr amrex::Real Cp_d
Definition: ERF_Constants.H:12
constexpr amrex::Real Rd_on_Rv
Definition: ERF_Constants.H:87
constexpr amrex::Real p_0
Definition: ERF_Constants.H:18
constexpr amrex::Real CONST_GRAV
Definition: ERF_Constants.H:21
constexpr amrex::Real Cp_l
Definition: ERF_Constants.H:14
constexpr amrex::Real R_d
Definition: ERF_Constants.H:10
constexpr amrex::Real L_v
Definition: ERF_Constants.H:16
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 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 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 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 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
const int klo
Definition: ERF_InitCustomPertVels_ParticleTests.H:4
amrex::Real gamma
Definition: ERF_InitCustomPert_IsentropicVortex.H:9
const int khi
Definition: ERF_InitCustomPert_ParticleTests.H:11
AMREX_ALWAYS_ASSERT(bx.length()[2]==khi+1)
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real erf_esatw(amrex::Real t, bool use_empirical=false)
Definition: ERF_MicrophysicsUtils.H:68
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:415
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:471
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:388
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:337
AMREX_FORCE_INLINE AMREX_GPU_HOST_DEVICE Real compute_saturation_pressure(const Real T_b, const bool use_empirical)
Definition: ERF_HSEUtils.H:308
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 &T, const Real &qt, const Real &qv, Real &P, Real &rd, Real &F)
Definition: ERF_HSEUtils.H:39
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=-1., const Real z_tr_2=-1., const Real theta_0=0., const Real theta_tr=0., const Real T_tr=0.)
Definition: ERF_HSEUtils.H:504
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:366
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:317
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:446
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:353
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:205
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:93
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:403
@ theta
Definition: ERF_MM5.H:20
@ rho
Definition: ERF_Kessler.H:22
@ qt
Definition: ERF_Kessler.H:27
@ qv
Definition: ERF_Kessler.H:28
@ T
Definition: ERF_IndexDefines.H:110
Definition: ERF_ConsoleIO.cpp:12
real(c_double), parameter g
Definition: ERF_module_model_constants.F90:19