18 auto domain =
m_geom.Domain();
19 int i_lo = domain.smallEnd(0);
20 int i_hi = domain.bigEnd(0);
21 int j_lo = domain.smallEnd(1);
22 int j_hi = domain.bigEnd(1);
23 int k_lo = domain.smallEnd(2);
24 int k_hi = domain.bigEnd(2);
28 auto ba =
tabs->boxArray();
29 auto dm =
tabs->DistributionMap();
30 fz.define(convert(ba, IntVect(0,0,1)), dm, 1, 0);
35 for ( MFIter mfi(*
tabs,TilingIfNotGPU()); mfi.isValid(); ++mfi) {
45 auto tbx = mfi.tilebox();
46 if (tbx.smallEnd(0) == i_lo) { tbx.growLo(0,-
m_real_width); }
47 if (tbx.bigEnd(0) == i_hi) { tbx.growHi(0,-
m_real_width); }
48 if (tbx.smallEnd(1) == j_lo) { tbx.growLo(1,-
m_real_width); }
49 if (tbx.bigEnd(1) == j_hi) { tbx.growHi(1,-
m_real_width); }
53 ParallelFor(tbx, [=] AMREX_GPU_DEVICE(
int i,
int j,
int k) noexcept
55 qv_array(i,j,k) = std::max(
Real(0), qv_array(i,j,k));
56 qc_array(i,j,k) = std::max(
Real(0), qc_array(i,j,k));
57 qp_array(i,j,k) = std::max(
Real(0), qp_array(i,j,k));
59 Real qsat_local, dtqsat_local;
60 Real pressure = pres_array(i,j,k);
61 erf_qsatw(tabs_array(i,j,k), pressure, qsat_local);
62 erf_dtqsatw(tabs_array(i,j,k), pressure, dtqsat_local);
64 if (qsat_local <=
Real(0)) {
65 amrex::Warning(
"qsat computed as non-positive; setting to Real(0)!");
70 qv_array(i,j,k), qc_array(i,j,k), qp_array(i,j,k), rho_array(i,j,k),
71 pressure, qsat_local, dtqsat_local, dtn, do_cond);
82 Real theta_over_T = theta_array(i,j,k)/tabs_array(i,j,k);
83 theta_array(i,j,k) += theta_over_T * d_fac_cond
88 qv_array(i,j,k) = std::max(
Real(0), qv_array(i,j,k));
89 qc_array(i,j,k) = std::max(
Real(0), qc_array(i,j,k));
90 qp_array(i,j,k) = std::max(
Real(0), qp_array(i,j,k));
92 qt_array(i,j,k) = qv_array(i,j,k) + qc_array(i,j,k);
96 for ( MFIter mfi(fz, TilingIfNotGPU()); mfi.isValid(); ++mfi ){
100 auto fz_array = fz.array(mfi);
101 const Box& tbz = mfi.tilebox();
103 ParallelFor(tbz, [=] AMREX_GPU_DEVICE(
int i,
int j,
int k) noexcept
105 const Real rho_km1 = (k == k_lo) ? rho_array(i,j,k) : rho_array(i,j,k-1);
106 const Real rho_k = (k == k_hi+1) ? rho_array(i,j,k-1) : rho_array(i,j,k);
107 const Real qp_km1 = (k == k_lo) ? qp_array(i,j,k) : qp_array(i,j,k-1);
108 const Real qp_k = (k == k_hi+1) ? qp_array(i,j,k-1) : qp_array(i,j,k);
117 auto const& ma_fz_arr = fz.const_arrays();
118 GpuTuple<Real> max = ParReduce(TypeList<ReduceOpMax>{},
121 [=] AMREX_GPU_DEVICE (
int box_no,
int i,
int j,
int k) noexcept
124 return { ma_fz_arr[box_no](i,j,k) };
127 AMREX_ALWAYS_ASSERT_WITH_MESSAGE(n_substep >= 1,
128 "Kessler: Number of precipitation substeps must be greater than 0!");
129 coef /=
Real(n_substep);
130 dtn /=
Real(n_substep);
132 for (
int nsub(0); nsub<n_substep; ++nsub) {
133 for ( MFIter mfi(*
tabs, TilingIfNotGPU()); mfi.isValid(); ++mfi ){
137 auto fz_array = fz.array(mfi);
139 const auto dJ_array = (
m_detJ_cc) ?
m_detJ_cc->const_array(mfi) : Array4<const Real>{};
141 const Box& tbx = mfi.tilebox();
142 const Box& tbz = mfi.tilebox(IntVect(0,0,1),IntVect(0));
144 ParallelFor(tbz, [=] AMREX_GPU_DEVICE(
int i,
int j,
int k) noexcept
146 const Real rho_km1 = (k == k_lo) ? rho_array(i,j,k) : rho_array(i,j,k-1);
147 const Real rho_k = (k == k_hi+1) ? rho_array(i,j,k-1) : rho_array(i,j,k);
148 const Real qp_km1 = (k == k_lo) ? qp_array(i,j,k) : qp_array(i,j,k-1);
149 const Real qp_k = (k == k_hi+1) ? qp_array(i,j,k-1) : qp_array(i,j,k);
157 rain_accum_array(i,j,k) = rain_accum_array(i,j,k)
158 + face_state.
rho * face_state.
qp * terminal_velocity * dtn /
Real(1000.0) *
Real(1000.0);
162 ParallelFor(tbx, [=] AMREX_GPU_DEVICE(
int i,
int j,
int k) noexcept
164 Real dJinv = (dJ_array) ?
Real(1)/dJ_array(i,j,k) :
Real(1);
167 fz_array(i,j,k+1) =
Real(0);
170 fz_array(i,j,k ) =
Real(0);
173 fz_array(i,j,k+1), fz_array(i,j,k), rho_array(i,j,k), dJinv, coef);
178 qp_array(i,j,k) += dq_sed;
179 qp_array(i,j,k) = std::max(
Real(0), qp_array(i,j,k));
185 if (solverChoice.
moisture_type == MoistureType::Kessler_NoRain) {
186 if (!do_cond) {
return; }
187 for ( MFIter mfi(*
tabs,TilingIfNotGPU()); mfi.isValid(); ++mfi) {
195 auto tbx = mfi.tilebox();
196 if (tbx.smallEnd(0) == i_lo) { tbx.growLo(0,-
m_real_width); }
197 if (tbx.bigEnd(0) == i_hi) { tbx.growHi(0,-
m_real_width); }
198 if (tbx.smallEnd(1) == j_lo) { tbx.growLo(1,-
m_real_width); }
199 if (tbx.bigEnd(1) == j_hi) { tbx.growHi(1,-
m_real_width); }
203 ParallelFor(tbx, [=] AMREX_GPU_DEVICE(
int i,
int j,
int k) noexcept
205 qc_array(i,j,k) = std::max(
Real(0), qc_array(i,j,k));
209 Real pressure = pres_array(i,j,k);
210 erf_qsatw(tabs_array(i,j,k), pressure, qsat);
221 Real theta_over_T = theta_array(i,j,k)/tabs_array(i,j,k);
222 theta_array(i,j,k) += theta_over_T * d_fac_cond
225 qv_array(i,j,k) = std::max(
Real(0), qv_array(i,j,k));
226 qc_array(i,j,k) = std::max(
Real(0), qc_array(i,j,k));
228 qt_array(i,j,k) = qv_array(i,j,k) + qc_array(i,j,k);
ParallelFor(bx, [=] AMREX_GPU_DEVICE(int i, int j, int k) noexcept { const Real *dx=geomdata.CellSize();const Real x=(i+myhalf) *dx[0];const Real y=(j+myhalf) *dx[1];const Real Omg=erf_vortex_Gaussian(x, y, xc, yc, R, beta, sigma);const Real deltaT=-(gamma - one)/(two *sigma *sigma) *Omg *Omg;const Real rho_norm=std::pow(one+deltaT, inv_gm1);const Real T=(one+deltaT) *T_inf;const Real p=std::pow(rho_norm, Gamma)/Gamma *rho_0 *a_inf *a_inf;const Real rho_theta=rho_0 *rho_norm *(T *std::pow(p_0/p, rdOcp));state_pert(i, j, k, RhoTheta_comp)=rho_theta - getRhoThetagivenP(p_hse(i, j, k));const Real r2d_xy=std::sqrt((x-xc) *(x-xc)+(y-yc) *(y-yc));state_pert(i, j, k, RhoScalar_comp)=fourth *(one+std::cos(PI *std::min(r2d_xy, R)/R));})
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE KesslerSaturationAdjustment kessler_saturation_adjustment(const amrex::Real qv, const amrex::Real qc, const amrex::Real qsat, const amrex::Real dtqsat, const bool do_cond) noexcept
Definition: ERF_KesslerUtils.H:67
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE int kessler_num_sedimentation_substeps(const amrex::Real current_reduced_value, const amrex::Real dt, const amrex::Real dzmin) noexcept
Definition: ERF_KesslerUtils.H:50
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE KesslerSourceTerms kessler_warm_rain_sources(const amrex::Real qv, const amrex::Real qc, const amrex::Real qp, const amrex::Real rho, const amrex::Real pressure_current_units, const amrex::Real qsat, const amrex::Real dtqsat, const amrex::Real dt, const bool do_cond) noexcept
Definition: ERF_KesslerUtils.H:131
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE KesslerFaceState kessler_face_state(const int k, const int k_lo, const int k_hi, const amrex::Real rho_km1, const amrex::Real rho_k, const amrex::Real qp_km1, const amrex::Real qp_k) noexcept
Definition: ERF_KesslerUtils.H:92
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real kessler_sedimentation_tendency(const amrex::Real fz_hi, const amrex::Real fz_lo, const amrex::Real rho, const amrex::Real dJinv, const amrex::Real coef) noexcept
Definition: ERF_KesslerUtils.H:120
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real kessler_terminal_velocity(const amrex::Real rho, const amrex::Real qp) noexcept
Definition: ERF_KesslerUtils.H:32
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real kessler_precip_flux(const amrex::Real rho, const amrex::Real terminal_velocity, const amrex::Real qp) noexcept
Definition: ERF_KesslerUtils.H:42
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE bool kessler_is_small_sedimentation_value(const amrex::Real value) noexcept
Definition: ERF_KesslerUtils.H:60
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void erf_dtqsatw(amrex::Real t, amrex::Real p, amrex::Real &dtqsatw)
Definition: ERF_MicrophysicsUtils.H:244
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void erf_qsatw(amrex::Real t, amrex::Real p, amrex::Real &qsatw)
Definition: ERF_MicrophysicsUtils.H:228
amrex::Real Real
Definition: ERF_ShocInterface.H:19
amrex::Geometry m_geom
Definition: ERF_Kessler.H:152
amrex::MultiFab * m_detJ_cc
Definition: ERF_Kessler.H:175
amrex::Real m_dzmin
Definition: ERF_Kessler.H:161
amrex::Real m_fac_cond
Definition: ERF_Kessler.H:170
bool m_do_cond
Definition: ERF_Kessler.H:171
amrex::Array< FabPtr, MicVar_Kess::NumVars > mic_fab_vars
Definition: ERF_Kessler.H:178
int m_real_width
Definition: ERF_Kessler.H:155
@ qp
Definition: ERF_Kessler.H:31
@ qcl
Definition: ERF_Kessler.H:29
@ tabs
Definition: ERF_Kessler.H:24
@ pres
Definition: ERF_Kessler.H:25
@ rho
Definition: ERF_Kessler.H:22
@ theta
Definition: ERF_Kessler.H:23
@ qt
Definition: ERF_Kessler.H:27
@ rain_accum
Definition: ERF_Kessler.H:33
@ qv
Definition: ERF_Kessler.H:28
Definition: ERF_KesslerUtils.H:26
amrex::Real rho
Definition: ERF_KesslerUtils.H:27
amrex::Real qp
Definition: ERF_KesslerUtils.H:28
Definition: ERF_KesslerUtils.H:21
amrex::Real dq_cloud_to_vapor
Definition: ERF_KesslerUtils.H:23
amrex::Real dq_vapor_to_cloud
Definition: ERF_KesslerUtils.H:22
Definition: ERF_KesslerUtils.H:14
amrex::Real dq_rain_to_vapor
Definition: ERF_KesslerUtils.H:18
amrex::Real dq_cloud_to_vapor
Definition: ERF_KesslerUtils.H:16
amrex::Real dq_cloud_to_rain
Definition: ERF_KesslerUtils.H:17
amrex::Real dq_vapor_to_cloud
Definition: ERF_KesslerUtils.H:15
MoistureType moisture_type
Definition: ERF_DataStruct.H:1249