18 auto domain =
m_geom.Domain();
19 int k_lo = domain.smallEnd(2);
20 int k_hi = domain.bigEnd(2);
24 auto ba =
tabs->boxArray();
25 auto dm =
tabs->DistributionMap();
26 fz.define(convert(ba, IntVect(0,0,1)), dm, 1, 0);
37 for ( MFIter mfi(*
tabs,TilingIfNotGPU()); mfi.isValid(); ++mfi) {
47 auto tbx = mfi.tilebox();
51 ParallelFor(tbx, [=] AMREX_GPU_DEVICE(
int i,
int j,
int k) noexcept
53 qv_array(i,j,k) = std::max(
Real(0), qv_array(i,j,k));
54 qc_array(i,j,k) = std::max(
Real(0), qc_array(i,j,k));
55 qp_array(i,j,k) = std::max(
Real(0), qp_array(i,j,k));
57 Real qsat_local, dtqsat_local;
58 Real pressure = pres_array(i,j,k);
60 erf_qsatw(tabs_array(i,j,k), pressure, qsat_local);
61 erf_dtqsatw(tabs_array(i,j,k), pressure, dtqsat_local);
63 if (qsat_local <=
Real(0)) {
64 amrex::Warning(
"qsat computed as non-positive; setting to Real(0)!");
69 qv_array(i,j,k), qc_array(i,j,k), qp_array(i,j,k), rho_array(i,j,k),
70 pressure, qsat_local, dtqsat_local, dtn, do_cond, d_fac_cond);
81 Real theta_over_T = theta_array(i,j,k)/tabs_array(i,j,k);
82 theta_array(i,j,k) += theta_over_T * d_fac_cond
87 qv_array(i,j,k) = std::max(
Real(0), qv_array(i,j,k));
88 qc_array(i,j,k) = std::max(
Real(0), qc_array(i,j,k));
89 qp_array(i,j,k) = std::max(
Real(0), qp_array(i,j,k));
91 qt_array(i,j,k) = qv_array(i,j,k) + qc_array(i,j,k);
95 for ( MFIter mfi(fz, TilingIfNotGPU()); mfi.isValid(); ++mfi ){
99 auto fz_array = fz.array(mfi);
100 const Box& tbz = mfi.tilebox();
102 ParallelFor(tbz, [=] AMREX_GPU_DEVICE(
int i,
int j,
int k) noexcept
104 const Real rho_km1 = (k == k_lo) ? rho_array(i,j,k) : rho_array(i,j,k-1);
105 const Real rho_k = (k == k_hi+1) ? rho_array(i,j,k-1) : rho_array(i,j,k);
106 const Real qp_km1 = (k == k_lo) ? qp_array(i,j,k) : qp_array(i,j,k-1);
107 const Real qp_k = (k == k_hi+1) ? qp_array(i,j,k-1) : qp_array(i,j,k);
121 GpuTuple<Real> max_terminal_velocity = ParReduce(TypeList<ReduceOpMax>{},
124 [=] AMREX_GPU_DEVICE (
int box_no,
int i,
int j,
int k) noexcept
127 const auto&
rho_arr = ma_rho_arr[box_no];
128 const auto& qp_arr = ma_qp_arr[box_no];
131 const Real qp_km1 = (k == k_lo) ? qp_arr(i,j,k) : qp_arr(i,j,k-1);
132 const Real qp_k = (k == k_hi+1) ? qp_arr(i,j,k-1) : qp_arr(i,j,k);
137 Real max_vt = get<0>(max_terminal_velocity);
147 ParallelDescriptor::ReduceRealMax(max_vt);
152 "Kessler: the minimum cell height was never set (Set_dzmin), so the sedimentation substeps cannot be sized");
155 "Kessler: Number of precipitation substeps must be greater than 0!");
156 coef /=
Real(n_substep);
157 dtn /=
Real(n_substep);
159 for (
int nsub(0); nsub<n_substep; ++nsub)
167 for ( MFIter mfi(*
tabs,
TileNoZ()); mfi.isValid(); ++mfi ){
171 auto fz_array = fz.array(mfi);
173 const auto dJ_array = (
m_detJ_cc) ?
m_detJ_cc->const_array(mfi) : Array4<const Real>{};
175 const Box& tbx = mfi.tilebox();
176 const Box& tbz = mfi.tilebox(IntVect(0,0,1),IntVect(0));
178 ParallelFor(tbz, [=] AMREX_GPU_DEVICE(
int i,
int j,
int k) noexcept
180 const Real rho_km1 = (k == k_lo) ? rho_array(i,j,k) : rho_array(i,j,k-1);
181 const Real rho_k = (k == k_hi+1) ? rho_array(i,j,k-1) : rho_array(i,j,k);
182 const Real qp_km1 = (k == k_lo) ? qp_array(i,j,k) : qp_array(i,j,k-1);
183 const Real qp_k = (k == k_hi+1) ? qp_array(i,j,k-1) : qp_array(i,j,k);
189 const Real donor_rho = rho_array(i,j,donor_k);
190 const Real donor_qp = std::max(
Real(0), qp_array(i,j,donor_k));
191 const Real donor_detJ = (dJ_array) ? dJ_array(i,j,donor_k) :
Real(1);
198 const Real max_flux = donor_rho * donor_qp * donor_detJ / coef;
199 fz_array(i,j,k) = amrex::min(
205 rain_accum_array(i,j,k) = rain_accum_array(i,j,k)
210 ParallelFor(tbx, [=] AMREX_GPU_DEVICE(
int i,
int j,
int k) noexcept
212 Real dJinv = (dJ_array) ?
Real(1)/dJ_array(i,j,k) :
Real(1);
217 Real f_hi = fz_array(i,j,k+1);
218 Real f_lo = fz_array(i,j,k );
227 f_hi, f_lo, rho_array(i,j,k), dJinv, coef);
232 qp_array(i,j,k) += dq_sed;
233 qp_array(i,j,k) = std::max(
Real(0), qp_array(i,j,k));
239 if (solverChoice.
moisture_type == MoistureType::Kessler_NoRain) {
240 if (!do_cond) {
return; }
241 for ( MFIter mfi(*
tabs,TilingIfNotGPU()); mfi.isValid(); ++mfi) {
249 auto tbx = mfi.tilebox();
253 ParallelFor(tbx, [=] AMREX_GPU_DEVICE(
int i,
int j,
int k) noexcept
255 qc_array(i,j,k) = std::max(
Real(0), qc_array(i,j,k));
259 Real pressure = pres_array(i,j,k);
261 erf_qsatw(tabs_array(i,j,k), pressure, qsat);
266 do_cond, d_fac_cond);
273 Real theta_over_T = theta_array(i,j,k)/tabs_array(i,j,k);
274 theta_array(i,j,k) += theta_over_T * d_fac_cond
277 qv_array(i,j,k) = std::max(
Real(0), qv_array(i,j,k));
278 qc_array(i,j,k) = std::max(
Real(0), qc_array(i,j,k));
280 qt_array(i,j,k) = qv_array(i,j,k) + qc_array(i,j,k);
AMREX_ALWAYS_ASSERT_WITH_MESSAGE(m_cloud_chamber_config.active, "Cloud Chamber: initializer reached without a parsed configuration")
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, const amrex::Real latent_over_cp) noexcept
Definition: ERF_KesslerUtils.H:89
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:62
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE KesslerFaceState kessler_face_state(const int k, 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:114
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, const amrex::Real latent_over_cp) noexcept
Definition: ERF_KesslerUtils.H:156
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:145
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:44
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real kessler_rain_accumulation_increment(const amrex::Real precip_mass_per_area) noexcept
Definition: ERF_KesslerUtils.H:72
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:54
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE bool kessler_is_small_sedimentation_value(const amrex::Real value) noexcept
Definition: ERF_KesslerUtils.H:82
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE int kessler_face_donor_k(const int k, const int k_hi) noexcept
Definition: ERF_KesslerUtils.H:37
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void erf_dtqsatw(amrex::Real t, amrex::Real p, amrex::Real &dtqsatw)
Definition: ERF_MicrophysicsUtils.H:280
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void erf_qsatw(amrex::Real t, amrex::Real p, amrex::Real &qsatw)
Definition: ERF_MicrophysicsUtils.H:264
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);})
amrex::Real Real
Definition: ERF_ShocInterface.H:19
AMREX_FORCE_INLINE amrex::IntVect TileNoZ()
Definition: ERF_TileNoZ.H:11
auto rho_arr
Definition: ERF_UpdateWSubsidence_SineMassFlux.H:3
amrex::Geometry m_geom
Definition: ERF_Kessler.H:219
amrex::MultiFab * m_detJ_cc
Definition: ERF_Kessler.H:238
amrex::Real m_dzmin
Definition: ERF_Kessler.H:225
amrex::Real m_fac_cond
Definition: ERF_Kessler.H:231
bool m_do_cond
Definition: ERF_Kessler.H:233
amrex::Array< FabPtr, MicVar_Kess::NumVars > mic_fab_vars
Definition: ERF_Kessler.H:241
@ qp
Definition: ERF_Kessler.H:34
@ qcl
Definition: ERF_Kessler.H:32
@ tabs
Definition: ERF_Kessler.H:27
@ pres
Definition: ERF_Kessler.H:28
@ rho
Definition: ERF_Kessler.H:25
@ theta
Definition: ERF_Kessler.H:26
@ qt
Definition: ERF_Kessler.H:30
@ rain_accum
Definition: ERF_Kessler.H:36
@ qv
Definition: ERF_Kessler.H:31
Definition: ERF_KesslerUtils.H:27
amrex::Real rho
Definition: ERF_KesslerUtils.H:28
amrex::Real qp
Definition: ERF_KesslerUtils.H:29
Definition: ERF_KesslerUtils.H:22
amrex::Real dq_cloud_to_vapor
Definition: ERF_KesslerUtils.H:24
amrex::Real dq_vapor_to_cloud
Definition: ERF_KesslerUtils.H:23
Definition: ERF_KesslerUtils.H:15
amrex::Real dq_rain_to_vapor
Definition: ERF_KesslerUtils.H:19
amrex::Real dq_cloud_to_vapor
Definition: ERF_KesslerUtils.H:17
amrex::Real dq_cloud_to_rain
Definition: ERF_KesslerUtils.H:18
amrex::Real dq_vapor_to_cloud
Definition: ERF_KesslerUtils.H:16
MoistureType moisture_type
Moisture or microphysics model.
Definition: ERF_DataStruct.H:2237