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

#include <ERF_ShocPDF.H>

Static Public Member Functions

static void diagnose_pdf (ShocColumnData &col, const ShocRuntimeOptions &opts, amrex::Real dt)
 

Member Function Documentation

◆ diagnose_pdf()

void ShocPDF::diagnose_pdf ( ShocColumnData col,
const ShocRuntimeOptions opts,
amrex::Real  dt 
)
static
279 {
280  // Interim native-SHOC contract: this PDF remains liquid-cloud
281  // macrophysics. It may carry pre-existing ice through the thermodynamic
282  // state, but it does not create or repartition cloud ice here.
283  FArrayBox w3_zt, thl_sec_zt, qw_sec_zt, wthl_zt, wqw_zt, qwthl_zt;
284  const auto layout = col.layout;
285  const Box cell_box(IntVect(0,0,0), IntVect(layout.ncell - 1, layout.nlev - 1, 0));
286  w3_zt.resize(cell_box, 1, The_Async_Arena());
287  thl_sec_zt.resize(cell_box, 1, The_Async_Arena());
288  qw_sec_zt.resize(cell_box, 1, The_Async_Arena());
289  wthl_zt.resize(cell_box, 1, The_Async_Arena());
290  wqw_zt.resize(cell_box, 1, The_Async_Arena());
291  qwthl_zt.resize(cell_box, 1, The_Async_Arena());
292 
293  {
294  BL_PROFILE("SHOC::advance::pdf::interpolate");
295  interpolate_iface_to_cc(col, col.w3, w3_zt, shoc_large_neg());
296  interpolate_iface_to_cc(col, col.thl_sec, thl_sec_zt, 0.0_rt);
297  interpolate_iface_to_cc(col, col.qw_sec, qw_sec_zt, 0.0_rt);
298  interpolate_iface_to_cc(col, col.wthl_sec, wthl_zt, shoc_large_neg());
299  interpolate_iface_to_cc(col, col.wqw_sec, wqw_zt, shoc_large_neg());
300  interpolate_iface_to_cc(col, col.qwthl_sec, qwthl_zt, shoc_large_neg());
301  }
302 
303  auto shoc_cldfrac = col.shoc_cldfrac.array();
304  auto shoc_ql = col.shoc_ql.array();
305  auto shoc_ql2 = col.shoc_ql2.array();
306  auto shoc_cond = col.shoc_cond.array();
307  auto shoc_evap = col.shoc_evap.array();
308  auto wqls_sec = col.wqls_sec.array();
309  auto wthv_sec = col.wthv_sec.array();
310 
311  const auto thetal = col.thetal.const_array();
312  const auto qw = col.qw.const_array();
313  const auto w_field = col.w.const_array();
314  const auto p_mid = col.p_mid.const_array();
315  const auto thl_sec = thl_sec_zt.const_array();
316  const auto qw_sec = qw_sec_zt.const_array();
317  const auto qwthl_sec = qwthl_zt.const_array();
318  const auto wthl_sec = wthl_zt.const_array();
319  const auto wqw_sec = wqw_zt.const_array();
320  const auto w_sec = col.w_sec.const_array();
321  const auto w3 = w3_zt.const_array();
322 
323  {
324  BL_PROFILE("SHOC::advance::pdf::main_kernel");
325  ParallelFor(cell_box, [=] AMREX_GPU_DEVICE (int ic, int k, int) noexcept
326  {
327  const Real thl_first = thetal(ic,k,0);
328  const Real qw_first = qw(ic,k,0);
329  const Real w_first = w_field(ic,k,0);
330  const Real w2sec = amrex::max(w_sec(ic,k,0), 0.0_rt);
331  const Real sqrtw2 = std::sqrt(w2sec);
332  const Real sqrtthl = amrex::max(shoc_thl_tol(), std::sqrt(amrex::max(thl_sec(ic,k,0), 0.0_rt)));
333  const Real sqrtqt = amrex::max(shoc_rt_tol(), std::sqrt(amrex::max(qw_sec(ic,k,0), 0.0_rt)));
334 
335  Real skew_w = 0.0, w1_1 = w_first, w1_2 = w_first, w2_1 = 0.0, w2_2 = 0.0, a = 0.5;
336  vv_parameters(w_first, w2sec, w3(ic,k,0), skew_w, w1_1, w1_2, w2_1, w2_2, a);
337 
338  Real thl1_1 = thl_first, thl1_2 = thl_first, thl2_1 = 0.0, thl2_2 = 0.0;
339  Real sqrtthl2_1 = 0.0, sqrtthl2_2 = 0.0;
340  thl_parameters(wthl_sec(ic,k,0), sqrtw2, sqrtthl, amrex::max(thl_sec(ic,k,0), 0.0_rt),
341  thl_first, w1_1, w1_2, skew_w, a,
342  thl1_1, thl1_2, thl2_1, thl2_2, sqrtthl2_1, sqrtthl2_2);
343 
344  Real qw1_1 = qw_first, qw1_2 = qw_first, qw2_1 = 0.0, qw2_2 = 0.0;
345  Real sqrtqw2_1 = 0.0, sqrtqw2_2 = 0.0;
346  qw_parameters(wqw_sec(ic,k,0), sqrtw2, skew_w, sqrtqt, amrex::max(qw_sec(ic,k,0), 0.0_rt),
347  w1_2, w1_1, qw_first, a,
348  qw1_1, qw1_2, qw2_1, qw2_2, sqrtqw2_1, sqrtqw2_2);
349 
350  w1_1 = w1_1 * sqrtw2 + w_first;
351  w1_2 = w1_2 * sqrtw2 + w_first;
352 
353  const Real r_qwthl_1 = inplume_correlation(sqrtqw2_1, sqrtthl2_1, a,
354  sqrtqw2_2, sqrtthl2_2,
355  qwthl_sec(ic,k,0), qw1_1, qw_first,
356  thl1_1, thl_first, qw1_2, thl1_2);
357 
358  Real Tl1_1 = amrex::max(shoc_tl_min(), compute_temperature(thl1_1, p_mid(ic,k,0)));
359  Real Tl1_2 = amrex::max(shoc_tl_min(), compute_temperature(thl1_2, p_mid(ic,k,0)));
360  Real qs1 = 0.0_rt, beta1 = 0.0_rt, qs2 = 0.0_rt, beta2 = 0.0_rt;
361  compute_qs_beta(Tl1_1, p_mid(ic,k,0), qs1, beta1);
362  compute_qs_beta(Tl1_2, p_mid(ic,k,0), qs2, beta2);
363 
364  Real s1 = 0.0_rt, std_s1 = 0.0_rt, qn1 = 0.0_rt, c1 = 0.0_rt;
365  Real s2 = 0.0_rt, std_s2 = 0.0_rt, qn2 = 0.0_rt, c2 = 0.0_rt;
366  compute_s_terms(qw1_1, qs1, beta1, p_mid(ic,k,0), thl2_1, qw2_1,
367  sqrtthl2_1, sqrtqw2_1, r_qwthl_1, s1, std_s1, qn1, c1);
368 
369  if (qw1_1 == qw1_2 && thl2_1 == thl2_2 && qs1 == qs2) {
370  s2 = s1;
371  std_s2 = std_s1;
372  qn2 = qn1;
373  c2 = c1;
374  } else {
375  compute_s_terms(qw1_2, qs2, beta2, p_mid(ic,k,0), thl2_2, qw2_2,
376  sqrtthl2_2, sqrtqw2_2, r_qwthl_1, s2, std_s2, qn2, c2);
377  }
378 
379  const Real ql1 = amrex::min(qn1, qw1_1);
380  const Real ql2 = amrex::min(qn2, qw1_2);
381  const Real old_ql = shoc_ql(ic,k,0);
382  const Real cldfrac = amrex::min(1.0_rt, a * c1 + (1.0_rt - a) * c2);
383  const Real ql = amrex::max(0.0_rt, a * ql1 + (1.0_rt - a) * ql2);
384  const Real ql2_var = amrex::max(0.0_rt, a * (s1 * ql1 + c1 * std_s1 * std_s1)
385  + (1.0_rt - a) * (s2 * ql2 + c2 * std_s2 * std_s2)
386  - ql * ql);
387  const Real wqls = a * ((w1_1 - w_first) * ql1) + (1.0_rt - a) * ((w1_2 - w_first) * ql2);
388 
389  shoc_cldfrac(ic,k,0) = clamp01(cldfrac);
390  shoc_ql(ic,k,0) = ql;
391  shoc_ql2(ic,k,0) = ql2_var;
392  wqls_sec(ic,k,0) = wqls;
393  wthv_sec(ic,k,0) = compute_buoyancy_flux(wthl_sec(ic,k,0), wqw_sec(ic,k,0),
394  p_mid(ic,k,0), wqls);
395 
396  if (opts.extra_shoc_diags) {
397  const Real ql_change = ql - old_ql;
398  shoc_cond(ic,k,0) = amrex::max(0.0_rt, ql_change / amrex::max(dt, 1.0e-12_rt));
399  shoc_evap(ic,k,0) = amrex::max(0.0_rt, -ql_change / amrex::max(dt, 1.0e-12_rt));
400  } else {
401  shoc_cond(ic,k,0) = 0.0_rt;
402  shoc_evap(ic,k,0) = 0.0_rt;
403  }
404  });
405  }
406 }
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
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:478
@ qn2
Definition: ERF_AdvanceWSM6.cpp:103
real(c_double), parameter c2
Definition: ERF_module_model_constants.F90:35
real(c_double), private c1
Definition: ERF_module_mp_morr_two_moment.F90:212
amrex::FArrayBox shoc_cond
Definition: ERF_ShocTypes.H:246
amrex::FArrayBox w_sec
Definition: ERF_ShocTypes.H:258
amrex::FArrayBox w3
Definition: ERF_ShocTypes.H:257
amrex::FArrayBox shoc_evap
Definition: ERF_ShocTypes.H:247
amrex::FArrayBox wthv_sec
Definition: ERF_ShocTypes.H:241
amrex::FArrayBox wqw_sec
Definition: ERF_ShocTypes.H:253
amrex::FArrayBox shoc_ql
Definition: ERF_ShocTypes.H:243
amrex::FArrayBox w
Definition: ERF_ShocTypes.H:226
amrex::FArrayBox qw_sec
Definition: ERF_ShocTypes.H:250
ShocColumnLayout layout
Definition: ERF_ShocTypes.H:205
amrex::FArrayBox qw
Definition: ERF_ShocTypes.H:221
amrex::FArrayBox p_mid
Definition: ERF_ShocTypes.H:211
amrex::FArrayBox wqls_sec
Definition: ERF_ShocTypes.H:245
amrex::FArrayBox wthl_sec
Definition: ERF_ShocTypes.H:252
amrex::FArrayBox thl_sec
Definition: ERF_ShocTypes.H:249
amrex::FArrayBox shoc_ql2
Definition: ERF_ShocTypes.H:244
amrex::FArrayBox qwthl_sec
Definition: ERF_ShocTypes.H:251
amrex::FArrayBox shoc_cldfrac
Definition: ERF_ShocTypes.H:242
amrex::FArrayBox thetal
Definition: ERF_ShocTypes.H:217
bool extra_shoc_diags
Definition: ERF_ShocTypes.H:100

Referenced by ShocDiagnostics::diagnose_post_implicit().

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

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