1 #ifndef SUPERDROPLET_PC_DEFN_H_
2 #define SUPERDROPLET_PC_DEFN_H_
4 #ifdef ERF_USE_PARTICLES
6 #include <AMReX_Enum.H>
7 #include <AMReX_Array.H>
8 #include <AMReX_REAL.H>
9 #include <AMReX_Particles.H>
17 using SDSpeciesMassArr = amrex::GpuArray<amrex::ParticleReal*,SupDropInit::num_species_max>;
18 using SDAerosolMassArr = amrex::GpuArray<amrex::ParticleReal*,SupDropInit::num_aerosols_max>;
21 using SuperDropletsRealIdx = ERFParticlesRealIdx;
24 using SuperDropletsIntIdx = ERFParticlesIntIdx;
27 struct SuperDropletsIntIdxSoA_RT
36 struct SuperDropletsRealIdxSoA_RT
43 #ifdef ERF_USE_ML_UPHYS_DIAGNOSTICS
52 struct SDIceRealIdxSoA_RT
65 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
66 static int ridx_a (
const int a_i,
70 amrex::ignore_unused(a_num_a);
71 amrex::ignore_unused(a_num_s);
72 return SDPCDefn::SuperDropletsRealIdxSoA_RT::ncomps
76 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
77 static int ridx_s (
const int a_i,
81 amrex::ignore_unused(a_num_s);
82 return SDPCDefn::SuperDropletsRealIdxSoA_RT::ncomps
87 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
88 static int idx_a (
const int a_i,
92 return SDPCDefn::SuperDropletsRealIdx::ncomps + ridx_a(a_i,a_num_a,a_num_s);
95 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
96 static int idx_s (
const int a_i,
100 return SDPCDefn::SuperDropletsRealIdx::ncomps + ridx_s(a_i,a_num_a,a_num_s);
103 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
104 static int ridx_ice_Tfz (
const int a_num_a,
107 return SDPCDefn::SuperDropletsRealIdxSoA_RT::ncomps
110 + SDPCDefn::SDIceRealIdxSoA_RT::T_fz;
113 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
114 static int ridx_ice_a (
const int a_num_a,
117 return SDPCDefn::SuperDropletsRealIdxSoA_RT::ncomps
120 + SDPCDefn::SDIceRealIdxSoA_RT::a;
123 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
124 static int ridx_ice_c (
const int a_num_a,
127 return SDPCDefn::SuperDropletsRealIdxSoA_RT::ncomps
130 + SDPCDefn::SDIceRealIdxSoA_RT::c;
133 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
134 static int ridx_ice_mrime (
const int a_num_a,
137 return SDPCDefn::SuperDropletsRealIdxSoA_RT::ncomps
140 + SDPCDefn::SDIceRealIdxSoA_RT::m_rime;
143 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
144 static int ridx_ice_nmono (
const int a_num_a,
147 return SDPCDefn::SuperDropletsRealIdxSoA_RT::ncomps
150 + SDPCDefn::SDIceRealIdxSoA_RT::n_mono;
153 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
154 static int idx_ice_Tfz (
const int a_num_a,
157 return SDPCDefn::SuperDropletsRealIdx::ncomps + ridx_ice_Tfz(a_num_a,a_num_s);
160 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
161 static int idx_ice_a (
const int a_num_a,
164 return SDPCDefn::SuperDropletsRealIdx::ncomps + ridx_ice_a(a_num_a,a_num_s);
167 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
168 static int idx_ice_c (
const int a_num_a,
171 return SDPCDefn::SuperDropletsRealIdx::ncomps + ridx_ice_c(a_num_a,a_num_s);
174 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
175 static int idx_ice_mrime (
const int a_num_a,
178 return SDPCDefn::SuperDropletsRealIdx::ncomps + ridx_ice_mrime(a_num_a,a_num_s);
181 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
182 static int idx_ice_nmono (
const int a_num_a,
185 return SDPCDefn::SuperDropletsRealIdx::ncomps + ridx_ice_nmono(a_num_a,a_num_s);
188 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
189 static auto ice_rho (
const amrex::ParticleReal a_a,
190 const amrex::ParticleReal a_c,
191 const amrex::ParticleReal a_mass )
193 auto vol =
static_cast<amrex::ParticleReal
>(
four_thirds_pi)*a_a*a_a*a_c;
194 if (vol == amrex::ParticleReal(0)) {
196 return amrex::ParticleReal(0);
203 AMREX_GPU_DEVICE AMREX_FORCE_INLINE
204 static amrex::ParticleReal SD_total_mass (
const int a_idx,
207 const SDPCDefn::SDSpeciesMassArr& a_sp_mass,
208 const SDPCDefn::SDAerosolMassArr& a_ae_mass )
210 amrex::ParticleReal retval =
zero;
211 for (
int j = 0; j < a_num_sp; j++) {
212 retval += a_sp_mass[j][a_idx];
214 for (
int j = 0; j < a_num_ae; j++) {
215 retval += a_ae_mass[j][a_idx];
221 AMREX_GPU_DEVICE AMREX_FORCE_INLINE
222 static amrex::ParticleReal SD_effective_radius (
const int a_idx,
224 amrex::ParticleReal a_rho_w,
227 const int*
const a_sp_sol_arr,
228 const int*
const a_ae_sol_arr,
229 const SDPCDefn::SDSpeciesMassArr& a_sp_mass,
230 const SDPCDefn::SDAerosolMassArr& a_ae_mass,
231 const amrex::ParticleReal*
const a_sp_rho,
232 const amrex::ParticleReal*
const a_ae_rho )
234 amrex::ParticleReal m_w = a_sp_mass[a_idx_w][a_idx];
235 amrex::ParticleReal m_s =
zero;
236 amrex::ParticleReal m_p =
zero;
237 amrex::ParticleReal rho_p =
zero;
238 for (
int j = 0; j < a_num_sp; j++) {
240 if (a_sp_sol_arr[j]) {
241 m_s += a_sp_mass[j][a_idx];
243 m_p += a_sp_mass[j][a_idx];
244 rho_p += a_sp_rho[j]*a_sp_mass[j][a_idx];
248 for (
int j = 0; j < a_num_ae; j++) {
249 if (a_ae_sol_arr[j]) {
250 m_s += a_ae_mass[j][a_idx];
252 m_p += a_ae_mass[j][a_idx];
253 rho_p += a_ae_rho[j]*a_ae_mass[j][a_idx];
258 const auto rho_p_avg = rho_p / amrex::max(m_p, std::numeric_limits<amrex::ParticleReal>::min());
259 rho_p = (m_p >
zero) ? rho_p_avg :
one;
260 auto m_t = m_w + m_s + (a_rho_w/rho_p)*m_p;
266 AMREX_GPU_DEVICE AMREX_FORCE_INLINE
267 static amrex::ParticleReal SD_dry_radius (
const int a_idx,
270 const int*
const a_sp_sol_arr,
271 const int*
const a_ae_sol_arr,
272 const SDPCDefn::SDSpeciesMassArr& a_sp_mass,
273 const SDPCDefn::SDAerosolMassArr& a_ae_mass,
274 const amrex::ParticleReal*
const a_sp_rho,
275 const amrex::ParticleReal*
const a_ae_rho )
277 amrex::ParticleReal m_p =
zero;
278 amrex::ParticleReal rho_p =
zero;
279 for (
int j = 0; j < a_num_sp; j++) {
280 if (!a_sp_sol_arr[j]) {
281 m_p += a_sp_mass[j][a_idx];
282 rho_p += a_sp_rho[j]*a_sp_mass[j][a_idx];
285 for (
int j = 0; j < a_num_ae; j++) {
286 if (!a_ae_sol_arr[j]) {
287 m_p += a_ae_mass[j][a_idx];
288 rho_p += a_ae_rho[j]*a_ae_mass[j][a_idx];
292 const auto rho_p_avg = rho_p / amrex::max(m_p, std::numeric_limits<amrex::ParticleReal>::min());
293 rho_p = (m_p >
zero) ? rho_p_avg :
one;
306 AMREX_GPU_DEVICE AMREX_FORCE_INLINE
307 static amrex::ParticleReal SD_INP_surface_area (
311 const int*
const a_sp_is_INP,
312 const int*
const a_ae_is_INP,
313 const SDPCDefn::SDSpeciesMassArr& a_sp_mass,
314 const SDPCDefn::SDAerosolMassArr& a_ae_mass,
315 const amrex::ParticleReal*
const a_sp_rho,
316 const amrex::ParticleReal*
const a_ae_rho )
318 amrex::ParticleReal total_area = 0.0;
321 for (
int j = 0; j < a_num_sp; j++) {
322 if (a_sp_is_INP[j] && a_sp_mass[j][a_idx] > 0.0) {
323 auto vol = a_sp_mass[j][a_idx] / a_sp_rho[j];
324 auto r = std::cbrt(vol * 3.0 / (4.0 *
PI));
325 total_area += 4.0 *
PI * r * r;
330 for (
int j = 0; j < a_num_ae; j++) {
331 if (a_ae_is_INP[j] && a_ae_mass[j][a_idx] > 0.0) {
332 auto vol = a_ae_mass[j][a_idx] / a_ae_rho[j];
333 auto r = std::cbrt(vol * 3.0 / (4.0 *
PI));
334 total_area += 4.0 *
PI * r * r;
356 struct INAS_Niemand2012 {
359 INAS_Niemand2012 () =
default;
372 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
374 return a0 * std::exp(-a1 * T_degC +
a2);
380 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
382 return 1.0 - std::exp(-
A * n_s(T_degC));
393 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
397 return Tfz_homogeneous + 273.15;
402 auto P_max = P_freeze(Tfz_min,
A);
414 auto T_degC = (
a2 - std::log(
y / (
A * a0))) / a1;
417 T_degC = std::max(T_degC, Tfz_min);
418 T_degC = std::min(T_degC, Tfz_max);
433 AMREX_GPU_DEVICE AMREX_FORCE_INLINE
434 static auto SD_liquid_fraction (
const int a_p,
437 const SDPCDefn::SDSpeciesMassArr& a_sp_mass )
439 if (a_i_i < 0) {
return amrex::ParticleReal(1); }
440 auto m_water = a_sp_mass[a_i_w][a_p];
441 auto m_ice = a_sp_mass[a_i_i][a_p];
442 auto m_cond = m_water + m_ice;
443 return (m_cond > amrex::ParticleReal(0)) ? (m_water/m_cond) : amrex::ParticleReal(1);
447 AMREX_GPU_DEVICE AMREX_FORCE_INLINE
448 static auto SD_phase (
const int a_p,
451 const SDPCDefn::SDSpeciesMassArr& a_sp_mass )
454 return SDPhase::water;
456 auto m_water = a_sp_mass[a_i_w][a_p];
457 auto m_ice = a_sp_mass[a_i_i][a_p];
459 return (m_water > 0.0) ? SDPhase::mixed : SDPhase::ice;
461 return SDPhase::water;
475 enum struct SDCoalescenceKernelType {
493 enum struct SDMassChangeTIMethod {
494 RK3BS, RK4, BE, CN, DIRK2
AMREX_ENUM(PlotFileType, None, Amrex, Netcdf)
AMREX_ALWAYS_ASSERT(bx.length()[2]==khi+1)
Dimensionless numeric literals and pure mathematical constants.
constexpr amrex::Real one
Definition: ERF_NumericalConstants.H:37
constexpr amrex::Real zero
Definition: ERF_NumericalConstants.H:36
constexpr amrex::Real PI
Definition: ERF_NumericalConstants.H:46
constexpr amrex::Real four_thirds_pi
Definition: ERF_NumericalConstants.H:48
amrex::Real Real
Definition: ERF_ShocInterface.H:19
constexpr int A
Definition: ERF_TwoStreamColumn.H:603
real(c_double), parameter a2
Definition: ERF_module_model_constants.F90:95