ERF
Energy Research and Forecasting: An Atmospheric Modeling Code
ERF_InitCustomPert_SuperCell.H
Go to the documentation of this file.
1 
2  const bool use_moisture = (sc.moisture_type != MoistureType::None);
3 
4  const int khi = geomdata.Domain().bigEnd()[2];
5 
6  AMREX_ALWAYS_ASSERT(bx.length()[2] == khi+1);
7 
8  ParmParse pp_prob("prob");
9  Real q_t = 0.02;
10  pp_prob.query("qt_init",q_t);
11 
12  Real eq_pot_temp = 320.0;
13  pp_prob.query("eq_pot_temp",eq_pot_temp);
14 
15  bool use_empirical = false;
16  pp_prob.query("use_empirical_psat",use_empirical);
17 
18  // This is what we do at k = 0 -- note we assume p = p_0 and T = T_0 at z=0
19  const amrex::Real& dz = geomdata.CellSize()[2];
20 
21  // Call the routine to calculate the 1d background condition
22 
23  Vector<Real> h_r(khi+2);
24  Vector<Real> h_p(khi+2);
25  Vector<Real> h_t(khi+2);
26  Vector<Real> h_q_v(khi+2);
27 
28  amrex::Gpu::DeviceVector<Real> d_r(khi+2);
29  amrex::Gpu::DeviceVector<Real> d_p(khi+2);
30  amrex::Gpu::DeviceVector<Real> d_t(khi+2);
31  amrex::Gpu::DeviceVector<Real> d_q_v(khi+2);
32 
33  Real height = 1200.;
34  pp_prob.query("height",height);
35 
36  Real z_tr = 12000.;
37  pp_prob.query("z_tr",z_tr);
38 
39  Real x_c = 0.0 ; pp_prob.query("x_c", x_c);
40  Real y_c = 0.0 ; pp_prob.query("x_c", x_c);
41  Real z_c = 1.5e3; pp_prob.query("z_c", z_c);
42 
43  Real r_c = 1.0;
44 
45  Real x_r = 10.0e3; pp_prob.query("x_r", x_r);
46  Real y_r = 10.0e3; pp_prob.query("y_r", y_r);
47  Real z_r = 1.5e3; pp_prob.query("z_r", z_r);
48 
49  Real T_tr = 213.0; pp_prob.query("T_tr", T_tr);
50  Real theta_tr = 343.0; pp_prob.query("theta_tr",theta_tr);
51  Real theta_c = 3.0; pp_prob.query("theta_c", theta_c);
52  Real theta_0 = 300.0; pp_prob.query("theta_0",theta_0);
53 
54  HSEutils::init_isentropic_hse_no_terrain(h_t.data(), h_r.data(),h_p.data(),h_q_v.data(),dz,khi,
57 
58  amrex::Gpu::copyAsync(amrex::Gpu::hostToDevice, h_r.begin(), h_r.end(), d_r.begin());
59  amrex::Gpu::copyAsync(amrex::Gpu::hostToDevice, h_p.begin(), h_p.end(), d_p.begin());
60  amrex::Gpu::copyAsync(amrex::Gpu::hostToDevice, h_t.begin(), h_t.end(), d_t.begin());
61  amrex::Gpu::copyAsync(amrex::Gpu::hostToDevice, h_q_v.begin(), h_q_v.end(), d_q_v.begin());
62 
63  Real* t = d_t.data();
64  Real* p = d_p.data();
65 
66  ParallelFor(bx, [=] AMREX_GPU_DEVICE(int i, int j, int k) noexcept
67  {
68  // Geometry (note we must include these here to get the data on device)
69  const auto prob_lo = geomdata.ProbLo();
70  const auto dx = geomdata.CellSize();
71  const Real x = prob_lo[0] + (i + 0.5) * dx[0];
72  const Real y = prob_lo[1] + (j + 0.5) * dx[1];
73  const Real z = prob_lo[2] + (k + 0.5) * dx[2];
74  Real rad, delta_theta, theta_total, temperature, rho, RH, scalar;
75 
76  // Introduce the warm bubble. Assume that the bubble is pressure matche with the background
77 
78  rad = std::pow(std::pow((x - x_c)/x_r,2) + std::pow((y - y_c)/y_r,2) + std::pow((z - z_c)/z_r,2), 0.5);
79 
80  if(rad <= r_c) {
81  delta_theta = theta_c*std::pow(cos(PI*rad/2.0),2);
82  scalar = std::pow(cos(PI*rad/2.0),2);
83  } else {
84  delta_theta = 0.0;
85  scalar = 0.0;
86  }
87 
88  Real scaled_height = z / z_tr;
89  int which_zone = -1;
90  if (z <= height) {
91  which_zone = 1;
92  } else if (z <= z_tr) {
93  which_zone = 2;
94  } else {
95  which_zone = 3;
96  }
97 
98  theta_total = t[k] + delta_theta;
99  temperature = getTgivenPandTh(p[k], theta_total, (R_d/Cp_d));
100  Real T_b = getTgivenPandTh(p[k], t[k] , (R_d/Cp_d));
101  RH = HSEutils::compute_relative_humidity(p[k], T_b, use_empirical, which_zone, scaled_height);
102 
103  Real q_v_hot;
104  if (z < height) {
105  q_v_hot = 0.014;
106  } else {
107  q_v_hot = HSEutils::vapor_mixing_ratio(p[k], T_b, RH, use_empirical, which_zone);
108  }
109 
110  rho = p[k]/(R_d*temperature*(1.0 + (R_v/R_d)*q_v_hot));
111 
112  // Compute background quantities
113  Real temperature_back = getTgivenPandTh(p[k], t[k], (R_d/Cp_d));
114  Real T_back = getTgivenPandTh(p[k], t[k], (R_d/Cp_d));
115  Real RH_back = HSEutils::compute_relative_humidity(p[k], T_back, use_empirical, which_zone, scaled_height);
116 
117  Real q_v_back;
118  if (z < height) {
119  q_v_back = 0.014;
120  } else {
121  q_v_back = HSEutils::vapor_mixing_ratio(p[k], T_back, RH_back, use_empirical, which_zone);
122  }
123 
124  Real rho_back = getRhogivenTandPress(temperature_back, p[k], q_v_back);
125 
126  // This version perturbs rho but not p
127  state_pert(i, j, k, RhoTheta_comp) = rho*theta_total - rho_back*t[k]*(1.0 + (R_v/R_d)*q_v_back);// rho*d_t[k]*(1.0 + R_v_by_R_d*q_v_hot);
128  state_pert(i, j, k, Rho_comp) = rho - rho_back*(1.0 + q_v_back);
129 
130  // Set scalar = 0 everywhere
131  state_pert(i, j, k, RhoScalar_comp) = rho*scalar;
132 
133  // mean states
134  if (use_moisture) {
135  state_pert(i, j, k, RhoQ1_comp) = rho*q_v_hot;
136  state_pert(i, j, k, RhoQ2_comp) = 0.0;
137  }
138 
139  });
constexpr amrex::Real R_v
Definition: ERF_Constants.H:11
constexpr amrex::Real Cp_d
Definition: ERF_Constants.H:12
constexpr amrex::Real PI
Definition: ERF_Constants.H:6
constexpr amrex::Real R_d
Definition: ERF_Constants.H:10
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
#define RhoScalar_comp
Definition: ERF_IndexDefines.H:40
#define Rho_comp
Definition: ERF_IndexDefines.H:36
#define RhoTheta_comp
Definition: ERF_IndexDefines.H:37
#define RhoQ2_comp
Definition: ERF_IndexDefines.H:43
#define RhoQ1_comp
Definition: ERF_IndexDefines.H:42
const Real dx
Definition: ERF_InitCustomPert_ABL.H:23
state_pert(i, j, k, RhoTheta_comp)
Real T_back
Definition: ERF_InitCustomPert_Bubble.H:111
Real rho_back
Definition: ERF_InitCustomPert_Bubble.H:112
background fields should have been initialized with erf init_type<< std::endl;} Real qt_init=0.02;pp_prob.query("qt_init", qt_init);Real eq_pot_temp=320.0;pp_prob.query("eq_pot_temp", eq_pot_temp);bool use_empirical=false;pp_prob.query("use_empircal_psat", use_empirical);if(do_moist_bubble) { Vector< Real > h_r(khi+2);Vector< Real > h_p(khi+2);Vector< Real > h_t(khi+2);Vector< Real > h_q_v(khi+2);Gpu::DeviceVector< Real > d_r(khi+2);Gpu::DeviceVector< Real > d_p(khi+2);Gpu::DeviceVector< Real > d_t(khi+2);Gpu::DeviceVector< Real > d_q_v(khi+2);HSEutils::init_isentropic_hse_no_terrain(h_t.data(), h_r.data(), h_p.data(), h_q_v.data(), dz, khi, qt_init, eq_pot_temp, use_empirical, false);Gpu::copyAsync(Gpu::hostToDevice, h_r.begin(), h_r.end(), d_r.begin());Gpu::copyAsync(Gpu::hostToDevice, h_p.begin(), h_p.end(), d_p.begin());Gpu::copyAsync(Gpu::hostToDevice, h_t.begin(), h_t.end(), d_t.begin());Gpu::copyAsync(Gpu::hostToDevice, h_q_v.begin(), h_q_v.end(), d_q_v.begin());Real *theta_back=d_t.data();Real *p_back=d_p.data();Real *q_v_back=d_q_v.data();int moisture_type=1;if(sc.moisture_type==MoistureType::SAM) { moisture_type=1;} else if(sc.moisture_type==MoistureType::SAM_NoIce||sc.moisture_type==MoistureType::SAM_NoPrecip_NoIce) { moisture_type=2;} ParallelFor(bx,[=] AMREX_GPU_DEVICE(int i, int j, int k) { const auto prob_lo=geomdata.ProbLo();const auto dx=geomdata.CellSize();const Real x=prob_lo[0]+(i+0.5) *dx[0];const Real y=prob_lo[1]+(j+0.5) *dx[1];const Real z=prob_lo[2]+(k+0.5) *dx[2];Real rad, delta_theta, theta_total, rho, RH;rad=0.0;if(x_r > rad
Definition: ERF_InitCustomPert_Bubble.H:93
Real q_v_hot
Definition: ERF_InitCustomPert_Bubble.H:108
theta_total
Definition: ERF_InitCustomPert_Bubble.H:104
RH
Definition: ERF_InitCustomPert_Bubble.H:107
rho
Definition: ERF_InitCustomPert_Bubble.H:106
const amrex::Real * prob_lo
Definition: ERF_InitCustomPert_IsentropicVortex.H:16
Vector< Real > h_t(khi+2)
const int khi
Definition: ERF_InitCustomPert_SuperCell.H:4
Real T_tr
Definition: ERF_InitCustomPert_SuperCell.H:49
amrex::Gpu::DeviceVector< Real > d_q_v(khi+2)
Real z_c
Definition: ERF_InitCustomPert_SuperCell.H:41
const bool use_moisture
Definition: ERF_InitCustomPert_SuperCell.H:2
amrex::Gpu::DeviceVector< Real > d_t(khi+2)
Real x_r
Definition: ERF_InitCustomPert_SuperCell.H:45
Real x_c
Definition: ERF_InitCustomPert_SuperCell.H:39
ParmParse pp_prob("prob")
Real q_t
Definition: ERF_InitCustomPert_SuperCell.H:9
Real theta_c
Definition: ERF_InitCustomPert_SuperCell.H:51
ParallelFor(bx, [=] AMREX_GPU_DEVICE(int i, int j, int k) noexcept { const auto prob_lo=geomdata.ProbLo();const auto dx=geomdata.CellSize();const Real x=prob_lo[0]+(i+0.5) *dx[0];const Real y=prob_lo[1]+(j+0.5) *dx[1];const Real z=prob_lo[2]+(k+0.5) *dx[2];Real rad, delta_theta, theta_total, temperature, rho, RH, scalar;rad=std::pow(std::pow((x - x_c)/x_r, 2)+std::pow((y - y_c)/y_r, 2)+std::pow((z - z_c)/z_r, 2), 0.5);if(rad<=r_c) { delta_theta=theta_c *std::pow(cos(PI *rad/2.0), 2);scalar=std::pow(cos(PI *rad/2.0), 2);} else { delta_theta=0.0;scalar=0.0;} Real scaled_height=z/z_tr;int which_zone=-1;if(z<=height) { which_zone=1;} else if(z<=z_tr) { which_zone=2;} else { which_zone=3;} theta_total=t[k]+delta_theta;temperature=getTgivenPandTh(p[k], theta_total,(R_d/Cp_d));Real T_b=getTgivenPandTh(p[k], t[k],(R_d/Cp_d));RH=HSEutils::compute_relative_humidity(p[k], T_b, use_empirical, which_zone, scaled_height);Real q_v_hot;if(z< height) { q_v_hot=0.014;} else { q_v_hot=HSEutils::vapor_mixing_ratio(p[k], T_b, RH, use_empirical, which_zone);} rho=p[k]/(R_d *temperature *(1.0+(R_v/R_d) *q_v_hot));Real temperature_back=getTgivenPandTh(p[k], t[k],(R_d/Cp_d));Real T_back=getTgivenPandTh(p[k], t[k],(R_d/Cp_d));Real RH_back=HSEutils::compute_relative_humidity(p[k], T_back, use_empirical, which_zone, scaled_height);Real q_v_back;if(z< height) { q_v_back=0.014;} else { q_v_back=HSEutils::vapor_mixing_ratio(p[k], T_back, RH_back, use_empirical, which_zone);} Real rho_back=getRhogivenTandPress(temperature_back, p[k], q_v_back);state_pert(i, j, k, RhoTheta_comp)=rho *theta_total - rho_back *t[k] *(1.0+(R_v/R_d) *q_v_back);state_pert(i, j, k, Rho_comp)=rho - rho_back *(1.0+q_v_back);state_pert(i, j, k, RhoScalar_comp)=rho *scalar;if(use_moisture) { state_pert(i, j, k, RhoQ1_comp)=rho *q_v_hot;state_pert(i, j, k, RhoQ2_comp)=0.0;} })
Real * t
Definition: ERF_InitCustomPert_SuperCell.H:63
Vector< Real > h_q_v(khi+2)
Real z_r
Definition: ERF_InitCustomPert_SuperCell.H:47
Real y_c
Definition: ERF_InitCustomPert_SuperCell.H:40
const amrex::Real & dz
Definition: ERF_InitCustomPert_SuperCell.H:19
Real height
Definition: ERF_InitCustomPert_SuperCell.H:33
Real eq_pot_temp
Definition: ERF_InitCustomPert_SuperCell.H:12
bool use_empirical
Definition: ERF_InitCustomPert_SuperCell.H:15
AMREX_ALWAYS_ASSERT(bx.length()[2]==khi+1)
Real r_c
Definition: ERF_InitCustomPert_SuperCell.H:43
Vector< Real > h_r(khi+2)
amrex::Gpu::DeviceVector< Real > d_r(khi+2)
Real theta_tr
Definition: ERF_InitCustomPert_SuperCell.H:50
Vector< Real > h_p(khi+2)
Real theta_0
Definition: ERF_InitCustomPert_SuperCell.H:52
Real y_r
Definition: ERF_InitCustomPert_SuperCell.H:46
Real z_tr
Definition: ERF_InitCustomPert_SuperCell.H:36
amrex::Gpu::DeviceVector< Real > d_p(khi+2)
Real * p
Definition: ERF_InitCustomPert_SuperCell.H:64
amrex::Real Real
Definition: ERF_ShocInterface.H:19
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 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_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