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>
16 using SDSpeciesMassArr = amrex::GpuArray<amrex::ParticleReal*,SupDropInit::num_species_max>;
17 using SDAerosolMassArr = amrex::GpuArray<amrex::ParticleReal*,SupDropInit::num_aerosols_max>;
20 using SuperDropletsRealIdx = ERFParticlesRealIdx;
23 using SuperDropletsIntIdx = ERFParticlesIntIdx;
26 struct SuperDropletsIntIdxSoA_RT
35 struct SuperDropletsRealIdxSoA_RT
42 #ifdef ERF_USE_ML_UPHYS_DIAGNOSTICS
51 struct SDIceRealIdxSoA_RT
64 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
65 static int ridx_a(
const int a_i,
69 amrex::ignore_unused(a_num_a);
70 amrex::ignore_unused(a_num_s);
71 return SDPCDefn::SuperDropletsRealIdxSoA_RT::ncomps
75 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
76 static int ridx_s(
const int a_i,
80 amrex::ignore_unused(a_num_s);
81 return SDPCDefn::SuperDropletsRealIdxSoA_RT::ncomps
86 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
87 static int idx_a(
const int a_i,
91 return SDPCDefn::SuperDropletsRealIdx::ncomps + ridx_a(a_i,a_num_a,a_num_s);
94 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
95 static int idx_s(
const int a_i,
99 return SDPCDefn::SuperDropletsRealIdx::ncomps + ridx_s(a_i,a_num_a,a_num_s);
102 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
103 static int ridx_ice_Tfz(
const int a_num_a,
106 return SDPCDefn::SuperDropletsRealIdxSoA_RT::ncomps
109 + SDPCDefn::SDIceRealIdxSoA_RT::T_fz;
112 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
113 static int ridx_ice_a(
const int a_num_a,
116 return SDPCDefn::SuperDropletsRealIdxSoA_RT::ncomps
119 + SDPCDefn::SDIceRealIdxSoA_RT::a;
122 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
123 static int ridx_ice_c(
const int a_num_a,
126 return SDPCDefn::SuperDropletsRealIdxSoA_RT::ncomps
129 + SDPCDefn::SDIceRealIdxSoA_RT::c;
132 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
133 static int ridx_ice_mrime(
const int a_num_a,
136 return SDPCDefn::SuperDropletsRealIdxSoA_RT::ncomps
139 + SDPCDefn::SDIceRealIdxSoA_RT::m_rime;
142 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
143 static int ridx_ice_nmono(
const int a_num_a,
146 return SDPCDefn::SuperDropletsRealIdxSoA_RT::ncomps
149 + SDPCDefn::SDIceRealIdxSoA_RT::n_mono;
152 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
153 static int idx_ice_Tfz(
const int a_num_a,
156 return SDPCDefn::SuperDropletsRealIdx::ncomps + ridx_ice_Tfz(a_num_a,a_num_s);
159 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
160 static int idx_ice_a(
const int a_num_a,
163 return SDPCDefn::SuperDropletsRealIdx::ncomps + ridx_ice_a(a_num_a,a_num_s);
166 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
167 static int idx_ice_c(
const int a_num_a,
170 return SDPCDefn::SuperDropletsRealIdx::ncomps + ridx_ice_c(a_num_a,a_num_s);
173 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
174 static int idx_ice_mrime(
const int a_num_a,
177 return SDPCDefn::SuperDropletsRealIdx::ncomps + ridx_ice_mrime(a_num_a,a_num_s);
180 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
181 static int idx_ice_nmono(
const int a_num_a,
184 return SDPCDefn::SuperDropletsRealIdx::ncomps + ridx_ice_nmono(a_num_a,a_num_s);
187 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
188 static auto ice_rho(
const amrex::ParticleReal a_a,
189 const amrex::ParticleReal a_c,
190 const amrex::ParticleReal a_mass )
192 auto vol =
static_cast<amrex::ParticleReal
>(
four_thirds_pi)*a_a*a_a*a_c;
193 if (vol == amrex::ParticleReal(0)) {
195 return amrex::ParticleReal(0);
202 AMREX_GPU_DEVICE AMREX_FORCE_INLINE
203 static amrex::ParticleReal SD_total_mass(
const int a_idx,
206 const SDPCDefn::SDSpeciesMassArr& a_sp_mass,
207 const SDPCDefn::SDAerosolMassArr& a_ae_mass )
209 amrex::ParticleReal retval =
zero;
210 for (
int j = 0; j < a_num_sp; j++) {
211 retval += a_sp_mass[j][a_idx];
213 for (
int j = 0; j < a_num_ae; j++) {
214 retval += a_ae_mass[j][a_idx];
220 AMREX_GPU_DEVICE AMREX_FORCE_INLINE
221 static amrex::ParticleReal SD_effective_radius(
const int a_idx,
223 amrex::ParticleReal a_rho_w,
226 const int*
const a_sp_sol_arr,
227 const int*
const a_ae_sol_arr,
228 const SDPCDefn::SDSpeciesMassArr& a_sp_mass,
229 const SDPCDefn::SDAerosolMassArr& a_ae_mass,
230 const amrex::ParticleReal*
const a_sp_rho,
231 const amrex::ParticleReal*
const a_ae_rho )
233 amrex::ParticleReal m_w = a_sp_mass[a_idx_w][a_idx];
234 amrex::ParticleReal m_s =
zero;
235 amrex::ParticleReal m_p =
zero;
236 amrex::ParticleReal rho_p =
zero;
237 for (
int j = 0; j < a_num_sp; j++) {
239 if (a_sp_sol_arr[j]) {
240 m_s += a_sp_mass[j][a_idx];
242 m_p += a_sp_mass[j][a_idx];
243 rho_p += a_sp_rho[j]*a_sp_mass[j][a_idx];
247 for (
int j = 0; j < a_num_ae; j++) {
248 if (a_ae_sol_arr[j]) {
249 m_s += a_ae_mass[j][a_idx];
251 m_p += a_ae_mass[j][a_idx];
252 rho_p += a_ae_rho[j]*a_ae_mass[j][a_idx];
255 if (m_p >
zero) { rho_p /= m_p; }
256 else { rho_p =
one; }
257 auto m_t = m_w + m_s + (a_rho_w/rho_p)*m_p;
263 AMREX_GPU_DEVICE AMREX_FORCE_INLINE
264 static amrex::ParticleReal SD_dry_radius(
const int a_idx,
267 const int*
const a_sp_sol_arr,
268 const int*
const a_ae_sol_arr,
269 const SDPCDefn::SDSpeciesMassArr& a_sp_mass,
270 const SDPCDefn::SDAerosolMassArr& a_ae_mass,
271 const amrex::ParticleReal*
const a_sp_rho,
272 const amrex::ParticleReal*
const a_ae_rho )
274 amrex::ParticleReal m_p =
zero;
275 amrex::ParticleReal rho_p =
zero;
276 for (
int j = 0; j < a_num_sp; j++) {
277 if (!a_sp_sol_arr[j]) {
278 m_p += a_sp_mass[j][a_idx];
279 rho_p += a_sp_rho[j]*a_sp_mass[j][a_idx];
282 for (
int j = 0; j < a_num_ae; j++) {
283 if (!a_ae_sol_arr[j]) {
284 m_p += a_ae_mass[j][a_idx];
285 rho_p += a_ae_rho[j]*a_ae_mass[j][a_idx];
288 if (m_p >
zero) { rho_p /= m_p; }
289 else { rho_p =
one; }
302 AMREX_GPU_DEVICE AMREX_FORCE_INLINE
303 static amrex::ParticleReal SD_INP_surface_area(
307 const int*
const a_sp_is_INP,
308 const int*
const a_ae_is_INP,
309 const SDPCDefn::SDSpeciesMassArr& a_sp_mass,
310 const SDPCDefn::SDAerosolMassArr& a_ae_mass,
311 const amrex::ParticleReal*
const a_sp_rho,
312 const amrex::ParticleReal*
const a_ae_rho )
314 amrex::ParticleReal total_area = 0.0;
317 for (
int j = 0; j < a_num_sp; j++) {
318 if (a_sp_is_INP[j] && a_sp_mass[j][a_idx] > 0.0) {
319 auto vol = a_sp_mass[j][a_idx] / a_sp_rho[j];
320 auto r = std::cbrt(vol * 3.0 / (4.0 *
PI));
321 total_area += 4.0 *
PI * r * r;
326 for (
int j = 0; j < a_num_ae; j++) {
327 if (a_ae_is_INP[j] && a_ae_mass[j][a_idx] > 0.0) {
328 auto vol = a_ae_mass[j][a_idx] / a_ae_rho[j];
329 auto r = std::cbrt(vol * 3.0 / (4.0 *
PI));
330 total_area += 4.0 *
PI * r * r;
352 struct INAS_Niemand2012 {
355 INAS_Niemand2012 () =
default;
368 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
370 return a0 * std::exp(-a1 * T_degC +
a2);
376 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
378 return 1.0 - std::exp(-A * n_s(T_degC));
389 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
393 return Tfz_homogeneous + 273.15;
398 auto P_max = P_freeze(Tfz_min, A);
410 auto T_degC = (
a2 - std::log(
y / (A * a0))) / a1;
413 T_degC = std::max(T_degC, Tfz_min);
414 T_degC = std::min(T_degC, Tfz_max);
429 AMREX_GPU_DEVICE AMREX_FORCE_INLINE
430 static auto SD_liquid_fraction(
const int a_p,
433 const SDPCDefn::SDSpeciesMassArr& a_sp_mass )
435 if (a_i_i < 0) {
return amrex::ParticleReal(1); }
436 auto m_water = a_sp_mass[a_i_w][a_p];
437 auto m_ice = a_sp_mass[a_i_i][a_p];
438 auto m_cond = m_water + m_ice;
439 return (m_cond > amrex::ParticleReal(0)) ? (m_water/m_cond) : amrex::ParticleReal(1);
443 AMREX_GPU_DEVICE AMREX_FORCE_INLINE
444 static auto SD_phase(
const int a_p,
447 const SDPCDefn::SDSpeciesMassArr& a_sp_mass )
450 return SDPhase::water;
452 auto m_water = a_sp_mass[a_i_w][a_p];
453 auto m_ice = a_sp_mass[a_i_i][a_p];
455 return (m_water > 0.0) ? SDPhase::mixed : SDPhase::ice;
457 return SDPhase::water;
471 enum struct SDCoalescenceKernelType {
489 enum struct SDMassChangeTIMethod {
490 RK3BS, RK4, BE, CN, DIRK2
constexpr amrex::Real one
Definition: ERF_Constants.H:9
constexpr amrex::Real zero
Definition: ERF_Constants.H:8
constexpr amrex::Real PI
Definition: ERF_Constants.H:42
constexpr amrex::Real four_thirds_pi
Definition: ERF_Constants.H:44
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)
amrex::Real Real
Definition: ERF_ShocInterface.H:19
real(c_double), parameter a2
Definition: ERF_module_model_constants.F90:95