45 Real EPSTRB = 1.0e-24;
48 Real EPSQ1 = std::sqrt(EPSQ2);
59 Real A1 = 0.659888514560862645;
60 Real A2x = 0.6574209922667784586;
61 Real B1 = 11.87799326209552761;
62 Real B2 = 7.226971804046074028;
63 Real C1 = 0.000830955950095854396;
68 Real ADNH = 9.*A1*A2x*A2x*(12.*A1+3.*B2)*BTG*BTG;
69 Real ADNM = 18.*A1*A1*A2x*(B2-3.*A2x)*BTG;
70 Real ANMH = -9.*A1*A2x*A2x*BTG*BTG;
71 Real ANMM = -3.*A1*A2x*(3.*A2x+3.*B2*C1+18.*A1*C1-B2)*BTG;
72 Real BDNH = 3.*A2x*(7.*A1+B2)*BTG;
74 Real BEQH = A2x*B1*BTG+3.*A2x*(7.*A1+B2)*BTG;
75 Real BEQM = -A1*B1*(1.-3.*C1)+6.*A1*A1;
77 Real BNMM = A1*(1.-3.*C1);
78 Real BSHH = 9.*A1*A2x*A2x*BTG;
79 Real BSHM = 18.*A1*A1*A2x*C1;
80 Real BSMH = -3.*A1*A2x*(3.*A2x+3.*B2*C1+12.*A1*C1-B2)*BTG;
82 Real CESM = A1*(1.-3.*C1);
84 Real AEQH = 9.*A1*A2x*A2x*B1*BTG*BTG
85 + 9.*A1*A2x*A2x*(12.*A1+3.*B2)*BTG*BTG;
86 Real AEQM = 3.*A1*A2x*B1*(3.*A2x+3.*B2*C1+18.*A1*C1-B2)*BTG
87 + 18.*A1*A1*A2x*(B2-3.*A2x)*BTG;
89 Real REQU = -AEQH/AEQM;
91 Real EPSGM = REQU*EPSGH;
93 Real UBRYL = (18.*REQU*A1*A1*A2x*B2*C1*BTG + 9.*A1*A2x*A2x*B2*BTG*BTG)
95 Real UBRY = (1.+EPSRS)*UBRYL;
98 Real AUBH = 27.*A1*A2x*A2x*B2*BTG*BTG-ADNH*UBRY3;
99 Real AUBM = 54.*A1*A1*A2x*B2*C1*BTG-ADNM*UBRY3;
100 Real BUBH = (9.*A1*A2x+3.*A2x*B2)*BTG-BDNH*UBRY3;
101 Real BUBM = 18.*A1*A1*C1-BDNM*UBRY3;
102 Real CUBR = 1.-UBRY3;
103 Real RCUBR = 1./CUBR;
106 #pragma omp parallel if (Gpu::notInLaunchRegion())
108 for (MFIter mfi(eddyViscosity,
false); mfi.isValid(); ++mfi) {
110 const Box& bx = mfi.validbox();
111 const Array4<Real >& cell_data = cons_in.array(mfi);
112 const Array4<Real >& K_turb = eddyViscosity.array(mfi);
113 const Array4<Real const>& uvel =
xvel.array(mfi);
114 const Array4<Real const>& vvel =
yvel.array(mfi);
117 const Box& dbx = geom.Domain();
118 AMREX_ALWAYS_ASSERT(bx.smallEnd(2) == dbx.smallEnd(2) && bx.bigEnd(2) == dbx.bigEnd(2));
121 int klo = bx.smallEnd(2);
122 int khi = bx.bigEnd(2);
123 Box planexy = makeSlab(bx,2,klo);
126 const GeometryData gdata = geom.data();
129 const Box xybx = PerpendicularBox<ZDir>(bx, IntVect{0,0,0});
130 FArrayBox qturb(bx,1);
131 FArrayBox qintegral(xybx,2);
132 IArrayBox pbl_k(xybx,1);
133 qintegral.setVal<RunOn::Device>(0.0);
134 pbl_k.setVal<RunOn::Device>(khi);
135 const Array4<Real> qint = qintegral.array();
136 const Array4<Real> qvel = qturb.array();
137 const Array4<int> k_arr = pbl_k.array();
140 const Array4<Real const> &z_nd_arr = z_phys_nd->array(mfi);
141 const auto& dxInv = geom.InvCellSizeArray();
142 int izmin = geom.Domain().smallEnd(2);
143 int izmax = geom.Domain().bigEnd(2);
150 if (use_terrain_fitted_coords) {
151 ParallelFor(planexy, [=] AMREX_GPU_DEVICE (
int i,
int j,
int ) noexcept
154 for (
int k(klo); k<=khi; ++k) {
156 AMREX_ALWAYS_ASSERT_WITH_MESSAGE(q2 > 0.0,
"KE must have a positive value");
157 qvel(i,j,k) = std::sqrt(q2);
159 k_arr(i,j,0) = std::min(k,k_arr(i,j,0));
164 for (
int k(klo); k<=k_arr(i,j,0); ++k) {
167 Gpu::Atomic::Add(&qint(i,j,0,0), Zval*qvel(i,j,k)*dz);
168 Gpu::Atomic::Add(&qint(i,j,0,1), qvel(i,j,k)*dz);
172 ParallelFor(planexy, [=] AMREX_GPU_DEVICE (
int i,
int j,
int ) noexcept
175 for (
int k(klo); k<=khi; ++k) {
177 AMREX_ALWAYS_ASSERT_WITH_MESSAGE(q2 > 0.0,
"KE must have a positive value");
178 qvel(i,j,k) = std::sqrt(q2);
180 k_arr(i,j,0) = std::min(k,k_arr(i,j,0));
185 for (
int k(klo); k<=k_arr(i,j,0); ++k) {
187 const Real Zval = gdata.ProbLo(2) + (k + 0.5)*gdata.CellSize(2);
188 Gpu::Atomic::Add(&qint(i,j,0,0), Zval*qvel(i,j,k));
189 Gpu::Atomic::Add(&qint(i,j,0,1), qvel(i,j,k));
195 ParallelFor(planexy, [=] AMREX_GPU_DEVICE (
int i,
int j,
int ) noexcept
198 int kpbl = k_arr(i,j,0);
201 Real l0 = std::max(std::min(ALPHA*qint(i,j,0,0)/qint(i,j,0,1),EL0MAX),EL0MIN);
204 for (
int k(klo); k<=khi; ++k) {
207 Real dthetavdz, dudz, dvdz;
209 uvel, vvel, cell_data, izmin, izmax, dxInv[2]/met_h_zeta,
210 c_ext_dir_on_zlo, c_ext_dir_on_zhi,
211 u_ext_dir_on_zlo, u_ext_dir_on_zhi,
212 v_ext_dir_on_zlo, v_ext_dir_on_zhi,
213 dthetavdz, dudz, dvdz,
217 Real GML = std::max(dudz*dudz + dvdz*dvdz, EPSGM);
220 Real GHL = dthetavdz;
221 if (std::fabs(GHL)<=EPSGH) { GHL=EPSGH; }
226 if (GML/GHL <= REQU) {
229 Real AUBR = (AUBM*GML+AUBH*GHL)*GHL;
230 Real BUBR = BUBM*GML+BUBH*GHL;
231 Real QOL2ST = (-0.5*BUBR+std::sqrt(BUBR*BUBR*0.25-AUBR*CUBR))*RCUBR;
232 Real ELOQ2X = 1./QOL2ST;
233 ELM = std::max(std::sqrt(ELOQ2X*qvel(i,j,k)*qvel(i,j,k)),EPSL);
236 Real ADEN = (ADNM*GML+ADNH*GHL)*GHL;
237 Real BDEN = BDNM*GML+BDNH*GHL;
238 Real QOL2UN = -0.5*BDEN+std::sqrt(BDEN*BDEN*0.25-ADEN);
239 Real ELOQ2X = 1./(QOL2UN+EPSRU);
240 ELM = std::max(std::sqrt(ELOQ2X*qvel(i,j,k)*qvel(i,j,k)),EPSL);
246 L = std::min((met_h_zeta/dxInv[2])*ELFC, ELM);
249 : gdata.ProbLo(2) + (k + 0.5)*gdata.CellSize(2);
250 L = std::min(l0*d_kappa*zval / (d_kappa*zval + l0), ELM);
254 Real AEQU = (AEQM*GML+AEQH*GHL)*GHL;
255 Real BEQU = BEQM*GML+BEQH*GHL;
257 Real EQOL2 = -0.5*BEQU+std::sqrt(BEQU*BEQU*0.25-AEQU);
259 if ( ((GML+GHL*GHL)<=EPSTRB) ||
260 ((GHL>=EPSGH) && ((GML/GHL)<=REQU)) ||
265 Real ANUM=(ANMM*GML+ANMH*GHL)*GHL;
266 Real BNUM= BNMM*GML+BNMH*GHL;
268 Real ADEN=(ADNM*GML+ADNH*GHL)*GHL;
269 Real BDEN= BDNM*GML+BDNH*GHL;
272 Real ARHS=-(ANUM*BDEN-BNUM*ADEN)*2.;
276 Real DLOQ1=L/qvel(i,j,k);
278 Real ELOQ21=1./EQOL2;
279 Real ELOQ11=std::sqrt(ELOQ21);
280 Real ELOQ31=ELOQ21*ELOQ11;
281 Real ELOQ41=ELOQ21*ELOQ21;
282 Real ELOQ51=ELOQ21*ELOQ31;
284 Real RDEN1=1./(ADEN*ELOQ41+BDEN*ELOQ21+CDEN);
286 Real RHSP1=(ARHS*ELOQ51+BRHS*ELOQ31+CRHS*ELOQ11)*RDEN1*RDEN1;
289 Real ELOQ12=std::max(ELOQ11+(DLOQ1-ELOQ11)*exp(RHSP1*DTTURBL),EPS1);
291 Real ELOQ22=ELOQ12*ELOQ12;
292 Real ELOQ32=ELOQ22*ELOQ12;
293 Real ELOQ42=ELOQ22*ELOQ22;
294 Real ELOQ52=ELOQ22*ELOQ32;
296 Real RDEN2=1./(ADEN*ELOQ42+BDEN*ELOQ22+CDEN);
297 Real RHS2 =-(ANUM*ELOQ42+BNUM*ELOQ22)*RDEN2+RB1;
298 Real RHSP2= (ARHS*ELOQ52+BRHS*ELOQ32+CRHS*ELOQ12)*RDEN2*RDEN2;
299 Real RHST2=RHS2/RHSP2;
301 Real ELOQ13=std::max(ELOQ12-RHST2+(RHST2+DLOQ1-ELOQ12)*exp(RHSP2*DTTURBL),EPS1);
305 qvel(i,j,k) = std::max(L/ELOQN,EPSQ1);
306 if (qvel(i,j,k)==EPSQ1) {L = EPSL; }
320 cell_data(i,j,k,
RhoKE_comp) = 0.5*cell_data(i,j,k,
Rho_comp)*qvel(i,j,k)*qvel(i,j,k);
323 Real ELOQ2 = L*L/(qvel(i,j,k)*qvel(i,j,k));
324 Real ELOQ4 = ELOQ2*ELOQ2;
327 Real ADEN=(ADNM*GML+ADNH*GHL)*GHL;
328 Real BDEN= BDNM*GML+BDNH*GHL;
335 Real BESH=BSHM*GML+BSHH*GHL;
338 Real RDEN=1./(ADEN*ELOQ4+BDEN*ELOQ2+CDEN);
341 Real SM=(BESM*ELOQ2+CESM)*RDEN;
342 Real SH=(BESH*ELOQ2+CESH)*RDEN;
constexpr amrex::Real KAPPA
Definition: ERF_Constants.H:20
constexpr amrex::Real CONST_GRAV
Definition: ERF_Constants.H:21
#define Rho_comp
Definition: ERF_IndexDefines.H:36
#define RhoKE_comp
Definition: ERF_IndexDefines.H:38
AMREX_GPU_DEVICE AMREX_FORCE_INLINE void ComputeVerticalDerivativesPBL(int i, int j, int k, const amrex::Array4< const amrex::Real > &uvel, const amrex::Array4< const amrex::Real > &vvel, const amrex::Array4< const amrex::Real > &cell_data, const int izmin, const int izmax, const amrex::Real &dz_inv, const bool c_ext_dir_on_zlo, const bool c_ext_dir_on_zhi, const bool u_ext_dir_on_zlo, const bool u_ext_dir_on_zhi, const bool v_ext_dir_on_zlo, const bool v_ext_dir_on_zhi, amrex::Real &dthetadz, amrex::Real &dudz, amrex::Real &dvdz, const MoistureComponentIndices &moisture_indices)
Definition: ERF_PBLModels.H:181
amrex::Real Real
Definition: ERF_ShocInterface.H:19
AMREX_FORCE_INLINE AMREX_GPU_DEVICE amrex::Real Compute_h_zeta_AtCellCenter(const int &i, const int &j, const int &k, const amrex::GpuArray< amrex::Real, AMREX_SPACEDIM > &cellSizeInv, const amrex::Array4< const amrex::Real > &z_nd)
Definition: ERF_TerrainMetrics.H:47
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real Compute_Zrel_AtCellCenter(const int &i, const int &j, const int &k, const amrex::Array4< const amrex::Real > &z_nd)
Definition: ERF_TerrainMetrics.H:390
@ yvel_bc
Definition: ERF_IndexDefines.H:88
@ cons_bc
Definition: ERF_IndexDefines.H:76
@ xvel_bc
Definition: ERF_IndexDefines.H:87
@ ext_dir
Definition: ERF_IndexDefines.H:209
@ Theta_v
Definition: ERF_IndexDefines.H:176
@ Turb_lengthscale
Definition: ERF_IndexDefines.H:180
@ Q_v
Definition: ERF_IndexDefines.H:179
@ Mom_v
Definition: ERF_IndexDefines.H:175
@ KE_v
Definition: ERF_IndexDefines.H:177
@ rho
Definition: ERF_Kessler.H:22
@ xvel
Definition: ERF_IndexDefines.H:141
@ yvel
Definition: ERF_IndexDefines.H:142