PLUME-MoM-TSM  1.0
VolcanicPlumeModel
particles.f90
Go to the documentation of this file.
1 !********************************************************************************
3 !
10 !********************************************************************************
12  !
13  USE moments_module, ONLY : n_mom , n_nodes , n_sections
14 
16 
17  USE variables, ONLY : k_b
18  USE variables, ONLY : wp
19 
20  IMPLICIT NONE
21 
23  INTEGER :: n_part
24 
26  REAL(wp), ALLOCATABLE, DIMENSION(:) :: solid_partial_mass_fraction
27 
29  REAL(wp), ALLOCATABLE, DIMENSION(:) :: solid_partial_mass_fraction0
30 
32  REAL(wp), ALLOCATABLE, DIMENSION(:) :: solid_partial_volume_fraction
33 
35  REAL(wp), ALLOCATABLE, DIMENSION(:) :: solid_mass_fraction
36 
38  REAL(wp), ALLOCATABLE, DIMENSION(:) :: solid_mass_fraction0
39 
41  REAL(wp), ALLOCATABLE, DIMENSION(:) :: solid_volume_fraction
42 
44  REAL(wp), ALLOCATABLE, DIMENSION(:,:) :: bin_partial_mass_fraction
45 
47  REAL(wp), ALLOCATABLE, DIMENSION(:,:) :: particle_loss_rate
48 
50  REAL(wp), ALLOCATABLE, DIMENSION(:,:) :: cum_particle_loss_rate
51 
53  REAL(wp), ALLOCATABLE, DIMENSION(:,:,:) :: mom
54 
56  REAL(wp), ALLOCATABLE, DIMENSION(:,:,:) :: mom0
57 
59  REAL(wp), ALLOCATABLE, DIMENSION(:,:,:) :: set_mom
60 
62  REAL(wp), ALLOCATABLE, DIMENSION(:,:,:) :: set_cp_mom
63 
65  REAL(wp), ALLOCATABLE, DIMENSION(:,:,:) :: birth_mom
66 
68  REAL(wp), ALLOCATABLE, DIMENSION(:,:,:) :: death_mom
69 
71  REAL(wp), ALLOCATABLE :: shape_factor(:)
72 
74  REAL(wp), ALLOCATABLE :: phi1(:)
75 
77  REAL(wp), ALLOCATABLE :: rho1(:)
78 
80  REAL(wp), ALLOCATABLE :: shape1(:)
81 
83  REAL(wp), ALLOCATABLE :: phi2(:)
84 
86  REAL(wp), ALLOCATABLE :: rho2(:)
87 
89  REAL(wp), ALLOCATABLE :: shape2(:)
90 
92  REAL(wp), ALLOCATABLE :: cp_part(:)
93 
95  REAL(wp) :: cpsolid
96 
97 
98  REAL(wp) :: particles_beta0
99 
104  CHARACTER*10 :: settling_model
105 
110  CHARACTER(LEN=20) :: distribution
111 
115  LOGICAL, ALLOCATABLE :: aggregation_array(:)
116 
118  REAL(wp), ALLOCATABLE :: aggregate_porosity(:)
119 
125  CHARACTER(LEN=20) :: aggregation_model
126 
128  INTEGER, ALLOCATABLE :: aggr_idx(:)
129 
131  REAL(wp), ALLOCATABLE, DIMENSION(:,:,:) :: m_quad
132 
134  REAL(wp), ALLOCATABLE, DIMENSION(:,:,:) :: w_quad
135 
137  REAL(wp), ALLOCATABLE, DIMENSION(:,:,:) :: phi_quad
138 
140  REAL(wp), ALLOCATABLE, DIMENSION(:,:,:) :: diam_quad
141 
143  REAL(wp), ALLOCATABLE, DIMENSION(:,:,:) :: vol_quad
144 
146  REAL(wp), ALLOCATABLE, DIMENSION(:,:,:) :: rho_quad
147 
149  REAL(wp), ALLOCATABLE, DIMENSION(:,:,:) :: shape_quad
150 
152  REAL(wp), ALLOCATABLE, DIMENSION(:,:,:) :: set_vel_quad
153 
155  REAL(wp), ALLOCATABLE, DIMENSION(:,:,:) :: cp_quad
156 
158  REAL(wp), ALLOCATABLE, DIMENSION(:,:,:) :: f_quad
159 
161  REAL(wp) :: t_part
162 
164  REAL(wp), ALLOCATABLE, DIMENSION(:) :: phil
165 
167  REAL(wp), ALLOCATABLE, DIMENSION(:) :: phir
168 
170  REAL(wp), ALLOCATABLE, DIMENSION(:,:) :: m
171 
173  LOGICAL, ALLOCATABLE, DIMENSION(:,:,:,:,:) :: q_flag
174 
176  REAL(wp), ALLOCATABLE, DIMENSION(:,:,:,:,:,:) :: kernel_aggr
177 
178  REAL(wp),ALLOCATABLE, DIMENSION(:,:,:,:,:,:,:) :: a
179 
180  REAL(wp),ALLOCATABLE, DIMENSION(:,:,:,:,:,:,:) :: wij
181 
182  SAVE
183 
184 CONTAINS
185 
186  !******************************************************************************
188  !
195  !******************************************************************************
196 
197  SUBROUTINE allocate_particles
199  use, intrinsic :: iso_fortran_env
200  use, intrinsic :: ieee_arithmetic
201 
202  IMPLICIT NONE
203 
204  REAL(wp) :: notSet
205 
206  notset = ieee_value(0.0_wp, ieee_quiet_nan)
207 
208  ALLOCATE ( solid_partial_mass_fraction(1:n_part) )
209  ALLOCATE ( solid_partial_mass_fraction0(1:n_part) )
210  ALLOCATE ( solid_partial_volume_fraction(1:n_part) )
211  ALLOCATE ( solid_mass_fraction(1:n_part) )
212  ALLOCATE ( solid_mass_fraction0(1:n_part) )
213  ALLOCATE ( solid_volume_fraction(1:n_part) )
214 
216 
217  ALLOCATE ( particle_loss_rate(1:n_part,1:n_sections) )
218  ALLOCATE ( cum_particle_loss_rate(1:n_part,1:n_sections) )
219 
220  ! Allocation of the arrays for the moments
221  ALLOCATE ( mom0(0:n_mom-1,1:n_sections,1:n_part) )
222  ALLOCATE ( mom(0:n_mom-1,1:n_sections,1:n_part) )
223  ALLOCATE ( set_mom(0:n_mom-1,1:n_sections,1:n_part) )
224  ALLOCATE ( set_cp_mom(0:n_mom-1,1:n_sections,1:n_part) )
225  ALLOCATE ( birth_mom(0:n_mom-1,1:n_sections,1:n_part) )
226  ALLOCATE ( death_mom(0:n_mom-1,1:n_sections,1:n_part) )
227 
228  ! Allocation of the parameters for the variable density
229  ALLOCATE ( shape_factor(n_part) )
230  ALLOCATE ( phi1(n_part) )
231  ALLOCATE ( rho1(n_part) )
232  ALLOCATE ( shape1(n_part) )
233  ALLOCATE ( phi2(n_part) )
234  ALLOCATE ( rho2(n_part) )
235  ALLOCATE ( shape2(n_part) )
236 
237  ALLOCATE ( cp_part(n_part) )
238 
239  phi1(1:n_part) = notset
240  phi2(1:n_part) = notset
241 
242  shape_factor(1:n_part) = notset
243  shape1(1:n_part) = notset
244  shape2(1:n_part) = notset
245 
246  !Allocation of arrays for quadrature variables
247  ALLOCATE ( m_quad(n_nodes,n_sections,n_part) )
248  ALLOCATE ( w_quad(n_nodes,n_sections,n_part) )
249  ALLOCATE ( f_quad(n_nodes,n_sections,n_part) )
250 
251  ALLOCATE ( phi_quad(n_nodes,n_sections,n_part) )
252  ALLOCATE ( diam_quad(n_nodes,n_sections,n_part) )
253  ALLOCATE ( vol_quad(n_nodes,n_sections,n_part) )
254  ALLOCATE ( rho_quad(n_nodes,n_sections,n_part) )
255  ALLOCATE ( shape_quad(n_nodes,n_sections,n_part) )
256  ALLOCATE ( set_vel_quad(n_nodes,n_sections,n_part) )
257 
258  ! Allocation of arrays for aggregation
259  ALLOCATE ( aggregation_array(n_part) )
260  ALLOCATE ( aggregate_porosity(n_part) )
261  ALLOCATE ( aggr_idx(n_part) )
262 
263  ALLOCATE ( cp_quad(n_nodes,n_sections,n_part) )
264 
265  ALLOCATE ( phil(1:n_sections) , phir(1:n_sections) )
266 
267  ALLOCATE ( m(1:n_sections+1,1:n_part) )
268 
270 
272 
274 
276  n_part) )
277 
278 
279  END SUBROUTINE allocate_particles
280 
281  SUBROUTINE deallocate_particles
283  IMPLICIT NONE
284 
285  DEALLOCATE ( solid_partial_mass_fraction )
286  DEALLOCATE ( solid_partial_mass_fraction0 )
287  DEALLOCATE ( solid_partial_volume_fraction )
288  DEALLOCATE ( solid_mass_fraction )
289  DEALLOCATE ( solid_mass_fraction0 )
290  DEALLOCATE ( solid_volume_fraction )
291 
292  DEALLOCATE ( bin_partial_mass_fraction )
293 
295 
296  ! Allocation of the arrays for the moments
297  DEALLOCATE ( mom0 )
298  DEALLOCATE ( mom )
299  DEALLOCATE ( set_mom )
300  DEALLOCATE ( set_cp_mom )
301  DEALLOCATE ( birth_mom )
302  DEALLOCATE ( death_mom )
303 
304  ! Allocation of the parameters for the variable density
305  DEALLOCATE ( shape_factor )
306  DEALLOCATE ( phi1 )
307  DEALLOCATE ( rho1 )
308  DEALLOCATE ( shape1 )
309  DEALLOCATE ( phi2 )
310  DEALLOCATE ( rho2 )
311  DEALLOCATE ( shape2 )
312 
313  DEALLOCATE ( cp_part )
314 
315  DEALLOCATE ( m_quad )
316  DEALLOCATE ( w_quad )
317  DEALLOCATE ( f_quad )
318  DEALLOCATE ( cp_quad )
319 
320  DEALLOCATE ( set_vel_quad )
321 
322  ! Allocation of arrays for aggregation
323  DEALLOCATE ( aggregation_array )
324  DEALLOCATE ( aggregate_porosity )
325  DEALLOCATE ( aggr_idx )
326 
327  DEALLOCATE ( phil , phir )
328 
329  DEALLOCATE ( m)
330 
331  DEALLOCATE ( q_flag )
332  DEALLOCATE ( kernel_aggr )
333 
334  DEALLOCATE ( a )
335  DEALLOCATE ( wij )
336 
337  END SUBROUTINE deallocate_particles
338 
339  !******************************************************************************
341  !
352  !******************************************************************************
353 
354  FUNCTION particles_settling_velocity(diam,rhop,shape_fact)
355  !
356  USE meteo_module, ONLY : rho_atm , rho_atm0 , visc_atm
357 
358  USE variables, ONLY : gi , pi_g , verbose_level
359 
360  IMPLICIT NONE
361 
362  REAL(wp) :: particles_settling_velocity
363 
364  REAL(wp), INTENT(IN) :: diam
365  REAL(wp), INTENT(IN) :: rhop
366  REAL(wp), INTENT(IN) :: shape_fact
367 
368  REAL(wp) :: k1 , k2 , k3
369  REAL(wp) :: CD , CD1 , CD2
370 
371  REAL(wp) :: Reynolds , Reynoldsk1k2
372  REAL(wp) :: Vinit , Vg_Ganser
373 
374  INTEGER :: i
375 
377  REAL(wp) :: A_cs
378 
380  REAL(wp) :: Cd_100 , Cd_1000
381 
383  REAL(wp) :: Cd_interp
384 
386  REAL(wp) :: Us_100 , Us_1000
387 
389  REAL(wp) :: mass
390 
392  REAL(wp) :: Us , Us_1 ,Us_2
393 
395  REAL(wp) :: Rey1 , Rey2
396 
398  REAL(wp) :: c0 , c1 , c2
399 
401  REAL(wp) :: sqrt_delta
402 
403  IF ( settling_model .EQ. 'textor' ) THEN
404 
405  ! Textor et al. 2006
406 
407  IF ( diam .LE. 1.e-4_wp ) THEN
408 
409  k1 = 1.19d5 ! (m^2 kg^-1 s^-1 )
410 
411  particles_settling_velocity = k1 * rhop * sqrt( rho_atm0 / rho_atm ) &
412  * ( 0.5_wp * diam )**2
413 
414  ELSEIF ( diam .LE. 1.e-3_wp ) THEN
415 
416  k2 = 8.0_wp ! (m^3 kg^-1 s^-1 )
417 
418  particles_settling_velocity = k2 * rhop * sqrt( rho_atm0 / rho_atm ) &
419  * ( 0.5_wp * diam )
420 
421  ELSE
422 
423  k3 = 4.833_wp ! (m^2 kg^-0.5 s^-1 )
424  cd = 0.75_wp
425 
426  particles_settling_velocity = k3 * sqrt( rhop / cd ) &
427  * sqrt( rho_atm0 / rho_atm ) * sqrt( 0.5_wp * diam )
428 
429  END IF
430 
431  ELSEIF ( settling_model .EQ. 'ganser' ) THEN
432 
433  vinit = diam**2 * gi * ( rhop - rho_atm ) / (18.0_wp*visc_atm)
434 
435  DO i=1,10
436 
437  IF (i.EQ.1) reynolds = rho_atm * vinit * diam / visc_atm
438 
439  k1 = 3.0_wp / (1.0_wp + 2.0_wp * ( shape_fact**(-0.5_wp)))
440 
441  k2 = 10.0_wp**(1.8148_wp * ((-1.0_wp*log10(shape_fact))**0.5743_wp))
442 
443  reynoldsk1k2 = reynolds * k1 * k2
444 
445  cd1 = k2 * 24.0_wp / reynoldsk1k2 * &
446  ( 1.0_wp + 0.1118_wp * reynoldsk1k2**0.6567_wp )
447 
448  cd2 = 0.4305_wp * k2 / ( 1.0_wp + 3305.0_wp / reynoldsk1k2 )
449 
450  cd = cd1 + cd2
451 
452  vg_ganser = ( ( 4.0_wp * gi * diam * ( rhop - rho_atm ) ) &
453  / ( 3.0_wp * cd * rho_atm) )**0.5_wp
454 
455  reynolds = rho_atm * vg_ganser * diam / visc_atm
456 
457  ENDDO
458 
459  particles_settling_velocity = vg_ganser
460 
461  IF ( vg_ganser .LE. 0.0_wp ) THEN
462 
463  WRITE(*,*) 'diam',diam
464  WRITE(*,*) 'NEGATIVE VALUE', vinit,vg_ganser
465  READ(*,*)
466 
467  END IF
468 
469  ELSEIF ( settling_model .EQ. 'pfeiffer' ) THEN
470 
471  k1 = shape_fact**(-0.828_wp)
472  k2 = 2.0_wp * sqrt( 1.07_wp - shape_fact )
473 
474  mass = rhop * 4.0_wp/3.0_wp * pi_g * ( 0.5_wp * diam )**3
475 
476  a_cs = pi_g * ( 0.5_wp * diam )**2
477 
478  c0 = -2.0_wp * diam * mass * gi
479  c1 = 24.0_wp * visc_atm * k1 * a_cs
480  c2 = rho_atm * diam * k2 * a_cs
481 
482  sqrt_delta = sqrt( c1**2 - 4.0_wp * c0*c2 )
483 
484  us_1 = ( - c1 + sqrt_delta ) / ( 2.0_wp * c2 )
485  us_2 = ( - c1 - sqrt_delta ) / ( 2.0_wp * c2 )
486 
487 
488  cd_100 = 24.0_wp/100.0_wp * k1 + k2
489  us_100 = sqrt( 2.0_wp * mass * gi / ( cd_100*rho_atm * a_cs ) )
490 
491  cd_1000 = 1.0_wp
492  us_1000 = sqrt( 2.0_wp * mass * gi / ( cd_1000*rho_atm * a_cs ) )
493 
494  rey1 = rho_atm * diam * us_1 / visc_atm
495  rey2 = rho_atm * diam * us_2 / visc_atm
496 
497  IF ( verbose_level .GE. 4 ) THEN
498 
499  WRITE(*,*) 'rho_atm , diam , Us_1 , visc_atm',rho_atm , diam , us_1 , &
500  visc_atm
501  WRITE(*,*) 'Rey1,Rey2',rey1,rey2
502  READ(*,*)
503 
504  END IF
505 
506  ! Initialization only
507  us = us_1000
508 
509  IF ( ( rey1 .GT. 0.0_wp ) .AND. ( rey1 .LE. 100.0_wp ) ) THEN
510 
511  ! For small Reynolds numbers the drag coefficient is given by Eq.8
512  ! of Pfeiffer et al. 2005 and the settling velocity is Us_1
513 
514  us = us_1
515 
516  ELSEIF ( ( rey1 .GT. 100.0_wp ) .AND. ( rey1 .LE. 1000.0_wp ) ) THEN
517 
518  ! For intermediate Reyonlds numbers, 100<Re<1000, the drag coefficient
519  ! is linearly interpolated between Cd_100 and Cd_1000
520 
521  cd_interp = cd_100 + ( rey1 - 100.0_wp ) / ( 1000.0_wp - 100.0_wp ) * &
522  ( cd_1000 - cd_100)
523  us = sqrt( 2.0_wp * mass * gi / ( cd_interp * rho_atm * a_cs ) )
524 
525  ELSEIF ( rey1 .GT. 1000.0_wp ) THEN
526 
527  ! For large Reynolds numbers the drag coefficient is taken as Cd=1,
528  ! as in Pfeiffer et al. 2005 with the settling velocity is Us_1000
529 
530  us = us_1000
531 
532  END IF
533 
534  IF ( ( rey2 .GT. 0.0_wp ) .AND. ( rey2 .LE. 100.0_wp ) ) THEN
535 
536  us = us_2
537 
538  ELSEIF ( ( rey2 .GT. 100.0_wp ) .AND. ( rey2 .LE. 1000.0_wp ) ) THEN
539 
540  cd_interp = cd_100 + ( rey2 - 100.0_wp ) / ( 1000.0_wp - 100.0_wp ) &
541  * ( cd_1000 - cd_100 )
542 
543  us = sqrt( 2.0_wp * mass * gi / ( cd_interp * rho_atm * a_cs ) )
544 
545  ELSEIF ( rey2 .GT. 1000.0_wp ) THEN
546 
547  us = us_1000
548 
549  END IF
550 
551  particles_settling_velocity = us
552 
553  ELSE
554 
555  WRITE(*,*) 'wrong settling model'
556  stop
557 
558  END IF
559 
560  !WRITE(*,*) 'diam',diam
561  !WRITE(*,*) 'rhop',rhop
562  !WRITE(*,*) 'shape factor',shape_fact
563  !WRITE(*,*) 'particles_settling_velocit',particles_settling_velocity
564  !READ(*,*)
565 
566  RETURN
567 
568  END FUNCTION particles_settling_velocity
569 
570  !******************************************************************************
572  !
580  !******************************************************************************
581 
582  FUNCTION particles_heat_capacity(i_part,diam)
583  !
584  IMPLICIT NONE
585 
586  REAL(wp) :: particles_heat_capacity
587  INTEGER, INTENT(IN) :: i_part
588  REAL(wp), INTENT(IN) :: diam
589 
590  particles_heat_capacity = cp_part(i_part)
591 
592  END FUNCTION particles_heat_capacity
593 
594  !******************************************************************************
596  !
604  !******************************************************************************
605 
606  FUNCTION particles_density(i_part,phi)
607  !
608  IMPLICIT NONE
609 
610  REAL(wp) :: particles_density
611 
612  INTEGER, INTENT(IN) :: i_part
613  REAL(wp), INTENT(IN) :: phi
614 
615  REAL(wp) :: phi_temp,rho_temp
616 
617  IF ( phi1(i_part) .GT. phi2(i_part) ) THEN
618 
619  phi_temp = phi1(i_part)
620  rho_temp = rho1(i_part)
621 
622  phi1(i_part) = phi2(i_part)
623  rho1(i_part) = rho2(i_part)
624 
625  phi2(i_part) = phi_temp
626  rho2(i_part) = rho_temp
627 
628  END IF
629 
630  IF ( phi .LE. phi1(i_part) ) THEN
631 
632  particles_density = rho1(i_part)
633 
634  ELSEIF ( phi .LE. phi2(i_part) ) THEN
635 
636 
637  particles_density = rho1(i_part) + ( phi - phi1(i_part) ) / &
638  ( phi2(i_part) - phi1(i_part) ) * ( rho2(i_part) - rho1(i_part) )
639 
640  ELSE
641 
642  particles_density = rho2(i_part)
643 
644  END IF
645 
646  RETURN
647 
648  END FUNCTION particles_density
649 
650  !******************************************************************************
652  !
659  !******************************************************************************
660 
661  FUNCTION particles_shape(i_part,phi)
662  !
663  IMPLICIT NONE
664 
665  REAL(wp) :: particles_shape
666 
667  INTEGER, INTENT(IN) :: i_part
668  REAL(wp), INTENT(IN) :: phi
669 
670  REAL(wp) :: phi_temp,shape_temp
671 
672  IF ( phi1(i_part) .GT. phi2(i_part) ) THEN
673 
674  phi_temp = phi1(i_part)
675  shape_temp = shape1(i_part)
676 
677  phi1(i_part) = phi2(i_part)
678  shape1(i_part) = shape2(i_part)
679 
680  phi2(i_part) = phi_temp
681  shape2(i_part) = shape_temp
682 
683  END IF
684 
685  IF ( phi .LE. phi1(i_part) ) THEN
686 
687  particles_shape = shape1(i_part)
688 
689  ELSEIF ( phi .LE. phi2(i_part) ) THEN
690 
691 
692  particles_shape = shape1(i_part) + ( phi - phi1(i_part) ) / &
693  ( phi2(i_part) - phi1(i_part) ) * ( shape2(i_part) - shape1(i_part) )
694 
695  ELSE
696 
697  particles_shape = shape2(i_part)
698 
699  END IF
700 
701  RETURN
702 
703  END FUNCTION particles_shape
704 
705 
706  !******************************************************************************
708  !
727  !******************************************************************************
728 
729  FUNCTION particles_beta(temp,visc,diam_i,diam_j,rho_i,rho_j,Vs_i,Vs_j,lw_vf, &
730  ice_vf,solid_mf)
732  IMPLICIT NONE
733 
734  REAL(wp) :: particles_beta
735 
736  REAL(wp), INTENT(IN) :: temp
737  REAL(wp), INTENT(IN) :: visc
738  REAL(wp), INTENT(IN) :: diam_i
739  REAL(wp), INTENT(IN) :: diam_j
740  REAL(wp), INTENT(IN), OPTIONAL :: rho_i
741  REAL(wp), INTENT(IN), OPTIONAL :: rho_j
742  REAL(wp), INTENT(IN), OPTIONAL :: Vs_i
743  REAL(wp), INTENT(IN), OPTIONAL :: Vs_j
744  REAL(wp), INTENT(IN), OPTIONAL :: lw_vf
745  REAL(wp), INTENT(IN), OPTIONAL :: ice_vf
746  REAL(wp), INTENT(IN), OPTIONAL :: solid_mf
747 
748  SELECT CASE ( aggregation_model )
749 
750  CASE DEFAULT
751 
752  particles_beta = 0.0_wp
753 
754  CASE ( 'constant' )
755 
756  particles_beta = particles_beta0
757 
758  CASE ( 'brownian' )
759 
760  particles_beta = ( 2.0_wp * k_b * temp ) / ( 3.0_wp * visc ) * &
761  ( diam_i + diam_j ) ** 2 / ( diam_i * diam_j )
762 
763  CASE ( 'sum' )
764 
765  particles_beta = diam_i**3 + diam_j**3
766 
767  CASE ( 'costa')
768 
769  IF ( max(lw_vf,ice_vf) .LT. 1.0e-10_wp ) THEN
770 
771  particles_beta = 0.0_wp
772 
773  ELSE
774 
775  particles_beta = aggregation_kernel(diam_i,rho_i,vs_i,diam_j,rho_j,vs_j, &
776  lw_vf,ice_vf,solid_mf,temp,visc)
777 
778  END IF
779 
780  END SELECT
781 
782  IF ( verbose_level .GE. 2 ) THEN
783 
784  WRITE(*,*) 'beta =',particles_beta
785  WRITE(*,*)
786 
787  WRITE(*,fmt) ' ','END particles_beta'
788  indent_space = indent_space - 2
789  WRITE(fmt,*) indent_space
790  fmt = "(A" // trim(fmt) // ",A)"
791 
792  END IF
793 
794  RETURN
795 
796  END FUNCTION particles_beta
797 
798  !******************************************************************************
800  !
817  !******************************************************************************
818 
819  FUNCTION aggregation_kernel( diam_i , rho_i , Vs_i , diam_j , rho_j , Vs_j , &
820  lw_vf , ice_vf , solid_mf , temp , visc )
822  IMPLICIT NONE
823 
824  REAL(wp) :: aggregation_kernel
825 
826  REAL(wp), INTENT(IN) :: diam_i
827  REAL(wp), INTENT(IN) :: rho_i
828  REAL(wp), INTENT(IN) :: Vs_i
829  REAL(wp), INTENT(IN) :: diam_j
830  REAL(wp), INTENT(IN) :: rho_j
831  REAL(wp), INTENT(IN) :: Vs_j
832  REAL(wp), INTENT(IN) :: lw_vf
833  REAL(wp), INTENT(IN) :: ice_vf
834  REAL(wp), INTENT(IN) :: solid_mf
835  REAL(wp), INTENT(IN) :: temp
836  REAL(wp), INTENT(IN) :: visc
837 
838  REAL(wp) :: beta
839  REAL(wp) :: alfa
840 
841  IF ( verbose_level .GE. 2 ) THEN
842 
843  indent_space = indent_space + 2
844  WRITE(fmt,*) indent_space
845  fmt = "(A" // trim(fmt) // ",A)"
846  WRITE(*,fmt) ' ','BEGINNING aggregation_kernel'
847  READ(*,*)
848 
849  END IF
850 
851  !WRITE(*,*) 'aggregation_kernel: Vs_i,Vs_j',Vs_i,Vs_j
852 
853  beta = collision_kernel(diam_i,rho_i,vs_i,diam_j,rho_j,vs_j,temp,visc)
854 
855  alfa = coalescence_efficiency(diam_i,rho_i,vs_i,diam_j,rho_j,vs_j,lw_vf, &
856  ice_vf,solid_mf)
857 
858  aggregation_kernel = beta * alfa
859 
860  IF ( aggregation_kernel .GT. 0.0_wp ) THEN
861 
862  !WRITE(*,*) 'lw_vf,ice_vf',lw_vf,ice_vf
863  !WRITE(*,*) 'aggregation_kernel, beta, alfa',aggregation_kernel, beta, alfa
864  !READ(*,*)
865 
866  END IF
867 
868  IF ( verbose_level .GE. 2 ) THEN
869 
870  WRITE(*,fmt) ' ','END aggregation_kernel'
871  indent_space = indent_space - 2
872  WRITE(fmt,*) indent_space
873  fmt = "(A" // trim(fmt) // ",A)"
874 
875  END IF
876 
877  RETURN
878 
879  END FUNCTION aggregation_kernel
880 
881  !******************************************************************************
883  !
895  !******************************************************************************
896 
897  FUNCTION collision_kernel(diam_i,rho_i,Vs_i,diam_j,rho_j,Vs_j,temp,visc)
899  USE meteo_module, ONLY : visc_atm
900 
901  USE variables, ONLY: pi_g
902 
903  IMPLICIT NONE
904 
905  REAL(wp) :: collision_kernel
906 
907  REAL(wp),INTENT(IN) :: diam_i
908  REAL(wp),INTENT(IN) :: rho_i
909  REAL(wp),INTENT(IN) :: Vs_i
910  REAL(wp),INTENT(IN) :: diam_j
911  REAL(wp),INTENT(IN) :: rho_j
912  REAL(wp),INTENT(IN) :: Vs_j
913  REAL(wp),INTENT(IN) :: temp
914  REAL(wp),INTENT(IN) :: visc
915 
917  REAL(wp) :: beta_B
918 
920  REAL(wp) :: beta_S
921 
923  REAL(wp) :: beta_DS
924 
926  REAL(wp) :: E_coll
927 
929  REAL(wp) :: epsilon
930 
932  REAL(wp) :: Gamma_s
933 
934  !WRITE(*,*) 'collision_kernel'
935 
936  IF ( verbose_level .GE. 2 ) THEN
937 
938  indent_space = indent_space + 2
939  WRITE(fmt,*) indent_space
940  fmt = "(A" // trim(fmt) // ",A)"
941  WRITE(*,fmt) ' ','BEGINNING collision_kernel'
942  READ(*,*)
943 
944  END IF
945 
946  ! Eq. 3, first term Costa et al. JGR 2010
947  beta_b = 2.0_wp / 3.0_wp * k_b * temp / visc * ( diam_i + diam_j )**2 &
948  / ( diam_i*diam_j )
949 
950  ! Value from Table 1 (Costa 2010)
951  gamma_s = 0.0045_wp
952 
953  ! Eq. 3, second term Costa et al. JGR 2010
954  beta_s = 1.0_wp / 6.0_wp * gamma_s * ( diam_i + diam_j )**3
955 
956  ! Eq. 3, third term Costa et al. JGR 2010
957  beta_ds = pi_g / 4.0_wp * ( diam_i + diam_j )**2 * abs( vs_j - vs_i )
958 
959  ! WRITE(*,*) 'beta_B,beta_S,beta_DS',beta_B,beta_S, beta_DS
960 
961  collision_kernel = beta_b + beta_s + beta_ds
962 
963  IF ( verbose_level .GE. 2 ) THEN
964 
965  WRITE(*,fmt) ' ','END collision_kernel'
966  indent_space = indent_space - 2
967  WRITE(fmt,*) indent_space
968  fmt = "(A" // trim(fmt) // ",A)"
969 
970  END IF
971 
972  RETURN
973 
974  END FUNCTION collision_kernel
975 
976  !******************************************************************************
978  !
991  !******************************************************************************
992 
993  FUNCTION coalescence_efficiency(diam_i,rho_i,Vs_i,diam_j,rho_j,Vs_j,lw_vf, &
994  ice_vf,solid_mf)
996  USE variables, ONLY: gi
997 
998  IMPLICIT NONE
999 
1000  REAL(wp) :: coalescence_efficiency
1001 
1002  REAL(wp), INTENT(IN) :: diam_i
1003  REAL(wp), INTENT(IN) :: rho_i
1004  REAL(wp), INTENT(IN) :: Vs_i
1005  REAL(wp), INTENT(IN) :: diam_j
1006  REAL(wp), INTENT(IN) :: rho_j
1007  REAL(wp), INTENT(IN) :: Vs_j
1008  REAL(wp), INTENT(IN) :: lw_vf
1009  REAL(wp), INTENT(IN) :: ice_vf
1010  REAL(wp), INTENT(IN) :: solid_mf
1011 
1012  REAL(wp) :: coalescence_efficiency_ice , coalescence_efficiency_water
1013 
1015  REAL(wp) :: Stokes
1016 
1018  REAL(wp) :: Stokes_cr
1019 
1021  REAL(wp) :: q
1022 
1023  REAL(wp) :: mu_liq
1024 
1025  IF ( verbose_level .GE. 2 ) THEN
1026 
1027  indent_space = indent_space + 2
1028  WRITE(fmt,*) indent_space
1029  fmt = "(A" // trim(fmt) // ",A)"
1030  WRITE(*,fmt) ' ','BEGINNING coalescence_efficiency'
1031 
1032  END IF
1033 
1034  ! Modified from Eq. 5 Costa et al. JGR 2010
1035  coalescence_efficiency_ice = 0.09_wp * ice_vf
1036 
1037  mu_liq = 5.43e-4_wp
1038 
1039  ! Eq. 6 Costa et al. JGR 2010 (CHECK DENSITY!)
1040  stokes = 8.0_wp * ( 0.5_wp * ( rho_i + rho_j ) ) * abs( vs_i - vs_j ) / &
1041  ( 9.0_wp * mu_liq ) * diam_i * diam_j / ( diam_i + diam_j )
1042 
1043  stokes_cr = 1.3_wp
1044 
1045  q = 0.8_wp
1046 
1047  ! Modified from Eq. 8 Costa et al. JGR 2010
1048  coalescence_efficiency_water = 1.0_wp / ( 1.0_wp+( stokes/stokes_cr ) )**q &
1049  * lw_vf
1050 
1051  IF ( lw_vf .GT. 0.0_wp ) THEN
1052 
1053  IF ( ice_vf .GT. 0.0_wp ) THEN
1054 
1055  coalescence_efficiency = coalescence_efficiency_water &
1056  + coalescence_efficiency_ice
1057 
1058  ELSE
1059 
1060  coalescence_efficiency = coalescence_efficiency_water
1061 
1062  END IF
1063 
1064  ELSEIF ( ice_vf .GT. 0.0_wp ) THEN
1065 
1066  coalescence_efficiency = coalescence_efficiency_ice
1067 
1068  ELSE
1069 
1070  coalescence_efficiency = 0.0_wp
1071 
1072  END IF
1073 
1074 
1075  IF ( verbose_level .GE. 2 ) THEN
1076 
1077  WRITE(*,fmt) ' ','END coalescence_efficiency'
1078  indent_space = indent_space - 2
1079  WRITE(fmt,*) indent_space
1080  fmt = "(A" // trim(fmt) // ",A)"
1081 
1082  END IF
1083 
1084  RETURN
1085 
1086  END FUNCTION coalescence_efficiency
1087 
1088 
1089  !******************************************************************************
1091  !
1097  !******************************************************************************
1098 
1099  SUBROUTINE eval_particles_moments
1101  ! external variables
1102  USE variables, ONLY : verbose_level
1103 
1104  IMPLICIT NONE
1105 
1106  INTEGER :: i_part , j_part
1107  INTEGER :: i_sect , j_sect , k_sect
1108 
1109  INTEGER :: i_mom
1110  INTEGER :: i_node , j_node
1111 
1112  DO i_part=1,n_part
1113 
1114  DO i_sect=1,n_sections
1115 
1116  DO i_node=1,n_nodes
1117 
1118  ! Settling velocities at the quadrature points
1119  set_vel_quad(i_node,i_sect,i_part) = &
1120  particles_settling_velocity( diam_quad(i_node,i_sect,i_part), &
1121  rho_quad(i_node,i_sect,i_part) , &
1122  shape_quad(i_node,i_sect,i_part) )
1123 
1124  END DO
1125 
1126  DO i_mom=0,n_mom-1
1127 
1128  IF ( mom(1,i_sect,i_part) .GT. 0.0_wp ) THEN
1129 
1130  set_mom(i_mom,i_sect,i_part) = sum( set_vel_quad(:,i_sect,i_part) &
1131  * f_quad(:,i_sect,i_part) * w_quad(:,i_sect,i_part) &
1132  * m_quad(:,i_sect,i_part)**i_mom ) / mom(i_mom,i_sect,i_part)
1133 
1134  set_cp_mom(i_mom,i_sect,i_part) = &
1135  sum( set_vel_quad(:,i_sect,i_part ) &
1136  * cp_quad(:,i_sect,i_part) * f_quad(:,i_sect,i_part) &
1137  * w_quad(:,i_sect,i_part) * m_quad(:,i_sect,i_part)**i_mom ) &
1138  / mom(i_mom,i_sect,i_part)
1139 
1140  ELSE
1141 
1142  set_mom(i_mom,i_sect,i_part) = 0.0_wp
1143 
1144  set_cp_mom(i_mom,i_sect,i_part) = 0.0_wp
1145 
1146  END IF
1147 
1148  IF ( verbose_level .GE. 2 ) THEN
1149 
1150  WRITE(*,*) 'i_part,i_mom',i_part,i_mom
1151  WRITE(*,*) 'abscissas', m_quad(1:n_nodes,i_sect,i_part)
1152  WRITE(*,*) 'set_mom(i_mom,i_sect,i_part) = ' , &
1153  set_mom(i_mom,i_sect,i_part)
1154 
1155  END IF
1156 
1157  END DO
1158 
1159  END DO
1160 
1161  END DO
1162 
1163  RETURN
1164 
1165  END SUBROUTINE eval_particles_moments
1166 
1167  !******************************************************************************
1169  !
1176  !******************************************************************************
1177 
1178  SUBROUTINE eval_quad_values
1181 
1182  IMPLICIT NONE
1183 
1184  INTEGER :: i_part , i_sect
1185  REAL(wp) :: coeff_lin(4)
1186  REAL(wp) :: Mai , Mbi
1187  REAL(wp) :: alfai , betai,gamma1,gamma2
1188 
1189  REAL(wp) :: Ml , Mr
1190 
1191  INTEGER :: condition1(n_nodes) , condition2(n_nodes)
1192 
1193  DO i_part=1,n_part
1194 
1195  DO i_sect = 1,n_sections
1196 
1197  ml = m(i_sect,i_part)
1198  mr = m(i_sect+1,i_part)
1199 
1200  CALL linear_reconstruction( ml,mr,mom(:,i_sect,i_part), mai , mbi , &
1201  alfai , betai , gamma1 , gamma2 )
1202 
1203  f_quad(:,i_sect,i_part) = alfai * ( ( mr - m_quad(:,i_sect,i_part) ) &
1204  / ( mr - ml ) )**gamma1 + ( betai - alfai ) &
1205  * ( ( m_quad(:,i_sect,i_part) - ml ) / ( mr - ml ) )**gamma2
1206 
1207  END DO
1208 
1209  END DO
1210 
1211  RETURN
1212 
1213  END SUBROUTINE eval_quad_values
1214 
1215  !******************************************************************************
1217  !
1224  !******************************************************************************
1225 
1226  SUBROUTINE init_quadrature_points
1228  USE moments_module, ONLY : gaulegf
1229 
1230  IMPLICIT NONE
1231 
1232  REAL(wp) :: x(n_nodes) , w(n_nodes)
1233 
1234  INTEGER :: i_part , i_sect
1235 
1236  REAL(wp) :: Ml , Mr
1237 
1238  ! Compute the quadrature abscissas and weights on the interval [-1;1]
1239  CALL gaulegf(-1.0_wp, 1.0_wp, x, w, n_nodes)
1240 
1241  IF ( verbose_level .GE. 1 ) THEN
1242 
1243  WRITE(*,*) 'original quadrature points in [-1;1]'
1244  WRITE(*,*) x
1245  WRITE(*,*) w
1246  READ(*,*)
1247 
1248  END IF
1249 
1250  DO i_part=1,n_part
1251 
1252  DO i_sect=1,n_sections
1253 
1254  ml = m(i_sect,i_part)
1255  mr = m(i_sect+1,i_part)
1256 
1257  ! https://en.wikipedia.org/wiki/Gaussian_quadrature#Change_of_interval
1258  m_quad(:,i_sect,i_part) = 0.5_wp * ( ( mr - ml ) * x + ( mr + ml ) )
1259  w_quad(:,i_sect,i_part) = 0.5_wp * ( mr - ml ) * w
1260 
1261  IF ( verbose_level .GE. 1 ) THEN
1262 
1263  WRITE(*,*) 'i_part,i_sect',i_part,i_sect
1264  WRITE(*,*) 'Ml,Mr',ml,mr
1265  WRITE(*,"(100ES12.4)") m_quad(:,i_sect,i_part)
1266  WRITE(*,"(100ES12.3)") w_quad(:,i_sect,i_part)
1267  READ(*,*)
1268 
1269  END IF
1270 
1271  END DO
1272 
1273  END DO
1274 
1275  END SUBROUTINE init_quadrature_points
1276 
1277  !******************************************************************************
1279  !
1288  !******************************************************************************
1289 
1290  SUBROUTINE phifromm
1292  IMPLICIT NONE
1293 
1294  REAL(wp) :: diam1 , diam2
1295  REAL(wp) :: Vol1 , Vol2
1296  REAL(wp) :: M1 , M2
1297  REAL(wp) :: Vol(n_nodes,n_sections)
1298  REAL(wp) :: f1(n_nodes,n_sections) , f2(n_nodes,n_sections)
1299  REAL(wp) :: f(n_nodes,n_sections)
1300  REAL(wp) :: phiL(n_nodes,n_sections) , phiR(n_nodes,n_sections)
1301  REAL(wp) :: phi(n_nodes,n_sections)
1302  REAL(wp) :: diam(n_nodes,n_sections)
1303  REAL(wp) :: Mi(n_nodes,n_sections)
1304  REAL(wp) :: rho_p(1:n_nodes,1:n_sections)
1305  REAL(wp) :: shape_p(1:n_nodes,1:n_sections)
1306  REAL(wp) :: cond1(n_nodes,n_sections), cond2(n_nodes,n_sections)
1307  REAL(wp) :: cond3(n_nodes,n_sections)
1308 
1309  INTEGER :: i_part
1310  INTEGER :: i_sect
1311  INTEGER :: iter
1312  INTEGER :: j
1313 
1314  DO i_part=1,n_part
1315 
1316  ! convert from Krumbein scale to meters
1317  diam1 = 1.e-3_wp * 2.0_wp**( - phi2(i_part) )
1318  ! compute the volume from diameter and shape factor
1319  ! Vol1 = shape_factor(i_part) * diam1**3
1320  vol1 = shape2(i_part) * diam1**3
1321  ! compute the mass from volume and density
1322  m1 = vol1 * rho2(i_part)
1323 
1324  ! convert from Krumbein scale to meters
1325  diam2 = 1.e-3_wp * 2.0_wp**( - phi1(i_part) )
1326  ! compute the volume from diameter and shape factor
1327  ! Vol2 = shape_factor(i_part) * diam2**3
1328  vol2 = shape1(i_part) * diam2**3
1329  ! compute the mass from volume and density
1330  m2 = vol2 * rho1(i_part)
1331 
1332  ! Initialize the functions for the bisection method
1333  f1 = m_quad(1:n_nodes,1:n_sections,i_part) - m1
1334  f2 = m_quad(1:n_nodes,1:n_sections,i_part) - m2
1335 
1336  IF ( verbose_level .GE. 2 ) THEN
1337 
1338  WRITE(*,*) 'm_quad'
1339  DO i_sect=1,n_sections
1340 
1341  WRITE(*,*) m_quad(1:n_nodes,i_sect,i_part)
1342 
1343  END DO
1344 
1345  WRITE(*,*) 'f1'
1346  DO i_sect=1,n_sections
1347 
1348  WRITE(*,*) f1(1:n_nodes,i_sect)
1349 
1350  END DO
1351 
1352  WRITE(*,*) 'f2'
1353  DO i_sect=1,n_sections
1354 
1355  WRITE(*,*) f2(1:n_nodes,i_sect)
1356 
1357  END DO
1358 
1359  WRITE(*,*) 'f1*f2'
1360  DO i_sect=1,n_sections
1361 
1362  WRITE(*,*) f1(1:n_nodes,i_sect)*f2(1:n_nodes,i_sect)
1363 
1364  END DO
1365 
1366  READ(*,*)
1367 
1368  END IF
1369 
1370  ! Initialize the arrays of the left and right guess for the solution
1371  phil(1:n_nodes,1:n_sections) = phi2(i_part)
1372  phir(1:n_nodes,1:n_sections) = phi1(i_part)
1373 
1374  DO iter=1,30
1375 
1376  phi = 0.5_wp * (phil+phir)
1377  diam = 1.e-3_wp * 2.0_wp**( - phi )
1378  ! Vol = shape_factor(i_part) * diam**3
1379 
1380  shape_p = shape1(i_part) + ( phi - phi1(i_part) ) / ( phi2(i_part) - &
1381  phi1(i_part) ) * ( shape2(i_part) - shape1(i_part) )
1382  shape_p = 0.6_wp
1383  vol = shape_p * diam**3
1384 
1385  rho_p = rho1(i_part) + ( phi - phi1(i_part) ) / ( phi2(i_part) - &
1386  phi1(i_part) ) * ( rho2(i_part) - rho1(i_part) )
1387 
1388  mi = vol * rho_p
1389  f = m_quad(1:n_nodes,1:n_sections,i_part) - mi
1390 
1391  ! The phi-rho relationship is linear-piecewise, so we need some
1392  ! condition defining in which part we are
1393  cond1 = merge( 1.0_wp , 0.0_wp , f1*f2 .LT. 0.0_wp )
1394  cond2 = merge( 1.0_wp , 0.0_wp , f*f1 .LT. 0.0_wp )
1395  cond3 = merge( 1.0_wp , 0.0_wp , f1 .GT. 0.0_wp )
1396 
1397  phir = cond1 * ( cond2 * phi + (1.0_wp-cond2) * phir ) + &
1398  (1.0_wp-cond1) * ( cond3*phir + (1.0_wp-cond3)*phi )
1399 
1400  f2 = cond1 * ( cond2 * f + (1.0_wp-cond2) * f2 ) + &
1401  (1.0_wp-cond1) * ( cond3 * f2 + (1.0_wp-cond3) * f )
1402 
1403  phil = cond1 * ( (1.0_wp-cond2) * phi + cond2 * phil ) + &
1404  (1.0_wp-cond1) * ( (1.0_wp-cond3) * phil + cond3 * phi )
1405 
1406  f1 = cond1 * ( (1.0_wp-cond2) * f + cond2 * f1 ) + &
1407  (1.0_wp-cond1) * ( (1.0_wp-cond3) * f1 + cond3 * f )
1408 
1409  END DO
1410 
1411  ! the output of the bilinear iterations is the density
1412  rho_quad(1:n_nodes,1:n_sections,i_part) = rho_p
1413 
1414  shape_quad(1:n_nodes,1:n_sections,i_part) = shape_p
1415 
1416  ! we compute the volume from mass and density
1417  vol_quad(1:n_nodes,1:n_sections,i_part) = m_quad(:,:,i_part) / rho_p
1418 
1419  ! the diameter in m is computed from volume and shapefactor
1420  diam_quad(1:n_nodes,1:n_sections,i_part) = ( vol_quad(:,:,i_part) &
1421  / shape_quad(1:n_nodes,1:n_sections,i_part) )**( 1.0_wp/3.0_wp )
1422 
1423  ! the diameter in m is converted to phi
1424  phi_quad(1:n_nodes,1:n_sections,i_part) = &
1425  - log(1.e3_wp * diam_quad(1:n_nodes,1:n_sections,i_part)) / log(2.0_wp)
1426 
1427  DO i_sect=1,n_sections
1428 
1429  DO j=1,n_nodes
1430 
1431  cp_quad(j,i_sect,i_part) = particles_heat_capacity( i_part, &
1432  diam_quad(j,i_sect,i_part))
1433 
1434  END DO
1435 
1436  END DO
1437 
1438  IF ( verbose_level .GE. 1 ) THEN
1439 
1440  WRITE(*,*) 'i_part',i_part
1441  WRITE(*,*) 'phi'
1442  WRITE(*,"(100ES8.1)") phi_quad(1:n_nodes,1:n_sections,i_part)
1443  WRITE(*,*) 'diam'
1444  WRITE(*,"(100ES8.1)") diam_quad(1:n_nodes,1:n_sections,i_part)
1445  WRITE(*,*) 'vol'
1446  WRITE(*,"(100ES8.1)") vol_quad(1:n_nodes,1:n_sections,i_part)
1447  WRITE(*,*) 'rho'
1448  WRITE(*,"(100ES8.1)") rho_quad(1:n_nodes,1:n_sections,i_part)
1449  READ(*,*)
1450 
1451  END IF
1452 
1453  END DO
1454 
1455  RETURN
1456 
1457  END SUBROUTINE phifromm
1458 
1459  !******************************************************************************
1461  !
1475  !******************************************************************************
1476 
1477  SUBROUTINE update_aggregation(temp,visc,lw_vf,ice_vf,solid_mf)
1479  IMPLICIT NONE
1480 
1481  REAL(wp),INTENT(IN) :: temp
1482  REAL(wp),INTENT(IN) :: visc
1483  REAL(wp),INTENT(IN) :: lw_vf
1484  REAL(wp),INTENT(IN) :: ice_vf
1485  REAL(wp),INTENT(IN) :: solid_mf
1486 
1487  INTEGER :: i_part , j_part
1488  INTEGER :: i_sect , j_sect , k_sect
1489 
1490  INTEGER :: i_node , j_node
1491 
1492  REAL(wp) :: kernel_ji(n_nodes,n_nodes)
1493 
1494  REAL(wp) :: f1i(n_nodes)
1495  REAL(wp) :: f2j(n_nodes)
1496  REAL(wp) :: integrand_ijkm
1497  REAL(wp) :: f1i_f2j(n_nodes,n_nodes)
1498 
1499 
1500  DO i_part=1,n_part
1501 
1502  DO i_sect=1,n_sections
1503 
1504  DO j_part=1,n_part
1505 
1506  DO j_sect=1,n_sections
1507 
1508  DO i_node=1,n_nodes
1509 
1510  DO j_node=1,n_nodes
1511 
1512  ! If the kernel is a function of particle sizes only, then
1513  ! it can be initialized before the integration of the
1514  ! plume equation
1515  kernel_ji(j_node,i_node) = particles_beta( temp , visc , &
1516  diam_quad(j_node,j_sect,j_part) , &
1517  diam_quad(i_node,i_sect,i_part) , &
1518  rho_quad(j_node,j_sect,j_part) , &
1519  rho_quad(i_node,i_sect,i_part) , &
1520  set_vel_quad(j_node,j_sect,j_part) , &
1521  set_vel_quad(i_node,i_sect,i_part) , &
1522  lw_vf , ice_vf , solid_mf )
1523 
1524  END DO
1525 
1526  END DO
1527 
1528  kernel_aggr(:,:,j_sect,j_part,i_sect,i_part) = kernel_ji
1529 
1530  END DO
1531 
1532  END DO
1533 
1534  END DO
1535 
1536  END DO
1537 
1538  !--- Birth and death terms due to aggregation
1539  birth_mom(0:n_mom-1,1:n_sections,1:n_part) = 0.0_wp
1540  death_mom(0:n_mom-1,1:n_sections,1:n_part) = 0.0_wp
1541 
1542  ! loop over all particles which aggregate i_part
1543  DO i_part=1,n_part
1544 
1545  ! loop over sections of i_part-particles
1546  DO i_sect=1,n_sections
1547 
1548  ! linear reconstruction at nodes of section i_sect of part(i_part)
1549  f1i = f_quad(:,i_sect,i_part)
1550 
1551  ! loop over all particles which aggregate part(jp)
1552  DO j_part=1,n_part
1553 
1554  ! loop over sections of j_part-particles
1555  DO j_sect=1,n_sections
1556 
1557  f2j = f_quad(:,j_sect,j_part)
1558 
1559  ! interval of particles of family jp
1560  DO k_sect=1,n_sections
1561 
1562  ! check for combination of sections aggregation
1563  IF ( q_flag(k_sect,j_sect,i_sect,j_part,i_part) ) THEN
1564 
1565  DO i_node=1,n_nodes
1566 
1567  ! term accounting for the linear recontruction
1568  ! values at the quadrature nodes
1569  f1i_f2j(i_node,1:n_nodes) = f1i(1:n_nodes) * f2j(i_node)
1570 
1571  END DO
1572 
1573  integrand_ijkm = sum( &
1574  a(:,:,k_sect,j_sect,j_part,i_sect,i_part) &
1575  * wij(:,:,0,j_sect,j_part,i_sect,i_part) &
1576  * kernel_aggr(:,:,j_sect,j_part,i_sect,i_part) &
1577  * f1i_f2j )
1578 
1579  ! 0-moment of loss rate of i_part-particles in section
1580  ! i_sect becauseof aggregation with j_part-particles in
1581  ! section j_sect to form n_part-particles in section k_sect
1582  death_mom(0,i_sect,i_part) = death_mom(0,i_sect,i_part) &
1583  + integrand_ijkm
1584 
1585  ! 0-moment of birth rate of n_part-particles in section
1586  ! k_sect because of aggregation of i_part-particles in
1587  ! section i_sect with j_part-particles in section j_sect
1588  birth_mom(0,k_sect,n_part) = birth_mom(0,k_sect,n_part) &
1589  + 0.5_wp * integrand_ijkm
1590 
1591  integrand_ijkm = sum( &
1592  a(:,:,k_sect,j_sect,j_part,i_sect,i_part) &
1593  * wij(:,:,1,j_sect,j_part,i_sect,i_part) &
1594  * kernel_aggr(:,:,j_sect,j_part,i_sect,i_part) &
1595  * f1i_f2j )
1596 
1597  ! 1-moment of loss rate of i_part-particles in section
1598  ! i_sect becauseof aggregation with j_part-particles in
1599  ! section j_sect to form n_part-particles in section k_sect
1600  death_mom(1,i_sect,i_part) = death_mom(1,i_sect,i_part) &
1601  + integrand_ijkm
1602 
1603  ! 1-moment of birth rate of n_part-particles in section
1604  ! k_sect because of aggregation of i_part-particles in
1605  ! section i_sect with j_part-particles in section j_sect
1606  birth_mom(1,k_sect,n_part) = birth_mom(1,k_sect,n_part) &
1607  + integrand_ijkm
1608 
1609  END IF
1610 
1611  END DO
1612 
1613  END DO
1614 
1615  END DO
1616 
1617  END DO
1618 
1619  END DO
1620 
1621  RETURN
1622 
1623  END SUBROUTINE update_aggregation
1624 
1625 
1626  !******************************************************************************
1628  !
1635  !******************************************************************************
1636 
1637  SUBROUTINE init_aggregation
1639  IMPLICIT NONE
1640 
1641  REAL(wp) :: mi1(n_nodes) , mj2(n_nodes)
1642  REAL(wp) :: wi1(n_nodes) , wj2(n_nodes)
1643 
1644  REAL(wp) :: mij12(n_nodes,n_nodes)
1645  REAL(wp) :: wij12(n_nodes,n_nodes)
1646  INTEGER :: Aijk(n_nodes,n_nodes)
1647  REAL(wp) :: Wijm(n_nodes,n_nodes)
1648 
1649  REAL(wp) :: kernel_ji(n_nodes,n_nodes)
1650 
1651  INTEGER :: i_part , j_part
1652  INTEGER :: i_sect , j_sect , k_sect
1653  INTEGER :: i_mom
1654  INTEGER :: i_node , j_node
1655 
1656  DO i_part=1,n_part
1657 
1658  DO i_sect=1,n_sections
1659 
1660  mi1(1:n_nodes) = m_quad(:,i_sect,i_part)
1661  wi1(1:n_nodes) = w_quad(:,i_sect,i_part)
1662 
1663  DO j_part=1,n_part
1664 
1665  DO j_sect=1,n_sections
1666 
1667  mj2(1:n_nodes) = m_quad(:,j_sect,j_part)
1668  wj2(1:n_nodes) = w_quad(:,j_sect,j_part)
1669 
1670  DO i_node=1,n_nodes
1671 
1672  mij12(i_node,1:n_nodes) = mi1(1:n_nodes)+mj2(i_node)
1673  wij12(i_node,1:n_nodes) = wi1(1:n_nodes)*wj2(i_node)
1674 
1675  END DO
1676 
1677  DO k_sect=1,n_sections
1678 
1679  ! The array Aijk depends only on the sections i, j and k.
1680  ! The value is 1 when the sum of the mass of the particles
1681  ! i_part,i_sect,i_node and j_part,j_sect,j_node falls in
1682  ! the k_section of the class n_part
1683  aijk = merge(1 , 0 , ( mij12 .GE. m(k_sect,n_part) ) .AND. &
1684  ( mij12 .LE. m(k_sect+1,n_part) ) )
1685 
1686  ! this logical variable is true only when there are particles
1687  ! i_part/i_sect and particles j_part/j_sect aggregating
1688  ! to particles n_part/k_sect
1689  q_flag(k_sect,j_sect,i_sect,j_part,i_part) = &
1690  ( sum(aijk) .GT. 0 )
1691 
1692  a(:,:,k_sect,j_sect,j_part,i_sect,i_part) = aijk
1693 
1694  END DO
1695 
1696  DO i_mom=0,n_mom-1
1697 
1698  DO i_node=1,n_nodes
1699 
1700  wijm(i_node,1:n_nodes) = wij12(i_node,1:n_nodes) &
1701  * mi1(1:n_nodes)**i_mom
1702 
1703  END DO
1704 
1705  wij(:,:,i_mom,j_sect,j_part,i_sect,i_part) = wijm
1706 
1707  END DO
1708 
1709  END DO
1710 
1711  END DO
1712 
1713  END DO
1714 
1715  END DO
1716 
1717  WRITE(*,*) 'Aggregation initialization completed'
1718 
1719  RETURN
1720 
1721  END SUBROUTINE init_aggregation
1722 
1723 END MODULE particles_module
1724 
subroutine phifromm
Compute size from mass.
Definition: particles.f90:1291
real(wp), dimension(:), allocatable phi1
First diameter for the density function.
Definition: particles.f90:74
integer n_mom
Number of moments.
Definition: moments.f90:24
real(wp) function particles_shape(i_part, phi)
Particle shape factor.
Definition: particles.f90:662
integer n_part
number of particle phases
Definition: particles.f90:23
real(wp) visc_atm
Atmospheric kinematic viscosity.
Definition: meteo.f90:70
real(wp) function particles_beta(temp, visc, diam_i, diam_j, rho_i, rho_j, Vs_i, Vs_j, lw_vf, ice_vf, solid_mf)
Particles aggregation.
Definition: particles.f90:731
real(wp) t_part
Particle temperature for aggregation (Costa model)
Definition: particles.f90:161
real(wp) rho_atm
Atmospheric density.
Definition: meteo.f90:60
subroutine linear_reconstruction(Ml, Mr, mom, Ma, Mb, alfa, beta, gamma1, gamma2)
Definition: moments.f90:178
character(len=20) distribution
Ditribution of the particles: .
Definition: particles.f90:110
subroutine eval_particles_moments
Particles moments computation.
Definition: particles.f90:1100
real(wp), dimension(:,:,:), allocatable diam_quad
Particle diameters (meters) at quadrature points.
Definition: particles.f90:140
real(wp), dimension(:,:,:), allocatable m_quad
Abscissa of quadrature formulas.
Definition: particles.f90:131
character(len=20) aggregation_model
Aggregation kernel model: .
Definition: particles.f90:125
real(wp), dimension(:,:,:), allocatable phi_quad
Particle size (phi-scale) at quadrature points.
Definition: particles.f90:137
real(wp), dimension(:), allocatable shape1
Shape factor at phi=phi1.
Definition: particles.f90:80
real(wp), dimension(:,:), allocatable cum_particle_loss_rate
cumulative rate of particles lost up to the integration height ( kg s^-1)
Definition: particles.f90:50
subroutine init_quadrature_points
Quadrature initialization.
Definition: particles.f90:1227
real(wp) function particles_heat_capacity(i_part, diam)
Heat capacity.
Definition: particles.f90:583
real(wp), dimension(:,:,:,:,:,:,:), allocatable a
Definition: particles.f90:178
real(wp), dimension(:), allocatable solid_volume_fraction
volume fraction of the particle phases with respect to the mixture
Definition: particles.f90:41
subroutine allocate_particles
Particles variables allocation.
Definition: particles.f90:198
integer n_sections
Definition: moments.f90:26
real(wp), dimension(:,:,:), allocatable set_mom
Moments of the settling velocities.
Definition: particles.f90:59
real *8 pi_g
Greek pi.
Definition: variables.f90:30
integer n_nodes
Number of nodes for the quadrature.
Definition: moments.f90:18
Particles module.
Definition: particles.f90:11
subroutine deallocate_particles
Definition: particles.f90:282
real(wp), dimension(:), allocatable rho1
Density at phi=phi1.
Definition: particles.f90:77
real(wp), dimension(:,:,:), allocatable set_cp_mom
Moments of the settling velocities times the heat capacity.
Definition: particles.f90:62
logical aggregation_flag
Definition: variables.f90:72
character(len=40) fmt
Definition: variables.f90:85
real(wp), dimension(:,:,:), allocatable f_quad
Values of linear reconstructions at quadrature points.
Definition: particles.f90:158
subroutine gaulegf(x1, x2, x, w, n)
Definition: moments.f90:137
real(wp), dimension(:,:,:), allocatable rho_quad
Particle densities at quadrature points.
Definition: particles.f90:146
real(wp), dimension(:), allocatable cp_part
Heat capacity of particle phases.
Definition: particles.f90:92
real(wp), dimension(:,:), allocatable bin_partial_mass_fraction
mass fraction of the bins of particle with respect to the total solid
Definition: particles.f90:44
real(wp), dimension(:), allocatable solid_partial_mass_fraction
mass fraction of the particle phases with respect to the total solid
Definition: particles.f90:26
Meteo module.
Definition: meteo.f90:11
subroutine init_aggregation
Aggregation initialization.
Definition: particles.f90:1638
subroutine update_aggregation(temp, visc, lw_vf, ice_vf, solid_mf)
Aggregation terms.
Definition: particles.f90:1478
integer, dimension(:), allocatable aggr_idx
Index defining the couple aggregated-non aggregated.
Definition: particles.f90:128
real(wp), dimension(:,:,:), allocatable shape_quad
Particle densities at quadrature points.
Definition: particles.f90:149
real(wp), dimension(:), allocatable solid_mass_fraction
mass fraction of the particle phases with respect to the mixture
Definition: particles.f90:35
real(wp), dimension(:), allocatable aggregate_porosity
Array for porosity volume fraction of aggregates.
Definition: particles.f90:118
real(wp) rho_atm0
Atmospheric density at sea level.
Definition: meteo.f90:51
real(wp), dimension(:,:), allocatable m
boundaries of the sections in mass scale (kg)
Definition: particles.f90:170
Method of Moments module.
Definition: moments.f90:11
real(wp) function particles_settling_velocity(diam, rhop, shape_fact)
Settling velocity.
Definition: particles.f90:355
real(wp), dimension(:,:,:), allocatable mom
Moments of the particles diameter.
Definition: particles.f90:53
real(wp), dimension(:), allocatable phil
left boundaries of the sections in phi-scale
Definition: particles.f90:164
logical, dimension(:,:,:,:,:), allocatable q_flag
logical defining if particles ip/is+jp/js aggregates on section ks
Definition: particles.f90:173
real(wp) function aggregation_kernel(diam_i, rho_i, Vs_i, diam_j, rho_j, Vs_j, lw_vf, ice_vf, solid_mf, temp, visc)
Aggregation kernel.
Definition: particles.f90:821
real(wp), dimension(:), allocatable solid_partial_mass_fraction0
init mass fraction of the particle phases with respect to the total solid
Definition: particles.f90:29
real(wp), dimension(:,:,:), allocatable w_quad
Weights of quadrature formulas.
Definition: particles.f90:134
logical, dimension(:), allocatable aggregation_array
Flag for the aggregation: .
Definition: particles.f90:115
real(wp), dimension(:), allocatable shape_factor
shape factor for settling velocity (Pfeiffer)
Definition: particles.f90:71
real *8, parameter k_b
Boltzmann constant.
Definition: variables.f90:27
real(wp), dimension(:,:), allocatable particle_loss_rate
rate of particles lost from the plume in the integration steps ( kg s^-1)
Definition: particles.f90:47
real(wp), dimension(:,:,:,:,:,:), allocatable kernel_aggr
aggregation kernel computed for ip/is+jp/js
Definition: particles.f90:176
real(wp) particles_beta0
Definition: particles.f90:98
real(wp), dimension(:,:,:), allocatable birth_mom
Term accounting for the birth of aggregates in the moments equations.
Definition: particles.f90:65
real(wp) cpsolid
Average heat capacity of particles.
Definition: particles.f90:95
integer, parameter wp
working precision
Definition: variables.f90:21
real(wp), dimension(:), allocatable solid_mass_fraction0
initial mass fraction of the particle phases with respect to the mixture
Definition: particles.f90:38
real(wp), dimension(:), allocatable phir
right boundaries of the sections in phi-scale
Definition: particles.f90:167
real(wp), dimension(:,:,:,:,:,:,:), allocatable wij
Definition: particles.f90:180
real(wp) function collision_kernel(diam_i, rho_i, Vs_i, diam_j, rho_j, Vs_j, temp, visc)
Collision kernel.
Definition: particles.f90:898
real(wp), dimension(:,:,:), allocatable death_mom
Term accounting for the loss of particles because of aggregation.
Definition: particles.f90:68
real(wp) function particles_density(i_part, phi)
Particle density.
Definition: particles.f90:607
real *8 gi
Gravity acceleration.
Definition: variables.f90:24
real(wp), dimension(:,:,:), allocatable vol_quad
Particle volumes at quadrature points.
Definition: particles.f90:143
real(wp), dimension(:,:,:), allocatable set_vel_quad
Particle settling velocities at quadrature points.
Definition: particles.f90:152
real(wp), dimension(:), allocatable phi2
Second diameter for the density function.
Definition: particles.f90:83
subroutine eval_quad_values
Quadrature values computation.
Definition: particles.f90:1179
real(wp), dimension(:,:,:), allocatable cp_quad
Particle heat capacities at quadrature points.
Definition: particles.f90:155
real(wp), dimension(:,:,:), allocatable mom0
Initial moments of the particles diameter.
Definition: particles.f90:56
real(wp), dimension(:), allocatable rho2
Density at phi=phi2.
Definition: particles.f90:86
real(wp), dimension(:), allocatable solid_partial_volume_fraction
volume fraction of the particle phases with respect to the total solid
Definition: particles.f90:32
Global variables.
Definition: variables.f90:10
real(wp), dimension(:), allocatable shape2
Shape factor at phi=phi2.
Definition: particles.f90:89
real(wp) function coalescence_efficiency(diam_i, rho_i, Vs_i, diam_j, rho_j, Vs_j, lw_vf, ice_vf, solid_mf)
Coalescence efficiency.
Definition: particles.f90:995
character *10 settling_model
Settling model: .
Definition: particles.f90:104
integer indent_space
Definition: variables.f90:83
integer verbose_level
Level of verbose output (0 = minimal output on screen)
Definition: variables.f90:33