Function for computing the slow RHS for the evolution equations for the density, potential temperature and momentum.
63 BL_PROFILE_REGION(
"erf_make_sources()");
65 Real time =
static_cast<Real>(time_d);
79 const bool l_use_KE = tc.
use_tke;
82 const Box& domain = geom.Domain();
84 const GpuArray<Real, AMREX_SPACEDIM>
dxInv = geom.InvCellSizeArray();
85 const GpuArray<Real, AMREX_SPACEDIM>
dx = geom.CellSizeArray();
99 bool has_moisture = (solverChoice.
moisture_type != MoistureType::None);
104 Table1D<Real> dptr_r_plane, dptr_t_plane, dptr_qv_plane, dptr_qc_plane;
105 Table1D<Real> dptr_r_plane_if, dptr_t_plane_if;
106 TableData<Real, 1> r_plane_tab, t_plane_tab, qv_plane_tab, qc_plane_tab;
108 bool use_immersed_forcing = (solverChoice.
terrain_type == TerrainType::ImmersedForcing ||
113 if (use_immersed_forcing && r_plane_avg && t_plane_avg) {
115 dptr_r_plane_if = r_plane_avg;
116 dptr_t_plane_if = t_plane_avg;
120 bool compute_averages = (is_slow_step && dptr_wbar_sub);
122 if (compute_averages)
134 IntVect ng_c(S_data[
IntVars::cons].nGrowVect()); ng_c[2] = 1;
139 int ncomp = (!has_moisture) ? 2 :
RhoQ2_comp+1;
143 cons_ave.compute_averages(
ZDir(), cons_ave.field());
145 int ncell = cons_ave.ncell_line();
147 Gpu::HostVector< Real> r_plane_h(ncell);
148 Gpu::DeviceVector< Real> r_plane_d(ncell);
150 Gpu::HostVector< Real> t_plane_h(ncell);
151 Gpu::DeviceVector< Real> t_plane_d(ncell);
153 cons_ave.line_average(
Rho_comp , r_plane_h);
156 Gpu::copyAsync(Gpu::hostToDevice, r_plane_h.begin(), r_plane_h.end(), r_plane_d.begin());
157 Gpu::copyAsync(Gpu::hostToDevice, t_plane_h.begin(), t_plane_h.end(), t_plane_d.begin());
159 Real* dptr_r = r_plane_d.data();
160 Real* dptr_t = t_plane_d.data();
162 Box tdomain = domain; tdomain.grow(2,ng_c[2]);
163 r_plane_tab.resize({tdomain.smallEnd(2)}, {tdomain.bigEnd(2)});
164 t_plane_tab.resize({tdomain.smallEnd(2)}, {tdomain.bigEnd(2)});
168 dptr_r_plane = r_plane_tab.table();
169 dptr_t_plane = t_plane_tab.table();
170 ParallelFor(ncell, [=] AMREX_GPU_DEVICE (
int k) noexcept
172 dptr_r_plane(k-
offset) = dptr_r[k];
173 dptr_t_plane(k-
offset) = dptr_t[k];
178 Gpu::HostVector< Real> qv_plane_h(ncell), qc_plane_h(ncell);
179 Gpu::DeviceVector<Real> qv_plane_d(ncell), qc_plane_d(ncell);
182 cons_ave.line_average(
RhoQ1_comp, qv_plane_h);
183 Gpu::copyAsync(Gpu::hostToDevice, qv_plane_h.begin(), qv_plane_h.end(), qv_plane_d.begin());
186 cons_ave.line_average(
RhoQ2_comp, qc_plane_h);
187 Gpu::copyAsync(Gpu::hostToDevice, qc_plane_h.begin(), qc_plane_h.end(), qc_plane_d.begin());
189 Real* dptr_qv = qv_plane_d.data();
190 Real* dptr_qc = qc_plane_d.data();
192 qv_plane_tab.resize({tdomain.smallEnd(2)}, {tdomain.bigEnd(2)});
193 qc_plane_tab.resize({tdomain.smallEnd(2)}, {tdomain.bigEnd(2)});
195 dptr_qv_plane = qv_plane_tab.table();
196 dptr_qc_plane = qc_plane_tab.table();
197 ParallelFor(ncell, [=] AMREX_GPU_DEVICE (
int k) noexcept
199 dptr_qv_plane(k-
offset) = dptr_qv[k];
200 dptr_qc_plane(k-
offset) = dptr_qc[k];
215 int klo = domain.smallEnd(2);
216 int khi = domain.bigEnd(2);
238 #pragma omp parallel if (Gpu::notInLaunchRegion())
243 Box bx = mfi.tilebox();
245 const Array4<const Real>& cell_data = S_data[
IntVars::cons].array(mfi);
246 const Array4<const Real>& cell_prim = S_prim.array(mfi);
247 const Array4<Real> & cell_src = source.array(mfi);
249 const Array4<const Real>&
r0 = r_hse.const_array(mfi);
250 const Array4<const Real>& th0 = th_hse.const_array(mfi);
251 const Array4<const Real>& qv0 = qv_hse.const_array(mfi);
253 const Array4<const Real>& z_cc_arr = z_phys_cc->const_array(mfi);
255 const Array4<const Real>& t_blank_arr = (terrain_blank) ? terrain_blank->const_array(mfi) :
256 Array4<const Real>{};
286 if (solverChoice.
rad_type != RadiationType::None &&
287 is_slow_step && qheating_rates !=
nullptr) {
288 auto const& qheating_arr = qheating_rates->const_array(mfi);
289 ParallelFor(bx, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k) noexcept
293 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) );
303 if ((is_slow_step && !use_Rayleigh_fast) || (!is_slow_step && use_Rayleigh_fast)) {
308 ParallelFor(bx, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k) noexcept
311 Real sinesq = d_sinesq_at_lev[k];
312 cell_src(i, j, k, n) -= dampcoef*sinesq * (
theta -
thetabar[k]) * cell_data(i,j,k,
nr);
322 auto const& rhotheta_src_arr = rhotheta_src->const_array(mfi);
327 ParallelFor(bx, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k) noexcept
329 cell_src(i, j, k, n) += cell_data(i,j,k,
nr) * rhotheta_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) += rhotheta_src_arr(i, j, k);
340 ParallelFor(bx, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k) noexcept
342 cell_src(i, j, k, n) += cell_data(i,j,k,
nr) * rhotheta_src_arr(0, 0, k);
345 ParallelFor(bx, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k) noexcept
347 cell_src(i, j, k, n) += rhotheta_src_arr(0, 0, k);
358 auto const& rhoqt_src_arr = rhoqt_src->const_array(mfi);
363 ParallelFor(bx, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k) noexcept
365 cell_src(i, j, k, n) += cell_data(i,j,k,
nr) * rhoqt_src_arr(i, j, k);
368 ParallelFor(bx, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k) noexcept
370 cell_src(i, j, k, n) += rhoqt_src_arr(i, j, k);
376 ParallelFor(bx, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k) noexcept
378 cell_src(i, j, k, n) += cell_data(i,j,k,
nr) * rhoqt_src_arr(0, 0, k);
381 ParallelFor(bx, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k) noexcept
383 cell_src(i, j, k, n) += rhoqt_src_arr(0, 0, k);
396 ParallelFor(bx, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k) noexcept
398 Real dzInv = (z_cc_arr) ?
one/ (z_cc_arr(i,j,k+1) - z_cc_arr(i,j,k-1)) :
myhalf*
dxInv[2];
399 Real T_hi = dptr_t_plane(k+1) / dptr_r_plane(k+1);
400 Real T_lo = dptr_t_plane(k-1) / dptr_r_plane(k-1);
401 Real wbar_cc =
myhalf * (dptr_wbar_sub[k] + dptr_wbar_sub[k+1]);
402 cell_src(i, j, k, n) -= cell_data(i,j,k,
nr) * wbar_cc * (T_hi - T_lo) * dzInv;
405 ParallelFor(bx, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k) noexcept
407 Real dzInv = (z_cc_arr) ?
one/ (z_cc_arr(i,j,k+1) - z_cc_arr(i,j,k-1)) :
myhalf*
dxInv[2];
408 Real T_hi = dptr_t_plane(k+1) / dptr_r_plane(k+1);
409 Real T_lo = dptr_t_plane(k-1) / dptr_r_plane(k-1);
410 Real wbar_cc =
myhalf * (dptr_wbar_sub[k] + dptr_wbar_sub[k+1]);
411 cell_src(i, j, k, n) -= wbar_cc * (T_hi - T_lo) * dzInv;
423 ParallelFor(bx, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k) noexcept
425 Real dzInv = (z_cc_arr) ?
one/ (z_cc_arr(i,j,k+1) - z_cc_arr(i,j,k-1)) :
myhalf*
dxInv[2];
426 Real Qv_hi = dptr_qv_plane(k+1) / dptr_r_plane(k+1);
427 Real Qv_lo = dptr_qv_plane(k-1) / dptr_r_plane(k-1);
428 Real Qc_hi = dptr_qc_plane(k+1) / dptr_r_plane(k+1);
429 Real Qc_lo = dptr_qc_plane(k-1) / dptr_r_plane(k-1);
430 Real wbar_cc =
myhalf * (dptr_wbar_sub[k] + dptr_wbar_sub[k+1]);
431 cell_src(i, j, k, nv ) -= cell_data(i,j,k,
nr) * wbar_cc * (Qv_hi - Qv_lo) * dzInv;
432 cell_src(i, j, k, nv+1) -= cell_data(i,j,k,
nr) * wbar_cc * (Qc_hi - Qc_lo) * dzInv;
435 ParallelFor(bx, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k) noexcept
437 Real dzInv = (z_cc_arr) ?
one/ (z_cc_arr(i,j,k+1) - z_cc_arr(i,j,k-1)) :
myhalf*
dxInv[2];
438 Real Qv_hi = dptr_qv_plane(k+1) / dptr_r_plane(k+1);
439 Real Qv_lo = dptr_qv_plane(k-1) / dptr_r_plane(k-1);
440 Real Qc_hi = dptr_qc_plane(k+1) / dptr_r_plane(k+1);
441 Real Qc_lo = dptr_qc_plane(k-1) / dptr_r_plane(k-1);
442 Real wbar_cc =
myhalf * (dptr_wbar_sub[k] + dptr_wbar_sub[k+1]);
443 cell_src(i, j, k, nv ) -= wbar_cc * (Qv_hi - Qv_lo) * dzInv;
444 cell_src(i, j, k, nv+1) -= wbar_cc * (Qc_hi - Qc_lo) * dzInv;
452 if (l_use_ndiff && is_slow_step)
454 const Array4<const Real>& mf_mx = mapfac[
MapFacType::m_x]->const_array(mfi);
455 const Array4<const Real>& mf_my = mapfac[
MapFacType::m_y]->const_array(mfi);
459 cell_data, cell_data, cell_src, mf_mx, mf_my);
463 cell_prim, cell_data, cell_src, mf_mx, mf_my);
466 if (l_use_KE && l_diff_KE) {
468 cell_prim, cell_data, cell_src, mf_mx, mf_my);
472 cell_prim, cell_data, cell_src, mf_mx, mf_my);
488 const amrex::Array4<const amrex::Real>& pert_cell = turbPert.
pb_cell[level].const_array(mfi);
495 if (solverChoice.
terrain_type == TerrainType::ImmersedForcing &&
496 ((is_slow_step && !use_ImmersedForcing_fast) || (!is_slow_step && use_ImmersedForcing_fast))) {
498 const Array4<const Real>& u =
xvel.array(mfi);
499 const Array4<const Real>& v =
yvel.array(mfi);
503 cell_src, geom, solverChoice, dptr_r_plane_if, dptr_t_plane_if, time);
510 const Real* dx_arr = geom.CellSize();
511 const Real delta_xy = std::sqrt(dx_arr[0] * dx_arr[1]);
513 if ((solverChoice.
buildings_type == BuildingsType::ImmersedForcing) &&
514 ((is_slow_step && !use_ImmersedForcing_fast) || (!is_slow_step && use_ImmersedForcing_fast)) &&
515 (delta_xy <= 50.0)) {
517 const Array4<const Real>& u =
xvel.array(mfi);
518 const Array4<const Real>& v =
yvel.array(mfi);
519 const Array4<const Real>&
w =
zvel.array(mfi);
523 cell_src, geom, solverChoice, dptr_r_plane_if, dptr_t_plane_if, time);
538 Box xybx = makeSlab(bx,2,
klo);
540 AMREX_GPU_DEVICE(
int i,
int j,
int ) noexcept
550 for (
int k(
klo+1); k<=
khi+1; ++k) {
552 Real dz = (z_cc_arr) ?
myhalf * (z_cc_arr(i,j,k) - z_cc_arr(i,j,k-2)) :
dx[2];
556 if ( (qt_lo > qt_i) && (qt_hi < qt_i) ) {
557 zi =
myhalf * (z_cc_arr(i,j,k) + z_cc_arr(i,j,k-1));
568 Real flux_lo = F1*std::exp(-q_int) + F0*std::exp(-(q_int_inf - q_int));
573 for (
int k(
klo); k<=
khi; ++k) {
575 Real dz = (z_cc_arr) ?
myhalf * (z_cc_arr(i,j,k+1) - z_cc_arr(i,j,k-1)) :
dx[2];
578 Real z_hi =
myhalf * (z_cc_arr(i,j,k+1) + z_cc_arr(i,j,k));
579 Real flux_hi = F1*std::exp(-q_int) + F0*std::exp(-(q_int_inf - q_int));
585 Real dzInv = (z_cc_arr) ?
one/ (
myhalf * (z_cc_arr(i,j,k+1) - z_cc_arr(i,j,k-1))) :
dxInv[2];
588 Real dTdt = (flux_hi - flux_lo) * 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)
Apply sponge zone damping to cell-centered state variables.
Definition: ERF_ApplySpongeZoneBCs.cpp:21
constexpr amrex::Real Cp_d
Definition: ERF_Constants.H:36
constexpr amrex::Real RdoCp
Definition: ERF_Constants.H:41
@ thetabar
Definition: ERF_DataStruct.H:179
@ m_y
Definition: ERF_DataStruct.H:30
@ m_x
Definition: ERF_DataStruct.H:29
DirectionSelector< 2 > ZDir
Definition: ERF_DirectionSelector.H:55
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
void ImmersedForcingTerrain_Scalar(const Box &bx, const Array4< const Real > &u, const Array4< const Real > &v, const Array4< const Real > &cell_data, const Array4< const Real > &t_blank_arr, const Array4< const Real > &z_cc_arr, const Array4< Real > &cell_src, const Geometry &geom, const SolverChoice &solverChoice, const Table1D< Real > &r_avg, const Table1D< Real > &t_avg, const Real time)
Definition: ERF_ImmersedForcing.cpp:949
void ImmersedForcingBuildings_Scalar(const Box &bx, const Array4< const Real > &u, const Array4< const Real > &v, const Array4< const Real > &w, const Array4< const Real > &cell_data, const Array4< const Real > &t_blank_arr, const Array4< const Real > &z_cc_arr, const Array4< Real > &cell_src, const Geometry &geom, const SolverChoice &solverChoice, const Table1D< Real > &r_avg, const Table1D< Real > &t_avg, const Real time)
Definition: ERF_ImmersedForcing.cpp:1084
#define RhoScalar_comp
Definition: ERF_IndexDefines.H:43
#define Rho_comp
Definition: ERF_IndexDefines.H:39
#define RhoTheta_comp
Definition: ERF_IndexDefines.H:40
#define NDRY
Definition: ERF_IndexDefines.H:13
#define RhoQ2_comp
Definition: ERF_IndexDefines.H:46
#define NSCALARS
Definition: ERF_IndexDefines.H:16
#define PrimTheta_comp
Definition: ERF_IndexDefines.H:58
#define RhoQ1_comp
Definition: ERF_IndexDefines.H:45
#define RhoKE_comp
Definition: ERF_IndexDefines.H:41
amrex::GpuArray< Real, AMREX_SPACEDIM > dxInv
Definition: ERF_InitCustomPertVels_ParticleTests.H:17
const int klo
Definition: ERF_InitCustomPert_ABL.H:75
const Real dx
Definition: ERF_InitCustomPert_ABL.H:44
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);})
constexpr amrex::Real three
Definition: ERF_NumericalConstants.H:32
constexpr amrex::Real one
Definition: ERF_NumericalConstants.H:30
constexpr amrex::Real zero
Definition: ERF_NumericalConstants.H:29
constexpr amrex::Real myhalf
Definition: ERF_NumericalConstants.H:34
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:32
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:80
@ th0_comp
Definition: ERF_IndexDefines.H:79
@ r0_comp
Definition: ERF_IndexDefines.H:76
@ cons
Definition: ERF_IndexDefines.H:232
@ theta
Definition: ERF_SLM.H:19
@ qv
Definition: ERF_Kessler.H:31
@ nr
Definition: ERF_Morrison.H:47
@ xvel
Definition: ERF_IndexDefines.H:215
@ cons
Definition: ERF_IndexDefines.H:214
@ zvel
Definition: ERF_IndexDefines.H:217
@ yvel
Definition: ERF_IndexDefines.H:216
@ dz
Definition: ERF_AdvanceWDM6.cpp:272
@ zi
Definition: ERF_AdvanceWDM6.cpp:276
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_wdm6.F90:75
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:1974
MoistureType moisture_type
Moisture or microphysics model.
Definition: ERF_DataStruct.H:2237
int ave_plane
Averaging plane index used by diagnostics.
Definition: ERF_DataStruct.H:2260
amrex::Real num_diff_coeff
Numerical diffusion coefficient after input scaling.
Definition: ERF_DataStruct.H:2234
bool do_theta_advection
Whether custom vertical subsidence is applied to rho-theta.
Definition: ERF_DataStruct.H:2078
bool spatial_moisture_forcing
Whether spatially varying moisture forcing is enabled.
Definition: ERF_DataStruct.H:2083
static MeshType mesh_type
Vertical mesh representation.
Definition: ERF_DataStruct.H:1958
SpongeChoice spongeChoice
Sponge-layer options.
Definition: ERF_DataStruct.H:1973
bool four_stream_radiation
Whether the four-stream radiation approximation is enabled.
Definition: ERF_DataStruct.H:2029
DampingChoice dampingChoice
Damping-related options.
Definition: ERF_DataStruct.H:1972
static TerrainType terrain_type
Terrain or immersed-boundary representation.
Definition: ERF_DataStruct.H:1949
static BuildingsType buildings_type
Building representation.
Definition: ERF_DataStruct.H:1952
bool custom_rhotheta_forcing
Whether custom rho-theta forcing is enabled.
Definition: ERF_DataStruct.H:2075
bool spatial_rhotheta_forcing
Whether spatially varying rho-theta forcing is enabled.
Definition: ERF_DataStruct.H:2082
bool use_source_perturbation(int lev) const
Query whether source-term turbulent perturbations are enabled on a level.
Definition: ERF_DataStruct.H:2158
bool custom_w_subsidence
Whether custom vertical subsidence is enabled.
Definition: ERF_DataStruct.H:2077
bool custom_moisture_forcing
Whether custom moisture forcing is enabled.
Definition: ERF_DataStruct.H:2076
RadiationType rad_type
Radiation model.
Definition: ERF_DataStruct.H:2241
bool immersed_forcing_substep
Whether immersed-forcing source terms are applied only during substeps.
Definition: ERF_DataStruct.H:2032
bool custom_forcing_prim_vars
Whether custom forcing operates on primitive variables.
Definition: ERF_DataStruct.H:2081
bool use_num_diff
Whether sixth-order numerical diffusion is enabled.
Definition: ERF_DataStruct.H:2233
static SpongeType sponge_type
Selected sponge damping model.
Definition: ERF_SpongeStruct.H:100
Definition: ERF_TurbStruct.H:115
bool diffuse_tke_3D
Whether three-dimensional numerical diffusion is applied to TKE/QKE.
Definition: ERF_TurbStruct.H:927
bool use_tke
Whether any TKE or QKE closure is active.
Definition: ERF_TurbStruct.H:841
amrex::Vector< amrex::MultiFab > pb_cell
Per-cell perturbation amplitude storage.
Definition: ERF_TurbPertStruct.H:763
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:409