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];
256 if (m_p >
zero) { rho_p /= m_p; }
257 else { rho_p =
one; }
258 auto m_t = m_w + m_s + (a_rho_w/rho_p)*m_p;
264 AMREX_GPU_DEVICE AMREX_FORCE_INLINE
265 static amrex::ParticleReal SD_dry_radius(
const int a_idx,
268 const int*
const a_sp_sol_arr,
269 const int*
const a_ae_sol_arr,
270 const SDPCDefn::SDSpeciesMassArr& a_sp_mass,
271 const SDPCDefn::SDAerosolMassArr& a_ae_mass,
272 const amrex::ParticleReal*
const a_sp_rho,
273 const amrex::ParticleReal*
const a_ae_rho )
275 amrex::ParticleReal m_p =
zero;
276 amrex::ParticleReal rho_p =
zero;
277 for (
int j = 0; j < a_num_sp; j++) {
278 if (!a_sp_sol_arr[j]) {
279 m_p += a_sp_mass[j][a_idx];
280 rho_p += a_sp_rho[j]*a_sp_mass[j][a_idx];
283 for (
int j = 0; j < a_num_ae; j++) {
284 if (!a_ae_sol_arr[j]) {
285 m_p += a_ae_mass[j][a_idx];
286 rho_p += a_ae_rho[j]*a_ae_mass[j][a_idx];
289 if (m_p >
zero) { rho_p /= m_p; }
290 else { rho_p =
one; }
303 AMREX_GPU_DEVICE AMREX_FORCE_INLINE
304 static amrex::ParticleReal SD_INP_surface_area(
308 const int*
const a_sp_is_INP,
309 const int*
const a_ae_is_INP,
310 const SDPCDefn::SDSpeciesMassArr& a_sp_mass,
311 const SDPCDefn::SDAerosolMassArr& a_ae_mass,
312 const amrex::ParticleReal*
const a_sp_rho,
313 const amrex::ParticleReal*
const a_ae_rho )
315 amrex::ParticleReal total_area = 0.0;
318 for (
int j = 0; j < a_num_sp; j++) {
319 if (a_sp_is_INP[j] && a_sp_mass[j][a_idx] > 0.0) {
320 auto vol = a_sp_mass[j][a_idx] / a_sp_rho[j];
321 auto r = std::cbrt(vol * 3.0 / (4.0 *
PI));
322 total_area += 4.0 *
PI * r * r;
327 for (
int j = 0; j < a_num_ae; j++) {
328 if (a_ae_is_INP[j] && a_ae_mass[j][a_idx] > 0.0) {
329 auto vol = a_ae_mass[j][a_idx] / a_ae_rho[j];
330 auto r = std::cbrt(vol * 3.0 / (4.0 *
PI));
331 total_area += 4.0 *
PI * r * r;
353 struct INAS_Niemand2012 {
356 INAS_Niemand2012 () =
default;
369 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
371 return a0 * std::exp(-a1 * T_degC +
a2);
377 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
379 return 1.0 - std::exp(-
A * n_s(T_degC));
390 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
394 return Tfz_homogeneous + 273.15;
399 auto P_max = P_freeze(Tfz_min,
A);
411 auto T_degC = (
a2 - std::log(
y / (
A * a0))) / a1;
414 T_degC = std::max(T_degC, Tfz_min);
415 T_degC = std::min(T_degC, Tfz_max);
430 AMREX_GPU_DEVICE AMREX_FORCE_INLINE
431 static auto SD_liquid_fraction(
const int a_p,
434 const SDPCDefn::SDSpeciesMassArr& a_sp_mass )
436 if (a_i_i < 0) {
return amrex::ParticleReal(1); }
437 auto m_water = a_sp_mass[a_i_w][a_p];
438 auto m_ice = a_sp_mass[a_i_i][a_p];
439 auto m_cond = m_water + m_ice;
440 return (m_cond > amrex::ParticleReal(0)) ? (m_water/m_cond) : amrex::ParticleReal(1);
444 AMREX_GPU_DEVICE AMREX_FORCE_INLINE
445 static auto SD_phase(
const int a_p,
448 const SDPCDefn::SDSpeciesMassArr& a_sp_mass )
451 return SDPhase::water;
453 auto m_water = a_sp_mass[a_i_w][a_p];
454 auto m_ice = a_sp_mass[a_i_i][a_p];
456 return (m_water > 0.0) ? SDPhase::mixed : SDPhase::ice;
458 return SDPhase::water;
472 enum struct SDCoalescenceKernelType {
490 enum struct SDMassChangeTIMethod {
491 RK3BS, RK4, BE, CN, DIRK2
AMREX_ENUM(InitType, None, Input_Sounding, NCFile, WRFInput, Metgrid, Uniform, ConstantDensity, ConstantDensityLinearTheta, Isentropic, MoistBaseState, HindCast)
Initial-condition source used to populate the ERF state.
AMREX_ALWAYS_ASSERT(bx.length()[2]==khi+1)
Dimensionless numeric literals and pure mathematical constants.
constexpr amrex::Real one
Definition: ERF_NumericalConstants.H:30
constexpr amrex::Real zero
Definition: ERF_NumericalConstants.H:29
constexpr amrex::Real PI
Definition: ERF_NumericalConstants.H:39
constexpr amrex::Real four_thirds_pi
Definition: ERF_NumericalConstants.H:41
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