Function for computing the slow RHS for the evolution equations for the density, potential temperature and momentum.
56 BL_PROFILE_REGION(
"erf_make_sources()");
70 const bool l_use_KE = tc.
use_tke;
73 const Box& domain = geom.Domain();
75 const GpuArray<Real, AMREX_SPACEDIM> dxInv = geom.InvCellSizeArray();
76 const GpuArray<Real, AMREX_SPACEDIM> dx = geom.CellSizeArray();
87 bool has_moisture = (solverChoice.
moisture_type != MoistureType::None);
92 Table1D<Real> dptr_r_plane, dptr_t_plane, dptr_qv_plane, dptr_qc_plane;
93 TableData<Real, 1> r_plane_tab, t_plane_tab, qv_plane_tab, qc_plane_tab;
94 bool compute_averages =
false;
95 compute_averages = compute_averages ||
106 IntVect ng_c(S_data[
IntVars::cons].nGrowVect()); ng_c[2] = 1;
111 int ncomp = (!has_moisture) ? 2 :
RhoQ2_comp+1;
115 cons_ave.compute_averages(
ZDir(), cons_ave.field());
117 int ncell = cons_ave.ncell_line();
119 Gpu::HostVector< Real> r_plane_h(ncell);
120 Gpu::DeviceVector< Real> r_plane_d(ncell);
122 Gpu::HostVector< Real> t_plane_h(ncell);
123 Gpu::DeviceVector< Real> t_plane_d(ncell);
125 cons_ave.line_average(
Rho_comp , r_plane_h);
128 Gpu::copyAsync(Gpu::hostToDevice, r_plane_h.begin(), r_plane_h.end(), r_plane_d.begin());
129 Gpu::copyAsync(Gpu::hostToDevice, t_plane_h.begin(), t_plane_h.end(), t_plane_d.begin());
131 Real* dptr_r = r_plane_d.data();
132 Real* dptr_t = t_plane_d.data();
134 Box tdomain = domain; tdomain.grow(2,ng_c[2]);
135 r_plane_tab.resize({tdomain.smallEnd(2)}, {tdomain.bigEnd(2)});
136 t_plane_tab.resize({tdomain.smallEnd(2)}, {tdomain.bigEnd(2)});
140 dptr_r_plane = r_plane_tab.table();
141 dptr_t_plane = t_plane_tab.table();
142 ParallelFor(ncell, [=] AMREX_GPU_DEVICE (
int k) noexcept
144 dptr_r_plane(k-
offset) = dptr_r[k];
145 dptr_t_plane(k-
offset) = dptr_t[k];
150 Gpu::HostVector< Real> qv_plane_h(ncell), qc_plane_h(ncell);
151 Gpu::DeviceVector<Real> qv_plane_d(ncell), qc_plane_d(ncell);
154 cons_ave.line_average(
RhoQ1_comp, qv_plane_h);
155 Gpu::copyAsync(Gpu::hostToDevice, qv_plane_h.begin(), qv_plane_h.end(), qv_plane_d.begin());
158 cons_ave.line_average(
RhoQ2_comp, qc_plane_h);
159 Gpu::copyAsync(Gpu::hostToDevice, qc_plane_h.begin(), qc_plane_h.end(), qc_plane_d.begin());
161 Real* dptr_qv = qv_plane_d.data();
162 Real* dptr_qc = qc_plane_d.data();
164 qv_plane_tab.resize({tdomain.smallEnd(2)}, {tdomain.bigEnd(2)});
165 qc_plane_tab.resize({tdomain.smallEnd(2)}, {tdomain.bigEnd(2)});
167 dptr_qv_plane = qv_plane_tab.table();
168 dptr_qc_plane = qc_plane_tab.table();
169 ParallelFor(ncell, [=] AMREX_GPU_DEVICE (
int k) noexcept
171 dptr_qv_plane(k-
offset) = dptr_qv[k];
172 dptr_qc_plane(k-
offset) = dptr_qc[k];
181 int klo = domain.smallEnd(0);
182 int khi = domain.bigEnd(2);
183 int nk = khi - klo + 2;
184 Gpu::DeviceVector<Real> radiation_flux(nk,0.0);
185 Gpu::DeviceVector<Real> q_integral(nk,0.0);
186 Real* rad_flux = radiation_flux.data();
187 Real* q_int = q_integral.data();
208 #pragma omp parallel if (Gpu::notInLaunchRegion())
213 Box bx = mfi.tilebox();
215 const Array4<const Real>& cell_data = S_data[
IntVars::cons].array(mfi);
216 const Array4<const Real>& cell_prim = S_prim.array(mfi);
217 const Array4<Real> & cell_src = source.array(mfi);
219 const Array4<const Real>& r0 = r_hse.const_array(mfi);
221 const Array4<const Real>& z_cc_arr = z_phys_cc->const_array(mfi);
223 const Array4<const Real>& t_blank_arr = (terrain_blank) ? terrain_blank->const_array(mfi) :
224 Array4<const Real>{};
230 if (solverChoice.
rad_type != RadiationType::None && is_slow_step) {
231 auto const& qheating_arr = qheating_rates->const_array(mfi);
232 ParallelFor(bx, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k) noexcept
235 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) );
247 if ((is_slow_step && !use_Rayleigh_fast) || (!is_slow_step && use_Rayleigh_fast)) {
252 ParallelFor(bx, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k) noexcept
254 Real zcc = z_cc_arr(i,j,k);
255 Real zfrac = 1 - (ztop - zcc) / zdamp;
259 cell_src(i, j, k, n) -= dampcoef*sinefac*sinefac * (
theta -
thetabar[k]) * cell_data(i,j,k,
nr);
272 ParallelFor(bx, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k) noexcept
274 cell_src(i, j, k, n) += cell_data(i,j,k,
nr) * dptr_rhotheta_src[k];
277 ParallelFor(bx, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k) noexcept
279 cell_src(i, j, k, n) += dptr_rhotheta_src[k];
291 ParallelFor(bx, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k) noexcept
293 cell_src(i, j, k, n) += cell_data(i,j,k,
nr) * dptr_rhoqt_src[k];
296 ParallelFor(bx, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k) noexcept
298 cell_src(i, j, k, n) += dptr_rhoqt_src[k];
310 ParallelFor(bx, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k) noexcept
312 Real dzInv = (z_cc_arr) ? 1.0/ (z_cc_arr(i,j,k+1) - z_cc_arr(i,j,k-1)) : 0.5*dxInv[2];
313 Real T_hi = dptr_t_plane(k+1) / dptr_r_plane(k+1);
314 Real T_lo = dptr_t_plane(k-1) / dptr_r_plane(k-1);
315 Real wbar_cc = 0.5 * (dptr_wbar_sub[k] + dptr_wbar_sub[k+1]);
316 cell_src(i, j, k, n) -= cell_data(i,j,k,
nr) * wbar_cc * (T_hi - T_lo) * dzInv;
319 ParallelFor(bx, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k) noexcept
321 Real dzInv = (z_cc_arr) ? 1.0/ (z_cc_arr(i,j,k+1) - z_cc_arr(i,j,k-1)) : 0.5*dxInv[2];
322 Real T_hi = dptr_t_plane(k+1) / dptr_r_plane(k+1);
323 Real T_lo = dptr_t_plane(k-1) / dptr_r_plane(k-1);
324 Real wbar_cc = 0.5 * (dptr_wbar_sub[k] + dptr_wbar_sub[k+1]);
325 cell_src(i, j, k, n) -= wbar_cc * (T_hi - T_lo) * dzInv;
337 ParallelFor(bx, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k) noexcept
339 Real dzInv = (z_cc_arr) ? 1.0/ (z_cc_arr(i,j,k+1) - z_cc_arr(i,j,k-1)) : 0.5*dxInv[2];
340 Real Qv_hi = dptr_qv_plane(k+1) / dptr_r_plane(k+1);
341 Real Qv_lo = dptr_qv_plane(k-1) / dptr_r_plane(k-1);
342 Real Qc_hi = dptr_qc_plane(k+1) / dptr_r_plane(k+1);
343 Real Qc_lo = dptr_qc_plane(k-1) / dptr_r_plane(k-1);
344 Real wbar_cc = 0.5 * (dptr_wbar_sub[k] + dptr_wbar_sub[k+1]);
345 cell_src(i, j, k, nv ) -= cell_data(i,j,k,
nr) * wbar_cc * (Qv_hi - Qv_lo) * dzInv;
346 cell_src(i, j, k, nv+1) -= cell_data(i,j,k,
nr) * wbar_cc * (Qc_hi - Qc_lo) * dzInv;
349 ParallelFor(bx, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k) noexcept
351 Real dzInv = (z_cc_arr) ? 1.0/ (z_cc_arr(i,j,k+1) - z_cc_arr(i,j,k-1)) : 0.5*dxInv[2];
352 Real Qv_hi = dptr_qv_plane(k+1) / dptr_r_plane(k+1);
353 Real Qv_lo = dptr_qv_plane(k-1) / dptr_r_plane(k-1);
354 Real Qc_hi = dptr_qc_plane(k+1) / dptr_r_plane(k+1);
355 Real Qc_lo = dptr_qc_plane(k-1) / dptr_r_plane(k-1);
356 Real wbar_cc = 0.5 * (dptr_wbar_sub[k] + dptr_wbar_sub[k+1]);
357 cell_src(i, j, k, nv ) -= wbar_cc * (Qv_hi - Qv_lo) * dzInv;
358 cell_src(i, j, k, nv+1) -= wbar_cc * (Qc_hi - Qc_lo) * dzInv;
366 if (l_use_ndiff && is_slow_step) {
370 const Array4<const Real>& mf_mx = mapfac[
MapFacType::m_x]->const_array(mfi);
371 const Array4<const Real>& mf_my = mapfac[
MapFacType::m_y]->const_array(mfi);
375 cell_data, cell_data, cell_src, mf_mx, mf_my);
379 cell_prim, cell_data, cell_src, mf_mx, mf_my);
382 if (l_use_KE && l_diff_KE) {
384 cell_prim, cell_data, cell_src, mf_mx, mf_my);
388 cell_prim, cell_data, cell_src, mf_mx, mf_my);
401 if (solverChoice.
pert_type == PerturbationType::Source && is_slow_step) {
403 const amrex::Array4<const amrex::Real>& pert_cell = turbPert.
pb_cell[level].const_array(mfi);
421 for (
int nt = 1; nt < n_sounding_times; nt++) {
424 if (itime_n == n_sounding_times-1) {
427 itime_np1 = itime_n+1;
430 coeff_n =
Real(1.0) - coeff_np1;
439 ParallelFor(bx, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k) noexcept
441 Real nudge = (coeff_n*theta_inp_sound_n[k] + coeff_np1*theta_inp_sound_np1[k]) - (dptr_t_plane(k)/dptr_r_plane(k));
443 cell_src(i, j, k, n) += cell_data(i, j, k,
nr) * nudge;
450 if (solverChoice.
terrain_type == TerrainType::ImmersedForcing &&
451 ((is_slow_step && !use_ImmersedForcing_fast) || (!is_slow_step && use_ImmersedForcing_fast)))
453 const Array4<const Real>& u =
xvel.array(mfi);
454 const Array4<const Real>& v =
yvel.array(mfi);
457 const Real* dx_arr = geom.CellSize();
458 const Real dx_x = dx_arr[0];
459 const Real dx_y = dx_arr[1];
460 const Real dx_z = dx_arr[2];
463 const Real drag_coefficient = alpha_h / std::pow(dx_x*dx_y*dx_z, 1./3.);
465 const Real U_s = 1.0;
477 ParallelFor(bx, [=] AMREX_GPU_DEVICE(
int i,
int j,
int k) noexcept
479 const Real t_blank = t_blank_arr(i, j, k);
480 const Real t_blank_above = t_blank_arr(i, j, k+1);
481 const Real ux_cc_2r = 0.5 * (u(i ,j ,k+1) + u(i+1,j ,k+1));
482 const Real uy_cc_2r = 0.5 * (v(i ,j ,k+1) + v(i ,j+1,k+1));
483 const Real h_windspeed2r = std::sqrt(ux_cc_2r * ux_cc_2r + uy_cc_2r * uy_cc_2r);
489 if (init_surf_temp > 0.0) {
490 if (t_blank > 0 && (t_blank_above == 0.0)) {
491 const Real surf_temp = init_surf_temp + surf_heating_rate*time/3600;
493 cell_src(i, j, k-1,
RhoTheta_comp) -= drag_coefficient * U_s * bc_forcing_rt_srf;
499 if (t_blank > 0 && (t_blank_above == 0.0)) {
502 Real psi_h_neighbor = 0.0;
503 Real ustar = h_windspeed2r * kappa / (std::log((1.5) * dx_z / z0) - psi_m);
504 const Real Olen = -ustar * ustar * ustar *
theta / (kappa * ggg * tflux + tiny);
505 const Real zeta = (0.5) * dx_z / Olen;
506 const Real zeta_neighbor = (1.5) * dx_z / Olen;
511 psi_h_neighbor = sfuns.
calc_psi_h(zeta_neighbor);
512 ustar = h_windspeed2r * kappa / (std::log((1.5) * dx_z / z0) - psi_m);
515 if (!(ustar > 0.0 && !std::isnan(ustar))) { ustar = 0.0; }
516 if (!(ustar < 2.0 && !std::isnan(ustar))) { ustar = 2.0; }
517 if (psi_h_neighbor > std::log(1.5 * dx_z / z0)) { psi_h_neighbor = std::log(1.5 * dx_z / z0); }
518 if (psi_h > std::log(0.5 * dx_z / z0)) { psi_h = std::log(0.5 * dx_z / z0); }
521 const Real thetastar =
theta * ustar * ustar / (kappa * ggg * Olen);
522 const Real surf_temp = theta_neighbor - thetastar / kappa * (std::log((1.5) * dx_z / z0) - psi_h_neighbor);
523 const Real tTarget = surf_temp + thetastar / kappa * (std::log((0.5) * dx_z / z0) - psi_h);
526 cell_src(i, j, k,
RhoTheta_comp) -= drag_coefficient * U_s * bc_forcing_rt;
531 if (Olen_in != 1e-8){
532 if (t_blank > 0 && (t_blank_above == 0.0)) {
533 const Real Olen = Olen_in;
534 const Real zeta = (0.5) * dx_z / Olen;
535 const Real zeta_neighbor = (1.5) * dx_z / Olen;
541 const Real ustar = h_windspeed2r * kappa / (std::log((1.5) * dx_z / z0) - psi_m);
544 const Real thetastar =
theta * ustar * ustar / (kappa * ggg * Olen);
545 const Real surf_temp = theta_neighbor - thetastar / kappa * (std::log((1.5) * dx_z / z0) - psi_h_neighbor);
546 const Real tTarget = surf_temp + thetastar / kappa * (std::log((0.5) * dx_z / z0) - psi_h);
549 cell_src(i, j, k,
RhoTheta_comp) -= drag_coefficient * U_s * bc_forcing_rt;
561 AMREX_ALWAYS_ASSERT((bx.smallEnd(2) == klo) && (bx.bigEnd(2) == khi));
568 Box xybx = makeSlab(bx,2,klo);
569 ParallelFor(xybx, [=] AMREX_GPU_DEVICE(
int i,
int j,
int ) noexcept
573 Real zi = 0.5 * (z_cc_arr(i,j,khi) + z_cc_arr(i,j,khi-1));
575 for (
int k(klo+1); k<=khi+1; ++k) {
578 Real dz = (z_cc_arr) ? 0.5 * (z_cc_arr(i,j,k) - z_cc_arr(i,j,k-2)) : dx[2];
579 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;
582 if ( (qt_lo > qt_i) && (qt_hi < qt_i) ) {
583 zi = 0.5 * (z_cc_arr(i,j,k) + z_cc_arr(i,j,k-1));
589 Real q_int_inf = q_int[khi+1];
590 for (
int k(klo); k<=khi+1; ++k) {
592 Real z = 0.5 * (z_cc_arr(i,j,k) + z_cc_arr(i,j,k-1));
593 rad_flux[lk] = F1*std::exp(-q_int[lk]) + F0*std::exp(-(q_int_inf - q_int[lk]));
595 rad_flux[lk] +=
rhoi *
Cp_d * D * ( std::pow(z-zi,4./3.)/4. + zi*std::pow(z-zi,1./3.) ) ;
600 for (
int k(klo); k<=khi; ++k) {
603 Real dzInv = (z_cc_arr) ? 1.0/ (0.5 * (z_cc_arr(i,j,k+1) - z_cc_arr(i,j,k-1))) : dxInv[2];
606 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 > &z_phys_cc)
Definition: ERF_ApplySpongeZoneBCs.cpp:7
constexpr amrex::Real KAPPA
Definition: ERF_Constants.H:20
constexpr amrex::Real Cp_d
Definition: ERF_Constants.H:12
constexpr amrex::Real CONST_GRAV
Definition: ERF_Constants.H:21
constexpr amrex::Real PIoTwo
Definition: ERF_Constants.H:7
constexpr amrex::Real R_d
Definition: ERF_Constants.H:10
@ thetabar
Definition: ERF_DataStruct.H:91
@ m_y
Definition: ERF_DataStruct.H:23
@ m_x
Definition: ERF_DataStruct.H:22
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=0.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 RhoQ2_comp
Definition: ERF_IndexDefines.H:43
#define NSCALARS
Definition: ERF_IndexDefines.H:16
#define PrimTheta_comp
Definition: ERF_IndexDefines.H:50
#define RhoQ1_comp
Definition: ERF_IndexDefines.H:42
#define RhoKE_comp
Definition: ERF_IndexDefines.H:38
void NumericalDiffusion_Scal(const Box &bx, const int start_comp, const int num_comp, const Real 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
AMREX_FORCE_INLINE IntVect offset(const int face_dir, const int normal)
Definition: ERF_ReadBndryPlanes.cpp:28
amrex::Real Real
Definition: ERF_ShocInterface.H:19
AMREX_FORCE_INLINE amrex::IntVect TileNoZ()
Definition: ERF_TileNoZ.H:11
Definition: ERF_PlaneAverage.H:14
@ r0_comp
Definition: ERF_IndexDefines.H:63
@ cons
Definition: ERF_IndexDefines.H:158
@ theta
Definition: ERF_MM5.H:20
@ qv
Definition: ERF_Kessler.H:28
@ nc
Definition: ERF_Morrison.H:44
@ nr
Definition: ERF_Morrison.H:45
@ xvel
Definition: ERF_IndexDefines.H:141
@ cons
Definition: ERF_IndexDefines.H:140
@ yvel
Definition: ERF_IndexDefines.H:142
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
bool rayleigh_damp_T
Definition: ERF_DataStruct.H:942
amrex::Real if_init_surf_temp
Definition: ERF_DataStruct.H:964
amrex::Real if_surf_temp_flux
Definition: ERF_DataStruct.H:963
bool rayleigh_damp_substep
Definition: ERF_DataStruct.H:946
amrex::Real rayleigh_zdamp
Definition: ERF_DataStruct.H:944
RadiationType rad_type
Definition: ERF_DataStruct.H:1024
amrex::Real if_z0
Definition: ERF_DataStruct.H:962
bool custom_rhotheta_forcing
Definition: ERF_DataStruct.H:990
bool custom_w_subsidence
Definition: ERF_DataStruct.H:992
bool nudging_from_input_sounding
Definition: ERF_DataStruct.H:998
amrex::Real if_Cd_scalar
Definition: ERF_DataStruct.H:959
amrex::Real rayleigh_ztop
Definition: ERF_DataStruct.H:945
bool immersed_forcing_substep
Definition: ERF_DataStruct.H:955
amrex::Real if_Olen_in
Definition: ERF_DataStruct.H:966
bool use_num_diff
Definition: ERF_DataStruct.H:1013
bool four_stream_radiation
Definition: ERF_DataStruct.H:952
bool custom_moisture_forcing
Definition: ERF_DataStruct.H:991
amrex::Real num_diff_coeff
Definition: ERF_DataStruct.H:1014
amrex::Real if_surf_heating_rate
Definition: ERF_DataStruct.H:965
amrex::Vector< TurbChoice > turbChoice
Definition: ERF_DataStruct.H:905
MoistureType moisture_type
Definition: ERF_DataStruct.H:1020
bool custom_forcing_prim_vars
Definition: ERF_DataStruct.H:994
static TerrainType terrain_type
Definition: ERF_DataStruct.H:885
PerturbationType pert_type
Definition: ERF_DataStruct.H:1010
SpongeChoice spongeChoice
Definition: ERF_DataStruct.H:904
amrex::Real rayleigh_dampcoef
Definition: ERF_DataStruct.H:943
int ave_plane
Definition: ERF_DataStruct.H:1035
std::string sponge_type
Definition: ERF_SpongeStruct.H:58
Definition: ERF_TurbStruct.H:41
bool use_tke
Definition: ERF_TurbStruct.H:402
bool diffuse_tke_3D
Definition: ERF_TurbStruct.H:437
amrex::Vector< amrex::MultiFab > pb_cell
Definition: ERF_TurbPertStruct.H:640
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)
Definition: ERF_TurbPertStruct.H:324
Definition: ERF_MOSTStress.H:41
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real calc_psi_m(amrex::Real zeta) const
Definition: ERF_MOSTStress.H:91
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real calc_psi_h(amrex::Real zeta) const
Definition: ERF_MOSTStress.H:105