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,
29 const int RhoQr_comp)
const
35 auto const& cons_arrs =
cons.const_arrays();
36 auto thetav_min = amrex::ReduceToPlane<amrex::ReduceOpMin,amrex::Real>(dir, bxlow,
cons,
37 [=] AMREX_GPU_DEVICE (
int box_no,
int i,
int j,
int k) -> amrex::Real
39 return Thetav(i,j,k,cons_arrs[box_no],RhoQv_comp,RhoQc_comp,RhoQr_comp);
44 auto const& ba = pblh->boxArray();
45 auto const& dm = pblh->DistributionMap();
46 auto const& ng = pblh->nGrowVect();
48 amrex::MultiFab min_thetav(ba,dm,1,ng);
49 min_thetav.setVal(1.E34);
51 amrex::MultiFab pblh_tke(ba,dm,1,ng);
57 for (amrex::MFIter mfi(
cons,
TileNoZ()); mfi.isValid(); ++mfi)
59 const amrex::Box& domain = geom.Domain();
60 amrex::Box gtbx = mfi.growntilebox();
61 gtbx.setSmall(2,domain.smallEnd(2));
62 gtbx.setBig(2,domain.bigEnd(2));
64 auto min_thv_arr = min_thetav.array(mfi);
65 auto pblh_arr = pblh->array(mfi);
66 auto pblh_tke_arr = pblh_tke.array(mfi);
68 const auto cons_arr =
cons.const_array(mfi);
69 const auto lmask_arr = (lmask) ? lmask->const_array(mfi) : amrex::Array4<int> {};
76 const auto zphys_arr = z_phys_cc->const_array(mfi);
79 int imin = lbound(zphys_arr).x;
80 int jmin = lbound(zphys_arr).y;
81 int imax = ubound(zphys_arr).x;
82 int jmax = ubound(zphys_arr).y;
86 ParallelFor(gtbx, [=] AMREX_GPU_DEVICE(
int i,
int j,
int k) noexcept
88 int ii = amrex::max(amrex::min(i,imax),imin);
89 int jj = amrex::max(amrex::min(j,jmax),jmin);
92 amrex::Real thv =
Thetav(i,j,k,cons_arr,RhoQv_comp,RhoQc_comp,RhoQr_comp);
93 if (min_thv_arr(i,j,0) > thv) min_thv_arr(i,j,0) = thv;
98 ParallelFor(gtbx, [=] AMREX_GPU_DEVICE(
int i,
int j,
int k) noexcept
100 int ii = amrex::max(amrex::min(i,imax),imin);
101 int jj = amrex::max(amrex::min(j,jmax),jmin);
103 if (pblh_arr(i,j,0) == 0)
108 amrex::Real thv =
Thetav(i,j,k ,cons_arr,RhoQv_comp,RhoQc_comp,RhoQr_comp);
109 amrex::Real thv1 =
Thetav(i,j,k+1,cons_arr,RhoQv_comp,RhoQc_comp,RhoQr_comp);
111 int is_land = (lmask_arr) ? lmask_arr(i,j,0) : 1;
116 pblh_arr(i,j,0) = zphys_arr(ii,jj,k)
117 + (zphys_arr(ii,jj,k+1)-zphys_arr(ii,jj,k))/(thv1-thv)
124 pblh_arr(i,j,0) = zphys_arr(ii,jj,k)
125 + (zphys_arr(ii,jj,k+1)-zphys_arr(ii,jj,k))/(thv1-thv)
129 if (pblh_tke_arr(i,j,0) == 0)
138 amrex::Real TKEeps = 0.05 * maxtke;
139 TKEeps = amrex::max(TKEeps, 0.02);
141 if ((tke1 <= TKEeps) && (tke > TKEeps))
144 pblh_tke_arr(i,j,0) = zphys_arr(ii,jj,k)
145 + (zphys_arr(ii,jj,k+1)-zphys_arr(ii,jj,k))/(tke1-tke)
156 const amrex::Real dz_no_terrain = geom.CellSize(2);
162 AMREX_ASSERT(kmax > 0);
163 amrex::Box gtbxlow = gtbx;
164 gtbxlow.setBig(2,kmax);
166 ParallelFor(gtbxlow, [=] AMREX_GPU_DEVICE(
int i,
int j,
int k) noexcept
168 amrex::Real thv =
Thetav(i,j,k,cons_arr,RhoQv_comp,RhoQc_comp,RhoQr_comp);
169 if (min_thv_arr(i,j,0) > thv) min_thv_arr(i,j,0) = thv;
173 ParallelFor(gtbx, [=] AMREX_GPU_DEVICE(
int i,
int j,
int k) noexcept
175 if (pblh_arr(i,j,0) == 0)
180 amrex::Real thv =
Thetav(i,j,k ,cons_arr,RhoQv_comp,RhoQc_comp,RhoQr_comp);
181 amrex::Real thv1 =
Thetav(i,j,k+1,cons_arr,RhoQv_comp,RhoQc_comp,RhoQr_comp);
183 int is_land = (lmask_arr) ? lmask_arr(i,j,0) : 1;
188 pblh_arr(i,j,0) = (k+0.5)*dz_no_terrain
189 + dz_no_terrain/(thv1-thv)
196 pblh_arr(i,j,0) = (k+0.5)*dz_no_terrain
197 + dz_no_terrain/(thv1-thv)
201 if (pblh_tke_arr(i,j,0) == 0)
210 amrex::Real TKEeps = 0.05 * maxtke;
211 TKEeps = amrex::max(TKEeps, 0.02);
213 if ((tke1 <= TKEeps) && (tke > TKEeps))
216 pblh_tke_arr(i,j,0) = (k+0.5)*dz_no_terrain
217 + dz_no_terrain/(tke1-tke) * (TKEeps - tke);
227 for (amrex::MFIter mfi(*pblh); mfi.isValid(); ++mfi)
229 const auto cons_arr =
cons.const_array(mfi);
230 auto pblh_tke_arr = pblh_tke.array(mfi);
231 auto pblh_arr = pblh->array(mfi);
233 amrex::Box gtbx = mfi.growntilebox();
234 ParallelFor(gtbx, [=] AMREX_GPU_DEVICE(
int i,
int j,
int) noexcept
245 amrex::Real zi = pblh_arr(i,j,0);
246 pblh_tke_arr(i,j,0) = amrex::max(
247 amrex::min(pblh_tke_arr(i,j,0), zi+350.),
248 amrex::max(zi-350., 10.));
256 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 RhoQc_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:265
static constexpr amrex::Real theta_incr_land
Definition: ERF_PBLHeight.H:263
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 RhoQc_comp, const int RhoQr_comp) const
Definition: ERF_PBLHeight.H:22
static constexpr amrex::Real thetamin_height
Definition: ERF_PBLHeight.H:262
static constexpr amrex::Real theta_incr_water
Definition: ERF_PBLHeight.H:264
static constexpr amrex::Real sbl_damp
Definition: ERF_PBLHeight.H:266