ERF
Energy Research and Forecasting: An Atmospheric Modeling Code
ERF_InitCustomPert_ABL.H
Go to the documentation of this file.
1 
2  ParmParse pp("prob");
3 
4  Real rho_0 = 0.0; pp.query("rho_0", rho_0);
5  Real T_0 = 0.0; pp.query("T_0", T_0);
6  Real A_0 = 1.0; pp.query("A_0", A_0);
7  Real KE_0 = 0.1; pp.query("KE_0", KE_0);
8  Real rhoKE_0 = -1; pp.query("rhoKE_0", rhoKE_0);
9 
10  Real KE_decay_height = -1; pp.query("KE_decay_height", KE_decay_height);
11  Real KE_decay_order = 1; pp.query("KE_decay_order", KE_decay_order);
12 
13  // random initial perturbations (legacy code)
14  Real T_0_Pert_Mag = 0.0; pp.query("T_0_Pert_Mag", T_0_Pert_Mag);
15  bool pert_rhotheta = true; pp.query("pert_rhotheta", pert_rhotheta);
16 
17  // divergence-free initial perturbations
18  Real pert_deltaU = 0.0; pp.query("pert_deltaU", pert_deltaU);
19  Real pert_deltaV = 0.0; pp.query("pert_deltaV", pert_deltaV);
20  Real pert_ref_height = 100.0; pp.query("pert_ref_height", pert_ref_height);
21 
22  // Capture by value for GPU
23  const Real dx = geomdata.CellSize(0);
24  const Real dy = geomdata.CellSize(1);
25  const Real prob_lo_x = geomdata.ProbLo(0);
26  const Real prob_lo_y = geomdata.ProbLo(1);
27  const Real prob_lo_z = geomdata.ProbLo(2);
28  const Real prob_hi_x = geomdata.ProbHi(0);
29  const Real prob_hi_y = geomdata.ProbHi(1);
30  const Real prob_hi_z = geomdata.ProbHi(2);
31 
32  // Define a point (xc,yc,zc) at the center of the domain
33  const Real xc = 0.5 * (prob_lo_x + prob_hi_x);
34  const Real yc = 0.5 * (prob_lo_y + prob_hi_y);
35  const Real zc = 0.5 * (prob_lo_z + prob_hi_z);
36 
37  if (KE_decay_height > 0) {
38  amrex::Print() << "Initial KE profile (order " << KE_decay_order
39  << ") will extend up to " << KE_decay_height
40  << std::endl;
41  }
42 
43 #ifndef AMREX_USE_GPU
44  if (pert_ref_height > 0) {
45  if (T_0_Pert_Mag != 0.0) {
46  if (pert_rhotheta) {
47  amrex::Print() << "Adding random rho*theta perturbations" << std::endl;
48  } else {
49  amrex::Print() << "Adding random theta perturbations" << std::endl;
50  }
51  }
52  }
53 #endif
54 
55  ParallelForRNG(bx, [=] AMREX_GPU_DEVICE(int i, int j, int k, const amrex::RandomEngine& engine) noexcept
56  {
57  const Real x = prob_lo_x + (i + 0.5) * dx;
58  const Real y = prob_lo_y + (j + 0.5) * dy;
59  const Real z = z_cc(i,j,k);
60 
61  const Real r = std::sqrt((x-xc)*(x-xc) + (y-yc)*(y-yc) + (z-zc)*(z-zc));
62 
63  // Add temperature perturbations
64  if ((z <= pert_ref_height) && (T_0_Pert_Mag != 0.0)) {
65  Real rand_double = amrex::Random(engine); // Between 0.0 and 1.0
66  state_pert(i, j, k, RhoTheta_comp) = (rand_double*2.0 - 1.0)*T_0_Pert_Mag;
67  if (!pert_rhotheta) {
68  // we're perturbing theta, not rho*theta
69  state_pert(i, j, k, RhoTheta_comp) *= r_hse(i,j,k);
70  }
71  }
72 
73  // Set scalar = A_0*exp(-10r^2), where r is distance from center of domain
74  state_pert(i, j, k, RhoScalar_comp) = A_0 * exp(-10.*r*r);
75 
76  // Set an initial value for SGS KE
77  if (state_pert.nComp() > RhoKE_comp) {
78  // Deardorff
79  if (rhoKE_0 > 0) {
80  state_pert(i, j, k, RhoKE_comp) = rhoKE_0;
81  } else {
82  state_pert(i, j, k, RhoKE_comp) = r_hse(i,j,k) * KE_0;
83  }
84  if (KE_decay_height > 0) {
85  // scale initial SGS kinetic energy with height
86  state_pert(i, j, k, RhoKE_comp) *= amrex::max(
87  std::pow(1 - amrex::min(z/KE_decay_height,1.0), KE_decay_order),
88  1e-12);
89  }
90  }
91  });
92 
#define RhoScalar_comp
Definition: ERF_IndexDefines.H:40
#define RhoTheta_comp
Definition: ERF_IndexDefines.H:37
#define RhoKE_comp
Definition: ERF_IndexDefines.H:38
const Real prob_lo_z
Definition: ERF_InitCustomPert_ABL.H:27
const Real prob_lo_y
Definition: ERF_InitCustomPert_ABL.H:26
ParallelForRNG(bx, [=] AMREX_GPU_DEVICE(int i, int j, int k, const amrex::RandomEngine &engine) noexcept { const Real x=prob_lo_x+(i+0.5) *dx;const Real y=prob_lo_y+(j+0.5) *dy;const Real z=z_cc(i, j, k);const Real r=std::sqrt((x-xc) *(x-xc)+(y-yc) *(y-yc)+(z-zc) *(z-zc));if((z<=pert_ref_height) &&(T_0_Pert_Mag !=0.0)) { Real rand_double=amrex::Random(engine);state_pert(i, j, k, RhoTheta_comp)=(rand_double *2.0 - 1.0) *T_0_Pert_Mag;if(!pert_rhotheta) { state_pert(i, j, k, RhoTheta_comp) *=r_hse(i, j, k);} } state_pert(i, j, k, RhoScalar_comp)=A_0 *exp(-10.*r *r);if(state_pert.nComp() > RhoKE_comp) { if(rhoKE_0 > 0) { state_pert(i, j, k, RhoKE_comp)=rhoKE_0;} else { state_pert(i, j, k, RhoKE_comp)=r_hse(i, j, k) *KE_0;} if(KE_decay_height > 0) { state_pert(i, j, k, RhoKE_comp) *=amrex::max(std::pow(1 - amrex::min(z/KE_decay_height, 1.0), KE_decay_order), 1e-12);} } })
Real T_0_Pert_Mag
Definition: ERF_InitCustomPert_ABL.H:14
Real pert_ref_height
Definition: ERF_InitCustomPert_ABL.H:20
Real KE_0
Definition: ERF_InitCustomPert_ABL.H:7
const Real dy
Definition: ERF_InitCustomPert_ABL.H:24
Real rho_0
Definition: ERF_InitCustomPert_ABL.H:4
const Real zc
Definition: ERF_InitCustomPert_ABL.H:35
Real rhoKE_0
Definition: ERF_InitCustomPert_ABL.H:8
const Real yc
Definition: ERF_InitCustomPert_ABL.H:34
ParmParse pp("prob")
const Real prob_lo_x
Definition: ERF_InitCustomPert_ABL.H:25
Real T_0
Definition: ERF_InitCustomPert_ABL.H:5
Real pert_deltaV
Definition: ERF_InitCustomPert_ABL.H:19
const Real prob_hi_y
Definition: ERF_InitCustomPert_ABL.H:29
const Real prob_hi_x
Definition: ERF_InitCustomPert_ABL.H:28
Real KE_decay_order
Definition: ERF_InitCustomPert_ABL.H:11
Real pert_deltaU
Definition: ERF_InitCustomPert_ABL.H:18
const Real prob_hi_z
Definition: ERF_InitCustomPert_ABL.H:30
Real KE_decay_height
Definition: ERF_InitCustomPert_ABL.H:10
bool pert_rhotheta
Definition: ERF_InitCustomPert_ABL.H:15
Real A_0
Definition: ERF_InitCustomPert_ABL.H:6
const Real xc
Definition: ERF_InitCustomPert_ABL.H:33
const Real dx
Definition: ERF_InitCustomPert_ABL.H:23
state_pert(i, j, k, RhoTheta_comp)
amrex::Real Real
Definition: ERF_ShocInterface.H:19