1 #ifndef ERF_PBL_HEIGHT_H_
2 #define ERF_PBL_HEIGHT_H_
4 #include <AMReX_MultiFabUtil.H>
23 const amrex::MultiFab* z_phys_cc,
24 amrex::MultiFab* pblh,
25 const amrex::MultiFab&
cons,
26 const amrex::iMultiFab* lmask,
28 const int RhoQr_comp)
const
34 auto const& cons_arrs =
cons.const_arrays();
35 auto thetav_min = amrex::ReduceToPlane<amrex::ReduceOpMin,amrex::Real>(dir, bxlow,
cons,
36 [=] AMREX_GPU_DEVICE (
int box_no,
int i,
int j,
int k) -> amrex::Real
38 return Thetav(i,j,k,cons_arrs[box_no],RhoQv_comp,RhoQr_comp);
43 auto const& ba = pblh->boxArray();
44 auto const& dm = pblh->DistributionMap();
45 auto const& ng = pblh->nGrowVect();
47 amrex::MultiFab min_thetav(ba,dm,1,ng);
48 min_thetav.setVal(1.E34);
50 amrex::MultiFab pblh_tke(ba,dm,1,ng);
56 for (amrex::MFIter mfi(
cons,
TileNoZ()); mfi.isValid(); ++mfi)
58 const amrex::Box& domain = geom.Domain();
59 amrex::Box gtbx = mfi.growntilebox();
60 gtbx.setSmall(2,domain.smallEnd(2));
61 gtbx.setBig(2,domain.bigEnd(2));
63 auto min_thv_arr = min_thetav.array(mfi);
64 auto pblh_arr = pblh->array(mfi);
65 auto pblh_tke_arr = pblh_tke.array(mfi);
67 const auto cons_arr =
cons.const_array(mfi);
68 const auto lmask_arr = (lmask) ? lmask->const_array(mfi) : amrex::Array4<int> {};
75 const auto zphys_arr = z_phys_cc->const_array(mfi);
78 int imin = lbound(zphys_arr).x;
79 int jmin = lbound(zphys_arr).y;
80 int imax = ubound(zphys_arr).x;
81 int jmax = ubound(zphys_arr).y;
85 ParallelFor(gtbx, [=] AMREX_GPU_DEVICE(
int i,
int j,
int k) noexcept
87 int ii = amrex::max(amrex::min(i,imax),imin);
88 int jj = amrex::max(amrex::min(j,jmax),jmin);
91 amrex::Real thv =
Thetav(i,j,k,cons_arr,RhoQv_comp,RhoQr_comp);
92 if (min_thv_arr(i,j,0) > thv) min_thv_arr(i,j,0) = thv;
97 ParallelFor(gtbx, [=] AMREX_GPU_DEVICE(
int i,
int j,
int k) noexcept
99 int ii = amrex::max(amrex::min(i,imax),imin);
100 int jj = amrex::max(amrex::min(j,jmax),jmin);
102 if (pblh_arr(i,j,0) == 0)
107 amrex::Real thv =
Thetav(i,j,k ,cons_arr,RhoQv_comp,RhoQr_comp);
108 amrex::Real thv1 =
Thetav(i,j,k+1,cons_arr,RhoQv_comp,RhoQr_comp);
110 int is_land = (lmask_arr) ? lmask_arr(i,j,0) : 1;
115 pblh_arr(i,j,0) = zphys_arr(ii,jj,k)
116 + (zphys_arr(ii,jj,k+1)-zphys_arr(ii,jj,k))/(thv1-thv)
123 pblh_arr(i,j,0) = zphys_arr(ii,jj,k)
124 + (zphys_arr(ii,jj,k+1)-zphys_arr(ii,jj,k))/(thv1-thv)
128 if (pblh_tke_arr(i,j,0) == 0)
137 amrex::Real TKEeps = 0.05 * maxtke;
138 TKEeps = amrex::max(TKEeps, 0.02);
140 if ((tke1 <= TKEeps) && (tke > TKEeps))
143 pblh_tke_arr(i,j,0) = zphys_arr(ii,jj,k)
144 + (zphys_arr(ii,jj,k+1)-zphys_arr(ii,jj,k))/(tke1-tke)
155 const amrex::Real dz_no_terrain = geom.CellSize(2);
161 AMREX_ASSERT(kmax > 0);
162 amrex::Box gtbxlow = gtbx;
163 gtbxlow.setBig(2,kmax);
165 ParallelFor(gtbxlow, [=] AMREX_GPU_DEVICE(
int i,
int j,
int k) noexcept
167 amrex::Real thv =
Thetav(i,j,k,cons_arr,RhoQv_comp,RhoQr_comp);
168 if (min_thv_arr(i,j,0) > thv) min_thv_arr(i,j,0) = thv;
172 ParallelFor(gtbx, [=] AMREX_GPU_DEVICE(
int i,
int j,
int k) noexcept
174 if (pblh_arr(i,j,0) == 0)
179 amrex::Real thv =
Thetav(i,j,k ,cons_arr,RhoQv_comp,RhoQr_comp);
180 amrex::Real thv1 =
Thetav(i,j,k+1,cons_arr,RhoQv_comp,RhoQr_comp);
182 int is_land = (lmask_arr) ? lmask_arr(i,j,0) : 1;
187 pblh_arr(i,j,0) = (k+0.5)*dz_no_terrain
188 + dz_no_terrain/(thv1-thv)
195 pblh_arr(i,j,0) = (k+0.5)*dz_no_terrain
196 + dz_no_terrain/(thv1-thv)
200 if (pblh_tke_arr(i,j,0) == 0)
209 amrex::Real TKEeps = 0.05 * maxtke;
210 TKEeps = amrex::max(TKEeps, 0.02);
212 if ((tke1 <= TKEeps) && (tke > TKEeps))
215 pblh_tke_arr(i,j,0) = (k+0.5)*dz_no_terrain
216 + dz_no_terrain/(tke1-tke) * (TKEeps - tke);
226 for (amrex::MFIter mfi(*pblh); mfi.isValid(); ++mfi)
228 const auto cons_arr =
cons.const_array(mfi);
229 auto pblh_tke_arr = pblh_tke.array(mfi);
230 auto pblh_arr = pblh->array(mfi);
232 amrex::Box gtbx = mfi.growntilebox();
233 ParallelFor(gtbx, [=] AMREX_GPU_DEVICE(
int i,
int j,
int) noexcept
244 amrex::Real zi = pblh_arr(i,j,0);
245 pblh_tke_arr(i,j,0) = amrex::max(
246 amrex::min(pblh_tke_arr(i,j,0), zi+350.),
247 amrex::max(zi-350., 10.));
255 pblh_arr(i,j,0) = (1.-wt)*pblh_tke_arr(i,j,0) + wt*pblh_arr(i,j,0);
#define Rho_comp
Definition: ERF_IndexDefines.H:36
#define RhoKE_comp
Definition: ERF_IndexDefines.H:38
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real Thetav(int i, int j, int k, const amrex::Array4< const amrex::Real > &cell_data, const int RhoQv_comp, const int RhoQr_comp)
Definition: ERF_Thetav.H:10
AMREX_FORCE_INLINE amrex::IntVect TileNoZ()
Definition: ERF_TileNoZ.H:11
@ cons
Definition: ERF_IndexDefines.H:129
Definition: ERF_PBLHeight.H:8
static constexpr amrex::Real sbl_lim
Definition: ERF_PBLHeight.H:264
static constexpr amrex::Real theta_incr_land
Definition: ERF_PBLHeight.H:262
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 int RhoQv_comp, const int RhoQr_comp) const
Definition: ERF_PBLHeight.H:22
static constexpr amrex::Real thetamin_height
Definition: ERF_PBLHeight.H:261
static constexpr amrex::Real theta_incr_water
Definition: ERF_PBLHeight.H:263
static constexpr amrex::Real sbl_damp
Definition: ERF_PBLHeight.H:265