LCOV - code coverage report
Current view: top level - physics/carma/base - growevapl.F90 (source / functions) Hit Total Coverage
Test: coverage.info Lines: 91 100 91.0 %
Date: 2025-03-14 01:33:33 Functions: 1 1 100.0 %

          Line data    Source code
       1             : ! Include shortname defintions, so that the F77 code does not have to be modified to
       2             : ! reference the CARMA structure.
       3             : #include "carma_globaer.h"
       4             : 
       5             : !! This routine evaluate particle loss rates due to condensational
       6             : !! growth and evaporation for all condensing gases.
       7             : !!
       8             : !! The loss rates for each group are <growlg> and <evaplg>.
       9             : !!
      10             : !! Units are [s^-1].
      11             : !!
      12             : !! @author Andy Ackerman
      13             : !! @version Dec-1995
      14  1418703438 : subroutine growevapl(carma, cstate, iz, rc)
      15             : 
      16             :   ! types
      17             :   use carma_precision_mod
      18             :   use carma_enums_mod
      19             :   use carma_constants_mod
      20             :   use carma_types_mod
      21             :   use carmastate_mod
      22             :   use carma_mod
      23             : 
      24             :   implicit none
      25             : 
      26             :   type(carma_type), intent(in)         :: carma   !! the carma object
      27             :   type(carmastate_type), intent(inout) :: cstate  !! the carma state object
      28             :   integer, intent(in)                  :: iz      !! z index
      29             :   integer, intent(inout)               :: rc      !! return code, negative indicates failure
      30             : 
      31             :   ! Local declarations
      32             :   integer                        :: igroup
      33             :   integer                        :: iepart
      34             :   integer                        :: igas
      35             :   integer                        :: ibin
      36             :   integer                        :: isol
      37             :   integer                        :: nother
      38             :   integer                        :: ieoth_rel
      39             :   integer                        :: ieoth_abs
      40             :   integer                        :: jother
      41             :   real(kind=f)                   :: argsol
      42             :   real(kind=f)                   :: othermtot
      43             :   real(kind=f)                   :: condm
      44             :   real(kind=f)                   :: akas
      45             :   real(kind=f)                   :: expon
      46             :   real(kind=f)                   :: g0
      47             :   real(kind=f)                   :: g1
      48             :   real(kind=f)                   :: g2
      49             :   real(kind=f)                   :: ss
      50             :   real(kind=f)                   :: pvap
      51             :   real(kind=f)                   :: dpc
      52             :   real(kind=f)                   :: dpc1
      53             :   real(kind=f)                   :: dpcm1
      54             :   real(kind=f)                   :: rat1
      55             :   real(kind=f)                   :: rat2
      56             :   real(kind=f)                   :: rat3
      57             :   real(kind=f)                   :: rat4
      58             :   real(kind=f)                   :: ratt1
      59             :   real(kind=f)                   :: ratt2
      60             :   real(kind=f)                   :: ratt3
      61             :   real(kind=f)                   :: den1
      62             :   real(kind=f)                   :: test1
      63             :   real(kind=f)                   :: test2
      64             :   real(kind=f)                   :: x
      65             :   integer                        :: ieother(NELEM)
      66             :   real(kind=f)                   :: otherm(NELEM)
      67  2837406876 :   real(kind=f)                   :: dela(NBIN)
      68  2837406876 :   real(kind=f)                   :: delma(NBIN)
      69  2837406876 :   real(kind=f)                   :: aju(NBIN)
      70  2837406876 :   real(kind=f)                   :: ar(NBIN)
      71  2837406876 :   real(kind=f)                   :: al(NBIN)
      72  2837406876 :   real(kind=f)                   :: a6(NBIN)
      73  2837406876 :   real(kind=f)                   :: dmdt(NBIN)
      74             :   real(kind=f)                   :: growlg_max
      75             : 
      76             :   
      77  4256110314 :   do igroup = 1,NGROUP
      78             : 
      79             :     ! element of particle number concentration 
      80  2837406876 :     iepart = ienconc(igroup)
      81             :     
      82             :     ! condensing gas
      83  2837406876 :     igas = igrowgas(iepart)
      84             : 
      85  4256110314 :     if (igas .ne. 0) then
      86             :       ! Only valid for condensing liquid water and sulfric acid currently.
      87  2837406876 :       if ((igas /= igash2o) .and. (igas .ne. igash2so4)) then
      88           0 :         if (do_print) write(LUNOPRT,*) 'growevapl::ERROR - Invalid gas (', igas, ').'
      89           0 :         rc = -1
      90           0 :         return
      91             :       endif
      92             : 
      93             :       ! Treat condensation of gas <igas> to/from particle group <igroup>.
      94             :       !
      95             :       ! Bypass calculation if few particles are present 
      96  2837406876 :       if( pconmax(iz,igroup) .gt. FEW_PC )then
      97 35478933300 :         do ibin = 1,NBIN-1
      98             : 
      99             :           ! Determine the growth rate (dmdt). This calculation may take into account
     100             :           ! radiative effects on the particle which can affect the growth rates.
     101 35478933300 :           call pheat(carma, cstate, iz, igroup, iepart, ibin, igas, dmdt(ibin), rc)
     102             : 
     103             :         enddo     ! ibin = 1,NBIN-1
     104             : 
     105             :         ! Now calculate condensation/evaporation production and loss rates.
     106             :         ! Use Piecewise Polynomial Method [Colela and Woodard, J. Comp. Phys.,
     107             :         ! 54, 174-201, 1984]
     108             :         !
     109             :         ! First, use cubic fits to estimate concentration values at bin
     110             :         ! boundaries
     111 33704986635 :         do ibin = 2,NBIN-1
     112             : 
     113 31931039970 :           dpc = pc(iz,ibin,iepart) / dm(ibin,igroup)
     114 31931039970 :           dpc1 = pc(iz,ibin+1,iepart) / dm(ibin+1,igroup)
     115 31931039970 :           dpcm1 = pc(iz,ibin-1,iepart) / dm(ibin-1,igroup)
     116 31931039970 :           ratt1 = pratt(1,ibin,igroup)
     117 31931039970 :           ratt2 = pratt(2,ibin,igroup)
     118 31931039970 :           ratt3 = pratt(3,ibin,igroup)
     119 31931039970 :           dela(ibin) = ratt1 * ( ratt2*(dpc1-dpc) + ratt3*(dpc-dpcm1) )
     120 31931039970 :           delma(ibin) = 0._f
     121             : 
     122 31931039970 :           if( (dpc1-dpc)*(dpc-dpcm1) .gt. 0._f ) &
     123             :             delma(ibin) = min( abs(dela(ibin)), 2._f*abs(dpc-dpc1), &
     124 32899409334 :                  2._f*abs(dpc-dpcm1) ) * sign(1._f, dela(ibin))
     125             : 
     126             :         enddo     ! ibin = 2,NBIN-2
     127             : 
     128 31931039970 :         do ibin = 2,NBIN-2
     129             : 
     130 30157093305 :           dpc = pc(iz,ibin,iepart) / dm(ibin,igroup)
     131 30157093305 :           dpc1 = pc(iz,ibin+1,iepart) / dm(ibin+1,igroup)
     132 30157093305 :           dpcm1 = pc(iz,ibin-1,iepart) / dm(ibin-1,igroup)
     133 30157093305 :           rat1 = prat(1,ibin,igroup)
     134 30157093305 :           rat2 = prat(2,ibin,igroup)
     135 30157093305 :           rat3 = prat(3,ibin,igroup)
     136 30157093305 :           rat4 = prat(4,ibin,igroup)
     137 30157093305 :           den1 = pden1(ibin,igroup)
     138             : 
     139             :           ! <aju(ibin)> is the estimate for concentration (dn/dm) at bin
     140             :           ! boundary <ibin>+1/2.
     141 30157093305 :           aju(ibin) = dpc + rat1*(dpc1-dpc) + 1._f/den1 * &
     142             :                   ( rat2*(rat3-rat4)*(dpc1-dpc) - &
     143 30157093305 :                   dm(ibin,igroup)*rat3*delma(ibin+1) + &
     144 31931039970 :                   dm(ibin+1,igroup)*rat4*delma(ibin) )
     145             :         enddo     ! ibin = 2,NBIN-2
     146             : 
     147             :         ! Now construct polynomial functions in each bin
     148 30157093305 :         do ibin = 3,NBIN-2
     149 28383146640 :           al(ibin) = aju(ibin-1)
     150 30157093305 :           ar(ibin) = aju(ibin)
     151             :         enddo
     152             : 
     153             :         ! Use linear functions in first two and last two bins
     154  1773946665 :         if( NBIN .gt. 1 )then
     155  1773946665 :           ibin = NBIN
     156             :           
     157  1773946665 :           ar(2) = aju(2)
     158  1773946665 :           al(2) = pc(iz,1,iepart)/dm(1,igroup) + &
     159           0 :                       palr(1,igroup) * &
     160  1773946665 :                       (pc(iz,2,iepart)/dm(2,igroup)- &
     161  3547893330 :                       pc(iz,1,iepart)/dm(1,igroup))
     162  1773946665 :           ar(1) = al(2)
     163           0 :           al(1) = pc(iz,1,iepart)/dm(1,igroup) + &
     164  1773946665 :                       palr(2,igroup) * &
     165  1773946665 :                       (pc(iz,2,iepart)/dm(2,igroup)- &
     166  1773946665 :                       pc(iz,1,iepart)/dm(1,igroup))
     167             :           
     168  1773946665 :           al(ibin-1) = aju(ibin-2)
     169           0 :           ar(ibin-1) = pc(iz,ibin-1,iepart)/dm(ibin-1,igroup) + &
     170  1773946665 :                       palr(3,igroup) * &
     171  1773946665 :                       (pc(iz,ibin,iepart)/dm(ibin,igroup)- &
     172  1773946665 :                       pc(iz,ibin-1,iepart)/dm(ibin-1,igroup))
     173  1773946665 :           al(ibin) = ar(ibin-1)
     174           0 :           ar(ibin) = pc(iz,ibin-1,iepart)/dm(ibin-1,igroup) + &
     175  1773946665 :                       palr(4,igroup) * &
     176  1773946665 :                       (pc(iz,ibin,iepart)/dm(ibin,igroup)- &
     177  3547893330 :                       pc(iz,ibin-1,iepart)/dm(ibin-1,igroup))
     178             :         endif
     179             : 
     180             :         ! Next, ensure that polynomial functions do not deviate beyond the
     181             :         ! range [<al(ibin)>,<ar(ibin)>]
     182 37252879965 :         do ibin = 1,NBIN
     183             : 
     184 35478933300 :           dpc = pc(iz,ibin,iepart) / dm(ibin,igroup)
     185             : 
     186 35478933300 :           if( (ar(ibin)-dpc)*(dpc-al(ibin)) .le. 0._f )then
     187   805577301 :             al(ibin) = dpc
     188   805577301 :             ar(ibin) = dpc
     189             :           endif
     190             : 
     191 35478933300 :           test1 = (ar(ibin)-al(ibin))*(dpc - 0.5_f*(al(ibin)+ar(ibin)))
     192 35478933300 :           test2 = 1._f/6._f*(ar(ibin)-al(ibin))**2
     193             : 
     194 37252879965 :           if( test1 .gt. test2 )then
     195 15610577933 :              al(ibin) = 3._f*dpc - 2._f*ar(ibin)
     196 19868355367 :           elseif( test1 .lt. -test2 )then
     197   372143795 :              ar(ibin) = 3._f*dpc - 2._f*al(ibin)
     198             :           endif
     199             :         enddo
     200             : 
     201             :         !  Lastly, calculate fluxes across each bin boundary.
     202             :         !
     203             :         !  Use upwind advection when courant number > 1.
     204 37252879965 :         do ibin = 1,NBIN
     205 35478933300 :           dpc = pc(iz,ibin,iepart) / dm(ibin,igroup)
     206 35478933300 :           dela(ibin) = ar(ibin) - al(ibin)
     207 37252879965 :           a6(ibin) = 6._f * ( dpc - 0.5_f*(ar(ibin)+al(ibin)) )
     208             :         enddo
     209             : 
     210 35478933300 :         do ibin = 1,NBIN-1
     211             : 
     212 33704986635 :           if( dmdt(ibin) .gt. 0._f .and. &
     213  1773946665 :               pc(iz,ibin,iepart) .gt. SMALL_PC )then
     214             : 
     215 32817939583 :             x = dmdt(ibin)*dtime/dm(ibin,igroup)
     216             : 
     217 32817939583 :             if( x .lt. 1._f )then
     218           0 :               growlg(ibin,igroup) = dmdt(ibin)/pc(iz,ibin,iepart) &
     219             :                        * ( ar(ibin) - 0.5_f*dela(ibin)*x + &
     220 32816383287 :                        (x/2._f - x**2/3._f)*a6(ibin) )
     221             :             else
     222     1556296 :               growlg(ibin,igroup) = dmdt(ibin) / dm(ibin,igroup)
     223             :             endif
     224             : 
     225   887047052 :           elseif( dmdt(ibin) .lt. 0._f .and. &
     226             :               pc(iz,ibin+1,iepart) .gt. SMALL_PC )then
     227             : 
     228   609380597 :             x = -dmdt(ibin)*dtime/dm(ibin+1,igroup)
     229             : 
     230   609380597 :             if( x .lt. 1._f )then
     231           0 :               evaplg(ibin+1,igroup) = -dmdt(ibin)/ &
     232             :                       pc(iz,ibin+1,iepart) &
     233   605688161 :                       * ( al(ibin+1) + 0.5_f*dela(ibin+1)*x + &
     234  1211376322 :                       (x/2._f - (x**2)/3._f)*a6(ibin+1) )
     235             :             else
     236     3692436 :               evaplg(ibin+1,igroup) = -dmdt(ibin) / dm(ibin+1,igroup)
     237             :             endif
     238             : 
     239             :             ! Boundary conditions: for evaporation out of first bin (with cores), 
     240             :             ! use evaporation rate from second bin.
     241             : !            if( ibin .eq. 1 .and. ncore(igroup) .gt. 0 )then
     242   609380597 :             if( ibin .eq. 1)then
     243   213694496 :               evaplg(1,igroup) = -dmdt(1) / dm(1,igroup)
     244             :             endif
     245             :           endif
     246             : 
     247             :         enddo    ! ibin = 1,NBIN-1
     248             :       endif     ! (pconmax .gt. FEW_PC)
     249             :     endif      ! (igas = igrowgas(ielem)) .ne. 0 
     250             :   enddo       ! igroup = 1,NGROUP
     251             : 
     252             :   
     253             :   ! Return to caller with particle loss rates for growth and evaporation
     254             :   ! evaluated.
     255             :    return
     256  1418703438 : end

Generated by: LCOV version 1.14