Function for computing the slow RHS for the evolution equations for the density, potential temperature and momentum.
51 BL_PROFILE_REGION(
"erf_make_sources()");
65 const bool l_use_KE = tc.
use_tke;
68 const Box& domain = geom.Domain();
70 const GpuArray<Real, AMREX_SPACEDIM> dxInv = geom.InvCellSizeArray();
83 Table1D<Real> dptr_r_plane, dptr_t_plane, dptr_qv_plane, dptr_qc_plane;
84 TableData<Real, 1> r_plane_tab, t_plane_tab, qv_plane_tab, qc_plane_tab;
85 bool compute_averages =
false;
86 compute_averages = compute_averages ||
87 ( (solverChoice.
terrain_type == TerrainType::ImmersedForcing) &&
88 ((is_slow_step && !use_ImmersedForcing_fast) || (!is_slow_step && use_ImmersedForcing_fast)));
89 compute_averages = compute_averages ||
100 IntVect ng_c(S_data[
IntVars::cons].nGrowVect()); ng_c[2] = 1;
109 cons_ave.compute_averages(
ZDir(), cons_ave.field());
111 int ncell = cons_ave.ncell_line();
113 Gpu::HostVector< Real> r_plane_h(ncell);
114 Gpu::DeviceVector< Real> r_plane_d(ncell);
116 Gpu::HostVector< Real> t_plane_h(ncell);
117 Gpu::DeviceVector< Real> t_plane_d(ncell);
119 cons_ave.line_average(
Rho_comp , r_plane_h);
122 Gpu::copyAsync(Gpu::hostToDevice, r_plane_h.begin(), r_plane_h.end(), r_plane_d.begin());
123 Gpu::copyAsync(Gpu::hostToDevice, t_plane_h.begin(), t_plane_h.end(), t_plane_d.begin());
125 Real* dptr_r = r_plane_d.data();
126 Real* dptr_t = t_plane_d.data();
128 Box tdomain = domain; tdomain.grow(2,ng_c[2]);
129 r_plane_tab.resize({tdomain.smallEnd(2)}, {tdomain.bigEnd(2)});
130 t_plane_tab.resize({tdomain.smallEnd(2)}, {tdomain.bigEnd(2)});
134 dptr_r_plane = r_plane_tab.table();
135 dptr_t_plane = t_plane_tab.table();
136 ParallelFor(ncell, [=] AMREX_GPU_DEVICE (
int k) noexcept
138 dptr_r_plane(k-
offset) = dptr_r[k];
139 dptr_t_plane(k-
offset) = dptr_t[k];
144 Gpu::HostVector< Real> qv_plane_h(ncell), qc_plane_h(ncell);
145 Gpu::DeviceVector<Real> qv_plane_d(ncell), qc_plane_d(ncell);
148 cons_ave.line_average(
RhoQ1_comp, qv_plane_h);
149 Gpu::copyAsync(Gpu::hostToDevice, qv_plane_h.begin(), qv_plane_h.end(), qv_plane_d.begin());
152 cons_ave.line_average(
RhoQ2_comp, qc_plane_h);
153 Gpu::copyAsync(Gpu::hostToDevice, qc_plane_h.begin(), qc_plane_h.end(), qc_plane_d.begin());
155 Real* dptr_qv = qv_plane_d.data();
156 Real* dptr_qc = qc_plane_d.data();
158 qv_plane_tab.resize({tdomain.smallEnd(2)}, {tdomain.bigEnd(2)});
159 qc_plane_tab.resize({tdomain.smallEnd(2)}, {tdomain.bigEnd(2)});
161 dptr_qv_plane = qv_plane_tab.table();
162 dptr_qc_plane = qc_plane_tab.table();
163 ParallelFor(ncell, [=] AMREX_GPU_DEVICE (
int k) noexcept
165 dptr_qv_plane(k-
offset) = dptr_qv[k];
166 dptr_qc_plane(k-
offset) = dptr_qc[k];
189 #pragma omp parallel if (Gpu::notInLaunchRegion())
194 Box bx = mfi.tilebox();
196 const Array4<const Real>& cell_data = S_data[
IntVars::cons].array(mfi);
197 const Array4<const Real>& cell_prim = S_prim.array(mfi);
198 const Array4<Real> & cell_src = source.array(mfi);
200 const Array4<const Real>& r0 = r_hse.const_array(mfi);
202 const Array4<const Real>& z_cc_arr = z_phys_cc->const_array(mfi);
204 const Array4<const Real>& t_blank_arr = (terrain_blank) ? terrain_blank->const_array(mfi) :
205 Array4<const Real>{};
210 if (solverChoice.
rad_type != RadiationType::None && is_slow_step) {
211 auto const& qheating_arr = qheating_rates->const_array(mfi);
212 ParallelFor(bx, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k) noexcept
215 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) );
227 if ((is_slow_step && !use_Rayleigh_fast) || (!is_slow_step && use_Rayleigh_fast)) {
232 ParallelFor(bx, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k) noexcept
234 Real zcc = z_cc_arr(i,j,k);
235 Real zfrac = 1 - (ztop - zcc) / zdamp;
237 Real
theta = cell_prim(i,j,k,np);
238 Real sinefac = std::sin(
PIoTwo*zfrac);
239 cell_src(i, j, k, n) -= dampcoef*sinefac*sinefac * (
theta -
thetabar[k]) * cell_data(i,j,k,
nr);
252 ParallelFor(bx, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k) noexcept
254 cell_src(i, j, k, n) += cell_data(i,j,k,
nr) * dptr_rhotheta_src[k];
257 ParallelFor(bx, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k) noexcept
259 cell_src(i, j, k, n) += dptr_rhotheta_src[k];
271 ParallelFor(bx, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k) noexcept
273 cell_src(i, j, k, n) += cell_data(i,j,k,
nr) * dptr_rhoqt_src[k];
276 ParallelFor(bx, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k) noexcept
278 cell_src(i, j, k, n) += dptr_rhoqt_src[k];
290 ParallelFor(bx, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k) noexcept
292 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];
293 Real T_hi = dptr_t_plane(k+1) / dptr_r_plane(k+1);
294 Real T_lo = dptr_t_plane(k-1) / dptr_r_plane(k-1);
295 Real wbar_cc = 0.5 * (dptr_wbar_sub[k] + dptr_wbar_sub[k+1]);
296 cell_src(i, j, k, n) -= cell_data(i,j,k,
nr) * wbar_cc * (T_hi - T_lo) * dzInv;
299 ParallelFor(bx, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k) noexcept
301 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];
302 Real T_hi = dptr_t_plane(k+1) / dptr_r_plane(k+1);
303 Real T_lo = dptr_t_plane(k-1) / dptr_r_plane(k-1);
304 Real wbar_cc = 0.5 * (dptr_wbar_sub[k] + dptr_wbar_sub[k+1]);
305 cell_src(i, j, k, n) -= wbar_cc * (T_hi - T_lo) * dzInv;
317 ParallelFor(bx, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k) noexcept
319 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];
320 Real Qv_hi = dptr_qv_plane(k+1) / dptr_r_plane(k+1);
321 Real Qv_lo = dptr_qv_plane(k-1) / dptr_r_plane(k-1);
322 Real Qc_hi = dptr_qc_plane(k+1) / dptr_r_plane(k+1);
323 Real Qc_lo = dptr_qc_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, nv ) -= cell_data(i,j,k,
nr) * wbar_cc * (Qv_hi - Qv_lo) * dzInv;
326 cell_src(i, j, k, nv+1) -= cell_data(i,j,k,
nr) * wbar_cc * (Qc_hi - Qc_lo) * dzInv;
329 ParallelFor(bx, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k) noexcept
331 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];
332 Real Qv_hi = dptr_qv_plane(k+1) / dptr_r_plane(k+1);
333 Real Qv_lo = dptr_qv_plane(k-1) / dptr_r_plane(k-1);
334 Real Qc_hi = dptr_qc_plane(k+1) / dptr_r_plane(k+1);
335 Real Qc_lo = dptr_qc_plane(k-1) / dptr_r_plane(k-1);
336 Real wbar_cc = 0.5 * (dptr_wbar_sub[k] + dptr_wbar_sub[k+1]);
337 cell_src(i, j, k, nv ) -= wbar_cc * (Qv_hi - Qv_lo) * dzInv;
338 cell_src(i, j, k, nv+1) -= wbar_cc * (Qc_hi - Qc_lo) * dzInv;
346 if (l_use_ndiff && is_slow_step) {
350 const Array4<const Real>& mf_mx = mapfac[
MapFacType::m_x]->const_array(mfi);
351 const Array4<const Real>& mf_my = mapfac[
MapFacType::m_y]->const_array(mfi);
355 cell_data, cell_data, cell_src, mf_mx, mf_my);
359 cell_prim, cell_data, cell_src, mf_mx, mf_my);
362 if (l_use_KE && l_diff_KE) {
364 cell_prim, cell_data, cell_src, mf_mx, mf_my);
368 cell_prim, cell_data, cell_src, mf_mx, mf_my);
381 if (solverChoice.
pert_type == PerturbationType::Source && is_slow_step) {
383 const amrex::Array4<const amrex::Real>& pert_cell = turbPert.
pb_cell[level].const_array(mfi);
394 Real coeff_n = Real(1.0);
395 Real coeff_np1 = Real(0.0);
397 Real tau_inv = Real(1.0) / input_sounding_data.
tau_nudging;
401 for (
int nt = 1; nt < n_sounding_times; nt++) {
404 if (itime_n == n_sounding_times-1) {
407 itime_np1 = itime_n+1;
410 coeff_n = Real(1.0) - coeff_np1;
413 const Real* theta_inp_sound_n = input_sounding_data.
theta_inp_sound_d[itime_n].dataPtr();
414 const Real* theta_inp_sound_np1 = input_sounding_data.
theta_inp_sound_d[itime_np1].dataPtr();
419 ParallelFor(bx, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k) noexcept
421 Real nudge = (coeff_n*theta_inp_sound_n[k] + coeff_np1*theta_inp_sound_np1[k]) - (dptr_t_plane(k)/dptr_r_plane(k));
423 cell_src(i, j, k, n) += cell_data(i, j, k,
nr) * nudge;
430 if (solverChoice.
terrain_type == TerrainType::ImmersedForcing &&
431 ((is_slow_step && !use_ImmersedForcing_fast) || (!is_slow_step && use_ImmersedForcing_fast)))
433 Real dz = geom.CellSize(2);
434 const Real drag_coefficient = 10.0/dz;
435 const Real CdT = drag_coefficient;
436 const Real U_s = 1.0;
437 ParallelFor(bx, [=] AMREX_GPU_DEVICE(
int i,
int j,
int k) noexcept
439 const Real t_blank = t_blank_arr(i, j, k);
441 cell_src(i, j, k,
Rho_comp) -= t_blank * CdT * U_s * (cell_data(i,j,k,
Rho_comp) - dptr_r_plane(k));
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 PIoTwo
Definition: ERF_Constants.H:7
@ thetabar
Definition: ERF_DataStruct.H:83
@ m_y
Definition: ERF_DataStruct.H:22
@ m_x
Definition: ERF_DataStruct.H:21
DirectionSelector< 2 > ZDir
Definition: ERF_DirectionSelector.H:38
#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_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
@ nc
Definition: ERF_Morrison.H:44
@ nr
Definition: ERF_Morrison.H:45
@ cons
Definition: ERF_IndexDefines.H:140
bool rayleigh_damp_T
Definition: ERF_DataStruct.H:722
bool rayleigh_damp_substep
Definition: ERF_DataStruct.H:726
amrex::Real rayleigh_zdamp
Definition: ERF_DataStruct.H:724
RadiationType rad_type
Definition: ERF_DataStruct.H:787
bool custom_rhotheta_forcing
Definition: ERF_DataStruct.H:753
bool custom_w_subsidence
Definition: ERF_DataStruct.H:755
bool nudging_from_input_sounding
Definition: ERF_DataStruct.H:761
amrex::Real rayleigh_ztop
Definition: ERF_DataStruct.H:725
bool immersed_forcing_substep
Definition: ERF_DataStruct.H:729
bool use_num_diff
Definition: ERF_DataStruct.H:773
bool custom_moisture_forcing
Definition: ERF_DataStruct.H:754
amrex::Real num_diff_coeff
Definition: ERF_DataStruct.H:774
amrex::Vector< TurbChoice > turbChoice
Definition: ERF_DataStruct.H:698
MoistureType moisture_type
Definition: ERF_DataStruct.H:783
bool custom_forcing_prim_vars
Definition: ERF_DataStruct.H:757
static TerrainType terrain_type
Definition: ERF_DataStruct.H:681
PerturbationType pert_type
Definition: ERF_DataStruct.H:770
SpongeChoice spongeChoice
Definition: ERF_DataStruct.H:697
amrex::Real rayleigh_dampcoef
Definition: ERF_DataStruct.H:723
int ave_plane
Definition: ERF_DataStruct.H:798
std::string sponge_type
Definition: ERF_SpongeStruct.H:58
Definition: ERF_TurbStruct.H:31
bool use_tke
Definition: ERF_TurbStruct.H:285
bool diffuse_tke_3D
Definition: ERF_TurbStruct.H:297
amrex::Vector< amrex::MultiFab > pb_cell
Definition: ERF_TurbPertStruct.H:647
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