7 Vector<MultiFab>& S_old,
8 Vector<MultiFab>& S_data,
9 const Real old_step_time,
10 const Real old_stage_time,
11 const Real new_stage_time,
14 BL_PROFILE(
"slow_rhs_fun_pre");
26 if (verbose) Print() << std::setprecision(timeprecision)
27 <<
"Making slow rhs at time " << old_stage_time
28 <<
" for fast variables advancing from " << old_step_time
29 <<
" to " << new_stage_time << std::endl;
31 Real slow_dt = new_stage_time - old_step_time;
33 const GpuArray<Real, AMREX_SPACEDIM> dxInv = fine_geom.InvCellSizeArray();
38 YAFluxRegister* fr_as_crse =
nullptr;
39 YAFluxRegister* fr_as_fine =
nullptr;
40 if (solverChoice.coupling_type == CouplingType::TwoWay && finest_level > 0) {
41 if (level < finest_level) {
42 fr_as_crse = getAdvFluxReg(level+1);
46 fr_as_fine = getAdvFluxReg(level);
55 MultiFab* forest_drag = (solverChoice.do_forest_drag) ?
56 m_forest_drag[level]->get_drag_field() :
nullptr;
59 MultiFab* terrain_blank = (solverChoice.terrain_type == TerrainType::ImmersedForcing ||
60 solverChoice.buildings_type == BuildingsType::ImmersedForcing) ?
61 terrain_blanking[level].get() :
nullptr;
65 if (solverChoice.moisture_type != MoistureType::None) {
69 MultiFab p0_to_use, base_to_use;
70 MultiFab *zpn_to_use, *zpc_to_use, *ax_to_use, *ay_to_use, *az_to_use, *dJ_to_use;
73 std::unique_ptr<MultiFab> z_t_pert;
74 if ( solverChoice.terrain_type == TerrainType::MovingFittedMesh )
81 zpn_to_use = z_phys_nd_src[level].get();
82 zpc_to_use = z_phys_cc_src[level].get();
83 ax_to_use = ax_src[level].get();
84 ay_to_use = ay_src[level].get();
85 az_to_use = az_src[level].get();
86 dJ_to_use = detJ_cc_src[level].get();
91 zpn_to_use = z_phys_nd[level].get();
92 zpc_to_use = z_phys_cc[level].get();
93 ax_to_use = ax[level].get();
94 ay_to_use = ay[level].get();
95 az_to_use = az[level].get();
96 dJ_to_use = detJ_cc[level].get();
103 S_data, S_prim, cc_src, base_state[level], zpc_to_use,
105 qheating_rates[level].get(),
106 terrain_blank, fine_geom, solverChoice,
108 dptr_rhotheta_src, dptr_rhoqt_src,
109 dptr_wbar_sub, d_rayleigh_ptrs_at_lev, d_sinesq_at_lev,
110 input_sounding_data, turbPert,
true);
116 p0_to_use, *zpn_to_use, *zpc_to_use,
118 get_eb(level), gradp[level]);
123 make_buoyancy(level, S_data, S_prim,
qt, buoyancy, fine_geom, solverChoice, base_to_use,
124 micro->Get_Qstate_Moist_Size(), get_eb(level), solverChoice.anelastic[level]);
130 S_data, zpn_to_use, zpc_to_use, stretched_dz_h[level],
131 xvel_new, yvel_new, zvel_new,
132 xmom_src, ymom_src, zmom_src,
133 base_to_use, forest_drag, terrain_blank,
134 cosPhi_m[level].get(), sinPhi_m[level].get(), fine_geom, solverChoice,
136 (solverChoice.have_geo_wind_profile) ? d_u_geos[level].data():
nullptr,
137 (solverChoice.have_geo_wind_profile) ? d_v_geos[level].data():
nullptr,
138 dptr_wbar_sub, d_rayleigh_ptrs_at_lev, d_sinesq_at_lev, d_sinesq_stag_at_lev,
139 d_sponge_ptrs_at_lev,
140 (solverChoice.hindcast_lateral_forcing? &forecast_state_interp[level] :
nullptr),
141 input_sounding_data,
true);
147 xflux_imask[level], yflux_imask[level], zflux_imask[level],
148 thin_xforce[level], thin_yforce[level], thin_zforce[level]);
154 S_prim,
qt, avg_xmom[level], avg_ymom[level], avg_zmom[level],
155 xvel_new, yvel_new, zvel_new,
156 z_t_rk[level], cc_src, xmom_src, ymom_src, zmom_src, buoyancy,
157 (level > 0) ? &zmom_crse_rhs[level] :
nullptr,
158 Tau[level], Tau_corr[level],
159 SmnSmn, eddyDiffs, Hfx1, Hfx2, Hfx3, Q1fx1, Q1fx2, Q1fx3, Q2fx3, Diss,
160 fine_geom, solverChoice, m_SurfaceLayer, domain_bcs_type_d, domain_bcs_type,
161 *zpn_to_use, *zpc_to_use, *ax_to_use, *ay_to_use, *az_to_use, *dJ_to_use,
162 stretched_dz_d[level], gradp[level],
163 mapfac[level], get_eb(level),
165 shoc_interface[level],
167 fr_as_crse, fr_as_fine);
169 if ((solverChoice.vert_implicit_fac[nrk] > 0.) && solverChoice.implicit_before_substep) {
173 MultiFab::Saxpy(scratch, slow_dt, S_rhs[
IntVars::cons], 0, 0, 2, 0);
174 scratch.FillBoundary(geom[level].periodicity());
182 #ifdef ERF_IMPLICIT_W
187 if (solverChoice.implicit_momentum_diffusion) {
189 MultiFab::Saxpy(scratch_xmom, slow_dt, S_rhs[
IntVars::xmom], 0, 0, 1, 0);
190 scratch_xmom.FillBoundary(geom[level].periodicity());
193 MultiFab::Saxpy(scratch_ymom, slow_dt, S_rhs[
IntVars::ymom], 0, 0, 1, 0);
194 scratch_ymom.FillBoundary(geom[level].periodicity());
195 #ifdef ERF_IMPLICIT_W
197 MultiFab::Saxpy(scratch_zmom, slow_dt, S_rhs[
IntVars::zmom], 0, 0, 1, 0);
198 scratch_zmom.FillBoundary(geom[level].periodicity());
204 MultiFab::Saxpy(scratch, -1.0, S_old[
IntVars::cons], 1, 1, 1, 0);
205 scratch.mult(1.0 / slow_dt);
208 if (solverChoice.implicit_momentum_diffusion) {
209 MultiFab::Saxpy(scratch_xmom, -1.0, S_old[
IntVars::xmom], 0, 0, 1, 0);
210 scratch_xmom.mult(1.0 / slow_dt);
211 MultiFab::Copy(S_rhs[
IntVars::xmom], scratch_xmom, 0, 0, 1, 0);
213 MultiFab::Saxpy(scratch_ymom, -1.0, S_old[
IntVars::ymom], 0, 0, 1, 0);
214 scratch_ymom.mult(1.0 / slow_dt);
215 MultiFab::Copy(S_rhs[
IntVars::ymom], scratch_ymom, 0, 0, 1, 0);
216 #ifdef ERF_IMPLICIT_W
217 MultiFab::Saxpy(scratch_zmom, -1.0, S_old[
IntVars::zmom], 0, 0, 1, 0);
218 scratch_zmom.mult(1.0 / slow_dt);
219 MultiFab::Copy(S_rhs[
IntVars::zmom], scratch_zmom, 0, 0, 1, 0);
225 if (solverChoice.use_shoc) {
226 shoc_interface[level]->add_fast_tend(S_rhs);
233 if ( solverChoice.terrain_type == TerrainType::MovingFittedMesh )
240 MultiFab* r0_new = &r_hse_new;
241 MultiFab* p0_new = &p_hse_new;
242 MultiFab* pi0_new = &pi_hse_new;
243 MultiFab* th0_new = &th_hse_new;
248 MultiFab rt0(
p0->boxArray(),
p0->DistributionMap(),1,1);
249 MultiFab rt0_new(
p0->boxArray(),
p0->DistributionMap(),1,1);
250 MultiFab r0_temp(
p0->boxArray(),
p0->DistributionMap(),1,1);
257 Real dt_base = (new_stage_time - old_step_time);
259 const Real l_rdOcp = solverChoice.rdOcp;
262 #pragma omp parallel if (amrex::Gpu::notInLaunchRegion())
264 for ( MFIter mfi(*
p0,TilingIfNotGPU()); mfi.isValid(); ++mfi)
266 const Array4<Real > rt0_arr = rt0.array(mfi);
267 const Array4<Real > rt0_tmp_arr = rt0_new.array(mfi);
269 const Array4<Real const> r0_arr = r0->const_array(mfi);
270 const Array4<Real > r0_new_arr = r0_new->array(mfi);
271 const Array4<Real > r0_tmp_arr = r0_temp.array(mfi);
273 const Array4<Real const> p0_arr =
p0->const_array(mfi);
274 const Array4<Real > p0_new_arr = p0_new->array(mfi);
275 const Array4<Real > pi0_new_arr = pi0_new->array(mfi);
276 const Array4<Real > th0_new_arr = th0_new->array(mfi);
278 const Array4<Real >& z_t_arr = z_t_rk[level]->array(mfi);
280 const Array4<Real const>& dJ_old_arr = detJ_cc[level]->const_array(mfi);
281 const Array4<Real const>& dJ_new_arr = detJ_cc_new[level]->const_array(mfi);
282 const Array4<Real const>& dJ_src_arr = detJ_cc_src[level]->const_array(mfi);
284 Box gbx = mfi.growntilebox({1,1,1});
285 amrex::ParallelFor(gbx, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k) noexcept
289 r0_tmp_arr(i,j,k) = r0_new_arr(i,j,k);
292 Box gbx2 = mfi.growntilebox({1,1,0});
293 amrex::ParallelFor(gbx2, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k) noexcept
295 Real zflux_r_lo = -z_t_arr(i,j,k ) * 0.5 * (r0_tmp_arr(i,j,k) + r0_tmp_arr(i,j,k-1));
296 Real zflux_r_hi = -z_t_arr(i,j,k+1) * 0.5 * (r0_tmp_arr(i,j,k) + r0_tmp_arr(i,j,k+1));
298 Real zflux_rt_lo = zflux_r_lo * 0.5 * (rt0_tmp_arr(i,j,k)/r0_tmp_arr(i,j,k) + rt0_tmp_arr(i,j,k-1)/r0_tmp_arr(i,j,k-1));
299 Real zflux_rt_hi = zflux_r_hi * 0.5 * (rt0_tmp_arr(i,j,k)/r0_tmp_arr(i,j,k) + rt0_tmp_arr(i,j,k+1)/r0_tmp_arr(i,j,k+1));
301 Real invdetJ = 1.0 / dJ_src_arr(i,j,k);
303 Real src_r = - invdetJ * ( zflux_r_hi - zflux_r_lo ) * dxInv[2];
304 Real src_rt = - invdetJ * ( zflux_rt_hi - zflux_rt_lo ) * dxInv[2];
306 Real rho0_new = dJ_old_arr(i,j,k) * r0_arr(i,j,k) + dt_base * dJ_src_arr(i,j,k) * src_r;
307 Real rt0_tmp_new = dJ_old_arr(i,j,k) * rt0_arr(i,j,k) + dt_base * dJ_src_arr(i,j,k) * src_rt;
309 r0_new_arr(i,j,k) = rho0_new / dJ_new_arr(i,j,k);
310 rt0_tmp_new /= dJ_new_arr(i,j,k);
314 th0_new_arr(i,j,k) = rt0_tmp_new / r0_new_arr(i,j,k);
317 r0_new->FillBoundary(fine_geom.periodicity());
318 p0_new->FillBoundary(fine_geom.periodicity());
319 th0_new->FillBoundary(fine_geom.periodicity());
322 #ifdef ERF_USE_NETCDF
324 if (solverChoice.use_real_bcs && (level == 0)) {
327 new_stage_time, slow_dt, stop_time-start_time,
328 real_width, real_set_width, fine_geom,
329 S_rhs, S_old, S_data,
330 bdy_data_xlo, bdy_data_xhi,
331 bdy_data_ylo, bdy_data_yhi);
void add_thin_body_sources(MultiFab &xmom_src, MultiFab &ymom_src, MultiFab &zmom_src, std::unique_ptr< iMultiFab > &xflux_imask_lev, std::unique_ptr< iMultiFab > &yflux_imask_lev, std::unique_ptr< iMultiFab > &zflux_imask_lev, std::unique_ptr< MultiFab > &thin_xforce_lev, std::unique_ptr< MultiFab > &thin_yforce_lev, std::unique_ptr< MultiFab > &thin_zforce_lev)
Definition: ERF_AddThinBodySources.cpp:27
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real getPgivenRTh(const amrex::Real rhotheta, const amrex::Real qv=0.)
Definition: ERF_EOS.H:81
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
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real getRhoThetagivenP(const amrex::Real p, const amrex::Real qv=0.0)
Definition: ERF_EOS.H:172
void realbdy_compute_interior_ghost_rhs(const Real &bdy_time_interval, const Real &time, const Real &delta_t, const Real &stop_time_elapsed, int width, int set_width, const Geometry &geom, Vector< MultiFab > &S_rhs, Vector< MultiFab > &S_old_data, Vector< MultiFab > &S_cur_data, Vector< Vector< FArrayBox >> &bdy_data_xlo, Vector< Vector< FArrayBox >> &bdy_data_xhi, Vector< Vector< FArrayBox >> &bdy_data_ylo, Vector< Vector< FArrayBox >> &bdy_data_yhi)
Definition: ERF_InteriorGhostCells.cpp:174
void make_buoyancy(int lev, const Vector< MultiFab > &S_data, const MultiFab &S_prim, const MultiFab &qt, MultiFab &buoyancy, const Geometry geom, const SolverChoice &solverChoice, const MultiFab &base_state, const int n_qstate, const eb_ &ebfact, const int anelastic)
Definition: ERF_MakeBuoyancy.cpp:32
void make_gradp_pert(int level, const SolverChoice &solverChoice, const Geometry &geom, Vector< MultiFab > &S_data, const MultiFab &p0, const MultiFab &z_phys_nd, const MultiFab &z_phys_cc, Vector< std::unique_ptr< MultiFab >> &mapfac, const eb_ &ebfact, Vector< MultiFab > &gradp)
Definition: ERF_MakeGradP.cpp:28
void make_mom_sources(Real time, Real, const Vector< MultiFab > &S_data, const MultiFab *z_phys_nd, const MultiFab *z_phys_cc, Vector< Real > &stretched_dz_h, const MultiFab &xvel, const MultiFab &yvel, const MultiFab &wvel, MultiFab &xmom_src, MultiFab &ymom_src, MultiFab &zmom_src, const MultiFab &base_state, MultiFab *forest_drag, MultiFab *terrain_blank, MultiFab *cosPhi_mf, MultiFab *sinPhi_mf, const Geometry geom, const SolverChoice &solverChoice, Vector< std::unique_ptr< MultiFab >> &, const Real *dptr_u_geos, const Real *dptr_v_geos, const Real *dptr_wbar_sub, const Vector< Real * > d_rayleigh_ptrs_at_lev, const amrex::Real *d_sinesq_at_lev, const amrex::Real *d_sinesq_stag_at_lev, const Vector< Real * > d_sponge_ptrs_at_lev, const Vector< MultiFab > *forecast_state_at_lev, InputSoundingData &input_sounding_data, bool is_slow_step)
Definition: ERF_MakeMomSources.cpp:37
void make_sources(int level, int, Real dt, Real time, const Vector< MultiFab > &S_data, const MultiFab &S_prim, MultiFab &source, const MultiFab &base_state, const MultiFab *z_phys_cc, const MultiFab &xvel, const MultiFab &yvel, const MultiFab *qheating_rates, MultiFab *terrain_blank, const Geometry geom, const SolverChoice &solverChoice, Vector< std::unique_ptr< MultiFab >> &mapfac, const Real *dptr_rhotheta_src, const Real *dptr_rhoqt_src, const Real *dptr_wbar_sub, const Vector< Real * > d_rayleigh_ptrs_at_lev, const Real *d_sinesq_at_lev, InputSoundingData &input_sounding_data, TurbulentPerturbation &turbPert, bool is_slow_step)
Definition: ERF_MakeSources.cpp:33
amrex::Real Real
Definition: ERF_ShocInterface.H:19
void erf_slow_rhs_pre(int level, int finest_level, int nrk, Real dt, Vector< MultiFab > &S_rhs, Vector< MultiFab > &S_old, Vector< MultiFab > &S_data, const MultiFab &S_prim, const MultiFab &qt, MultiFab &avg_xmom, MultiFab &avg_ymom, MultiFab &avg_zmom, const MultiFab &xvel, const MultiFab &yvel, const MultiFab &zvel, std::unique_ptr< MultiFab > &z_t_mf, const MultiFab &cc_src, const MultiFab &xmom_src, const MultiFab &ymom_src, const MultiFab &zmom_src, const MultiFab &buoyancy, const MultiFab *zmom_crse_rhs, Vector< std::unique_ptr< MultiFab >> &Tau_lev, Vector< std::unique_ptr< MultiFab >> &Tau_corr_lev, MultiFab *SmnSmn, MultiFab *eddyDiffs, MultiFab *Hfx1, MultiFab *Hfx2, MultiFab *Hfx3, MultiFab *Q1fx1, MultiFab *Q1fx2, MultiFab *Q1fx3, MultiFab *Q2fx3, MultiFab *Diss, const Geometry geom, const SolverChoice &solverChoice, std::unique_ptr< SurfaceLayer > &SurfLayer, const Gpu::DeviceVector< BCRec > &domain_bcs_type_d, const Vector< BCRec > &domain_bcs_type_h, const MultiFab &z_phys_nd, const MultiFab &z_phys_cc, const MultiFab &ax, const MultiFab &ay, const MultiFab &az, const MultiFab &detJ, Gpu::DeviceVector< Real > &stretched_dz_d, Vector< MultiFab > &gradp, Vector< std::unique_ptr< MultiFab >> &mapfac, const eb_ &ebfact, YAFluxRegister *fr_as_crse, YAFluxRegister *fr_as_fine)
Definition: ERF_SlowRhsPre.cpp:65
auto slow_rhs_fun_pre
Definition: ERF_TI_slow_rhs_pre.H:6
auto cons_to_prim
Definition: ERF_TI_utils.H:4
auto make_qt
Definition: ERF_TI_utils.H:52
auto update_terrain_stage
Definition: ERF_TI_utils.H:164
@ num_comps
Definition: ERF_IndexDefines.H:68
@ pi0_comp
Definition: ERF_IndexDefines.H:65
@ p0_comp
Definition: ERF_IndexDefines.H:64
@ th0_comp
Definition: ERF_IndexDefines.H:66
@ r0_comp
Definition: ERF_IndexDefines.H:63
@ ymom
Definition: ERF_IndexDefines.H:160
@ cons
Definition: ERF_IndexDefines.H:158
@ zmom
Definition: ERF_IndexDefines.H:161
@ xmom
Definition: ERF_IndexDefines.H:159
@ qt
Definition: ERF_Kessler.H:27
real(c_double), parameter p0
Definition: ERF_module_model_constants.F90:40