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 
18  // The Dirichlet wall value of k (first cell above the wall) is pinned by
19  // erf_slow_rhs_post and the implicit solve; leave it untouched here.
20  const bool l_dirichlet_k = ( l_tc.rans_type == RANSType::kEqn && l_tc.dirichlet_k &&
21  (m_SurfaceLayer[Orientation(Direction::z, Orientation::low)] != nullptr) );
22  const int l_klo = fine_geom.Domain().smallEnd(2);
23 
26 
27  // Every state component from RhoQ1_comp to the end of the state. With SBM
28  // only the host-owned qv is limited; the projected liquid lanes are owned by
29  // the spectral solver.
30  const int l_nq = (l_sbm) ? 1 : S_new[IntVars::cons].nComp() - RhoQ1_comp;
31 
32  if (l_limit_Q) {
35  }
36 
38 #ifdef _OPENMP
39 #pragma omp parallel if (Gpu::notInLaunchRegion())
40 #endif
41  for ( MFIter mfi(S_new[IntVars::cons],TilingIfNotGPU()); mfi.isValid(); ++mfi)
42  {
43  const Box& tbx = mfi.tilebox();
44  const Array4<Real>& cons = S_new[IntVars::cons].array(mfi);
45 
46  if (l_limit_KE) {
47  const bool skip_klo = l_dirichlet_k && (tbx.smallEnd(2) <= l_klo);
48  ParallelFor(tbx, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept
49  {
50  if (skip_klo && k == l_klo) { return; }
51  const Real ke_floor = (l_tke_floor > zero) ? cons(i,j,k,Rho_comp) * l_tke_floor : l_eps;
52  cons(i,j,k,RhoKE_comp) = amrex::max(cons(i,j,k,RhoKE_comp), ke_floor);
53  });
54  }
55 
56  if (l_limit_Q) {
57  ParallelFor(tbx, l_nq, [=,zero_d=zero] AMREX_GPU_DEVICE (int i, int j, int k, int nn) noexcept
58  {
59  const int n = RhoQ1_comp + nn;
60  cons(i,j,k,n) = amrex::max(cons(i,j,k,n), zero_d);
61  });
62  }
63  } // mfi
64  } // limit KE or Q
65  } // profile
#define Rho_comp
Definition: ERF_IndexDefines.H:42
#define RhoQ1_comp
Definition: ERF_IndexDefines.H:48
#define RhoKE_comp
Definition: ERF_IndexDefines.H:44
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:22
const Real l_eps
Definition: ERF_ScalarLimitPost.H:25
const bool l_dirichlet_k
Definition: ERF_ScalarLimitPost.H:20
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:30
const bool l_limit_Q
Definition: ERF_ScalarLimitPost.H:15
const Real l_tke_floor
Definition: ERF_ScalarLimitPost.H:24
amrex::Real Real
Definition: ERF_ShocInterface.H:19
@ cons
Definition: ERF_IndexDefines.H:235
@ None
Definition: ERF_LSM_Types.H:6
@ nn
Definition: ERF_WDM6.H:32
@ cons
Definition: ERF_IndexDefines.H:217
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_TurbStruct.H:115
bool use_tke
Whether any TKE or QKE closure is active.
Definition: ERF_TurbStruct.H:927
RANSType rans_type
Selected RANS closure.
Definition: ERF_TurbStruct.H:828
amrex::Real tke_floor
Definition: ERF_TurbStruct.H:835
bool dirichlet_k
Whether TKE uses Dirichlet boundary treatment.
Definition: ERF_TurbStruct.H:830