Function for computing the slow RHS for the evolution equations for the density, potential temperature and momentum.
60 BL_PROFILE_REGION(
"erf_make_sources()");
62 Real time =
static_cast<Real>(time_d);
76 const bool l_use_KE = tc.
use_tke;
79 const Box& domain = geom.Domain();
81 const GpuArray<Real, AMREX_SPACEDIM>
dxInv = geom.InvCellSizeArray();
82 const GpuArray<Real, AMREX_SPACEDIM>
dx = geom.CellSizeArray();
96 bool has_moisture = (solverChoice.
moisture_type != MoistureType::None);
101 Table1D<Real> dptr_r_plane, dptr_t_plane, dptr_qv_plane, dptr_qc_plane;
102 TableData<Real, 1> r_plane_tab, t_plane_tab, qv_plane_tab, qc_plane_tab;
105 if (compute_averages)
116 IntVect ng_c(S_data[
IntVars::cons].nGrowVect()); ng_c[2] = 1;
121 int ncomp = (!has_moisture) ? 2 :
RhoQ2_comp+1;
125 cons_ave.compute_averages(
ZDir(), cons_ave.field());
127 int ncell = cons_ave.ncell_line();
129 Gpu::HostVector< Real> r_plane_h(ncell);
130 Gpu::DeviceVector< Real> r_plane_d(ncell);
132 Gpu::HostVector< Real> t_plane_h(ncell);
133 Gpu::DeviceVector< Real> t_plane_d(ncell);
135 cons_ave.line_average(
Rho_comp , r_plane_h);
138 Gpu::copyAsync(Gpu::hostToDevice, r_plane_h.begin(), r_plane_h.end(), r_plane_d.begin());
139 Gpu::copyAsync(Gpu::hostToDevice, t_plane_h.begin(), t_plane_h.end(), t_plane_d.begin());
141 Real* dptr_r = r_plane_d.data();
142 Real* dptr_t = t_plane_d.data();
144 Box tdomain = domain; tdomain.grow(2,ng_c[2]);
145 r_plane_tab.resize({tdomain.smallEnd(2)}, {tdomain.bigEnd(2)});
146 t_plane_tab.resize({tdomain.smallEnd(2)}, {tdomain.bigEnd(2)});
150 dptr_r_plane = r_plane_tab.table();
151 dptr_t_plane = t_plane_tab.table();
152 ParallelFor(ncell, [=] AMREX_GPU_DEVICE (
int k) noexcept
154 dptr_r_plane(k-
offset) = dptr_r[k];
155 dptr_t_plane(k-
offset) = dptr_t[k];
160 Gpu::HostVector< Real> qv_plane_h(ncell), qc_plane_h(ncell);
161 Gpu::DeviceVector<Real> qv_plane_d(ncell), qc_plane_d(ncell);
164 cons_ave.line_average(
RhoQ1_comp, qv_plane_h);
165 Gpu::copyAsync(Gpu::hostToDevice, qv_plane_h.begin(), qv_plane_h.end(), qv_plane_d.begin());
168 cons_ave.line_average(
RhoQ2_comp, qc_plane_h);
169 Gpu::copyAsync(Gpu::hostToDevice, qc_plane_h.begin(), qc_plane_h.end(), qc_plane_d.begin());
171 Real* dptr_qv = qv_plane_d.data();
172 Real* dptr_qc = qc_plane_d.data();
174 qv_plane_tab.resize({tdomain.smallEnd(2)}, {tdomain.bigEnd(2)});
175 qc_plane_tab.resize({tdomain.smallEnd(2)}, {tdomain.bigEnd(2)});
177 dptr_qv_plane = qv_plane_tab.table();
178 dptr_qc_plane = qc_plane_tab.table();
179 ParallelFor(ncell, [=] AMREX_GPU_DEVICE (
int k) noexcept
181 dptr_qv_plane(k-
offset) = dptr_qv[k];
182 dptr_qc_plane(k-
offset) = dptr_qc[k];
191 int klo = domain.smallEnd(0);
192 int khi = domain.bigEnd(2);
193 int nk =
khi - klo + 2;
194 Gpu::DeviceVector<Real> radiation_flux(nk,
zero);
195 Gpu::DeviceVector<Real> q_integral(nk,
zero);
196 Real* rad_flux = radiation_flux.data();
197 Real* q_int = q_integral.data();
219 #pragma omp parallel if (Gpu::notInLaunchRegion())
224 Box bx = mfi.tilebox();
226 const Array4<const Real>& cell_data = S_data[
IntVars::cons].array(mfi);
227 const Array4<const Real>& cell_prim = S_prim.array(mfi);
228 const Array4<Real> & cell_src = source.array(mfi);
230 const Array4<const Real>&
r0 = r_hse.const_array(mfi);
231 const Array4<const Real>& th0 = th_hse.const_array(mfi);
232 const Array4<const Real>& qv0 = qv_hse.const_array(mfi);
234 const Array4<const Real>& z_cc_arr = z_phys_cc->const_array(mfi);
236 const Array4<const Real>& t_blank_arr = (terrain_blank) ? terrain_blank->const_array(mfi) :
237 Array4<const Real>{};
243 if (solverChoice.
rad_type != RadiationType::None && is_slow_step) {
244 auto const& qheating_arr = qheating_rates->const_array(mfi);
245 ParallelFor(bx, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k) noexcept
248 cell_src(i,j,k,
RhoTheta_comp) += cell_data(i,j,k,
Rho_comp) * ( qheating_arr(i,j,k,0) + qheating_arr(i,j,k,1) );
259 if ((is_slow_step && !use_Rayleigh_fast) || (!is_slow_step && use_Rayleigh_fast)) {
264 ParallelFor(bx, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k) noexcept
267 Real sinesq = d_sinesq_at_lev[k];
268 cell_src(i, j, k, n) -= dampcoef*sinesq * (
theta -
thetabar[k]) * cell_data(i,j,k,
nr);
278 auto const& rhotheta_src_arr = rhotheta_src->const_array(mfi);
283 ParallelFor(bx, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k) noexcept
285 cell_src(i, j, k, n) += cell_data(i,j,k,
nr) * rhotheta_src_arr(i, j, k);
288 ParallelFor(bx, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k) noexcept
290 cell_src(i, j, k, n) += rhotheta_src_arr(i, j, k);
296 ParallelFor(bx, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k) noexcept
298 cell_src(i, j, k, n) += cell_data(i,j,k,
nr) * rhotheta_src_arr(0, 0, k);
301 ParallelFor(bx, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k) noexcept
303 cell_src(i, j, k, n) += rhotheta_src_arr(0, 0, k);
314 auto const& rhoqt_src_arr = rhoqt_src->const_array(mfi);
319 ParallelFor(bx, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k) noexcept
321 cell_src(i, j, k, n) += cell_data(i,j,k,
nr) * rhoqt_src_arr(i, j, k);
324 ParallelFor(bx, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k) noexcept
326 cell_src(i, j, k, n) += rhoqt_src_arr(i, j, k);
332 ParallelFor(bx, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k) noexcept
334 cell_src(i, j, k, n) += cell_data(i,j,k,
nr) * rhoqt_src_arr(0, 0, k);
337 ParallelFor(bx, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k) noexcept
339 cell_src(i, j, k, n) += rhoqt_src_arr(0, 0, k);
352 ParallelFor(bx, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k) noexcept
354 Real dzInv = (z_cc_arr) ?
one/ (z_cc_arr(i,j,k+1) - z_cc_arr(i,j,k-1)) :
myhalf*
dxInv[2];
355 Real T_hi = dptr_t_plane(k+1) / dptr_r_plane(k+1);
356 Real T_lo = dptr_t_plane(k-1) / dptr_r_plane(k-1);
357 Real wbar_cc =
myhalf * (dptr_wbar_sub[k] + dptr_wbar_sub[k+1]);
358 cell_src(i, j, k, n) -= cell_data(i,j,k,
nr) * wbar_cc * (T_hi - T_lo) * dzInv;
361 ParallelFor(bx, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k) noexcept
363 Real dzInv = (z_cc_arr) ?
one/ (z_cc_arr(i,j,k+1) - z_cc_arr(i,j,k-1)) :
myhalf*
dxInv[2];
364 Real T_hi = dptr_t_plane(k+1) / dptr_r_plane(k+1);
365 Real T_lo = dptr_t_plane(k-1) / dptr_r_plane(k-1);
366 Real wbar_cc =
myhalf * (dptr_wbar_sub[k] + dptr_wbar_sub[k+1]);
367 cell_src(i, j, k, n) -= wbar_cc * (T_hi - T_lo) * dzInv;
379 ParallelFor(bx, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k) noexcept
381 Real dzInv = (z_cc_arr) ?
one/ (z_cc_arr(i,j,k+1) - z_cc_arr(i,j,k-1)) :
myhalf*
dxInv[2];
382 Real Qv_hi = dptr_qv_plane(k+1) / dptr_r_plane(k+1);
383 Real Qv_lo = dptr_qv_plane(k-1) / dptr_r_plane(k-1);
384 Real Qc_hi = dptr_qc_plane(k+1) / dptr_r_plane(k+1);
385 Real Qc_lo = dptr_qc_plane(k-1) / dptr_r_plane(k-1);
386 Real wbar_cc =
myhalf * (dptr_wbar_sub[k] + dptr_wbar_sub[k+1]);
387 cell_src(i, j, k, nv ) -= cell_data(i,j,k,
nr) * wbar_cc * (Qv_hi - Qv_lo) * dzInv;
388 cell_src(i, j, k, nv+1) -= cell_data(i,j,k,
nr) * wbar_cc * (Qc_hi - Qc_lo) * dzInv;
391 ParallelFor(bx, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k) noexcept
393 Real dzInv = (z_cc_arr) ?
one/ (z_cc_arr(i,j,k+1) - z_cc_arr(i,j,k-1)) :
myhalf*
dxInv[2];
394 Real Qv_hi = dptr_qv_plane(k+1) / dptr_r_plane(k+1);
395 Real Qv_lo = dptr_qv_plane(k-1) / dptr_r_plane(k-1);
396 Real Qc_hi = dptr_qc_plane(k+1) / dptr_r_plane(k+1);
397 Real Qc_lo = dptr_qc_plane(k-1) / dptr_r_plane(k-1);
398 Real wbar_cc =
myhalf * (dptr_wbar_sub[k] + dptr_wbar_sub[k+1]);
399 cell_src(i, j, k, nv ) -= wbar_cc * (Qv_hi - Qv_lo) * dzInv;
400 cell_src(i, j, k, nv+1) -= wbar_cc * (Qc_hi - Qc_lo) * dzInv;
408 if (l_use_ndiff && is_slow_step)
410 const Array4<const Real>& mf_mx = mapfac[
MapFacType::m_x]->const_array(mfi);
411 const Array4<const Real>& mf_my = mapfac[
MapFacType::m_y]->const_array(mfi);
415 cell_data, cell_data, cell_src, mf_mx, mf_my);
419 cell_prim, cell_data, cell_src, mf_mx, mf_my);
422 if (l_use_KE && l_diff_KE) {
424 cell_prim, cell_data, cell_src, mf_mx, mf_my);
428 cell_prim, cell_data, cell_src, mf_mx, mf_my);
444 const amrex::Array4<const amrex::Real>& pert_cell = turbPert.
pb_cell[level].const_array(mfi);
462 for (
int nt = 1; nt < n_sounding_times; nt++) {
465 if (itime_n == n_sounding_times-1) {
468 itime_np1 = itime_n+1;
471 coeff_n =
one - coeff_np1;
480 ParallelFor(bx, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k) noexcept
482 Real nudge = (coeff_n*theta_inp_sound_n[k] + coeff_np1*theta_inp_sound_np1[k]) - (dptr_t_plane(k)/dptr_r_plane(k));
484 cell_src(i, j, k, n) += cell_data(i, j, k,
nr) * nudge;
491 if (solverChoice.
terrain_type == TerrainType::ImmersedForcing &&
492 ((is_slow_step && !use_ImmersedForcing_fast) || (!is_slow_step && use_ImmersedForcing_fast)))
494 const Array4<const Real>& u =
xvel.array(mfi);
495 const Array4<const Real>& v =
yvel.array(mfi);
498 const Real* dx_arr = geom.CellSize();
499 const Real dx_x = dx_arr[0];
500 const Real dx_y = dx_arr[1];
520 AMREX_GPU_DEVICE(
int i,
int j,
int k) noexcept
522 const Real dx_z = (z_cc_arr) ? (z_cc_arr(i,j,k) - z_cc_arr(i,j,k-1)) : dx_arr[2];
523 const Real drag_coefficient = alpha_h / std::pow(dx_x*dx_y*dx_z,
one/
three);
525 const Real t_blank = t_blank_arr(i, j, k);
526 const Real t_blank_above = t_blank_arr(i, j, k+1);
527 const Real ux_cc_2r =
myhalf * (u(i ,j ,k+1) + u(i+1,j ,k+1));
528 const Real uy_cc_2r =
myhalf * (v(i ,j ,k+1) + v(i ,j+1,k+1));
529 const Real h_windspeed2r = std::sqrt(ux_cc_2r * ux_cc_2r + uy_cc_2r * uy_cc_2r);
535 if (init_surf_temp >
zero) {
536 if (t_blank > 0 && (t_blank_above ==
zero)) {
537 const Real surf_temp = init_surf_temp + surf_heating_rate*time;
539 cell_src(i, j, k-1,
RhoTheta_comp) -= drag_coefficient * U_s * bc_forcing_rt_srf;
544 if (tflux !=
Real(1e-8)){
545 if (t_blank > 0 && (t_blank_above ==
zero)) {
549 Real ustar = h_windspeed2r * kappa / (std::log((
Real(1.5)) * dx_z /
z0) - psi_m);
550 const Real Olen = -ustar * ustar * ustar *
theta / (kappa * ggg * tflux + tiny);
552 const Real zeta_neighbor = (
Real(1.5)) * dx_z / Olen;
557 psi_h_neighbor = sfuns.
calc_psi_h(zeta_neighbor);
558 ustar = h_windspeed2r * kappa / (std::log((
Real(1.5)) * dx_z /
z0) - psi_m);
561 if (!(ustar >
zero && !std::isnan(ustar))) { ustar =
zero; }
562 if (!(ustar <
two && !std::isnan(ustar))) { ustar =
two; }
563 if (psi_h_neighbor > std::log(
Real(1.5) * dx_z /
z0)) { psi_h_neighbor = std::log(
Real(1.5) * dx_z /
z0); }
564 if (psi_h > std::log(
myhalf * dx_z /
z0)) { psi_h = std::log(
myhalf * dx_z /
z0); }
567 const Real thetastar =
theta * ustar * ustar / (kappa * ggg *
Olen);
568 const Real surf_temp = theta_neighbor - thetastar / kappa * (std::log((
Real(1.5)) * dx_z /
z0) - psi_h_neighbor);
569 const Real tTarget = surf_temp + thetastar / kappa * (std::log((
myhalf) * dx_z /
z0) - psi_h);
572 cell_src(i, j, k,
RhoTheta_comp) -= drag_coefficient * U_s * bc_forcing_rt;
577 if (Olen_in !=
Real(1e-8)){
578 if (t_blank > 0 && (t_blank_above ==
zero)) {
581 const Real zeta_neighbor = (
Real(1.5)) * dx_z / Olen;
587 const Real ustar = h_windspeed2r * kappa / (std::log((
Real(1.5)) * dx_z /
z0) - psi_m);
590 const Real thetastar =
theta * ustar * ustar / (kappa * ggg *
Olen);
591 const Real surf_temp = theta_neighbor - thetastar / kappa * (std::log((
Real(1.5)) * dx_z /
z0) - psi_h_neighbor);
592 const Real tTarget = surf_temp + thetastar / kappa * (std::log((
myhalf) * dx_z /
z0) - psi_h);
595 cell_src(i, j, k,
RhoTheta_comp) -= drag_coefficient * U_s * bc_forcing_rt;
606 const Real* dx_arr = geom.CellSize();
607 const Real dx_x = dx_arr[0];
608 const Real dx_y = dx_arr[1];
609 const Real delta_xy = std::pow(dx_x*dx_y,
myhalf);
610 if ((solverChoice.
buildings_type == BuildingsType::ImmersedForcing ) &&
611 ((is_slow_step && !use_ImmersedForcing_fast) || (!is_slow_step && use_ImmersedForcing_fast)) &&
614 const Array4<const Real>& u =
xvel.array(mfi);
615 const Array4<const Real>& v =
yvel.array(mfi);
616 const Array4<const Real>&
w =
zvel.array(mfi);
621 const Real min_t_blank =
Real(1.e-4);
633 ParallelFor(bx, [=] AMREX_GPU_DEVICE(
int i,
int j,
int k) noexcept
635 Real t_blank = t_blank_arr(i, j, k);
636 Real t_blank_below = t_blank_arr(i, j, k-1);
637 Real t_blank_above = t_blank_arr(i, j, k+1);
638 Real t_blank_north = t_blank_arr(i , j+1, k);
639 Real t_blank_south = t_blank_arr(i , j-1, k);
640 Real t_blank_east = t_blank_arr(i+1, j , k);
641 Real t_blank_west = t_blank_arr(i-1, j , k);
642 if (t_blank < min_t_blank) { t_blank =
zero; }
643 if (t_blank_below < min_t_blank) { t_blank_below =
zero; }
644 if (t_blank_north < min_t_blank) { t_blank_north =
zero; }
645 if (t_blank_south < min_t_blank) { t_blank_south =
zero; }
646 if (t_blank_east < min_t_blank) { t_blank_east =
zero; }
647 if (t_blank_west < min_t_blank) { t_blank_west =
zero; }
649 const Real dx_z = (z_cc_arr) ? (z_cc_arr(i,j,k) - z_cc_arr(i,j,k-1)) : dx_arr[2];
650 Real drag_coefficient = alpha_h / std::pow(dx_x*dx_y*dx_z,
one/
three);
652 const Real ux_cc_2r =
myhalf * (u(i ,j ,k+1) + u(i+1,j ,k+1));
653 const Real uy_cc_2r =
myhalf * (v(i ,j ,k+1) + v(i ,j+1,k+1));
654 const Real h_windspeed2r = std::sqrt(ux_cc_2r * ux_cc_2r + uy_cc_2r * uy_cc_2r);
660 if (init_surf_temp >
zero) {
661 const Real surf_temp = init_surf_temp + surf_heating_rate*time;
662 if (t_blank > 0 && (t_blank_above ==
zero) && (t_blank_below ==
one)) {
664 cell_src(i, j, k,
RhoTheta_comp) -= drag_coefficient * U_s * bc_forcing_rt_srf;
666 }
else if (((t_blank >
zero && t_blank < t_blank_west && t_blank_east ==
zero) ||
667 (t_blank >
zero && t_blank < t_blank_east && t_blank_west ==
zero) ||
668 (t_blank >
zero && t_blank < t_blank_north && t_blank_south ==
zero) ||
669 (t_blank >
zero && t_blank < t_blank_south && t_blank_north ==
zero))) {
674 if ((t_blank < t_blank_north) && (t_blank_north ==
one)) {
676 cell_src(i, j, k,
RhoTheta_comp) -= drag_coefficient * U_s * bc_forcing_rt_srf;
680 if ((t_blank < t_blank_south) && (t_blank_south ==
one)) {
682 cell_src(i, j, k,
RhoTheta_comp) -= drag_coefficient * U_s * bc_forcing_rt_srf;
686 if ((t_blank < t_blank_east) && (t_blank_east ==
one)) {
688 cell_src(i, j, k,
RhoTheta_comp) -= drag_coefficient * U_s * bc_forcing_rt_srf;
692 if ((t_blank < t_blank_west) && (t_blank_west ==
one)) {
694 cell_src(i, j, k,
RhoTheta_comp) -= drag_coefficient * U_s * bc_forcing_rt_srf;
701 if (tflux !=
Real(1.e-8)){
702 if (t_blank >
zero && (t_blank_above ==
zero)) {
706 Real ustar = h_windspeed2r * kappa / (std::log((1.5) * dx_z /
z0) - psi_m);
707 Real Olen = (Olen_in !=
Real(1e-8)) ? Olen_in : -ustar * ustar * ustar *
theta / (kappa * ggg * tflux + tiny);
709 for (
int iter = 0; iter < 2; ++iter) {
710 if (iter > 0) {
Olen = -ustar * ustar * ustar *
theta / (kappa * ggg * tflux + tiny); }
712 Real zeta_neighbor = (1.5) * dx_z / Olen;
717 psi_h_neighbor = sfuns.
calc_psi_h(zeta_neighbor);
718 ustar = h_windspeed2r * kappa / (std::log((1.5) * dx_z /
z0) - psi_m);
722 if (!(ustar >
zero && !std::isnan(ustar))) { ustar =
zero; }
723 if (!(ustar < 2.0 && !std::isnan(ustar))) { ustar = 2.0; }
724 if (psi_h_neighbor > std::log(1.5 * dx_z /
z0)) { psi_h_neighbor = std::log(1.5 * dx_z /
z0); }
725 if (psi_h > std::log(
myhalf * dx_z /
z0)) { psi_h = std::log(
myhalf * dx_z /
z0); }
728 const Real thetastar =
theta * ustar * ustar / (kappa * ggg *
Olen);
729 const Real surf_temp = theta_neighbor - thetastar / kappa * (std::log((1.5) * dx_z /
z0) - psi_h_neighbor);
730 const Real tTarget = surf_temp + thetastar / kappa * (std::log((
myhalf) * dx_z /
z0) - psi_h);
733 cell_src(i, j, k,
RhoTheta_comp) -= drag_coefficient * U_s * bc_forcing_rt;
735 }
else if (((t_blank >
zero && t_blank < t_blank_west && t_blank_east ==
zero) ||
736 (t_blank >
zero && t_blank < t_blank_east && t_blank_west ==
zero) ||
737 (t_blank >
zero && t_blank < t_blank_north && t_blank_south ==
zero) ||
738 (t_blank >
zero && t_blank < t_blank_south && t_blank_north ==
zero))) {
748 if (t_blank >
zero && t_blank < t_blank_north && t_blank_south ==
zero) {
749 ux_cellaway =
myhalf * (u(i ,j-1,k) + u(i+1,j-1,k ));
750 uz_cellaway =
myhalf * (
w(i ,j-1,k) +
w(i ,j-1,k+1));
760 if (t_blank >
zero && t_blank < t_blank_south && t_blank_north ==
zero) {
761 ux_cellaway =
myhalf * (u(i ,j+1,k) + u(i+1,j+1,k ));
762 uz_cellaway =
myhalf * (
w(i ,j+1,k) +
w(i ,j+1,k+1));
772 if (t_blank >
zero && t_blank < t_blank_east && t_blank_west ==
zero) {
773 uy_cellaway =
myhalf * (u(i-1,j ,k) + u(i-1,j+1,k ));
774 uz_cellaway =
myhalf * (
w(i-1,j ,k) +
w(i-1,j ,k+1));
784 if (t_blank >
zero && t_blank < t_blank_west && t_blank_east ==
zero) {
785 uy_cellaway =
myhalf * (u(i+1,j ,k) + u(i+1,j+1,k ));
786 uz_cellaway =
myhalf * (
w(i+1,j ,k) +
w(i+1,j ,k+1));
795 Real tan_wspd = std::sqrt(u1 * u1 + u2 * u2);
800 Real ustar = tan_wspd * kappa / (std::log(1.5 * delta /
z0) - psi_m);
801 Real Olen = (Olen_in !=
Real(1e-8)) ? Olen_in : -ustar * ustar * ustar *
theta / (kappa * ggg * tflux + tiny);
803 for (
int iter = 0; iter < 2; ++iter) {
804 if (iter > 0) {
Olen = -ustar * ustar * ustar *
theta / (kappa * ggg * tflux + tiny); }
806 Real zeta_neighbor = (1.5) * delta / Olen;
811 psi_h_neighbor = sfuns.
calc_psi_h(zeta_neighbor);
812 ustar = tan_wspd * kappa / (std::log((1.5) * delta /
z0) - psi_m);
816 if (!(ustar >
zero && !std::isnan(ustar))) { ustar =
zero; }
817 if (!(ustar < 2.0 && !std::isnan(ustar))) { ustar = 2.0; }
818 if (psi_h_neighbor > std::log(1.5 * delta /
z0)) { psi_h_neighbor = std::log(1.5 * delta /
z0); }
819 if (psi_h > std::log(
myhalf * delta /
z0)) { psi_h = std::log(
myhalf * delta /
z0); }
822 const Real thetastar =
theta * ustar * ustar / (kappa * ggg *
Olen);
823 const Real surf_temp = theta_neighbor - thetastar / kappa * (std::log((1.5) * delta /
z0) - psi_h_neighbor);
824 const Real tTarget = surf_temp + thetastar / kappa * (std::log((
myhalf) * delta /
z0) - psi_h);
827 cell_src(i, j, k,
RhoTheta_comp) -= drag_coefficient * U_s * bc_forcing_rt;
845 Box xybx = makeSlab(bx,2,klo);
847 AMREX_GPU_DEVICE(
int i,
int j,
int ) noexcept
853 for (
int k(klo+1); k<=
khi+1; ++k) {
856 Real dz = (z_cc_arr) ?
myhalf * (z_cc_arr(i,j,k) - z_cc_arr(i,j,k-2)) :
dx[2];
857 q_int[lk] = q_int[lk-1] + krad * cell_data(i,j,k-1,
Rho_comp) * cell_data(i,j,k-1,
RhoQ2_comp) *
dz;
860 if ( (qt_lo > qt_i) && (qt_hi < qt_i) ) {
861 zi =
myhalf * (z_cc_arr(i,j,k) + z_cc_arr(i,j,k-1));
868 for (
int k(klo); k<=
khi+1; ++k) {
870 Real z =
myhalf * (z_cc_arr(i,j,k) + z_cc_arr(i,j,k-1));
871 rad_flux[lk] = F1*std::exp(-q_int[lk]) + F0*std::exp(-(q_int_inf - q_int[lk]));
878 for (
int k(klo); k<=
khi; ++k) {
881 Real dzInv = (z_cc_arr) ?
one/ (
myhalf * (z_cc_arr(i,j,k+1) - z_cc_arr(i,j,k-1))) :
dxInv[2];
884 Real dTdt = (rad_flux[lk+1] - rad_flux[lk]) * dzInv / (-cell_data(i,j,k,
Rho_comp)*
Cp_d);
void ApplySpongeZoneBCsForCC(const SpongeChoice &spongeChoice, const Geometry geom, const Box &bx, const Array4< Real > &cell_rhs, const Array4< const Real > &cell_data, const Array4< const Real > &r0, const Array4< const Real > &th0, const Array4< const Real > &qv0, const Array4< const Real > &z_phys_cc, int n_qstate)
Definition: ERF_ApplySpongeZoneBCs.cpp:7
constexpr amrex::Real three
Definition: ERF_Constants.H:11
constexpr amrex::Real KAPPA
Definition: ERF_Constants.H:63
constexpr amrex::Real Cp_d
Definition: ERF_Constants.H:49
constexpr amrex::Real two
Definition: ERF_Constants.H:10
constexpr amrex::Real one
Definition: ERF_Constants.H:9
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
constexpr amrex::Real RdoCp
Definition: ERF_Constants.H:54
@ thetabar
Definition: ERF_DataStruct.H:152
@ m_y
Definition: ERF_DataStruct.H:28
@ m_x
Definition: ERF_DataStruct.H:27
DirectionSelector< 2 > ZDir
Definition: ERF_DirectionSelector.H:38
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real getExnergivenRTh(const amrex::Real rhotheta, const amrex::Real rdOcp, const amrex::Real qv=amrex::Real(0))
Definition: ERF_EOS.H:156
#define RhoScalar_comp
Definition: ERF_IndexDefines.H:40
#define Rho_comp
Definition: ERF_IndexDefines.H:36
#define RhoTheta_comp
Definition: ERF_IndexDefines.H:37
#define NDRY
Definition: ERF_IndexDefines.H:13
#define RhoQ2_comp
Definition: ERF_IndexDefines.H:43
#define NSCALARS
Definition: ERF_IndexDefines.H:16
#define PrimTheta_comp
Definition: ERF_IndexDefines.H:55
#define RhoQ1_comp
Definition: ERF_IndexDefines.H:42
#define RhoKE_comp
Definition: ERF_IndexDefines.H:38
amrex::GpuArray< Real, AMREX_SPACEDIM > dxInv
Definition: ERF_InitCustomPertVels_ParticleTests.H:17
Real z0
Definition: ERF_InitCustomPertVels_ScalarAdvDiff.H:8
const Real dx
Definition: ERF_InitCustomPert_ABL.H:23
const int khi
Definition: ERF_InitCustomPert_Bubble.H:21
AMREX_ALWAYS_ASSERT(bx.length()[2]==khi+1)
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);})
void NumericalDiffusion_Scal(const Box &bx, const int start_comp, const int num_comp, const double dt, const Real num_diff_coeff, const Array4< const Real > &prim_data, const Array4< const Real > &cell_data, const Array4< Real > &rhs, const Array4< const Real > &mfx_arr, const Array4< const Real > &mfy_arr)
Definition: ERF_NumericalDiffusion.cpp:18
Real w
Definition: ERF_Plotfile2DInterpolator.cpp:22
AMREX_FORCE_INLINE IntVect offset(const int face_dir, const int normal)
Definition: ERF_ReadBndryPlanes.cpp:31
amrex::Real Real
Definition: ERF_ShocInterface.H:19
AMREX_FORCE_INLINE amrex::IntVect TileNoZ()
Definition: ERF_TileNoZ.H:11
Definition: ERF_PlaneAverage.H:14
@ qv0_comp
Definition: ERF_IndexDefines.H:77
@ th0_comp
Definition: ERF_IndexDefines.H:76
@ r0_comp
Definition: ERF_IndexDefines.H:73
@ cons
Definition: ERF_IndexDefines.H:194
@ theta
Definition: ERF_SLM.H:20
@ qv
Definition: ERF_Kessler.H:30
@ nr
Definition: ERF_Morrison.H:46
@ xvel
Definition: ERF_IndexDefines.H:177
@ cons
Definition: ERF_IndexDefines.H:176
@ zvel
Definition: ERF_IndexDefines.H:179
@ yvel
Definition: ERF_IndexDefines.H:178
@ dz
Definition: ERF_AdvanceWSM6.cpp:104
@ zi
Definition: ERF_AdvanceWSM6.cpp:133
real(c_double), parameter epsilon
Definition: ERF_module_model_constants.F90:12
real(c_double), private rhoi
Definition: ERF_module_mp_morr_two_moment.F90:188
real(kind=kind_phys), parameter, private r0
Definition: ERF_module_mp_wsm6.F90:21
RayleighDampingType rayleigh_damping_type
Selected Rayleigh damping time-integration treatment.
Definition: ERF_DampingStruct.H:111
amrex::Real rayleigh_dampcoef
Rayleigh damping inverse time scale [1/s].
Definition: ERF_DampingStruct.H:98
bool rayleigh_damp_T
Whether Rayleigh damping is applied to potential temperature.
Definition: ERF_DampingStruct.H:97
amrex::Vector< TurbChoice > turbChoice
Turbulence options for each AMR level.
Definition: ERF_DataStruct.H:1393
MoistureType moisture_type
Moisture or microphysics model.
Definition: ERF_DataStruct.H:1604
amrex::Real if_Olen_in
Input Obukhov length for immersed-forcing MOST [m].
Definition: ERF_DataStruct.H:1462
int ave_plane
Averaging plane index used by diagnostics.
Definition: ERF_DataStruct.H:1618
amrex::Real if_z0
Immersed-forcing roughness length [m].
Definition: ERF_DataStruct.H:1458
amrex::Real num_diff_coeff
Numerical diffusion coefficient after input scaling.
Definition: ERF_DataStruct.H:1601
bool do_theta_advection
Whether custom vertical subsidence is applied to rho-theta.
Definition: ERF_DataStruct.H:1493
bool spatial_moisture_forcing
Whether spatially varying moisture forcing is enabled.
Definition: ERF_DataStruct.H:1498
static MeshType mesh_type
Vertical mesh representation.
Definition: ERF_DataStruct.H:1377
SpongeChoice spongeChoice
Sponge-layer options.
Definition: ERF_DataStruct.H:1392
bool four_stream_radiation
Whether the four-stream radiation approximation is enabled.
Definition: ERF_DataStruct.H:1445
DampingChoice dampingChoice
Damping-related options.
Definition: ERF_DataStruct.H:1391
static TerrainType terrain_type
Terrain or immersed-boundary representation.
Definition: ERF_DataStruct.H:1368
amrex::Real if_Cd_scalar
Immersed-forcing drag coefficient for scalars.
Definition: ERF_DataStruct.H:1453
static BuildingsType buildings_type
Building representation.
Definition: ERF_DataStruct.H:1371
bool custom_rhotheta_forcing
Whether custom rho-theta forcing is enabled.
Definition: ERF_DataStruct.H:1490
amrex::Real if_init_surf_temp
Initial immersed-forcing surface temperature [K].
Definition: ERF_DataStruct.H:1460
amrex::Real if_surf_temp_flux
Immersed-forcing surface temperature flux [K m/s].
Definition: ERF_DataStruct.H:1459
bool spatial_rhotheta_forcing
Whether spatially varying rho-theta forcing is enabled.
Definition: ERF_DataStruct.H:1497
bool use_source_perturbation(int lev) const
Query whether source-term turbulent perturbations are enabled on a level.
Definition: ERF_DataStruct.H:1547
bool custom_w_subsidence
Whether custom vertical subsidence is enabled.
Definition: ERF_DataStruct.H:1492
bool custom_moisture_forcing
Whether custom moisture forcing is enabled.
Definition: ERF_DataStruct.H:1491
amrex::Real if_surf_heating_rate
Immersed-forcing surface heating rate [K/hr].
Definition: ERF_DataStruct.H:1461
RadiationType rad_type
Radiation model.
Definition: ERF_DataStruct.H:1608
bool immersed_forcing_substep
Whether immersed-forcing source terms are applied only during substeps.
Definition: ERF_DataStruct.H:1448
bool custom_forcing_prim_vars
Whether custom forcing operates on primitive variables.
Definition: ERF_DataStruct.H:1496
bool nudging_from_input_sounding
Whether solution fields are nudged toward input sounding data.
Definition: ERF_DataStruct.H:1502
bool use_num_diff
Whether sixth-order numerical diffusion is enabled.
Definition: ERF_DataStruct.H:1600
static SpongeType sponge_type
Selected sponge damping model.
Definition: ERF_SpongeStruct.H:100
Definition: ERF_TurbStruct.H:114
bool diffuse_tke_3D
Whether three-dimensional numerical diffusion is applied to TKE/QKE.
Definition: ERF_TurbStruct.H:731
bool use_tke
Whether any TKE or QKE closure is active.
Definition: ERF_TurbStruct.H:666
amrex::Vector< amrex::MultiFab > pb_cell
Per-cell perturbation amplitude storage.
Definition: ERF_TurbPertStruct.H:755
void apply_tpi(const int &lev, const amrex::Box &vbx, const int &comp, const amrex::IndexType &m_ixtype, const amrex::Array4< amrex::Real > &src_arr, const amrex::Array4< amrex::Real const > &pert_cell)
Apply stored turbulent perturbations to a source or state array.
Definition: ERF_TurbPertStruct.H:401
Definition: ERF_MOSTStress.H:40
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real calc_psi_m(amrex::Real zeta) const
Definition: ERF_MOSTStress.H:105
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real calc_psi_h(amrex::Real zeta) const
Definition: ERF_MOSTStress.H:124