ERF
Energy Research and Forecasting: An Atmospheric Modeling Code
ShocTKE Class Reference

#include <ERF_ShocTKE.H>

Static Public Member Functions

static void compute_shear_production (const ShocColumnData &col, amrex::FArrayBox &sterm_iface)
 
static void integrate_column_stability (const ShocColumnData &col, amrex::Vector< amrex::Real > &brunt_int)
 
static void diagnose_tke_and_diffusivities (ShocColumnData &col, const ShocRuntimeOptions &opts, amrex::Real dt)
 

Member Function Documentation

◆ compute_shear_production()

void ShocTKE::compute_shear_production ( const ShocColumnData col,
amrex::FArrayBox &  sterm_iface 
)
static
109 {
110  const Box iface_box(IntVect(0,0,0), IntVect(col.layout.ncell - 1, col.layout.nlev, 0));
111  sterm_iface.resize(iface_box, 1, The_Async_Arena());
112  sterm_iface.template setVal<amrex::RunOn::Device>(0.0);
113 
114  auto sterm = sterm_iface.array();
115  const auto u = col.u.const_array();
116  const auto v = col.v.const_array();
117  const auto zt = col.zt.const_array();
118  const auto zi = col.zi.const_array();
119  const auto layout = col.layout;
120  const Box col_box(IntVect(0,0,0), IntVect(layout.ncell - 1, 0, 0));
121 
122  ParallelFor(col_box, [=] AMREX_GPU_DEVICE (int ic, int, int) noexcept
123  {
124  sterm(ic,0,0) = 0.0_rt;
125  sterm(ic,layout.nlev,0) = 0.0_rt;
126  for (int k = 1; k < layout.nlev; ++k) {
127  const Real dz_zi = interface_spacing(zt, zi, layout, ic, k);
128  const Real du_dz = (u(ic,k-1,0) - u(ic,k,0)) / dz_zi;
129  const Real dv_dz = (v(ic,k-1,0) - v(ic,k,0)) / dz_zi;
130  sterm(ic,k,0) = shoc_shear_ck() * (du_dz * du_dz + dv_dz * dv_dz);
131  }
132  });
133 }
ParallelFor(grown_box, [=] AMREX_GPU_DEVICE(int i, int j, int k) { qrcuten_arr(i, j, k)=Real(0);qscuten_arr(i, j, k)=Real(0);qicuten_arr(i, j, k)=Real(0);})
amrex::Real Real
Definition: ERF_ShocInterface.H:19
@ zi
Definition: ERF_AdvanceWSM6.cpp:133
ShocColumnLayout layout
Definition: ERF_ShocTypes.H:205
amrex::FArrayBox zi
Definition: ERF_ShocTypes.H:209
amrex::FArrayBox v
Definition: ERF_ShocTypes.H:225
amrex::FArrayBox zt
Definition: ERF_ShocTypes.H:208
amrex::FArrayBox u
Definition: ERF_ShocTypes.H:224
int nlev
Definition: ERF_ShocTypes.H:196
int ncell
Definition: ERF_ShocTypes.H:195
Here is the call graph for this function:

◆ diagnose_tke_and_diffusivities()

void ShocTKE::diagnose_tke_and_diffusivities ( ShocColumnData col,
const ShocRuntimeOptions opts,
amrex::Real  dt 
)
static
157 {
158  AMREX_ALWAYS_ASSERT(dt > 0.0);
159 
160  const Box cell_box(IntVect(0,0,0), IntVect(col.layout.ncell - 1, col.layout.nlev - 1, 0));
161  FArrayBox sterm_iface;
162  FArrayBox sterm_zt(cell_box, 1, The_Async_Arena());
163  FArrayBox a_diss(cell_box, 1, The_Async_Arena());
164 
165  compute_shear_production(col, sterm_iface);
166  interpolate_iface_to_cc(col, sterm_iface, sterm_zt, 0.0);
167 
168  auto tke = col.tke.array();
169  auto isotropy = col.isotropy.array();
170  auto tk = col.tk.array();
171  auto tkh = col.tkh.array();
172  auto tke_tend = col.tke_tend.array();
173  auto shear_prod_arr = col.shear_prod.array();
174  auto buoy_prod_arr = col.buoy_prod.array();
175  auto diss_arr = col.diss_tke.array();
176 
177  const auto wthv_sec = col.wthv_sec.const_array();
178  const auto shoc_mix = col.shoc_mix.const_array();
179  const auto brunt = col.brunt.const_array();
180  const auto zt = col.zt.const_array();
181  const auto tabs = col.tabs.const_array();
182  const auto pblh = col.pblh.const_array();
183  const auto sterm = sterm_zt.const_array();
184  auto a_diss_arr = a_diss.array();
185  const auto dz = col.dz.const_array();
186  const auto p_mid = col.p_mid.const_array();
187  const auto zi = col.zi.const_array();
188  const auto layout = col.layout;
189  const Box col_box(IntVect(0,0,0), IntVect(layout.ncell - 1, 0, 0));
190 
191  ParallelFor(col_box, [=] AMREX_GPU_DEVICE (int ic, int, int) noexcept
192  {
193  const Real z_sfc = zi(ic,0,0);
194  Real brunt_int = 0.0_rt;
195  for (int k = 0; k < layout.nlev; ++k) {
196  if (p_mid(ic,k,0) > shoc_trop_pres()) {
197  brunt_int += dz(ic,k,0) * brunt(ic,k,0);
198  }
199 
200  const Real old_tke = amrex::max(0.0_rt, tke(ic,k,0));
201  const Real buoy_prod = opts.shoc_1p5tke
202  ? -old_tke * brunt(ic,k,0)
203  : (CONST_GRAV / shoc_base_temp()) * wthv_sec(ic,k,0);
204  const Real shear_prod = tk(ic,k,0) * sterm(ic,k,0);
205  const Real mix = amrex::max(shoc_mix(ic,k,0), 1.0e-12_rt);
206  const Real diss = shoc_tke_cee() / mix * old_tke * std::sqrt(old_tke);
207  const Real net_prod = opts.signed_tke_production
208  ? (shear_prod + buoy_prod)
209  : amrex::max(0.0_rt, shear_prod + buoy_prod);
210  const Real raw_new_tke = shoc_clamp(old_tke + dt * (net_prod - diss),
211  shoc_min_tke(), shoc_max_tke());
212  const Real top_factor = top_taper_factor(zt, zi, layout, opts, ic, k);
213  const Real new_tke = shoc_clamp(shoc_min_tke() +
214  top_factor * (raw_new_tke - shoc_min_tke()),
215  shoc_min_tke(), shoc_max_tke());
216 
217  a_diss_arr(ic,k,0) = top_factor * diss;
218  shear_prod_arr(ic,k,0) = top_factor * shear_prod;
219  buoy_prod_arr(ic,k,0) = top_factor * buoy_prod;
220  diss_arr(ic,k,0) = top_factor * diss;
221  tke_tend(ic,k,0) = new_tke - old_tke;
222  tke(ic,k,0) = new_tke;
223  }
224 
225  Real lambda = opts.lambda_low + ((brunt_int / CONST_GRAV) - opts.lambda_thresh) * opts.lambda_slope;
226  lambda = shoc_clamp(lambda, opts.lambda_low, opts.lambda_high);
227 
228  for (int k = 0; k < layout.nlev; ++k) {
229  const Real diss = amrex::max(a_diss_arr(ic,k,0), 1.0e-12_rt);
230  const Real tscale = 2.0_rt * tke(ic,k,0) / diss;
231  const Real local_lambda = (brunt(ic,k,0) <= 0.0_rt) ? 0.0_rt : lambda;
232  isotropy(ic,k,0) = amrex::min(shoc_max_iso(),
233  tscale / (1.0_rt + local_lambda * brunt(ic,k,0) * tscale * tscale));
234 
235  const Real zt_agl = shoc::height_agl(zt(ic,k,0), z_sfc);
236  const bool use_stable_mix = (zt_agl < pblh(ic,0,0) + shoc_pbl_trans()) &&
237  (tabs(ic,0,0) < shoc_tabs_crit());
238  if (use_stable_mix) {
239  const Real sterm_sqrt = std::sqrt(amrex::max(sterm(ic,k,0), 0.0_rt));
240  tkh(ic,k,0) = shoc_stable_ckh() * shoc_mix(ic,k,0) * shoc_mix(ic,k,0) * sterm_sqrt;
241  tk(ic,k,0) = shoc_stable_ckm() * shoc_mix(ic,k,0) * shoc_mix(ic,k,0) * sterm_sqrt;
242  } else {
243  tkh(ic,k,0) = opts.coeff_kh * isotropy(ic,k,0) * tke(ic,k,0);
244  tk(ic,k,0) = opts.coeff_km * isotropy(ic,k,0) * tke(ic,k,0);
245  }
246 
247  const Real top_factor = top_taper_factor(zt, zi, layout, opts, ic, k);
248  isotropy(ic,k,0) *= top_factor;
249  tkh(ic,k,0) = top_factor * amrex::max(0.0_rt, tkh(ic,k,0));
250  tk(ic,k,0) = top_factor * amrex::max(0.0_rt, tk(ic,k,0));
251  }
252  });
253 }
constexpr amrex::Real CONST_GRAV
Definition: ERF_Constants.H:53
AMREX_ALWAYS_ASSERT(bx.length()[2]==khi+1)
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE T shoc_clamp(T value, T lo, T hi)
Definition: ERF_ShocTypes.H:382
static void compute_shear_production(const ShocColumnData &col, amrex::FArrayBox &sterm_iface)
Definition: ERF_ShocTKE.cpp:107
@ tabs
Definition: ERF_Kessler.H:25
@ dz
Definition: ERF_AdvanceWSM6.cpp:104
@ tk
Definition: ERF_AdvanceWSM6.cpp:111
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real height_agl(amrex::Real z, amrex::Real z_sfc) noexcept
Definition: ERF_ShocGpuUtils.H:46
amrex::FArrayBox buoy_prod
Definition: ERF_ShocTypes.H:239
amrex::FArrayBox dz
Definition: ERF_ShocTypes.H:210
amrex::FArrayBox diss_tke
Definition: ERF_ShocTypes.H:240
amrex::FArrayBox tk
Definition: ERF_ShocTypes.H:236
amrex::FArrayBox shoc_mix
Definition: ERF_ShocTypes.H:233
amrex::FArrayBox wthv_sec
Definition: ERF_ShocTypes.H:241
amrex::FArrayBox shear_prod
Definition: ERF_ShocTypes.H:238
amrex::FArrayBox pblh
Definition: ERF_ShocTypes.H:230
amrex::FArrayBox isotropy
Definition: ERF_ShocTypes.H:235
amrex::FArrayBox tke
Definition: ERF_ShocTypes.H:223
amrex::FArrayBox tkh
Definition: ERF_ShocTypes.H:237
amrex::FArrayBox tke_tend
Definition: ERF_ShocTypes.H:275
amrex::FArrayBox tabs
Definition: ERF_ShocTypes.H:222
amrex::FArrayBox p_mid
Definition: ERF_ShocTypes.H:211
amrex::FArrayBox brunt
Definition: ERF_ShocTypes.H:234
bool shoc_1p5tke
Definition: ERF_ShocTypes.H:99
amrex::Real coeff_kh
Definition: ERF_ShocTypes.H:94
amrex::Real lambda_high
Definition: ERF_ShocTypes.H:83
amrex::Real lambda_thresh
Definition: ERF_ShocTypes.H:85
amrex::Real coeff_km
Definition: ERF_ShocTypes.H:95
amrex::Real lambda_slope
Definition: ERF_ShocTypes.H:84
amrex::Real lambda_low
Definition: ERF_ShocTypes.H:82
bool signed_tke_production
Definition: ERF_ShocTypes.H:106

Referenced by ShocDiagnostics::diagnose_pre_implicit().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ integrate_column_stability()

void ShocTKE::integrate_column_stability ( const ShocColumnData col,
amrex::Vector< amrex::Real > &  brunt_int 
)
static
138 {
139  brunt_int.assign(col.layout.ncell, 0.0);
140  const auto dz = col.dz.const_array();
141  const auto p_mid = col.p_mid.const_array();
142  const auto brunt = col.brunt.const_array();
143 
144  for (int ic = 0; ic < col.layout.ncell; ++ic) {
145  for (int k = 0; k < col.layout.nlev; ++k) {
146  if (p_mid(ic,k,0) > shoc_trop_pres()) {
147  brunt_int[ic] += dz(ic,k,0) * brunt(ic,k,0);
148  }
149  }
150  }
151 }

The documentation for this class was generated from the following files: