1 #ifndef ERF_PBL_HEIGHT_H_
2 #define ERF_PBL_HEIGHT_H_
4 #include <AMReX_MultiFabUtil.H>
27 const amrex::MultiFab* z_phys_cc,
28 amrex::MultiFab* pblh,
29 const amrex::MultiFab&
cons,
30 const amrex::iMultiFab* lmask,
37 auto const& cons_arrs =
cons.const_arrays();
38 auto thetav_min = amrex::ReduceToPlane<amrex::ReduceOpMin,amrex::Real>(dir, bxlow,
cons,
39 [=] AMREX_GPU_DEVICE (
int box_no,
int i,
int j,
int k) ->
amrex::Real
41 return GetThetav(i,j,k,cons_arrs[box_no],moisture_indices);
46 auto const& ba = pblh->boxArray();
47 auto const& dm = pblh->DistributionMap();
48 auto const&
ng = pblh->nGrowVect();
50 amrex::MultiFab min_thetav(ba,dm,1,
ng);
53 amrex::MultiFab pblh_tke(ba,dm,1,
ng);
54 pblh_tke.setVal(
zero);
63 "MYNNPBLH::compute_pblh: the state must carry a ghost cell in z; the scan reads "
64 "one cell above the top of every box");
66 "MYNNPBLH::compute_pblh: z_phys_cc must carry a ghost cell in z; the scan reads "
67 "one cell above the top of every box");
70 for (amrex::MFIter mfi(
cons,
TileNoZ()); mfi.isValid(); ++mfi)
72 const amrex::Box& domain = geom.Domain();
85 const amrex::Box& vbx = mfi.validbox();
87 "MYNNPBLH::compute_pblh: every box must start at the bottom of the domain");
88 amrex::Box gtbx = mfi.growntilebox(
ng);
89 gtbx.setSmall(2,vbx.smallEnd(2));
90 gtbx.setBig(2,vbx.bigEnd(2));
97 amrex::Box gtbx2d = gtbx; gtbx2d.setRange(2,0);
98 const int klo = gtbx.smallEnd(2);
99 const int khi = gtbx.bigEnd(2);
101 auto min_thv_arr = min_thetav.array(mfi);
102 auto pblh_arr = pblh->array(mfi);
103 auto pblh_tke_arr = pblh_tke.array(mfi);
105 const auto cons_arr =
cons.const_array(mfi);
106 const auto lmask_arr = (lmask) ? lmask->const_array(mfi) : amrex::Array4<int> {};
113 const auto zphys_arr = z_phys_cc->const_array(mfi);
116 int imin = lbound(zphys_arr).x;
117 int jmin = lbound(zphys_arr).y;
118 int imax = ubound(zphys_arr).x;
119 int jmax = ubound(zphys_arr).y;
123 ParallelFor(gtbx2d, [=] AMREX_GPU_DEVICE(
int i,
int j,
int) noexcept
125 int ii = amrex::max(amrex::min(i,imax),imin);
126 int jj = amrex::max(amrex::min(j,jmax),jmin);
129 for (
int k(
klo); k <=
khi; ++k) {
132 min_thv = amrex::min(min_thv, thv);
135 min_thv_arr(i,j,0) = min_thv;
139 ParallelFor(gtbx2d, [=] AMREX_GPU_DEVICE(
int i,
int j,
int) noexcept
141 int ii = amrex::max(amrex::min(i,imax),imin);
142 int jj = amrex::max(amrex::min(j,jmax),jmin);
145 const int is_land = (lmask_arr) ? lmask_arr(i,j,0) : 1;
150 for (
int k(
klo); k <=
khi; ++k)
164 zi = zphys_arr(ii,jj,k)
165 + (zphys_arr(ii,jj,k+1)-zphys_arr(ii,jj,k))/(thv1-thv)
172 zi = zphys_arr(ii,jj,k)
173 + (zphys_arr(ii,jj,k+1)-zphys_arr(ii,jj,k))/(thv1-thv)
189 if ((tke1 <= TKEeps) && (tke > TKEeps))
192 zi_tke = zphys_arr(ii,jj,k)
193 + (zphys_arr(ii,jj,k+1)-zphys_arr(ii,jj,k))/(tke1-tke)
198 if ((
zi != 0) && (zi_tke != 0)) {
break; }
201 pblh_arr(i,j,0) =
zi;
202 pblh_tke_arr(i,j,0) = zi_tke;
210 const amrex::Real dz_no_terrain = geom.CellSize(2);
216 AMREX_ASSERT(kmax > 0);
217 const int khi_low = amrex::min(kmax,
khi);
219 ParallelFor(gtbx2d, [=] AMREX_GPU_DEVICE(
int i,
int j,
int) noexcept
222 for (
int k(
klo); k <= khi_low; ++k) {
224 min_thv = amrex::min(min_thv, thv);
226 min_thv_arr(i,j,0) = min_thv;
230 ParallelFor(gtbx2d, [=] AMREX_GPU_DEVICE(
int i,
int j,
int) noexcept
233 const int is_land = (lmask_arr) ? lmask_arr(i,j,0) : 1;
238 for (
int k(
klo); k <=
khi; ++k)
253 + dz_no_terrain/(thv1-thv)
261 + dz_no_terrain/(thv1-thv)
277 if ((tke1 <= TKEeps) && (tke > TKEeps))
280 zi_tke = (k+
myhalf)*dz_no_terrain
281 + dz_no_terrain/(tke1-tke) * (TKEeps - tke);
285 if ((
zi != 0) && (zi_tke != 0)) {
break; }
288 pblh_arr(i,j,0) =
zi;
289 pblh_tke_arr(i,j,0) = zi_tke;
297 for (amrex::MFIter mfi(*pblh); mfi.isValid(); ++mfi)
299 const auto cons_arr =
cons.const_array(mfi);
300 auto pblh_tke_arr = pblh_tke.array(mfi);
301 auto pblh_arr = pblh->array(mfi);
303 amrex::Box gtbx = mfi.growntilebox();
304 ParallelFor(gtbx, [=] AMREX_GPU_DEVICE(
int i,
int j,
int) noexcept
316 pblh_tke_arr(i,j,0) = amrex::max(
326 pblh_arr(i,j,0) = (
one-wt)*pblh_tke_arr(i,j,0) + wt*pblh_arr(i,j,0);
constexpr amrex::Real bogus_large_value
Definition: ERF_Constants.H:17
#define Rho_comp
Definition: ERF_IndexDefines.H:39
#define RhoKE_comp
Definition: ERF_IndexDefines.H:41
const int klo
Definition: ERF_InitCustomPert_ABL.H:75
const int khi
Definition: ERF_InitCustomPert_Bubble.H:21
AMREX_ALWAYS_ASSERT_WITH_MESSAGE(m_cloud_chamber_config.active, "Cloud Chamber: initializer reached without a parsed configuration")
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real GetThetav(const int &i, const int &j, const int &k, const amrex::Array4< amrex::Real const > &cell_data, const MoistureComponentIndices &moisture_indices)
Definition: ERF_MoistUtils.H:74
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 two
Definition: ERF_NumericalConstants.H:31
constexpr amrex::Real one
Definition: ERF_NumericalConstants.H:30
constexpr amrex::Real zero
Definition: ERF_NumericalConstants.H:29
constexpr amrex::Real myhalf
Definition: ERF_NumericalConstants.H:34
amrex::Real Real
Definition: ERF_ShocInterface.H:19
AMREX_FORCE_INLINE amrex::IntVect TileNoZ()
Definition: ERF_TileNoZ.H:11
@ ng
Definition: ERF_Morrison.H:50
@ cons
Definition: ERF_IndexDefines.H:214
@ zi
Definition: ERF_AdvanceWDM6.cpp:276
Diagnostic utility for the planetary boundary layer height.
Definition: ERF_PBLHeight.H:12
static constexpr amrex::Real sbl_lim
Upper limit of the stable boundary layer height [m].
Definition: ERF_PBLHeight.H:347
AMREX_GPU_HOST AMREX_FORCE_INLINE void compute_pblh(const amrex::Geometry &geom, const amrex::MultiFab *z_phys_cc, amrex::MultiFab *pblh, const amrex::MultiFab &cons, const amrex::iMultiFab *lmask, const MoistureComponentIndices &moisture_indices) const
Definition: ERF_PBLHeight.H:26
static constexpr amrex::Real sbl_damp
Transition length for blending [m].
Definition: ERF_PBLHeight.H:348
static constexpr amrex::Real theta_incr_water
Theta increase determining the capping inversion height over water [K].
Definition: ERF_PBLHeight.H:346
static constexpr amrex::Real thetamin_height
Height below which minimum theta-v is determined [m].
Definition: ERF_PBLHeight.H:344
static constexpr amrex::Real theta_incr_land
Theta increase determining the capping inversion height over land [K].
Definition: ERF_PBLHeight.H:345
The moisture data carried by the active microphysics scheme.
Definition: ERF_DataStruct.H:223