1 #ifndef SUPERDROPLET_PC_COALESCENCE_H_
2 #define SUPERDROPLET_PC_COALESCENCE_H_
8 #ifdef ERF_USE_PARTICLES
34 template<
typename RT,
int SPACEDIM>
35 struct CollisionKernel
37 const RT lambda_mfp = RT(6.62e-8);
38 const RT para_Asc = RT(2.51);
39 const RT para_Bsc = RT(0.8);
40 const RT para_Csc = RT(0.55);
41 const RT k_coeff = RT(1.0);
44 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
45 RT golovin (
const RT a_r1,
46 const RT a_r2 )
const noexcept
51 return b * (X_1 + X_2);
71 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
72 RT sedimentation (
const RT a_r1,
78 const SDKernelRelativeVelocityType a_vel_type )
const noexcept
80 auto p = std::min(a_r1,a_r2) / std::max(a_r1,a_r2);
81 auto E = RT(0.5)*
p*
p / ((RT(1.0)+
p)*(RT(1.0)+
p));
84 if (a_vel_type == SDKernelRelativeVelocityType::radial_velocity) {
86 for (
int d = 0; d < SPACEDIM; d++) {
87 const RT ddv = a_v1[d]-a_v2[d];
88 const RT ddx = a_x1[d]-a_x2[d];
94 dv = (dr > RT(0)) ? std::abs(dv) / std::sqrt(dr) : std::sqrt(dv2);
96 for (
int d = 0; d < SPACEDIM; d++) {
97 dv += (a_v1[d]-a_v2[d])*(a_v1[d]-a_v2[d]);
102 return PI*(a_r1+a_r2)*(a_r1+a_r2)*E*dv;
125 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
126 RT Longs (
const RT a_r1,
128 const RT*
const a_v1,
129 const RT*
const a_v2,
130 const RT*
const a_x1,
131 const RT*
const a_x2,
132 const SDKernelRelativeVelocityType a_vel_type )
const noexcept
134 auto r1 = std::max( a_r1, a_r2 );
135 auto r2 = std::min( a_r1, a_r2 );
139 if( r1 <= RT(5.E-5) ) {
140 c_rate = RT(4.5E+8) * ( r1*r1 ) * ( RT(1.0) - RT(3.E-6)/(std::max(RT(3.01E-6),r1)) );
142 c_rate *= (
PI*sumr*sumr);
145 if (a_vel_type == SDKernelRelativeVelocityType::radial_velocity) {
147 for (
int d = 0; d < SPACEDIM; d++) {
148 const RT ddv = a_v1[d]-a_v2[d];
149 const RT ddx = a_x1[d]-a_x2[d];
155 dv = (dr > RT(0)) ? std::abs(dv) / std::sqrt(dr) : std::sqrt(dv2);
157 for (
int d = 0; d < SPACEDIM; d++) {
158 dv += (a_v1[d]-a_v2[d])*(a_v1[d]-a_v2[d]);
169 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
170 RT Halls_data_r0col (
const int a_i )
const noexcept
172 static const RT vec[15] = { RT(6.0),
193 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
194 int Halls_data_r0col (
const RT a_r )
const noexcept
196 auto radius_microns = a_r*RT(1.0e6);
198 for (i = 0; i < 15; i++) {
199 if (radius_microns <= Halls_data_r0col(i)) {
return i; }
207 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
208 RT Halls_data_ratcol (
const int a_i )
const noexcept
210 static const RT vec[21] = {RT(0.00),
237 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
238 int Halls_data_ratcol (
const RT a_r )
const noexcept
241 for (i = 1; i < 20; i++) {
242 if (a_r <= Halls_data_ratcol(i)) {
return i; }
250 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
251 RT Halls_data_ecoll (
const int a_i,
252 const int a_j )
const noexcept
254 const RT ecoll[21][15] =
255 { {RT(0.0010),RT(0.0010),RT(0.0010),RT(0.0010),RT(0.0010),RT(0.0010),RT(0.0010),RT(0.0010),RT(0.0010),RT(0.0010),RT(0.0010),RT(0.0010),RT(0.0010),RT(0.0010),RT(0.0010)},
256 {RT(0.0030),RT(0.0030),RT(0.0030),RT(0.0040),RT(0.0050),RT(0.0050),RT(0.0050),RT(0.0100),RT(0.1000),RT(0.0500),RT(0.2000),RT(0.5000),RT(0.7700),RT(0.8700),RT(0.9700)},
257 {RT(0.0070),RT(0.0070),RT(0.0070),RT(0.0080),RT(0.0090),RT(0.0100),RT(0.0100),RT(0.0700),RT(0.4000),RT(0.4300),RT(0.5800),RT(0.7900),RT(0.9300),RT(0.9600),RT(1.0000)},
258 {RT(0.0090),RT(0.0090),RT(0.0090),RT(0.0120),RT(0.0150),RT(0.0100),RT(0.0200),RT(0.2800),RT(0.6000),RT(0.6400),RT(0.7500),RT(0.9100),RT(0.9700),RT(0.9800),RT(1.0000)},
259 {RT(0.0140),RT(0.0140),RT(0.0140),RT(0.0150),RT(0.0160),RT(0.0300),RT(0.0600),RT(0.5000),RT(0.7000),RT(0.7700),RT(0.8400),RT(0.9500),RT(0.9700),RT(1.0000),RT(1.0000)},
260 {RT(0.0170),RT(0.0170),RT(0.0170),RT(0.0200),RT(0.0220),RT(0.0600),RT(0.1000),RT(0.6200),RT(0.7800),RT(0.8400),RT(0.8800),RT(0.9500),RT(1.0000),RT(1.0000),RT(1.0000)},
261 {RT(0.0300),RT(0.0300),RT(0.0240),RT(0.0220),RT(0.0320),RT(0.0620),RT(0.2000),RT(0.6800),RT(0.8300),RT(0.8700),RT(0.9000),RT(0.9500),RT(1.0000),RT(1.0000),RT(1.0000)},
262 {RT(0.0250),RT(0.0250),RT(0.0250),RT(0.0360),RT(0.0430),RT(0.1300),RT(0.2700),RT(0.7400),RT(0.8600),RT(0.8900),RT(0.9200),RT(1.0000),RT(1.0000),RT(1.0000),RT(1.0000)},
263 {RT(0.0270),RT(0.0270),RT(0.0270),RT(0.0400),RT(0.0520),RT(0.2000),RT(0.4000),RT(0.7800),RT(0.8800),RT(0.9000),RT(0.9400),RT(1.0000),RT(1.0000),RT(1.0000),RT(1.0000)},
264 {RT(0.0300),RT(0.0300),RT(0.0300),RT(0.0470),RT(0.0640),RT(0.2500),RT(0.5000),RT(0.8000),RT(0.9000),RT(0.9100),RT(0.9500),RT(1.0000),RT(1.0000),RT(1.0000),RT(1.0000)},
265 {RT(0.0400),RT(0.0400),RT(0.0330),RT(0.0370),RT(0.0680),RT(0.2400),RT(0.5500),RT(0.8000),RT(0.9000),RT(0.9100),RT(0.9500),RT(1.0000),RT(1.0000),RT(1.0000),RT(1.0000)},
266 {RT(0.0350),RT(0.0350),RT(0.0350),RT(0.0550),RT(0.0790),RT(0.2900),RT(0.5800),RT(0.8000),RT(0.9000),RT(0.9100),RT(0.9500),RT(1.0000),RT(1.0000),RT(1.0000),RT(1.0000)},
267 {RT(0.0370),RT(0.0370),RT(0.0370),RT(0.0620),RT(0.0820),RT(0.2900),RT(0.5900),RT(0.7800),RT(0.9000),RT(0.9100),RT(0.9500),RT(1.0000),RT(1.0000),RT(1.0000),RT(1.0000)},
268 {RT(0.0370),RT(0.0370),RT(0.0370),RT(0.0600),RT(0.0800),RT(0.2900),RT(0.5800),RT(0.7700),RT(0.8900),RT(0.9100),RT(0.9500),RT(1.0000),RT(1.0000),RT(1.0000),RT(1.0000)},
269 {RT(0.0370),RT(0.0370),RT(0.0370),RT(0.0410),RT(0.0750),RT(0.2500),RT(0.5400),RT(0.7600),RT(0.8800),RT(0.9200),RT(0.9500),RT(1.0000),RT(1.0000),RT(1.0000),RT(1.0000)},
270 {RT(0.0370),RT(0.0370),RT(0.0370),RT(0.0520),RT(0.0670),RT(0.2500),RT(0.5100),RT(0.7700),RT(0.8800),RT(0.9300),RT(0.9700),RT(1.0000),RT(1.0000),RT(1.0000),RT(1.0000)},
271 {RT(0.0370),RT(0.0370),RT(0.0370),RT(0.0470),RT(0.0570),RT(0.2500),RT(0.4900),RT(0.7700),RT(0.8900),RT(0.9500),RT(1.0000),RT(1.0000),RT(1.0000),RT(1.0000),RT(1.0000)},
272 {RT(0.0360),RT(0.0360),RT(0.0360),RT(0.0420),RT(0.0480),RT(0.2300),RT(0.4700),RT(0.7800),RT(0.9200),RT(1.0000),RT(1.0200),RT(1.0200),RT(1.0200),RT(1.0200),RT(1.0200)},
273 {RT(0.0400),RT(0.0400),RT(0.0350),RT(0.0330),RT(0.0400),RT(0.1120),RT(0.4500),RT(0.7900),RT(1.0100),RT(1.0300),RT(1.0400),RT(1.0400),RT(1.0400),RT(1.0400),RT(1.0400)},
274 {RT(0.0330),RT(0.0330),RT(0.0330),RT(0.0330),RT(0.0330),RT(0.1190),RT(0.4700),RT(0.9500),RT(1.3000),RT(1.7000),RT(2.3000),RT(2.3000),RT(2.3000),RT(2.3000),RT(2.3000)},
275 {RT(0.0270),RT(0.0270),RT(0.0270),RT(0.0270),RT(0.0270),RT(0.1250),RT(0.5200),RT(1.4000),RT(2.3000),RT(3.0000),RT(4.0000),RT(4.0000),RT(4.0000),RT(4.0000),RT(4.0000)} };
276 return ecoll[a_i][a_j];
283 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
284 RT Halls (
const RT a_r1,
286 const RT*
const a_v1,
287 const RT*
const a_v2,
288 const RT*
const a_x1,
289 const RT*
const a_x2,
290 const SDKernelRelativeVelocityType a_vel_type )
const noexcept
292 auto r1 = std::max( a_r1, a_r2 );
293 auto r2 = std::min( a_r1, a_r2 );
294 auto ratio = r2 / r1;
297 int irr = Halls_data_r0col(r1);
298 int iqq = Halls_data_ratcol(ratio);
304 RT
q = ( ratio - Halls_data_ratcol(iqq-1) )
305 / ( Halls_data_ratcol(iqq) - Halls_data_ratcol(iqq-1) );
307 RT ek = (RT(1.0)-
q) * Halls_data_ecoll(iqq-1,14)
308 +
q * Halls_data_ecoll(iqq ,14);
310 c_rate = std::min( ek, RT(1.0) );
312 }
else if ((irr >= 1) && (irr < 15)) {
314 RT
p = ( r1*RT(1.0e6) - Halls_data_r0col(irr-1) )
315 / ( Halls_data_r0col(irr) - Halls_data_r0col(irr-1) );
317 RT
q = ( ratio - Halls_data_ratcol(iqq-1) )
318 / ( Halls_data_ratcol(iqq) - Halls_data_ratcol(iqq-1) );
320 c_rate = (RT(1.0)-
p) * (RT(1.0)-
q) * Halls_data_ecoll(iqq-1,irr-1)
321 +
p * (RT(1.0)-
q) * Halls_data_ecoll(iqq-1,irr )
322 + (RT(1.0)-
p) *
q * Halls_data_ecoll(iqq ,irr-1)
323 +
p *
q * Halls_data_ecoll(iqq ,irr );
327 RT
q = ( ratio - Halls_data_ratcol(iqq-1) )
328 / ( Halls_data_ratcol(iqq) - Halls_data_ratcol(iqq-1) );
330 c_rate = (RT(1.0)-
q) * Halls_data_ecoll(iqq-1,0)
331 +
q * Halls_data_ecoll(iqq ,0);
334 c_rate *= (
PI*sumr*sumr);
337 if (a_vel_type == SDKernelRelativeVelocityType::radial_velocity) {
339 for (
int d = 0; d < SPACEDIM; d++) {
340 const RT ddv = a_v1[d]-a_v2[d];
341 const RT ddx = a_x1[d]-a_x2[d];
347 dv = (dr > RT(0)) ? std::abs(dv) / std::sqrt(dr) : std::sqrt(dv2);
349 for (
int d = 0; d < SPACEDIM; d++) {
350 dv += (a_v1[d]-a_v2[d])*(a_v1[d]-a_v2[d]);
373 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
374 RT Brownian_SeinfeldPandis (
const RT a_r1,
379 const RT a_temperature )
const noexcept
382 RT diameter_1 = 2*a_r1;
383 RT diameter_2 = 2*a_r2;
385 RT p_crs = a_pressure;
386 RT t_crs = a_temperature;
389 RT T_degC = t_crs - RT(273.15);
390 RT vis_crs = RT(0.0);
391 if( T_degC >= RT(0.0) ) {
392 vis_crs = ( RT(1.7180) + RT(4.9E-3)*T_degC ) * RT(1.E-5);
394 vis_crs = ( RT(1.7180) + RT(4.9E-3)*T_degC -RT(1.2E-5)*T_degC*T_degC ) * RT(1.E-5);
404 dtmp = RT(1.2570) + RT(0.40) * exp(-RT(0.550)*diameter_1/lambda_crs);
405 RT slip_corr_1 = RT(1.0) + (RT(2.0)*lambda_crs*dtmp)/(diameter_1);
406 dtmp = RT(1.2570) + RT(0.40) * exp(-RT(0.550)*diameter_2/lambda_crs);
407 RT slip_corr_2 = RT(1.0) + (RT(2.0)*lambda_crs*dtmp)/(diameter_2);
410 dtmp = (
boltz*t_crs)/(RT(3.0)*
PI*vis_crs);
411 RT diff_term_1 = dtmp * (slip_corr_1/diameter_1);
412 RT diff_term_2 = dtmp * (slip_corr_2/diameter_2);
415 dtmp = (RT(8.0)*
boltz*t_crs)/
PI;
416 RT vel_term_1 = std::sqrt(dtmp/a_mass_1);
417 RT vel_term_2 = std::sqrt(dtmp/a_mass_2);
421 RT lambda_1 = dtmp * (diff_term_1/vel_term_1);
422 RT lambda_2 = dtmp * (diff_term_2/vel_term_2);
425 RT d1l1_sq = diameter_1*diameter_1+lambda_1*lambda_1;
426 dtmp = (diameter_1+lambda_1)*(diameter_1+lambda_1)*(diameter_1+lambda_1)
427 - d1l1_sq*std::sqrt(d1l1_sq);
428 RT length_term_1 = dtmp/(RT(3.0)*diameter_1*lambda_1) - diameter_1;
429 RT d2l2_sq = diameter_2*diameter_2+lambda_2*lambda_2;
430 dtmp = (diameter_2+lambda_2)*(diameter_2+lambda_2)*(diameter_2+lambda_2)
431 - d2l2_sq*std::sqrt(d2l2_sq);
432 RT length_term_2 = dtmp/(RT(3.0)*diameter_2*lambda_2) - diameter_2;
435 RT sumdia = diameter_1 + diameter_2;
436 RT sumd = diff_term_1 + diff_term_2;
437 RT sumc = std::sqrt( vel_term_1*vel_term_1 + vel_term_2*vel_term_2 );
438 RT sumg = std::sqrt( RT(2.0)*length_term_1*length_term_1 + RT(2.0)*length_term_2*length_term_2 );
440 dtmp = sumdia/(sumdia+RT(2.0)*sumg) + (RT(8.0)*sumd)/(sumdia*sumc);
441 RT k12 = RT(2.0)*
PI * sumdia*sumd/dtmp;
463 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
464 RT BeardGrover1974 (
const RT a_sr,
466 const RT a_Fr )
const noexcept
469 const RT A0 = -RT(0.1007);
470 const RT A1 = -RT(0.358);
471 const RT A2 = RT(0.0261);
472 const RT B0 = RT(0.1465);
473 const RT B1 = RT(1.302);
474 const RT B2 = -RT(0.607);
475 const RT B3 = RT(0.293);
478 if ( a_Re > RT(400.0)) {
481 auto F = std::log(a_Re);
482 auto G = A0 + A1*F + A2*F*F;
486 auto z = std::log(a_Fr/K0);
487 auto H = std::max(B0 + B1*
z + B2*
z*
z + B3*
z*
z*
z,RT(0.0));
488 auto yc0 = (RT(2.0)/
PI)*std::atan(
H);
490 auto retval = (yc0+a_sr)*(yc0+a_sr) / ((RT(1.0)+a_sr)*(RT(1.0)+a_sr));
508 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
509 RT ErfaniMitchell2017_Plate (
const RT a_Re,
510 const RT a_Fr )
const noexcept
512 if (a_Re < RT(1.0)) {
516 auto Re_l = std::min(a_Re,RT(120.0));
517 auto Fr_l = std::min(a_Fr,RT(35.0));
518 auto Re_l_2 = Re_l*Re_l;
519 auto Re_l_3 = Re_l_2*Re_l;
520 auto Re_l_4 = Re_l_2*Re_l_2;
521 auto Re_l_5 = Re_l_4*Re_l;
522 auto K_t = -RT(5.07e-10)*Re_l_5
530 if (Re_l <= RT(10.0)) { K_c = RT(1.250) * std::pow(Re_l, RT(-0.350)); }
531 else if (Re_l <= RT(40.0)) { K_c = RT(1.072) * std::pow(Re_l, RT(-0.301)); }
532 else if (Re_l <= RT(120.0)) { K_c = RT(0.356) * std::pow(Re_l, RT(-0.003)); }
534 auto retval = RT(0.0);
535 if (Fr_l <= RT(0.35)) {
536 retval = RT(0.787) * std::pow(Fr_l, RT(0.988)) * std::max(RT(0.263)*std::log(Re_l)-RT(0.264), RT(0.0));
537 }
else if(Fr_l <= K_t) {
538 retval = (RT(0.7475)*std::log10(Fr_l)+RT(0.620)) * std::max(RT(0.263)*std::log(Re_l)-RT(0.264), RT(0.0));
540 auto E_1 = (RT(0.7475)*std::log10(K_t)+RT(0.620)) * std::max(RT(0.263)*std::log(Re_l)-RT(0.264), RT(0.0));
541 auto E_2 = std::sqrt( std::max(RT(1.0) - RT(0.2)*(std::log10(Fr_l/K_c)-std::sqrt(RT(5.0)))
542 *(std::log10(Fr_l/K_c)-std::sqrt(RT(5.0))),
544 retval = std::max(E_1,E_2);
564 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
565 RT ErfaniMitchell2017_Column (
const RT a_Re,
566 const RT a_Fr )
const noexcept
568 if (a_Re < RT(0.2)) {
572 auto Re_l = std::min(a_Re,RT(20.0));
573 auto Fr_l = std::min(a_Fr,RT(20.0));
576 if (Re_l <= RT(2.0)) {
577 K_t = RT(0.0251)*Re_l*Re_l
581 K_t = -RT(0.0003)*Re_l*Re_l*Re_l
582 +RT(0.0124)*Re_l*Re_l
587 auto para_r = RT(0.0), K_c = RT(0.0);
588 if (Re_l <= RT(1.7)) {
589 para_r = RT(0.7422) * std::pow(Re_l, RT(0.2111));
590 K_c = RT(0.7797) * std::pow(Re_l, RT(-0.009));
592 para_r = RT(0.8025) * std::pow(Re_l, RT(0.0604));
593 K_c = RT(1.0916) * std::pow(Re_l, RT(-0.635));
596 auto retval = RT(0.0);
598 if (Re_l <= RT(3.0)) {
599 retval= RT(0.787) * std::pow(Fr_l, RT(0.988)) * (-RT(0.0121)*Re_l*Re_l + RT(0.1297)*Re_l + RT(0.0598));
601 retval = RT(0.787) * std::pow(Fr_l, RT(0.988)) * (-RT(0.0005)*Re_l*Re_l + RT(0.1028)*Re_l + RT(0.0359));
604 auto tmp = std::log10(Fr_l/K_c)-std::sqrt(RT(3.5));
605 retval = para_r * std::sqrt( std::max(RT(1.0)-
tmp*
tmp/RT(3.5), RT(0.0)) );
constexpr amrex::Real two
Definition: ERF_Constants.H:10
constexpr amrex::Real avogadro
Definition: ERF_Constants.H:106
constexpr amrex::Real fourth
Definition: ERF_Constants.H:14
constexpr amrex::Real mwdair
Definition: ERF_Constants.H:107
constexpr amrex::Real boltz
Definition: ERF_Constants.H:105
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.
Real H
Definition: ERF_InitCustomPert_MovingTerrain.H:7
@ qv
Definition: ERF_Kessler.H:30
@ q
Definition: ERF_WSM6.H:184
@ p
Definition: ERF_WSM6.H:191
@ tmp
Definition: ERF_AdvanceWSM6.cpp:114