ERF
Energy Research and Forecasting: An Atmospheric Modeling Code
ERF_ScalarLimitPost.H
Go to the documentation of this file.
1  // *****************************************************************************
2  // Limit the slow scalars once the whole stage update is complete: after the
3  // explicit update in erf_slow_rhs_post, the implicit vertical diffusion
4  // in ERF_ImplicitPost.H and (with EB) state redistribution. Doing this in
5  // one place keeps explicit and implicit diffusion consistent.
6  // - rho*KE is floored at rho*tke_floor (or machine epsilon if tke_floor <= 0)
7  // - rho*Q is floored at zero
8  // *****************************************************************************
9  {
10  BL_PROFILE("slow_rhs_post_limit");
11 
12  const TurbChoice& l_tc = solverChoice.turbChoice[level];
13 
14  const bool l_limit_KE = l_tc.use_tke;
15  const bool l_limit_Q = (solverChoice.moisture_type != MoistureType::None);
16  const bool l_sbm = (solverChoice.moisture_type == MoistureType::SBM);
17  const DiffChoice l_diff_choice = solverChoice.diffChoice;
18 
19  // The Dirichlet wall value of k (first cell above the wall) is pinned by
20  // erf_slow_rhs_post and the implicit solve; leave it untouched here.
21  const bool l_dirichlet_k = ( l_tc.rans_type == RANSType::kEqn && l_tc.dirichlet_k &&
22  (m_SurfaceLayer[Orientation(Direction::z, Orientation::low)] != nullptr) );
23  const int l_klo = fine_geom.Domain().smallEnd(2);
24 
27 
28  // Every state component from RhoQ1_comp to the end of the state. With SBM
29  // only the host-owned qv is limited; the projected liquid lanes are owned by
30  // the spectral solver.
31  const int l_nq = (l_sbm) ? 1 : S_new[IntVars::cons].nComp() - RhoQ1_comp;
32 
33  if (l_limit_Q) {
36  }
37 
39 #ifdef _OPENMP
40 #pragma omp parallel if (Gpu::notInLaunchRegion())
41 #endif
42  for ( MFIter mfi(S_new[IntVars::cons],TilingIfNotGPU()); mfi.isValid(); ++mfi)
43  {
44  const Box& tbx = mfi.tilebox();
45  const Array4<Real>& cons = S_new[IntVars::cons].array(mfi);
46 
47  if (l_limit_KE) {
48  const bool skip_klo = l_dirichlet_k && (tbx.smallEnd(2) <= l_klo);
49  ParallelFor(tbx, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept
50  {
51  if (skip_klo && k == l_klo) { return; }
52  const Real ke_floor = (l_tke_floor > zero) ? cons(i,j,k,Rho_comp) * l_tke_floor : l_eps;
53  cons(i,j,k,RhoKE_comp) = amrex::max(cons(i,j,k,RhoKE_comp), ke_floor);
54  });
55  }
56 
57  if (l_limit_Q) {
58  ParallelFor(tbx, l_nq, [=,zero_d=zero] AMREX_GPU_DEVICE (int i, int j, int k, int nn) noexcept
59  {
60  const int n = RhoQ1_comp + nn;
61  if (!l_diff_choice.host_transports(n)) { return; }
62  cons(i,j,k,n) = amrex::max(cons(i,j,k,n), zero_d);
63  });
64  }
65  } // mfi
66  } // limit KE or Q
67  } // profile
#define Rho_comp
Definition: ERF_IndexDefines.H:53
#define RhoQ1_comp
Definition: ERF_IndexDefines.H:66
#define RhoKE_comp
Definition: ERF_IndexDefines.H:55
ParallelFor(fab_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);})
constexpr amrex::Real zero
Definition: ERF_NumericalConstants.H:36
const bool l_sbm
Definition: ERF_ScalarLimitPost.H:16
const int l_klo
Definition: ERF_ScalarLimitPost.H:23
const Real l_eps
Definition: ERF_ScalarLimitPost.H:26
const DiffChoice l_diff_choice
Definition: ERF_ScalarLimitPost.H:17
const bool l_dirichlet_k
Definition: ERF_ScalarLimitPost.H:21
const TurbChoice & l_tc
Definition: ERF_ScalarLimitPost.H:12
const bool l_limit_KE
Definition: ERF_ScalarLimitPost.H:14
const int l_nq
Definition: ERF_ScalarLimitPost.H:31
const bool l_limit_Q
Definition: ERF_ScalarLimitPost.H:15
const Real l_tke_floor
Definition: ERF_ScalarLimitPost.H:25
amrex::Real Real
Definition: ERF_ShocInterface.H:19
@ cons
Definition: ERF_IndexDefines.H:272
@ None
Definition: ERF_LSM_Types.H:6
@ nn
Definition: ERF_WDM6.H:33
@ cons
Definition: ERF_IndexDefines.H:254
void require_host_write_range_allowed(const bool sbm_active, const int start_component, const int num_components, const HostWritePath path)
Definition: ERF_SBMOwnership.cpp:47
real(c_double), parameter epsilon
Definition: ERF_module_model_constants.F90:12
Definition: ERF_DiffStruct.H:24
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE bool host_transports(int n) const noexcept
Definition: ERF_DiffStruct.H:121
Definition: ERF_TurbStruct.H:119
bool use_tke
Whether any TKE or QKE closure is active.
Definition: ERF_TurbStruct.H:983
RANSType rans_type
Selected RANS closure.
Definition: ERF_TurbStruct.H:877
amrex::Real tke_floor
Definition: ERF_TurbStruct.H:884
bool dirichlet_k
Whether TKE uses Dirichlet boundary treatment.
Definition: ERF_TurbStruct.H:879