49 Real EPSQ1 = std::sqrt(EPSQ2);
60 Real A1 =
Real(0.659888514560862645);
61 Real A2x =
Real(0.6574209922667784586);
62 Real B1 =
Real(11.87799326209552761);
63 Real B2 =
Real(7.226971804046074028);
64 Real C1 =
Real(0.000830955950095854396);
71 Real ANMH = -
Real(9.)*A1*A2x*A2x*BTG*BTG;
85 Real AEQH =
Real(9.)*A1*A2x*A2x*B1*BTG*BTG
90 Real REQU = -AEQH/AEQM;
92 Real EPSGM = REQU*EPSGH;
94 Real UBRYL = (
Real(18.)*REQU*A1*A1*A2x*B2*C1*BTG +
Real(9.)*A1*A2x*A2x*B2*BTG*BTG)
99 Real AUBH =
Real(27.)*A1*A2x*A2x*B2*BTG*BTG-ADNH*UBRY3;
100 Real AUBM =
Real(54.)*A1*A1*A2x*B2*C1*BTG-ADNM*UBRY3;
102 Real BUBM =
Real(18.)*A1*A1*C1-BDNM*UBRY3;
107 #pragma omp parallel if (Gpu::notInLaunchRegion())
109 for (MFIter mfi(eddyViscosity,
false); mfi.isValid(); ++mfi) {
111 const Box& bx = mfi.validbox();
112 const Array4<Real >& cell_data = cons_in.array(mfi);
113 const Array4<Real >& K_turb = eddyViscosity.array(mfi);
114 const Array4<Real const>& uvel =
xvel.array(mfi);
115 const Array4<Real const>& vvel =
yvel.array(mfi);
118 const Box& dbx = geom.Domain();
122 int klo = bx.smallEnd(2);
123 int khi = bx.bigEnd(2);
124 Box planexy = makeSlab(bx,2,klo);
127 const GeometryData gdata = geom.data();
130 const Box xybx = PerpendicularBox<ZDir>(bx, IntVect{0,0,0});
131 FArrayBox qturb(bx,1);
132 FArrayBox qintegral(xybx,2);
133 IArrayBox pbl_k(xybx,1);
134 qintegral.setVal<RunOn::Device>(0);
135 pbl_k.setVal<RunOn::Device>(
khi);
136 const Array4<Real> qint = qintegral.array();
137 const Array4<Real> qvel = qturb.array();
138 const Array4<int> k_arr = pbl_k.array();
141 const Array4<Real const> &z_nd_arr = z_phys_nd->array(mfi);
143 const auto&
dxInv = geom.InvCellSizeArray();
144 int izmin = geom.Domain().smallEnd(2);
145 int izmax = geom.Domain().bigEnd(2);
152 if (use_terrain_fitted_coords) {
153 ParallelFor(planexy, [=] AMREX_GPU_DEVICE (
int i,
int j,
int ) noexcept
156 for (
int k(klo); k<=
khi; ++k) {
158 AMREX_ALWAYS_ASSERT_WITH_MESSAGE(q2 >
zero,
"KE must have a positive value");
159 qvel(i,j,k) = std::sqrt(q2);
161 k_arr(i,j,0) = std::min(k,k_arr(i,j,0));
166 for (
int k(klo); k<=k_arr(i,j,0); ++k) {
169 Gpu::Atomic::Add(&qint(i,j,0,0), Zval*qvel(i,j,k)*
dz);
170 Gpu::Atomic::Add(&qint(i,j,0,1), qvel(i,j,k)*
dz);
174 ParallelFor(planexy, [=] AMREX_GPU_DEVICE (
int i,
int j,
int ) noexcept
177 for (
int k(klo); k<=
khi; ++k) {
179 AMREX_ALWAYS_ASSERT_WITH_MESSAGE(q2 >
zero,
"KE must have a positive value");
180 qvel(i,j,k) = std::sqrt(q2);
182 k_arr(i,j,0) = std::min(k,k_arr(i,j,0));
187 for (
int k(klo); k<=k_arr(i,j,0); ++k) {
189 const Real Zval = gdata.ProbLo(2) + (k +
myhalf)*gdata.CellSize(2);
190 Gpu::Atomic::Add(&qint(i,j,0,0), Zval*qvel(i,j,k));
191 Gpu::Atomic::Add(&qint(i,j,0,1), qvel(i,j,k));
197 ParallelFor(planexy, [=] AMREX_GPU_DEVICE (
int i,
int j,
int ) noexcept
200 int kpbl = k_arr(i,j,0);
203 Real l0 = std::max(std::min(ALPHA*qint(i,j,0,0)/qint(i,j,0,1),EL0MAX),EL0MIN);
206 for (
int k(klo); k<=
khi; ++k) {
209 Real dthetavdz, dudz, dvdz;
211 uvel, vvel, cell_data, izmin, izmax, pbl_derivative_dz_inv(i,j,k),
212 c_ext_dir_on_zlo, c_ext_dir_on_zhi,
213 u_ext_dir_on_zlo, u_ext_dir_on_zhi,
214 v_ext_dir_on_zlo, v_ext_dir_on_zhi,
215 dthetavdz, dudz, dvdz,
219 Real GML = std::max(dudz*dudz + dvdz*dvdz, EPSGM);
222 Real GHL = dthetavdz;
223 if (std::fabs(GHL)<=EPSGH) { GHL=EPSGH; }
228 if (GML/GHL <= REQU) {
231 Real AUBR = (AUBM*GML+AUBH*GHL)*GHL;
232 Real BUBR = BUBM*GML+BUBH*GHL;
235 ELM = std::max(std::sqrt(ELOQ2X*qvel(i,j,k)*qvel(i,j,k)),EPSL);
238 Real ADEN = (ADNM*GML+ADNH*GHL)*GHL;
239 Real BDEN = BDNM*GML+BDNH*GHL;
241 Real ELOQ2X =
one/(QOL2UN+EPSRU);
242 ELM = std::max(std::sqrt(ELOQ2X*qvel(i,j,k)*qvel(i,j,k)),EPSL);
248 L = std::min((met_h_zeta/
dxInv[2])*ELFC, ELM);
251 : gdata.ProbLo(2) + (k +
myhalf)*gdata.CellSize(2);
252 L = std::min(l0*d_kappa*zval / (d_kappa*zval + l0), ELM);
256 Real AEQU = (AEQM*GML+AEQH*GHL)*GHL;
257 Real BEQU = BEQM*GML+BEQH*GHL;
261 if ( ((GML+GHL*GHL)<=EPSTRB) ||
262 ((GHL>=EPSGH) && ((GML/GHL)<=REQU)) ||
267 Real ANUM=(ANMM*GML+ANMH*GHL)*GHL;
268 Real BNUM= BNMM*GML+BNMH*GHL;
270 Real ADEN=(ADNM*GML+ADNH*GHL)*GHL;
271 Real BDEN= BDNM*GML+BDNH*GHL;
274 Real ARHS=-(ANUM*BDEN-BNUM*ADEN)*
two;
278 Real DLOQ1=L/qvel(i,j,k);
281 Real ELOQ11=std::sqrt(ELOQ21);
282 Real ELOQ31=ELOQ21*ELOQ11;
283 Real ELOQ41=ELOQ21*ELOQ21;
284 Real ELOQ51=ELOQ21*ELOQ31;
286 Real RDEN1=
one/(ADEN*ELOQ41+BDEN*ELOQ21+CDEN);
288 Real RHSP1=(ARHS*ELOQ51+BRHS*ELOQ31+CRHS*ELOQ11)*RDEN1*RDEN1;
290 Real DTTURBL =
static_cast<Real>(dt);
291 Real ELOQ12=std::max(ELOQ11+(DLOQ1-ELOQ11)*exp(RHSP1*DTTURBL),EPS1);
293 Real ELOQ22=ELOQ12*ELOQ12;
294 Real ELOQ32=ELOQ22*ELOQ12;
295 Real ELOQ42=ELOQ22*ELOQ22;
296 Real ELOQ52=ELOQ22*ELOQ32;
298 Real RDEN2=
one/(ADEN*ELOQ42+BDEN*ELOQ22+CDEN);
299 Real RHS2 =-(ANUM*ELOQ42+BNUM*ELOQ22)*RDEN2+RB1;
300 Real RHSP2= (ARHS*ELOQ52+BRHS*ELOQ32+CRHS*ELOQ12)*RDEN2*RDEN2;
301 Real RHST2=RHS2/RHSP2;
303 Real ELOQ13=std::max(ELOQ12-RHST2+(RHST2+DLOQ1-ELOQ12)*exp(RHSP2*DTTURBL),EPS1);
307 qvel(i,j,k) = std::max(L/ELOQN,EPSQ1);
308 if (qvel(i,j,k)==EPSQ1) {L = EPSL; }
322 cell_data(i,j,k,
RhoKE_comp) =
myhalf*cell_data(i,j,k,
Rho_comp)*qvel(i,j,k)*qvel(i,j,k);
325 Real ELOQ2 = L*L/(qvel(i,j,k)*qvel(i,j,k));
326 Real ELOQ4 = ELOQ2*ELOQ2;
329 Real ADEN=(ADNM*GML+ADNH*GHL)*GHL;
330 Real BDEN= BDNM*GML+BDNH*GHL;
337 Real BESH=BSHM*GML+BSHH*GHL;
340 Real RDEN=
one/(ADEN*ELOQ4+BDEN*ELOQ2+CDEN);
343 Real SM=(BESM*ELOQ2+CESM)*RDEN;
344 Real SH=(BESH*ELOQ2+CESH)*RDEN;
constexpr amrex::Real three
Definition: ERF_Constants.H:11
constexpr amrex::Real KAPPA
Definition: ERF_Constants.H:63
constexpr amrex::Real two
Definition: ERF_Constants.H:10
constexpr amrex::Real one
Definition: ERF_Constants.H:9
constexpr amrex::Real fourth
Definition: ERF_Constants.H:14
constexpr amrex::Real zero
Definition: ERF_Constants.H:8
constexpr amrex::Real myhalf
Definition: ERF_Constants.H:13
constexpr amrex::Real CONST_GRAV
Definition: ERF_Constants.H:64
#define Rho_comp
Definition: ERF_IndexDefines.H:36
#define RhoKE_comp
Definition: ERF_IndexDefines.H:38
amrex::GpuArray< Real, AMREX_SPACEDIM > dxInv
Definition: ERF_InitCustomPertVels_ParticleTests.H:17
const int khi
Definition: ERF_InitCustomPert_Bubble.H:21
AMREX_ALWAYS_ASSERT(bx.length()[2]==khi+1)
rho
Definition: ERF_InitCustomPert_Bubble.H:107
ParallelFor(grown_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);})
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 PBLDerivativeDzInv &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:254
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:55
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:389
@ yvel_bc
Definition: ERF_IndexDefines.H:103
@ cons_bc
Definition: ERF_IndexDefines.H:86
@ xvel_bc
Definition: ERF_IndexDefines.H:102
@ ext_dir
Definition: ERF_IndexDefines.H:248
@ Theta_v
Definition: ERF_IndexDefines.H:211
@ Turb_lengthscale
Definition: ERF_IndexDefines.H:215
@ Q_v
Definition: ERF_IndexDefines.H:214
@ Mom_v
Definition: ERF_IndexDefines.H:210
@ KE_v
Definition: ERF_IndexDefines.H:212
@ xvel
Definition: ERF_IndexDefines.H:176
@ yvel
Definition: ERF_IndexDefines.H:177
@ dz
Definition: ERF_AdvanceWSM6.cpp:104
Definition: ERF_PBLModels.H:416