Ignore:
Timestamp:
May 22, 2024, 3:16:36 PM (5 weeks ago)
Author:
lebasn
Message:

StratAer?: New model version (microphysic, composition routine, code cleaning, new params...)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • LMDZ6/trunk/libf/phylmd/StratAer/coagulate.F90

    r4762 r4950  
    2626  USE aerophys
    2727  USE infotrac_phy
    28   USE phys_local_var_mod, ONLY: DENSO4, f_r_wet
    29 
     28  USE phys_local_var_mod, ONLY: DENSO4, DENSO4B, f_r_wet, f_r_wetB
     29  USE strataer_local_var_mod, ONLY: flag_new_strat_compo
     30 
    3031  IMPLICIT NONE
    3132
     
    4344  ! local variables in coagulation routine
    4445  INTEGER                                       :: i,j,k,nb,ilon,ilev
    45   REAL, DIMENSION(nbtr_bin)                     :: radius ! aerosol particle radius in each bin [m]
     46  REAL, DIMENSION(nbtr_bin)                     :: radiusdry ! dry aerosol particle radius in each bin [m]
     47  REAL, DIMENSION(nbtr_bin)                     :: radiuswet ! wet aerosol particle radius in each bin [m]
    4648  REAL, DIMENSION(klon,klev,nbtr_bin)           :: tr_t ! Concentration Traceur at time t [U/KgA]
    4749  REAL, DIMENSION(klon,klev,nbtr_bin)           :: tr_tp1 ! Concentration Traceur at time t+1 [U/KgA]
    4850  REAL, DIMENSION(nbtr_bin,nbtr_bin,nbtr_bin)   :: ff   ! Volume fraction of intermediate particles
    49   REAL, DIMENSION(nbtr_bin)                     :: V    ! Volume of bins
     51  REAL, DIMENSION(nbtr_bin)                     :: Vdry ! Volume dry of bins
     52  REAL, DIMENSION(nbtr_bin)                     :: Vwet ! Volume wet of bins
    5053  REAL, DIMENSION(nbtr_bin,nbtr_bin)            :: Vij  ! Volume sum of i and j
    5154  REAL                                          :: eta  ! Dynamic viscosity of air
     
    8285  include "YOMCST.h"
    8386
    84   DO i=1, nbtr_bin
    85    radius(i)=mdw(i)/2.
    86    V(i)= radius(i)**3.  !neglecting factor 4*RPI/3
    87   ENDDO
    88 
    89   DO j=1, nbtr_bin
    90   DO i=1, nbtr_bin
    91    Vij(i,j)= V(i)+V(j)
    92   ENDDO
    93   ENDDO
    94 
     87! ff(i,j,k): Volume fraction of Vi,j that is partitioned to each model bin k
     88! just need to be calculated in model initialization because mdw(:) size is fixed
     89! no need to recalculate radius, Vdry, Vij, and ff every timestep because it is for 
     90! dry aerosols
     91  DO i=1, nbtr_bin
     92     radiusdry(i)=mdw(i)/2.
     93     Vdry(i)=radiusdry(i)**3.  !neglecting factor 4*RPI/3
     94     Vwet(i)=0.0
     95  ENDDO
     96
     97  DO j=1, nbtr_bin
     98     DO i=1, nbtr_bin
     99        Vij(i,j)= Vdry(i)+Vdry(j)
     100     ENDDO
     101  ENDDO
     102 
    95103!--pre-compute the f(i,j,k) from Jacobson equation 13
    96104  ff=0.0
     
    100108    IF (k.EQ.1) THEN
    101109      ff(i,j,k)= 0.0
    102     ELSEIF (k.GT.1.AND.V(k-1).LT.Vij(i,j).AND.Vij(i,j).LT.V(k)) THEN
     110    ELSEIF (k.GT.1.AND.Vdry(k-1).LT.Vij(i,j).AND.Vij(i,j).LT.Vdry(k)) THEN
    103111      ff(i,j,k)= 1.-ff(i,j,k-1)
    104112    ELSEIF (k.EQ.nbtr_bin) THEN
    105       IF (Vij(i,j).GE.v(k)) THEN
     113      IF (Vij(i,j).GE.Vdry(k)) THEN
    106114        ff(i,j,k)= 1.
    107115      ELSE
    108116        ff(i,j,k)= 0.0
    109117      ENDIF
    110     ELSEIF (k.LE.(nbtr_bin-1).AND.V(k).LE.Vij(i,j).AND.Vij(i,j).LT.V(k+1)) THEN
    111       ff(i,j,k)= V(k)/Vij(i,j)*(V(k+1)-Vij(i,j))/(V(k+1)-V(k))
     118    ELSEIF (k.LE.(nbtr_bin-1).AND.Vdry(k).LE.Vij(i,j).AND.Vij(i,j).LT.Vdry(k+1)) THEN
     119      ff(i,j,k)= Vdry(k)/Vij(i,j)*(Vdry(k+1)-Vij(i,j))/(Vdry(k+1)-Vdry(k))
    112120    ENDIF
    113121  ENDDO
    114122  ENDDO
    115123  ENDDO
    116 
     124! End of just need to be calculated at initialization because mdw(:) size is fixed
     125 
    117126  DO ilon=1, klon
    118127  DO ilev=1, klev
     
    120129  IF (is_strato(ilon,ilev)) THEN
    121130  !compute actual wet particle radius & volume for every grid box
    122   DO i=1, nbtr_bin
    123    radius(i)=f_r_wet(ilon,ilev)*mdw(i)/2.
    124    V(i)= radius(i)**3.  !neglecting factor 4*RPI/3
    125   ENDDO
    126 
     131  IF(flag_new_strat_compo) THEN
     132     DO i=1, nbtr_bin
     133        radiuswet(i)=f_r_wetB(ilon,ilev,i)*mdw(i)/2.
     134        Vwet(i)= radiuswet(i)**3.  !neglecting factor 4*RPI/3
     135!!      Vwet(i)= Vdry(i)*(f_r_wetB(ilon,ilev,i)**3)
     136     ENDDO
     137  ELSE
     138     DO i=1, nbtr_bin
     139        radiuswet(i)=f_r_wet(ilon,ilev)*mdw(i)/2.
     140        Vwet(i)= radiuswet(i)**3.  !neglecting factor 4*RPI/3
     141!!      Vwet(i)= Vdry(i)*(f_r_wet(ilon,ilev)**3)
     142     ENDDO
     143  ENDIF
     144 
    127145!--Calculations for the coagulation kernel---------------------------------------------------------
    128146
     
    150168  Di=0.0
    151169  DO i=1, nbtr_bin
    152    Kn(i)=mnfrpth/radius(i)
    153    Di(i)=RKBOL*t_seri(ilon,ilev)/(6.*RPI*radius(i)*eta)*(1.+Kn(i)*(1.249+0.42*exp(-0.87/Kn(i))))
     170      Kn(i)=mnfrpth/radiuswet(i)
     171      Di(i)=RKBOL*t_seri(ilon,ilev)/(6.*RPI*radiuswet(i)*eta)*(1.+Kn(i)*(1.249+0.42*exp(-0.87/Kn(i))))
    154172  ENDDO
    155173
    156174!--pre-compute the thermal velocity of a particle thvelpar(i) from equation 20
    157175  thvelpar=0.0
    158   DO i=1, nbtr_bin
    159    m_par(i)=4./3.*RPI*radius(i)**3.*DENSO4(ilon,ilev)*1000.
    160    thvelpar(i)=sqrt(8.*RKBOL*t_seri(ilon,ilev)/(RPI*m_par(i)))
    161   ENDDO
     176  IF(flag_new_strat_compo) THEN
     177     DO i=1, nbtr_bin
     178        m_par(i)=4./3.*RPI*radiuswet(i)**3.*DENSO4B(ilon,ilev,i)*1000.
     179        thvelpar(i)=sqrt(8.*RKBOL*t_seri(ilon,ilev)/(RPI*m_par(i)))
     180     ENDDO
     181  ELSE
     182     DO i=1, nbtr_bin
     183        m_par(i)=4./3.*RPI*radiuswet(i)**3.*DENSO4(ilon,ilev)*1000.
     184        thvelpar(i)=sqrt(8.*RKBOL*t_seri(ilon,ilev)/(RPI*m_par(i)))
     185     ENDDO
     186  ENDIF
    162187
    163188!--pre-compute the particle mean free path mfppar(i) from equation 22
     
    171196  delta=0.0
    172197  DO i=1, nbtr_bin
    173    delta(i)=((2.*radius(i)+mfppar(i))**3.-(4.*radius(i)**2.+mfppar(i)**2.)**1.5)/ &
    174            & (6.*radius(i)*mfppar(i))-2.*radius(i)
    175   ENDDO
    176 
     198      delta(i)=((2.*radiuswet(i)+mfppar(i))**3.-(4.*radiuswet(i)**2.+mfppar(i)**2.)**1.5)/ &
     199           & (6.*radiuswet(i)*mfppar(i))-2.*radiuswet(i)
     200  ENDDO
     201
     202!   beta(i,j): coagulation kernel (rate coefficient) of 2 colliding particles i,j
    177203!--pre-compute the beta(i,j) from equation 17 in Jacobson
    178204  num=0.0
     
    180206  DO i=1, nbtr_bin
    181207!
    182    num=4.*RPI*(radius(i)+radius(j))*(Di(i)+Di(j))
    183    denom=(radius(i)+radius(j))/(radius(i)+radius(j)+sqrt(delta(i)**2.+delta(j)**2.))+ &
    184         & 4.*(Di(i)+Di(j))/(sqrt(thvelpar(i)**2.+thvelpar(j)**2.)*(radius(i)+radius(j)))
    185    beta(i,j)=num/denom
     208     num=4.*RPI*(radiuswet(i)+radiuswet(j))*(Di(i)+Di(j))
     209     denom=(radiuswet(i)+radiuswet(j))/(radiuswet(i)+radiuswet(j)+sqrt(delta(i)**2.+delta(j)**2.))+ &
     210          & 4.*(Di(i)+Di(j))/(sqrt(thvelpar(i)**2.+thvelpar(j)**2.)*(radiuswet(i)+radiuswet(j)))
     211     beta(i,j)=num/denom
    186212!
    187213!--compute enhancement factor due to van der Waals forces
    188214   IF (ok_vdw .EQ. 0) THEN      !--no enhancement factor
    189      Evdw=1.0
     215      Evdw=1.0
    190216   ELSEIF (ok_vdw .EQ. 1) THEN  !--E(0) case
    191      AvdWi = AvdW/(RKBOL*t_seri(ilon,ilev))*(4.*radius(i)*radius(j))/(radius(i)+radius(j))**2.
    192      xvdW = LOG(1.+AvdWi)
    193      EvdW = 1. + avdW1*xvdW + avdW3*xvdW**3
     217      AvdWi = AvdW/(RKBOL*t_seri(ilon,ilev))*(4.*radiuswet(i)*radiuswet(j))/(radiuswet(i)+radiuswet(j))**2.
     218      xvdW = LOG(1.+AvdWi)
     219      EvdW = 1. + avdW1*xvdW + avdW3*xvdW**3
    194220   ELSEIF (ok_vdw .EQ. 2) THEN  !--E(infinity) case
    195      AvdWi = AvdW/(RKBOL*t_seri(ilon,ilev))*(4.*radius(i)*radius(j))/(radius(i)+radius(j))**2.
    196      xvdW = LOG(1.+AvdWi)
    197      EvdW = 1. + SQRT(AvdWi/3.)/(1.+bvdW0*SQRT(AvdWi)) + bvdW1*xvdW + bvdW3*xvdW**3.
     221      AvdWi = AvdW/(RKBOL*t_seri(ilon,ilev))*(4.*radiuswet(i)*radiuswet(j))/(radiuswet(i)+radiuswet(j))**2.
     222      xvdW = LOG(1.+AvdWi)
     223      EvdW = 1. + SQRT(AvdWi/3.)/(1.+bvdW0*SQRT(AvdWi)) + bvdW1*xvdW + bvdW3*xvdW**3.
    198224   ENDIF
    199225!
     
    209235  denom=0.0
    210236  DO j=1, nbtr_bin
    211   denom=denom+(1.-ff(k,j,k))*beta(k,j)*tr_t(ilon,ilev,j)
     237     !    fraction of coagulation of k and j that is not giving k
     238     denom=denom+(1.-ff(k,j,k))*beta(k,j)*tr_t(ilon,ilev,j)
    212239  ENDDO
    213240
     
    219246    num=0.0
    220247    DO j=1, k
    221     numi=0.0
    222     DO i=1, k-1
    223     numi=numi+ff(i,j,k)*beta(i,j)*V(i)*tr_tp1(ilon,ilev,i)*tr_t(ilon,ilev,j)
     248       numi=0.0
     249       DO i=1, k-1
     250!           
     251!           see Jacobson: " In order to conserve volume and volume concentration (which
     252!           coagulation physically does) while giving up some accuracy in number concentration"
     253!
     254!           Coagulation of i and j giving k
     255!           with V(i) and then V(j) because it considers i,j and j,i with the double loop
     256!
     257!           BUT WHY WET VOLUME V(i) in old STRATAER? tracers are already dry aerosols and coagulation
     258!           kernel beta(i,j) accounts for wet aerosols -> reply below
     259!
     260!             numi=numi+ff(i,j,k)*beta(i,j)*V(i)*tr_tp1(ilon,ilev,i)*tr_t(ilon,ilev,j)
     261            numi=numi+ff(i,j,k)*beta(i,j)*Vdry(i)*tr_tp1(ilon,ilev,i)*tr_t(ilon,ilev,j)
     262       ENDDO
     263       num=num+numi
    224264    ENDDO
    225     num=num+numi
    226     ENDDO
    227265
    228266!--calculate new concentration of other bins
    229     tr_tp1(ilon,ilev,k)=(V(k)*tr_t(ilon,ilev,k)+pdtcoag*num)/(1.+pdtcoag*denom)/V(k)
     267!      tr_tp1(ilon,ilev,k)=(V(k)*tr_t(ilon,ilev,k)+pdtcoag*num)/( (1.+pdtcoag*denom)*V(k) )
     268    tr_tp1(ilon,ilev,k)=(Vdry(k)*tr_t(ilon,ilev,k)+pdtcoag*num)/( (1.+pdtcoag*denom)*Vdry(k) )
     269!
     270!       In constant composition (no dependency on aerosol size because no kelvin effect)
     271!       V(l)= (f_r_wet(ilon,ilev)**3)*((mdw(l)/2.)**3) = (f_r_wet(ilon,ilev)**3)*Vdry(i)
     272!       so numi and num are proportional (f_r_wet(ilon,ilev)**3)
     273!       and so
     274!        tr_tp1(ilon,ilev,k)=(V(k)*tr_t(ilon,ilev,k)+pdtcoag*num)/( (1.+pdtcoag*denom)*V(k) )
     275!                     =(Vdry(k)*tr_t(ilon,ilev,k)+pdtcoag*num_dry)/( (1.+pdtcoag*denom)*Vdry(k) )
     276!          with num_dry=...beta(i,j)*Vdry(i)*....
     277!       so in old STRATAER (.not.flag_new_strat_compo), it was correct
    230278  ENDIF
    231279
     
    234282!--convert tracer concentration back from [number/m3] to [number/KgA] and write into tr_seri
    235283  DO i=1, nbtr_bin
    236    tr_seri(ilon,ilev,i+nbtr_sulgas) = tr_tp1(ilon,ilev,i) / zrho
     284     tr_seri(ilon,ilev,i+nbtr_sulgas) = tr_tp1(ilon,ilev,i) / zrho
    237285  ENDDO
    238286
     
    240288  ENDDO !--end of loop klev
    241289  ENDDO !--end of loop klon
     290! *********************************************
    242291
    243292END SUBROUTINE COAGULATE
Note: See TracChangeset for help on using the changeset viewer.