Function for computing the slow RHS for the evolution equations for the density, potential temperature and momentum.
62 BL_PROFILE_REGION(
"erf_make_sources()");
64 Real time =
static_cast<Real>(time_d);
78 const bool l_use_KE = tc.
use_tke;
81 const Box& domain = geom.Domain();
83 const GpuArray<Real, AMREX_SPACEDIM>
dxInv = geom.InvCellSizeArray();
84 const GpuArray<Real, AMREX_SPACEDIM>
dx = geom.CellSizeArray();
98 bool has_moisture = (solverChoice.
moisture_type != MoistureType::None);
103 Table1D<Real> dptr_r_plane, dptr_t_plane, dptr_qv_plane, dptr_qc_plane;
104 Table1D<Real> dptr_r_plane_if, dptr_t_plane_if;
105 TableData<Real, 1> r_plane_tab, t_plane_tab, qv_plane_tab, qc_plane_tab;
107 bool use_immersed_forcing = (solverChoice.
terrain_type == TerrainType::ImmersedForcing ||
112 if (use_immersed_forcing && r_plane_avg && t_plane_avg) {
114 dptr_r_plane_if = r_plane_avg;
115 dptr_t_plane_if = t_plane_avg;
119 bool compute_averages = (is_slow_step && dptr_wbar_sub);
121 if (compute_averages)
133 IntVect ng_c(S_data[
IntVars::cons].nGrowVect()); ng_c[2] = 1;
138 int ncomp = (!has_moisture) ? 2 :
RhoQ2_comp+1;
142 cons_ave.compute_averages(
ZDir(), cons_ave.field());
144 int ncell = cons_ave.ncell_line();
146 Gpu::HostVector< Real> r_plane_h(ncell);
147 Gpu::DeviceVector< Real> r_plane_d(ncell);
149 Gpu::HostVector< Real> t_plane_h(ncell);
150 Gpu::DeviceVector< Real> t_plane_d(ncell);
152 cons_ave.line_average(
Rho_comp , r_plane_h);
155 Gpu::copyAsync(Gpu::hostToDevice, r_plane_h.begin(), r_plane_h.end(), r_plane_d.begin());
156 Gpu::copyAsync(Gpu::hostToDevice, t_plane_h.begin(), t_plane_h.end(), t_plane_d.begin());
158 Real* dptr_r = r_plane_d.data();
159 Real* dptr_t = t_plane_d.data();
161 Box tdomain = domain; tdomain.grow(2,ng_c[2]);
162 r_plane_tab.resize({tdomain.smallEnd(2)}, {tdomain.bigEnd(2)});
163 t_plane_tab.resize({tdomain.smallEnd(2)}, {tdomain.bigEnd(2)});
167 dptr_r_plane = r_plane_tab.table();
168 dptr_t_plane = t_plane_tab.table();
169 ParallelFor(ncell, [=] AMREX_GPU_DEVICE (
int k) noexcept
171 dptr_r_plane(k-
offset) = dptr_r[k];
172 dptr_t_plane(k-
offset) = dptr_t[k];
177 Gpu::HostVector< Real> qv_plane_h(ncell), qc_plane_h(ncell);
178 Gpu::DeviceVector<Real> qv_plane_d(ncell), qc_plane_d(ncell);
181 cons_ave.line_average(
RhoQ1_comp, qv_plane_h);
182 Gpu::copyAsync(Gpu::hostToDevice, qv_plane_h.begin(), qv_plane_h.end(), qv_plane_d.begin());
185 cons_ave.line_average(
RhoQ2_comp, qc_plane_h);
186 Gpu::copyAsync(Gpu::hostToDevice, qc_plane_h.begin(), qc_plane_h.end(), qc_plane_d.begin());
188 Real* dptr_qv = qv_plane_d.data();
189 Real* dptr_qc = qc_plane_d.data();
191 qv_plane_tab.resize({tdomain.smallEnd(2)}, {tdomain.bigEnd(2)});
192 qc_plane_tab.resize({tdomain.smallEnd(2)}, {tdomain.bigEnd(2)});
194 dptr_qv_plane = qv_plane_tab.table();
195 dptr_qc_plane = qc_plane_tab.table();
196 ParallelFor(ncell, [=] AMREX_GPU_DEVICE (
int k) noexcept
198 dptr_qv_plane(k-
offset) = dptr_qv[k];
199 dptr_qc_plane(k-
offset) = dptr_qc[k];
214 int klo = domain.smallEnd(2);
215 int khi = domain.bigEnd(2);
237 #pragma omp parallel if (Gpu::notInLaunchRegion())
242 Box bx = mfi.tilebox();
244 const Array4<const Real>& cell_data = S_data[
IntVars::cons].array(mfi);
245 const Array4<const Real>& cell_prim = S_prim.array(mfi);
246 const Array4<Real> & cell_src = source.array(mfi);
248 const Array4<const Real>&
r0 = r_hse.const_array(mfi);
249 const Array4<const Real>& th0 = th_hse.const_array(mfi);
250 const Array4<const Real>& qv0 = qv_hse.const_array(mfi);
252 const Array4<const Real>& z_cc_arr = z_phys_cc->const_array(mfi);
254 const Array4<const Real>& t_blank_arr = (terrain_blank) ? terrain_blank->const_array(mfi) :
255 Array4<const Real>{};
261 if (solverChoice.
rad_type != RadiationType::None && is_slow_step) {
262 auto const& qheating_arr = qheating_rates->const_array(mfi);
263 ParallelFor(bx, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k) noexcept
266 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) );
277 if ((is_slow_step && !use_Rayleigh_fast) || (!is_slow_step && use_Rayleigh_fast)) {
282 ParallelFor(bx, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k) noexcept
285 Real sinesq = d_sinesq_at_lev[k];
286 cell_src(i, j, k, n) -= dampcoef*sinesq * (
theta -
thetabar[k]) * cell_data(i,j,k,
nr);
296 auto const& rhotheta_src_arr = rhotheta_src->const_array(mfi);
301 ParallelFor(bx, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k) noexcept
303 cell_src(i, j, k, n) += cell_data(i,j,k,
nr) * rhotheta_src_arr(i, j, k);
306 ParallelFor(bx, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k) noexcept
308 cell_src(i, j, k, n) += rhotheta_src_arr(i, j, k);
314 ParallelFor(bx, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k) noexcept
316 cell_src(i, j, k, n) += cell_data(i,j,k,
nr) * rhotheta_src_arr(0, 0, k);
319 ParallelFor(bx, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k) noexcept
321 cell_src(i, j, k, n) += rhotheta_src_arr(0, 0, k);
332 auto const& rhoqt_src_arr = rhoqt_src->const_array(mfi);
337 ParallelFor(bx, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k) noexcept
339 cell_src(i, j, k, n) += cell_data(i,j,k,
nr) * rhoqt_src_arr(i, j, k);
342 ParallelFor(bx, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k) noexcept
344 cell_src(i, j, k, n) += rhoqt_src_arr(i, j, k);
350 ParallelFor(bx, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k) noexcept
352 cell_src(i, j, k, n) += cell_data(i,j,k,
nr) * rhoqt_src_arr(0, 0, k);
355 ParallelFor(bx, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k) noexcept
357 cell_src(i, j, k, n) += rhoqt_src_arr(0, 0, k);
370 ParallelFor(bx, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k) noexcept
372 Real dzInv = (z_cc_arr) ?
one/ (z_cc_arr(i,j,k+1) - z_cc_arr(i,j,k-1)) :
myhalf*
dxInv[2];
373 Real T_hi = dptr_t_plane(k+1) / dptr_r_plane(k+1);
374 Real T_lo = dptr_t_plane(k-1) / dptr_r_plane(k-1);
375 Real wbar_cc =
myhalf * (dptr_wbar_sub[k] + dptr_wbar_sub[k+1]);
376 cell_src(i, j, k, n) -= cell_data(i,j,k,
nr) * 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 T_hi = dptr_t_plane(k+1) / dptr_r_plane(k+1);
383 Real T_lo = dptr_t_plane(k-1) / dptr_r_plane(k-1);
384 Real wbar_cc =
myhalf * (dptr_wbar_sub[k] + dptr_wbar_sub[k+1]);
385 cell_src(i, j, k, n) -= wbar_cc * (T_hi - T_lo) * dzInv;
397 ParallelFor(bx, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k) noexcept
399 Real dzInv = (z_cc_arr) ?
one/ (z_cc_arr(i,j,k+1) - z_cc_arr(i,j,k-1)) :
myhalf*
dxInv[2];
400 Real Qv_hi = dptr_qv_plane(k+1) / dptr_r_plane(k+1);
401 Real Qv_lo = dptr_qv_plane(k-1) / dptr_r_plane(k-1);
402 Real Qc_hi = dptr_qc_plane(k+1) / dptr_r_plane(k+1);
403 Real Qc_lo = dptr_qc_plane(k-1) / dptr_r_plane(k-1);
404 Real wbar_cc =
myhalf * (dptr_wbar_sub[k] + dptr_wbar_sub[k+1]);
405 cell_src(i, j, k, nv ) -= cell_data(i,j,k,
nr) * wbar_cc * (Qv_hi - Qv_lo) * dzInv;
406 cell_src(i, j, k, nv+1) -= cell_data(i,j,k,
nr) * wbar_cc * (Qc_hi - Qc_lo) * dzInv;
409 ParallelFor(bx, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k) noexcept
411 Real dzInv = (z_cc_arr) ?
one/ (z_cc_arr(i,j,k+1) - z_cc_arr(i,j,k-1)) :
myhalf*
dxInv[2];
412 Real Qv_hi = dptr_qv_plane(k+1) / dptr_r_plane(k+1);
413 Real Qv_lo = dptr_qv_plane(k-1) / dptr_r_plane(k-1);
414 Real Qc_hi = dptr_qc_plane(k+1) / dptr_r_plane(k+1);
415 Real Qc_lo = dptr_qc_plane(k-1) / dptr_r_plane(k-1);
416 Real wbar_cc =
myhalf * (dptr_wbar_sub[k] + dptr_wbar_sub[k+1]);
417 cell_src(i, j, k, nv ) -= wbar_cc * (Qv_hi - Qv_lo) * dzInv;
418 cell_src(i, j, k, nv+1) -= wbar_cc * (Qc_hi - Qc_lo) * dzInv;
426 if (l_use_ndiff && is_slow_step)
428 const Array4<const Real>& mf_mx = mapfac[
MapFacType::m_x]->const_array(mfi);
429 const Array4<const Real>& mf_my = mapfac[
MapFacType::m_y]->const_array(mfi);
433 cell_data, cell_data, cell_src, mf_mx, mf_my);
437 cell_prim, cell_data, cell_src, mf_mx, mf_my);
440 if (l_use_KE && l_diff_KE) {
442 cell_prim, cell_data, cell_src, mf_mx, mf_my);
446 cell_prim, cell_data, cell_src, mf_mx, mf_my);
462 const amrex::Array4<const amrex::Real>& pert_cell = turbPert.
pb_cell[level].const_array(mfi);
469 if (solverChoice.
terrain_type == TerrainType::ImmersedForcing &&
470 ((is_slow_step && !use_ImmersedForcing_fast) || (!is_slow_step && use_ImmersedForcing_fast))) {
472 const Array4<const Real>& u =
xvel.array(mfi);
473 const Array4<const Real>& v =
yvel.array(mfi);
477 cell_src, geom, solverChoice, dptr_r_plane_if, dptr_t_plane_if, time);
484 const Real* dx_arr = geom.CellSize();
485 const Real delta_xy = std::sqrt(dx_arr[0] * dx_arr[1]);
487 if ((solverChoice.
buildings_type == BuildingsType::ImmersedForcing) &&
488 ((is_slow_step && !use_ImmersedForcing_fast) || (!is_slow_step && use_ImmersedForcing_fast)) &&
489 (delta_xy <= 50.0)) {
491 const Array4<const Real>& u =
xvel.array(mfi);
492 const Array4<const Real>& v =
yvel.array(mfi);
493 const Array4<const Real>&
w =
zvel.array(mfi);
497 cell_src, geom, solverChoice, dptr_r_plane_if, dptr_t_plane_if, time);
512 Box xybx = makeSlab(bx,2,klo);
514 AMREX_GPU_DEVICE(
int i,
int j,
int ) noexcept
524 for (
int k(klo+1); k<=
khi+1; ++k) {
526 Real dz = (z_cc_arr) ?
myhalf * (z_cc_arr(i,j,k) - z_cc_arr(i,j,k-2)) :
dx[2];
530 if ( (qt_lo > qt_i) && (qt_hi < qt_i) ) {
531 zi =
myhalf * (z_cc_arr(i,j,k) + z_cc_arr(i,j,k-1));
541 Real z_lo =
myhalf * (z_cc_arr(i,j,klo) + z_cc_arr(i,j,klo-1));
542 Real flux_lo = F1*std::exp(-q_int) + F0*std::exp(-(q_int_inf - q_int));
547 for (
int k(klo); k<=
khi; ++k) {
549 Real dz = (z_cc_arr) ?
myhalf * (z_cc_arr(i,j,k+1) - z_cc_arr(i,j,k-1)) :
dx[2];
552 Real z_hi =
myhalf * (z_cc_arr(i,j,k+1) + z_cc_arr(i,j,k));
553 Real flux_hi = F1*std::exp(-q_int) + F0*std::exp(-(q_int_inf - q_int));
559 Real dzInv = (z_cc_arr) ?
one/ (
myhalf * (z_cc_arr(i,j,k+1) - z_cc_arr(i,j,k-1))) :
dxInv[2];
562 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 three
Definition: ERF_Constants.H:11
constexpr amrex::Real Cp_d
Definition: ERF_Constants.H:49
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 RdoCp
Definition: ERF_Constants.H:54
@ thetabar
Definition: ERF_DataStruct.H:153
@ m_y
Definition: ERF_DataStruct.H:29
@ m_x
Definition: ERF_DataStruct.H:28
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:840
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:972
#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 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);})
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: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:20
@ qv
Definition: ERF_Kessler.H:30
@ nr
Definition: ERF_Morrison.H:46
@ 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:270
@ zi
Definition: ERF_AdvanceWDM6.cpp:274
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:1864
MoistureType moisture_type
Moisture or microphysics model.
Definition: ERF_DataStruct.H:2124
int ave_plane
Averaging plane index used by diagnostics.
Definition: ERF_DataStruct.H:2141
amrex::Real num_diff_coeff
Numerical diffusion coefficient after input scaling.
Definition: ERF_DataStruct.H:2121
bool do_theta_advection
Whether custom vertical subsidence is applied to rho-theta.
Definition: ERF_DataStruct.H:1964
bool spatial_moisture_forcing
Whether spatially varying moisture forcing is enabled.
Definition: ERF_DataStruct.H:1969
static MeshType mesh_type
Vertical mesh representation.
Definition: ERF_DataStruct.H:1848
SpongeChoice spongeChoice
Sponge-layer options.
Definition: ERF_DataStruct.H:1863
bool four_stream_radiation
Whether the four-stream radiation approximation is enabled.
Definition: ERF_DataStruct.H:1916
DampingChoice dampingChoice
Damping-related options.
Definition: ERF_DataStruct.H:1862
static TerrainType terrain_type
Terrain or immersed-boundary representation.
Definition: ERF_DataStruct.H:1839
static BuildingsType buildings_type
Building representation.
Definition: ERF_DataStruct.H:1842
bool custom_rhotheta_forcing
Whether custom rho-theta forcing is enabled.
Definition: ERF_DataStruct.H:1961
bool spatial_rhotheta_forcing
Whether spatially varying rho-theta forcing is enabled.
Definition: ERF_DataStruct.H:1968
bool use_source_perturbation(int lev) const
Query whether source-term turbulent perturbations are enabled on a level.
Definition: ERF_DataStruct.H:2044
bool custom_w_subsidence
Whether custom vertical subsidence is enabled.
Definition: ERF_DataStruct.H:1963
bool custom_moisture_forcing
Whether custom moisture forcing is enabled.
Definition: ERF_DataStruct.H:1962
RadiationType rad_type
Radiation model.
Definition: ERF_DataStruct.H:2128
bool immersed_forcing_substep
Whether immersed-forcing source terms are applied only during substeps.
Definition: ERF_DataStruct.H:1919
bool custom_forcing_prim_vars
Whether custom forcing operates on primitive variables.
Definition: ERF_DataStruct.H:1967
bool use_num_diff
Whether sixth-order numerical diffusion is enabled.
Definition: ERF_DataStruct.H:2120
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:736
bool use_tke
Whether any TKE or QKE closure is active.
Definition: ERF_TurbStruct.H:671
amrex::Vector< amrex::MultiFab > pb_cell
Per-cell perturbation amplitude storage.
Definition: ERF_TurbPertStruct.H:762
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:408