LCOV - code coverage report
Current view: | top level - physics/cam - ndrop_bam.F90 (source / functions) |  |  | Hit | Total | Coverage
Test: | coverage.info |  | Lines: | 145 | 181 | 80.1 %
Date: | 2024-12-17 17:57:11 |  | Functions: | 4 | 4 | 100.0 %

              Line data    Source code
           1             : module ndrop_bam
           2             :
           3             : !---------------------------------------------------------------------------------
           4             : !
           5             : !   CAM Interface for droplet activation by bulk aerosols.
           6             : !
           7             : !---------------------------------------------------------------------------------
           8             :
           9             : use shr_kind_mod,     only: r8=>shr_kind_r8
          10             : use spmd_utils,       only: masterproc
          11             : use ppgrid,           only: pcols, pver, pverp
          12             : use physconst,        only: gravit, rair, tmelt, cpair, rh2o, &
          13             :      r_universal, mwh2o, rhoh2o, latvap
          14             :
          15             : use rad_constituents, only: rad_cnst_get_info, rad_cnst_get_aer_props
          16             :
          17             : use shr_spfn_mod,     only: erf => shr_spfn_erf, &
          18             :                             erfc => shr_spfn_erfc
          19             : use wv_saturation,    only: qsat
          20             : use cam_history,      only: addfld, add_default, outfld
          21             : use cam_logfile,      only: iulog
          22             : use cam_abortutils,   only: endrun
          23             : use ref_pres,         only: top_lev=>trop_cloud_top_lev
          24             :
          25             : implicit none
          26             : private
          27             : save
          28             :
          29             : public :: ndrop_bam_init, ndrop_bam_run, ndrop_bam_ccn
          30             :
          31             : ! activate parameters
          32             :
          33             : real(r8) :: pi     ! pi
          34             : integer,  parameter :: psat = 6           ! number of supersaturations to calc ccn concentration
          35             : real(r8), parameter :: supersat(psat) = & ! supersaturation (%) to determine ccn concentration
          36             :                        (/0.02_r8,0.05_r8,0.1_r8,0.2_r8,0.5_r8,1.0_r8/)
          37             : real(r8)              :: super(psat)
          38             : real(r8), allocatable :: ccnfact(:,:)
          39             :
          40             : real(r8), allocatable :: alogsig(:)       ! natl log of geometric standard dev of aerosol
          41             : real(r8), allocatable :: exp45logsig(:)
          42             : real(r8), allocatable :: argfactor(:)
          43             : real(r8), allocatable :: amcube(:)        ! cube of dry mode radius (m)
          44             : real(r8), allocatable :: smcrit(:)        ! critical supersatuation for activation
          45             : real(r8), allocatable :: lnsm(:)          ! ln(smcrit)
          46             : real(r8), allocatable :: amcubefactor(:)  ! factors for calculating mode radius
          47             : real(r8), allocatable :: smcritfactor(:)  ! factors for calculating critical supersaturation
          48             : real(r8), allocatable :: f1(:), f2(:)     ! abdul-razzak functions of width
          49             :
          50             : real(r8) :: aten
          51             : real(r8) :: third, sixth
          52             : real(r8) :: sq2, sqpi
          53             : real(r8) :: alogten, alog2, alog3, alogaten
          54             :
          55             : real(r8) :: pref = 1013.25e2_r8 ! reference pressure (Pa)
          56             :
          57             : ! aerosol properties
          58             : character(len=20), allocatable :: aername(:)
          59             : real(r8), allocatable :: dryrad_aer(:)
          60             : real(r8), allocatable :: density_aer(:)
          61             : real(r8), allocatable :: hygro_aer(:)
          62             : real(r8), allocatable :: dispersion_aer(:)
          63             : real(r8), allocatable :: num_to_mass_aer(:)
          64             :
          65             : integer :: naer_all      ! number of aerosols affecting climate
          66             : integer :: idxsul   = -1 ! index in aerosol list for sulfate
          67             :
          68             : !===============================================================================
          69             : contains
          70             : !===============================================================================
          71             :
          72        1536 : subroutine ndrop_bam_init
          73             :
          74             :   use phys_control, only: phys_getopts
          75             :
          76             :    !-----------------------------------------------------------------------
          77             :    !
          78             :    ! Initialize constants for droplet activation by bulk aerosols
          79             :    !
          80             :    !-----------------------------------------------------------------------
          81             :
          82             :    integer  :: l, m, iaer
          83             :    real(r8) :: surften       ! surface tension of water w/respect to air (N/m)
          84             :    real(r8) :: arg
          85             :    logical  :: history_amwg
          86             :    !-------------------------------------------------------------------------------
          87             :
          88        1536 :    call phys_getopts(history_amwg_out=history_amwg)
          89             :
          90             :    ! Access the physical properties of the bulk aerosols that are affecting the climate
          91             :    ! by using routines from the rad_constituents module.
          92             :
          93        1536 :    call rad_cnst_get_info(0, naero=naer_all)
          94             :    allocate( &
          95           0 :       aername(naer_all),        &
          96           0 :       dryrad_aer(naer_all),     &
          97           0 :       density_aer(naer_all),    &
          98           0 :       hygro_aer(naer_all),      &
          99           0 :       dispersion_aer(naer_all), &
         100       13824 :       num_to_mass_aer(naer_all) )
         101             :
         102       21504 :    do iaer = 1, naer_all
         103             :       call rad_cnst_get_aer_props(0, iaer, &
         104           0 :          aername         = aername(iaer), &
         105           0 :          dryrad_aer      = dryrad_aer(iaer), &
         106           0 :          density_aer     = density_aer(iaer), &
         107           0 :          hygro_aer       = hygro_aer(iaer), &
         108           0 :          dispersion_aer  = dispersion_aer(iaer), &
         109       19968 :          num_to_mass_aer = num_to_mass_aer(iaer) )
         110             :
         111             :       ! Look for sulfate aerosol in this list (Bulk aerosol only)
         112       19968 :       if (trim(aername(iaer)) == 'SULFATE') idxsul   = iaer
         113             :
         114             :       ! aerosol number concentration
         115       41472 :       call addfld(trim(aername(iaer))//'_m3', (/ 'lev' /), 'A', 'm-3', 'aerosol number concentration')
         116             :
         117             :    end do
         118             :
         119        1536 :    if (masterproc) then
         120           2 :       write(iulog,*) 'ndrop_bam_init: iaer, name, dryrad, density, hygro, dispersion, num_to_mass'
         121          28 :       do iaer = 1, naer_all
         122          26 :          write(iulog,*) iaer, aername(iaer), dryrad_aer(iaer), density_aer(iaer), hygro_aer(iaer), &
         123          54 :             dispersion_aer(iaer), num_to_mass_aer(iaer)
         124             :       end do
         125           2 :       if (idxsul < 1) then
         126           0 :          write(iulog,*) 'ndrop_bam_init: SULFATE aerosol properties NOT FOUND'
         127             :       else
         128           2 :          write(iulog,*) 'ndrop_bam_init: SULFATE aerosol properties FOUND at index ',idxsul
         129             :       end if
         130             :    end if
         131             :
         132        3072 :    call addfld ('CCN1',(/ 'lev' /), 'A','#/cm3','CCN concentration at S=0.02%')
         133        3072 :    call addfld ('CCN2',(/ 'lev' /), 'A','#/cm3','CCN concentration at S=0.05%')
         134        3072 :    call addfld ('CCN3',(/ 'lev' /), 'A','#/cm3','CCN concentration at S=0.1%')
         135        3072 :    call addfld ('CCN4',(/ 'lev' /), 'A','#/cm3','CCN concentration at S=0.2%')
         136        3072 :    call addfld ('CCN5',(/ 'lev' /), 'A','#/cm3','CCN concentration at S=0.5%')
         137        3072 :    call addfld ('CCN6',(/ 'lev' /), 'A','#/cm3','CCN concentration at S=1.0%')
         138             :
         139        1536 :    if (history_amwg) then
         140        1536 :       call add_default('CCN3', 1, ' ')
         141             :    end if
         142             :
         143             :    ! set parameters for droplet activation, following abdul-razzak and ghan 2000, JGR
         144             :
         145        1536 :    third   = 1._r8/3._r8
         146        1536 :    sixth   = 1._r8/6._r8
         147        1536 :    sq2     = sqrt(2._r8)
         148        1536 :    pi      = 4._r8*atan(1.0_r8)
         149        1536 :    sqpi    = sqrt(pi)
         150        1536 :    surften = 0.076_r8
         151        1536 :    aten    = 2._r8*mwh2o*surften/(r_universal*tmelt*rhoh2o)
         152        1536 :    alogaten= log(aten)
         153        1536 :    alog2   = log(2._r8)
         154        1536 :    alog3   = log(3._r8)
         155        1536 :    super(:)= 0.01_r8*supersat(:)
         156             :
         157             :    allocate(                  &
         158           0 :       alogsig(naer_all),      &
         159           0 :       exp45logsig(naer_all),  &
         160           0 :       argfactor(naer_all),    &
         161           0 :       f1(naer_all),           &
         162           0 :       f2(naer_all),           &
         163           0 :       amcubefactor(naer_all), &
         164           0 :       smcritfactor(naer_all), &
         165           0 :       amcube(naer_all),       &
         166           0 :       smcrit(naer_all),       &
         167           0 :       lnsm(naer_all),         &
         168       21504 :       ccnfact(psat,naer_all)  )
         169             :
         170             :
         171       21504 :    do m = 1, naer_all
         172             :
         173             :       ! Skip aerosols that don't have a dispersion defined.
         174       19968 :       if (dispersion_aer(m) == 0._r8) cycle
         175             :
         176       19968 :       alogsig(m)     = log(dispersion_aer(m))
         177       19968 :       exp45logsig(m) = exp(4.5_r8*alogsig(m)*alogsig(m))
         178       19968 :       argfactor(m)   = 2._r8/(3._r8*sqrt(2._r8)*alogsig(m))
         179       19968 :       f1(m)          = 0.5_r8*exp(2.5_r8*alogsig(m)*alogsig(m))
         180       19968 :       f2(m)          = 1._r8 + 0.25_r8*alogsig(m)
         181       19968 :       amcubefactor(m)= 3._r8/(4._r8*pi*exp45logsig(m)*density_aer(m))
         182       19968 :       smcritfactor(m)= 2._r8*aten*sqrt(aten/(27._r8*max(1.e-10_r8,hygro_aer(m))))
         183       19968 :       amcube(m)      = amcubefactor(m)/num_to_mass_aer(m)
         184             :
         185       19968 :       if (hygro_aer(m) .gt. 1.e-10_r8) then
         186       19968 :          smcrit(m) = smcritfactor(m)/sqrt(amcube(m))
         187             :       else
         188           0 :          smcrit(m) = 100._r8
         189             :       endif
         190       19968 :       lnsm(m) = log(smcrit(m))
         191             :
         192      141312 :       do l = 1, psat
         193      119808 :          arg = argfactor(m)*log(smcrit(m)/super(l))
         194      139776 :          if (arg < 2) then
         195       90624 :             if (arg < -2) then
         196       52224 :                ccnfact(l,m) = 1.e-6_r8
         197             :             else
         198       38400 :                ccnfact(l,m) = 1.e-6_r8*0.5_r8*erfc(arg)
         199             :             endif
         200             :          else
         201       29184 :             ccnfact(l,m) = 0._r8
         202             :          endif
         203             :       enddo
         204             :
         205             :    end do
         206             :
         207        1536 : end subroutine ndrop_bam_init
         208             :
         209             : !===============================================================================
         210             :
         211   512413729 : subroutine ndrop_bam_run( &
         212   512413729 :    wbar, tair, rhoair, na, pmode, &
         213   512413729 :    nmode, ma, nact)
         214             :
         215             :    ! calculates number fraction of aerosols activated as CCN
         216             :    ! assumes an internal mixture within each of up to pmode multiple aerosol modes
         217             :    ! a gaussian spectrum of updrafts can be treated.
         218             :
         219             :    !      mks units
         220             :
         221             :    !      Abdul-Razzak and Ghan, A parameterization of aerosol activation.
         222             :    !      2. Multiple aerosol types. J. Geophys. Res., 105, 6837-6844.
         223             :
         224             :    ! input
         225             :    integer,  intent(in) :: pmode         ! dimension of modes
         226             :    integer,  intent(in) :: nmode         ! number of aerosol modes
         227             :    real(r8), intent(in) :: wbar          ! grid cell mean vertical velocity (m/s)
         228             :    real(r8), intent(in) :: tair          ! air temperature (K)
         229             :    real(r8), intent(in) :: rhoair        ! air density (kg/m3)
         230             :    real(r8), intent(in) :: na(pmode)     ! aerosol number concentration (1/m3)
         231             :    real(r8), intent(in) :: ma(pmode)     ! aerosol mass concentration (kg/m3)
         232             :
         233             :    ! output
         234             :    real(r8), intent(out) :: nact         ! number fraction of aerosols activated
         235             :
         236             :    ! local variables
         237             :    integer :: maxmodes
         238             :
         239   512413729 :    real(r8), allocatable :: volc(:) ! total aerosol volume  concentration (m3/m3)
         240   512413729 :    real(r8), allocatable :: eta(:)
         241   512413729 :    real(r8), allocatable :: smc(:)
         242   512413729 :    real(r8), allocatable :: etafactor2(:)
         243   512413729 :    real(r8), allocatable :: amcubeloc(:)
         244   512413729 :    real(r8), allocatable :: lnsmloc(:)
         245             :
         246             :    real(r8) :: pres     ! pressure (Pa)
         247             :    real(r8) :: diff0
         248             :    real(r8) :: conduct0 ! thermal conductivity (Joule/m/sec/deg)
         249             :    real(r8) :: qs       ! water vapor saturation mixing ratio
         250             :    real(r8) :: dqsdt    ! change in qs with temperature
         251             :    real(r8) :: gloc     ! thermodynamic function (m2/s)
         252             :    real(r8) :: zeta
         253             :    real(r8) :: lnsmax   ! ln(smax)
         254             :    real(r8) :: alpha
         255             :    real(r8) :: gammaloc
         256             :    real(r8) :: beta
         257             :    real(r8) :: sqrtg
         258             :    real(r8) :: wnuc
         259             :    real(r8) :: alw
         260             :    real(r8) :: sqrtalw
         261             :    real(r8) :: smax
         262             :    real(r8) :: x
         263             :    real(r8) :: etafactor1
         264             :    real(r8) :: etafactor2max
         265             :    real(r8) :: es
         266             :    integer  :: m
         267             :    !-------------------------------------------------------------------------------
         268             :
         269   512413729 :    maxmodes = naer_all
         270             :    allocate( &
         271             :       volc(maxmodes),       &
         272             :       eta(maxmodes),        &
         273             :       smc(maxmodes),        &
         274             :       etafactor2(maxmodes), &
         275             :       amcubeloc(maxmodes),  &
         276  4099309832 :       lnsmloc(maxmodes)     )
         277             :
         278   512413729 :    if (maxmodes < pmode) then
         279           0 :       write(iulog,*)'ndrop_bam_run: maxmodes,pmode=',maxmodes,pmode
         280           0 :       call endrun('ndrop_bam_run')
         281             :    endif
         282             :
         283   512413729 :    nact = 0._r8
         284             :
         285   512413729 :    if (nmode .eq. 1  .and.  na(1) .lt. 1.e-20_r8) return
         286             :
         287   512413729 :    if (wbar .le. 0._r8) return
         288             :
         289   512413729 :    pres     = rair*rhoair*tair
         290   512413729 :    diff0    = 0.211e-4_r8*(pref/pres)*(tair/tmelt)**1.94_r8
         291   512413729 :    conduct0 = (5.69_r8 + 0.017_r8*(tair-tmelt))*4.186e2_r8*1.e-5_r8 ! convert to J/m/s/deg
         292   512413729 :    call qsat(tair, pres, es, qs)
         293   512413729 :    dqsdt    = latvap/(rh2o*tair*tair)*qs
         294   512413729 :    alpha    = gravit*(latvap/(cpair*rh2o*tair*tair) - 1._r8/(rair*tair))
         295   512413729 :    gammaloc = (1 + latvap/cpair*dqsdt)/(rhoair*qs)
         296             :    ! growth coefficent Abdul-Razzak & Ghan 1998 eqn 16
         297             :    ! should depend on mean radius of mode to account for gas kinetic effects
         298             :    gloc     = 1._r8/(rhoh2o/(diff0*rhoair*qs)                               &
         299   512413729 :               + latvap*rhoh2o/(conduct0*tair)*(latvap/(rh2o*tair) - 1._r8))
         300   512413729 :    sqrtg    = sqrt(gloc)
         301   512413729 :    beta     = 4._r8*pi*rhoh2o*gloc*gammaloc
         302   512413729 :    etafactor2max = 1.e10_r8/(alpha*wbar)**1.5_r8 ! this should make eta big if na is very small.
         303             :
         304  7173792206 :    do m = 1, nmode
         305             :       ! skip aerosols with no dispersion, since they aren't meant to be CCN
         306  6661378477 :       if (dispersion_aer(m) == 0._r8) then
         307           0 :          smc(m)=100._r8
         308           0 :          cycle
         309             :       end if
         310             :       ! internal mixture of aerosols
         311  6661378477 :       volc(m) = ma(m)/(density_aer(m)) ! only if variable size dist
         312  6661378477 :       if (volc(m) > 1.e-39_r8 .and. na(m) > 1.e-39_r8) then
         313  6661378477 :          etafactor2(m) = 1._r8/(na(m)*beta*sqrtg)  !fixed or variable size dist
         314             :          ! number mode radius (m)
         315  6661378477 :          amcubeloc(m) = (3._r8*volc(m)/(4._r8*pi*exp45logsig(m)*na(m)))  ! only if variable size dist
         316  6661378477 :          smc(m) = smcrit(m) ! only for prescribed size dist
         317             :
         318  6661378477 :          if (hygro_aer(m) > 1.e-10_r8) then   ! loop only if variable size dist
         319  6661378477 :             smc(m) = 2._r8*aten*sqrt(aten/(27._r8*hygro_aer(m)*amcubeloc(m)))
         320             :          else
         321           0 :             smc(m) = 100._r8
         322             :          endif
         323             :       else
         324           0 :          smc(m) = 1._r8
         325           0 :          etafactor2(m) = etafactor2max ! this should make eta big if na is very small.
         326             :       end if
         327  7173792206 :       lnsmloc(m) = log(smc(m)) ! only if variable size dist
         328             :    end do
         329             :
         330             :    ! single  updraft
         331   512413729 :    wnuc    = wbar
         332   512413729 :    alw     = alpha*wnuc
         333   512413729 :    sqrtalw = sqrt(alw)
         334   512413729 :    zeta    = 2._r8*sqrtalw*aten/(3._r8*sqrtg)
         335   512413729 :    etafactor1 = 2._r8*alw*sqrtalw
         336             :
         337  7173792206 :    do m = 1, nmode
         338             :       ! skip aerosols with no dispersion, since they aren't meant to be CCN
         339  7173792206 :       if (dispersion_aer(m) /= 0._r8) eta(m) = etafactor1*etafactor2(m)
         340             :    end do
         341             :
         342   512413729 :    call maxsat(zeta, eta, nmode, smc, smax)
         343   512413729 :    lnsmax = log(smax)
         344             :
         345   512413729 :    nact = 0._r8
         346  7173792206 :    do m = 1, nmode
         347             :       ! skip aerosols with no dispersion, since they aren't meant to be CCN
         348  6661378477 :       if (dispersion_aer(m) == 0._r8) cycle
         349  6661378477 :       x = 2*(lnsmloc(m) - lnsmax)/(3*sq2*alogsig(m))
         350  7173792206 :       nact = nact + 0.5_r8*(1._r8 - erf(x))*na(m)
         351             :    end do
         352   512413729 :    nact = nact/rhoair ! convert from #/m3 to #/kg
         353             :
         354           0 :    deallocate( &
         355             :       volc,       &
         356           0 :       eta,        &
         357           0 :       smc,        &
         358           0 :       etafactor2, &
         359           0 :       amcubeloc,  &
         360   512413729 :       lnsmloc     )
         361             :
         362  1537241187 : end subroutine ndrop_bam_run
         363             :
         364             : !===============================================================================
         365             :
         366     4467528 : subroutine ndrop_bam_ccn(lchnk, ncol, maerosol, naer2)
         367             :
         368             :    !-------------------------------------------------------------------------------
         369             :    !
         370             :    ! Write diagnostic bulk aerosol ccn concentration
         371             :    !
         372             :    !-------------------------------------------------------------------------------
         373             :
         374             :    ! Input arguments
         375             :    integer,  intent(in) :: lchnk           ! chunk identifier
         376             :    integer,  intent(in) :: ncol            ! number of columns
         377             :    real(r8), intent(in) :: naer2(:,:,:)    ! aerosol number concentration (1/m3)
         378             :    real(r8), intent(in) :: maerosol(:,:,:) ! aerosol mass conc (kg/m3)
         379             :
         380             :    ! Local variables
         381             :    integer :: i, k, l, m
         382             :    real(r8) :: arg
         383             :
         384             :    character*8, parameter :: ccn_name(psat)=(/'CCN1','CCN2','CCN3','CCN4','CCN5','CCN6'/)
         385             :    real(r8) :: amcubesulfate(pcols)  ! cube of dry mode radius (m) of sulfate
         386             :    real(r8) :: smcritsulfate(pcols)  ! critical supersatuation for activation of sulfate
         387             :    real(r8) :: ccnfactsulfate
         388             :    real(r8) :: ccn(pcols,pver,psat)  ! number conc of aerosols activated at supersat
         389             :    !-------------------------------------------------------------------------------
         390             :
         391 41656581720 :    ccn(:ncol,:,:) = 0._r8
         392             :
         393   379739880 :    do k = top_lev, pver
         394             :
         395  5258280456 :       do m = 1, naer_all
         396             :
         397  4878540576 :          if (m == idxsul) then
         398             :             ! Lohmann treatment for sulfate has variable size distribution
         399  6266175552 :             do i = 1, ncol
         400  6266175552 :                if (naer2(i,k,m) > 0._r8) then
         401  5890903200 :                   amcubesulfate(i) = amcubefactor(m)*maerosol(i,k,m)/(naer2(i,k,m))
         402  5890903200 :                   smcritsulfate(i) = smcritfactor(m)/sqrt(amcubesulfate(i))
         403             :                else
         404           0 :                   smcritsulfate(i) = 1._r8
         405             :                end if
         406             :             end do
         407             :          end if
         408             :
         409 34525056384 :          do l = 1, psat
         410             :
         411 34149784032 :             if (m == idxsul) then
         412             :                ! This code is modifying ccnfact for sulfate only.
         413 37597053312 :                do i = 1, ncol
         414 35345419200 :                   arg = argfactor(m)*log(smcritsulfate(i)/super(l))
         415 35345419200 :                   if (arg < 2) then
         416 35345419200 :                      if (arg < -2) then
         417             :                         ccnfactsulfate = 1.0e-6_r8
         418             :                      else
         419 35345419200 :                         ccnfactsulfate = 0.5e-6_r8*erfc(arg)
         420             :                      end if
         421             :                   else
         422             :                      ccnfactsulfate = 0.0_r8
         423             :                   end if
         424 37597053312 :                   ccn(i,k,l) = ccn(i,k,l) + naer2(i,k,m)*ccnfactsulfate
         425             :                end do
         426             :             else
         427             :                ! Non-sulfate species use ccnfact computed by the init routine
         428 >45116*10^7 :                ccn(:ncol,k,l) = ccn(:ncol,k,l) + naer2(:ncol,k,m)*ccnfact(l,m)
         429             :             end if
         430             :
         431             :          end do   ! supersaturation
         432             :       end do      ! bulk aerosol
         433             :    end do         ! level
         434             :
         435    31272696 :    do l = 1, psat
         436    31272696 :       call outfld(ccn_name(l), ccn(1,1,l), pcols, lchnk)
         437             :    end do
         438             :
         439    62545392 :    do l = 1, naer_all
         440    62545392 :       call outfld(trim(aername(l))//'_m3', naer2(:,:,l), pcols, lchnk)
         441             :    end do
         442             :
         443     4467528 : end subroutine ndrop_bam_ccn
         444             :
         445             : !===============================================================================
         446             :
         447   512413729 : subroutine maxsat(zeta, eta, nmode, smc, smax)
         448             :
         449             :    ! calculates maximum supersaturation for multiple
         450             :    ! competing aerosol modes.
         451             :
         452             :    ! Abdul-Razzak and Ghan, A parameterization of aerosol activation.
         453             :    ! 2. Multiple aerosol types. J. Geophys. Res., 105, 6837-6844.
         454             :
         455             :    real(r8), intent(in) :: zeta
         456             :    integer,  intent(in) :: nmode ! number of modes
         457             :    real(r8), intent(in) :: smc(:) ! critical supersaturation for number mode radius
         458             :    real(r8), intent(in) :: eta(:)
         459             :
         460             :    real(r8), intent(out) :: smax ! maximum supersaturation
         461             :
         462             :    integer :: m  ! mode index
         463             :    real(r8) :: sum, g1, g2
         464             :
         465   512413729 :    do m=1,nmode
         466   512413729 :       if(zeta.gt.1.e5_r8*eta(m).or.smc(m)*smc(m).gt.1.e5_r8*eta(m))then
         467             :          ! weak forcing. essentially none activated
         468           0 :          smax=1.e-20_r8
         469             :       else
         470             :          ! significant activation of this mode. calc activation all modes.
         471             :          go to 1
         472             :       endif
         473             :    enddo
         474             :
         475   512413729 :    return
         476             :
         477             : 1  continue
         478             :
         479             :    sum=0
         480  7173792206 :    do m=1,nmode
         481  7173792206 :       if(eta(m).gt.1.e-20_r8)then
         482  6661378477 :          g1=sqrt(zeta/eta(m))
         483  6661378477 :          g1=g1*g1*g1
         484  6661378477 :          g2=smc(m)/sqrt(eta(m)+3*zeta)
         485  6661378477 :          g2=sqrt(g2)
         486  6661378477 :          g2=g2*g2*g2
         487  6661378477 :          sum=sum+(f1(m)*g1+f2(m)*g2)/(smc(m)*smc(m))
         488             :       else
         489             :          sum=1.e20_r8
         490             :       endif
         491             :    enddo
         492             :
         493   512413729 :    smax=1._r8/sqrt(sum)
         494             :
         495             : end subroutine maxsat
         496             :
         497             : !===============================================================================
         498             :
         499             : end module ndrop_bam

Generated by: LCOV version 1.14