LCOV - code coverage report
Current view: | top level - chemistry/bulk_aero - aero_model.F90 (source / functions) |  |  | Hit | Total | Coverage
Test: | coverage.info |  | Lines: | 63 | 427 | 14.8 %
Date: | 2025-01-13 21:54:50 |  | Functions: | 4 | 9 | 44.4 %

              Line data    Source code
           1             : !===============================================================================
           2             : ! Bulk Aerosol Model
           3             : !===============================================================================
           4             : module aero_model
           5             :   use shr_kind_mod,      only: r8 => shr_kind_r8
           6             :   use constituents,      only: pcnst, cnst_name, cnst_get_ind
           7             :   use ppgrid,            only: pcols, pver, pverp
           8             :   use cam_abortutils,    only: endrun
           9             :   use cam_logfile,       only: iulog
          10             :   use perf_mod,          only: t_startf, t_stopf
          11             :   use camsrfexch,        only: cam_in_t, cam_out_t
          12             :   use aerodep_flx,       only: aerodep_flx_prescribed
          13             :   use physics_types,     only: physics_state, physics_ptend, physics_ptend_init
          14             :   use physics_buffer,    only: physics_buffer_desc
          15             :   use physconst,         only: gravit, rair
          16             :   use dust_model,        only: dust_active, dust_names, dust_nbin
          17             :   use seasalt_model,     only: sslt_active=>seasalt_active, seasalt_names, seasalt_nbin
          18             :   use spmd_utils,        only: masterproc
          19             :   use physics_buffer,    only: pbuf_get_field, pbuf_get_index
          20             :   use cam_history,       only: outfld
          21             :   use infnan,            only: nan, assignment(=)
          22             :
          23             :   implicit none
          24             :   private
          25             :
          26             :   public :: aero_model_readnl
          27             :   public :: aero_model_register
          28             :   public :: aero_model_init
          29             :   public :: aero_model_gasaerexch ! create, grow, change, and shrink aerosols.
          30             :   public :: aero_model_drydep     ! aerosol dry deposition and sediment
          31             :   public :: aero_model_wetdep     ! aerosol wet removal
          32             :   public :: aero_model_emissions  ! aerosol emissions
          33             :   public :: aero_model_surfarea    ! tropospheric aerosol wet surface area for chemistry
          34             :   public :: aero_model_strat_surfarea   ! stub
          35             :
          36             :   public :: wetdep_lq
          37             :
          38             :  ! Misc private data
          39             :
          40             :   integer :: so4_ndx, cb2_ndx, oc2_ndx, nit_ndx
          41             :   integer :: soa_ndx, soai_ndx, soam_ndx, soab_ndx, soat_ndx, soax_ndx
          42             :
          43             :   ! Namelist variables
          44             :   character(len=16) :: wetdep_list(pcnst) = ' '
          45             :   character(len=16) :: drydep_list(pcnst) = ' '
          46             :
          47             :   integer :: ndrydep = 0
          48             :   integer,allocatable :: drydep_indices(:)
          49             :   integer :: nwetdep = 0
          50             :   integer,allocatable :: wetdep_indices(:)
          51             :   logical :: drydep_lq(pcnst)
          52             :   logical, protected :: wetdep_lq(pcnst)
          53             :
          54             :   integer :: fracis_idx = 0
          55             :
          56             :   real(r8) :: aer_sol_facti(pcnst) ! in-cloud solubility factor
          57             :   real(r8) :: aer_sol_factb(pcnst) ! below-cloud solubility factor
          58             :   real(r8) :: aer_scav_coef(pcnst)
          59             :
          60             : contains
          61             :
          62             :   !=============================================================================
          63             :   ! reads aerosol namelist options
          64             :   !=============================================================================
          65           0 :   subroutine aero_model_readnl(nlfile)
          66             :
          67             :     use namelist_utils,  only: find_group_name
          68             :     use units,           only: getunit, freeunit
          69             :     use mpishorthand
          70             :
          71             :     character(len=*), intent(in) :: nlfile  ! filepath for file containing namelist input
          72             :
          73             :     ! Local variables
          74             :     integer :: unitn, ierr
          75             :     character(len=*), parameter :: subname = 'aero_model_readnl'
          76             :
          77             :     ! Namelist variables
          78             :     character(len=16) :: aer_wetdep_list(pcnst) = ' '
          79             :     character(len=16) :: aer_drydep_list(pcnst) = ' '
          80             :
          81             :     namelist /aerosol_nl/ aer_wetdep_list, aer_drydep_list
          82             :     namelist /aerosol_nl/ aer_sol_facti, aer_sol_factb, aer_scav_coef
          83             :     !-----------------------------------------------------------------------------
          84           0 :     aer_sol_facti = nan
          85           0 :     aer_sol_factb = nan
          86           0 :     aer_scav_coef = nan
          87             :
          88             :     ! Read namelist
          89           0 :     if (masterproc) then
          90           0 :        unitn = getunit()
          91           0 :        open( unitn, file=trim(nlfile), status='old' )
          92           0 :        call find_group_name(unitn, 'aerosol_nl', status=ierr)
          93           0 :        if (ierr == 0) then
          94           0 :           read(unitn, aerosol_nl, iostat=ierr)
          95           0 :           if (ierr /= 0) then
          96           0 :              call endrun(subname // ':: ERROR reading namelist')
          97             :           end if
          98             :        end if
          99           0 :        close(unitn)
         100           0 :        call freeunit(unitn)
         101             :     end if
         102             :
         103             : #ifdef SPMD
         104             :     ! Broadcast namelist variables
         105           0 :     call mpibcast(aer_wetdep_list, len(aer_wetdep_list(1))*pcnst, mpichar, 0, mpicom)
         106           0 :     call mpibcast(aer_drydep_list, len(aer_drydep_list(1))*pcnst, mpichar, 0, mpicom)
         107           0 :     call mpibcast(aer_sol_facti, pcnst, mpir8, 0, mpicom)
         108           0 :     call mpibcast(aer_sol_factb, pcnst, mpir8, 0, mpicom)
         109           0 :     call mpibcast(aer_scav_coef, pcnst, mpir8, 0, mpicom)
         110             : #endif
         111             :
         112           0 :     wetdep_list = aer_wetdep_list
         113           0 :     drydep_list = aer_drydep_list
         114             :
         115           0 :   end subroutine aero_model_readnl
         116             :
         117             :   !=============================================================================
         118             :   !=============================================================================
         119        1536 :   subroutine aero_model_register()
         120             :     use mo_setsoa, only : soa_register
         121             :
         122        1536 :     call soa_register()
         123        1536 :   end subroutine aero_model_register
         124             :
         125             :   !=============================================================================
         126             :   !=============================================================================
         127        1536 :   subroutine aero_model_init( pbuf2d )
         128             :
         129             :     use mo_chem_utls,   only: get_inv_ndx, get_spc_ndx
         130             :     use cam_history,    only: addfld, add_default, horiz_only
         131             :     use phys_control,   only: phys_getopts
         132             :     use mo_aerosols,    only: aerosols_inti
         133             :     use mo_setsoa,      only: soa_inti
         134             :     use dust_model,     only: dust_init
         135             :     use seasalt_model,  only: seasalt_init
         136             :     use aer_drydep_mod, only: inidrydep
         137             :     use wetdep,         only: wetdep_init
         138             :     use mo_setsox,      only: has_sox
         139             :
         140             :     ! args
         141             :     type(physics_buffer_desc), pointer :: pbuf2d(:,:)
         142             :
         143             :     ! local vars
         144             :     character(len=12), parameter :: subrname = 'aero_model_init'
         145             :     integer :: m, id
         146             :     character(len=20) :: dummy
         147             :     logical  :: history_aerosol ! Output MAM or SECT aerosol tendencies
         148             :     logical  :: history_dust    ! Output dust
         149             :
         150             :     call phys_getopts( history_aerosol_out = history_aerosol,&
         151        1536 :                        history_dust_out    = history_dust   )
         152             :
         153        1536 :     call aerosols_inti()
         154        1536 :     call soa_inti(pbuf2d)
         155        1536 :     call dust_init()
         156        1536 :     call seasalt_init()
         157        1536 :     call wetdep_init()
         158             :
         159        1536 :     fracis_idx = pbuf_get_index('FRACIS')
         160             :
         161        1536 :     nwetdep = 0
         162        1536 :     ndrydep = 0
         163             :
         164        6144 :     count_species: do m = 1,pcnst
         165        4608 :        if ( len_trim(wetdep_list(m)) /= 0 ) then
         166           0 :           nwetdep = nwetdep+1
         167             :        endif
         168        6144 :        if ( len_trim(drydep_list(m)) /= 0 ) then
         169           0 :           ndrydep = ndrydep+1
         170             :        endif
         171             :     enddo count_species
         172             :
         173        1536 :     if (nwetdep>0) &
         174           0 :          allocate(wetdep_indices(nwetdep))
         175        1536 :     if (ndrydep>0) &
         176           0 :          allocate(drydep_indices(ndrydep))
         177             :
         178        1536 :     do m = 1,ndrydep
         179           0 :        call cnst_get_ind ( drydep_list(m), id, abort=.false. )
         180           0 :        if (id>0) then
         181           0 :           drydep_indices(m) = id
         182             :        else
         183           0 :           call endrun(subrname//': invalid drydep species: '//trim(drydep_list(m)) )
         184             :        endif
         185             :
         186        1536 :        if (masterproc) then
         187           0 :           write(iulog,*) subrname//': '//drydep_list(m)//' will have drydep applied'
         188             :        endif
         189             :     enddo
         190        1536 :     do m = 1,nwetdep
         191           0 :        call cnst_get_ind ( wetdep_list(m), id, abort=.false. )
         192           0 :        if (id>0) then
         193           0 :           wetdep_indices(m) = id
         194             :        else
         195           0 :           call endrun(subrname//': invalid wetdep species: '//trim(wetdep_list(m)) )
         196             :        endif
         197             :
         198        1536 :        if (masterproc) then
         199           0 :           write(iulog,*) subrname//': '//wetdep_list(m)//' will have wet removal'
         200             :        endif
         201             :     enddo
         202             :
         203             :     ! set flags for drydep tendencies
         204        1536 :     drydep_lq(:) = .false.
         205        1536 :     do m=1,ndrydep
         206           0 :        id = drydep_indices(m)
         207        1536 :        drydep_lq(id) =  .true.
         208             :     enddo
         209             :
         210             :     ! set flags for wetdep tendencies
         211        1536 :     wetdep_lq(:) = .false.
         212        1536 :     do m=1,nwetdep
         213           0 :        id = wetdep_indices(m)
         214        1536 :        wetdep_lq(id) = .true.
         215             :     enddo
         216             :
         217        1536 :     do m = 1,ndrydep
         218             :
         219           0 :        dummy = trim(drydep_list(m)) // 'TB'
         220           0 :        call addfld (dummy,horiz_only, 'A','kg/m2/s',trim(drydep_list(m))//' turbulent dry deposition flux')
         221           0 :        if ( history_aerosol ) then
         222           0 :           call add_default (dummy, 1, ' ')
         223             :        endif
         224           0 :        dummy = trim(drydep_list(m))  // 'GV'
         225           0 :        call addfld (dummy,horiz_only, 'A','kg/m2/s',trim(drydep_list(m)) //' gravitational dry deposition flux')
         226           0 :        if ( history_aerosol ) then
         227           0 :           call add_default (dummy, 1, ' ')
         228             :        endif
         229           0 :        dummy = trim(drydep_list(m))  // 'DD'
         230           0 :        call addfld (dummy,horiz_only, 'A','kg/m2/s',trim(drydep_list(m)) //' dry deposition flux at bottom (grav + turb)')
         231           0 :        if ( history_aerosol ) then
         232           0 :           call add_default (dummy, 1, ' ')
         233             :        endif
         234           0 :        dummy = trim(drydep_list(m)) // 'DT'
         235           0 :        call addfld (dummy,(/ 'lev' /), 'A','kg/kg/s',trim(drydep_list(m))//' dry deposition')
         236           0 :        if ( history_aerosol ) then
         237           0 :           call add_default (dummy, 1, ' ')
         238             :        endif
         239           0 :        dummy = trim(drydep_list(m)) // 'DV'
         240           0 :        call addfld (dummy,(/ 'lev' /), 'A','m/s',trim(drydep_list(m))//' deposition velocity')
         241        1536 :        if ( history_aerosol ) then
         242           0 :           call add_default (dummy, 1, ' ')
         243             :        endif
         244             :
         245             :     enddo
         246             :
         247        1536 :     if (ndrydep>0) then
         248             :
         249           0 :        call inidrydep(rair, gravit)
         250             :
         251           0 :        dummy = 'RAM1'
         252           0 :        call addfld (dummy,horiz_only, 'A','frac','RAM1')
         253           0 :        if ( history_aerosol ) then
         254           0 :           call add_default (dummy, 1, ' ')
         255             :        endif
         256           0 :        dummy = 'airFV'
         257           0 :        call addfld (dummy,horiz_only, 'A','frac','FV')
         258           0 :        if ( history_aerosol ) then
         259           0 :           call add_default (dummy, 1, ' ')
         260             :        endif
         261             :
         262           0 :        if (sslt_active) then
         263           0 :           dummy = 'SSTSFDRY'
         264           0 :           call addfld (dummy,horiz_only, 'A','kg/m2/s','Sea salt deposition flux at surface')
         265           0 :           if ( history_aerosol ) then
         266           0 :              call add_default (dummy, 1, ' ')
         267             :           endif
         268             :        endif
         269           0 :        if (dust_active) then
         270           0 :           dummy = 'DSTSFDRY'
         271           0 :           call addfld (dummy,horiz_only, 'A','kg/m2/s','Dust deposition flux at surface')
         272           0 :           if ( history_aerosol ) then
         273           0 :              call add_default (dummy, 1, ' ')
         274             :           endif
         275             :        endif
         276             :
         277             :     endif
         278             :
         279        1536 :     do m = 1,nwetdep
         280             :
         281           0 :        call addfld (trim(wetdep_list(m))//'SFWET', horiz_only,  'A','kg/m2/s', &
         282           0 :             'Wet deposition flux at surface')
         283             :        call addfld (trim(wetdep_list(m))//'SFSIC', horiz_only,  'A','kg/m2/s', &
         284           0 :             'Wet deposition flux (incloud, convective) at surface')
         285             :        call addfld (trim(wetdep_list(m))//'SFSIS', horiz_only,  'A','kg/m2/s', &
         286           0 :             'Wet deposition flux (incloud, stratiform) at surface')
         287             :        call addfld (trim(wetdep_list(m))//'SFSBC', horiz_only,  'A','kg/m2/s', &
         288           0 :             'Wet deposition flux (belowcloud, convective) at surface')
         289             :        call addfld (trim(wetdep_list(m))//'SFSBS', horiz_only,  'A','kg/m2/s', &
         290           0 :             'Wet deposition flux (belowcloud, stratiform) at surface')
         291             :        call addfld (trim(wetdep_list(m))//'WET',   (/ 'lev' /), 'A','kg/kg/s', &
         292           0 :             'wet deposition tendency')
         293             :        call addfld (trim(wetdep_list(m))//'SIC',   (/ 'lev' /), 'A','kg/kg/s', &
         294           0 :             trim(wetdep_list(m))//' ic wet deposition')
         295             :        call addfld (trim(wetdep_list(m))//'SIS',   (/ 'lev' /), 'A','kg/kg/s', &
         296           0 :             trim(wetdep_list(m))//' is wet deposition')
         297             :        call addfld (trim(wetdep_list(m))//'SBC',   (/ 'lev' /), 'A','kg/kg/s', &
         298           0 :             trim(wetdep_list(m))//' bc wet deposition')
         299             :        call addfld (trim(wetdep_list(m))//'SBS',   (/ 'lev' /), 'A','kg/kg/s', &
         300        1536 :             trim(wetdep_list(m))//' bs wet deposition')
         301             :     enddo
         302             :
         303        1536 :     if (nwetdep>0) then
         304           0 :        if (sslt_active) then
         305           0 :           dummy = 'SSTSFWET'
         306           0 :           call addfld (dummy,horiz_only, 'A','kg/m2/s','Sea salt wet deposition flux at surface')
         307           0 :           if ( history_aerosol ) then
         308           0 :              call add_default (dummy, 1, ' ')
         309             :           endif
         310             :        endif
         311           0 :        if (dust_active) then
         312           0 :           dummy = 'DSTSFWET'
         313           0 :           call addfld (dummy,horiz_only, 'A','kg/m2/s','Dust wet deposition flux at surface')
         314           0 :           if ( history_aerosol ) then
         315           0 :              call add_default (dummy, 1, ' ')
         316             :           endif
         317             :        endif
         318             :     endif
         319             :
         320        1536 :     if (dust_active) then
         321             :        ! emissions diagnostics ....
         322             :
         323           0 :        do m = 1, dust_nbin
         324           0 :           dummy = trim(dust_names(m)) // 'SF'
         325           0 :           call addfld (dummy,horiz_only, 'A','kg/m2/s',trim(dust_names(m))//' dust surface emission')
         326           0 :           if (history_aerosol) then
         327           0 :              call add_default (dummy, 1, ' ')
         328             :           endif
         329             :        enddo
         330             :
         331           0 :        dummy = 'DSTSFMBL'
         332           0 :        call addfld (dummy,horiz_only, 'A','kg/m2/s','Mobilization flux at surface')
         333           0 :        if (history_aerosol .or. history_dust) then
         334           0 :           call add_default (dummy, 1, ' ')
         335             :        endif
         336             :
         337           0 :        dummy = 'LND_MBL'
         338           0 :        call addfld (dummy,horiz_only, 'A','frac','Soil erodibility factor')
         339           0 :        if (history_aerosol) then
         340           0 :           call add_default (dummy, 1, ' ')
         341             :        endif
         342             :
         343             :     endif
         344             :
         345        1536 :     if (sslt_active) then
         346             :
         347           0 :        dummy = 'SSTSFMBL'
         348           0 :        call addfld (dummy,horiz_only, 'A','kg/m2/s','Mobilization flux at surface')
         349           0 :        if (history_aerosol) then
         350           0 :           call add_default (dummy, 1, ' ')
         351             :        endif
         352             :
         353           0 :        do m = 1, seasalt_nbin
         354           0 :           dummy = trim(seasalt_names(m)) // 'SF'
         355           0 :           call addfld (dummy,horiz_only, 'A','kg/m2/s',trim(seasalt_names(m))//' seasalt surface emission')
         356           0 :           if (history_aerosol) then
         357           0 :              call add_default (dummy, 1, ' ')
         358             :           endif
         359             :        enddo
         360             :
         361             :     endif
         362             :
         363        1536 :     if( has_sox ) then
         364        3072 :        call addfld( 'XPH_LWC',(/ 'lev' /), 'A','kg/kg', 'pH value multiplied by lwc')
         365             :
         366        1536 :        if ( history_aerosol ) then
         367           0 :           call add_default ('XPH_LWC', 1, ' ')
         368             :        endif
         369             :     endif
         370             :
         371        1536 :     so4_ndx    = get_spc_ndx( 'SO4' )
         372        1536 :     soa_ndx    = get_spc_ndx( 'SOA' )
         373        1536 :     soai_ndx   = get_spc_ndx( 'SOAI' )
         374        1536 :     soam_ndx   = get_spc_ndx( 'SOAM' )
         375        1536 :     soab_ndx   = get_spc_ndx( 'SOAB' )
         376        1536 :     soat_ndx   = get_spc_ndx( 'SOAT' )
         377        1536 :     soax_ndx   = get_spc_ndx( 'SOAX' )
         378        1536 :     cb2_ndx    = get_spc_ndx( 'CB2' )
         379        1536 :     oc2_ndx    = get_spc_ndx( 'OC2' )
         380        1536 :     nit_ndx    = get_spc_ndx( 'NH4NO3' )
         381             :
         382        1536 :   end subroutine aero_model_init
         383             :
         384             :   !=============================================================================
         385             :   !=============================================================================
         386     7445880 :   subroutine aero_model_drydep  ( state, pbuf, obklen, ustar, cam_in, dt, cam_out, ptend )
         387             :
         388        1536 :     use dust_sediment_mod, only: dust_sediment_tend
         389             :     use aer_drydep_mod,    only: d3ddflux, calcram
         390             :     use dust_model,        only: dust_depvel, dust_nbin, dust_names
         391             :     use seasalt_model,     only: sslt_depvel=>seasalt_depvel, sslt_nbin=>seasalt_nbin, sslt_names=>seasalt_names
         392             :
         393             :     ! args
         394             :     type(physics_state),    intent(in)    :: state     ! Physics state variables
         395             :     real(r8),               intent(in)    :: obklen(:)
         396             :     real(r8),               intent(in)    :: ustar(:)  ! sfc fric vel
         397             :     type(cam_in_t), target, intent(in)    :: cam_in    ! import state
         398             :     real(r8),               intent(in)    :: dt        ! time step
         399             :     type(cam_out_t),        intent(inout) :: cam_out   ! export state
         400             :     type(physics_ptend),    intent(out)   :: ptend     ! indivdual parameterization tendencies
         401             :     type(physics_buffer_desc),    pointer :: pbuf(:)
         402             :
         403             :   ! local vars
         404     1489176 :     real(r8), pointer :: landfrac(:) ! land fraction
         405     1489176 :     real(r8), pointer :: icefrac(:)  ! ice fraction
         406     1489176 :     real(r8), pointer :: ocnfrac(:)  ! ocean fraction
         407     1489176 :     real(r8), pointer :: fvin(:)     !
         408     1489176 :     real(r8), pointer :: ram1in(:)   ! for dry dep velocities from land model for progseasalts
         409             :
         410             :     real(r8) :: fv(pcols)            ! for dry dep velocities, from land modified over ocean & ice
         411             :     real(r8) :: ram1(pcols)          ! for dry dep velocities, from land modified over ocean & ice
         412             :
         413             :      ! local decarations
         414             :
         415             :     integer, parameter :: naero = sslt_nbin+dust_nbin
         416             :     integer, parameter :: begslt = 1
         417             :     integer, parameter :: endslt = sslt_nbin
         418             :     integer, parameter :: begdst = sslt_nbin+1
         419             :     integer, parameter :: enddst = sslt_nbin+dust_nbin
         420             :
         421             :     integer :: ncol, lchnk
         422             :
         423             :     character(len=6) :: aeronames(naero) ! = (/ sslt_names, dust_names /)
         424             :
         425             :     real(r8) :: vlc_trb(pcols,naero)    !Turbulent deposn velocity (m/s)
         426             :     real(r8) :: vlc_grv(pcols,pver,naero)  !grav deposn velocity (m/s)
         427             :     real(r8) :: vlc_dry(pcols,pver,naero)  !dry deposn velocity (m/s)
         428             :
         429             :     real(r8) :: dep_trb(pcols)       !kg/m2/s
         430             :     real(r8) :: dep_grv(pcols)       !kg/m2/s (total of grav and trb)
         431             :
         432             :     real(r8) :: tsflx_dst(pcols)
         433             :     real(r8) :: tsflx_slt(pcols)
         434             :     real(r8) :: pvaeros(pcols,pverp)    ! sedimentation velocity in Pa
         435             :     real(r8) :: sflx(pcols)
         436             :
         437             :     real(r8) :: tvs(pcols,pver)
         438             :     real(r8) :: rho(pcols,pver)      ! air density in kg/m3
         439             :
         440             :     integer :: m,mm, i, im
         441             :
         442     1489176 :     if (ndrydep<1) return
         443             :
         444           0 :     landfrac => cam_in%landfrac(:)
         445           0 :     icefrac  => cam_in%icefrac(:)
         446           0 :     ocnfrac  => cam_in%ocnfrac(:)
         447           0 :     fvin     => cam_in%fv(:)
         448           0 :     ram1in   => cam_in%ram1(:)
         449             :
         450           0 :     lchnk = state%lchnk
         451           0 :     ncol  = state%ncol
         452             :
         453             :     ! calc ram and fv over ocean and sea ice ...
         454             :     call calcram( ncol,landfrac,icefrac,ocnfrac,obklen,&
         455             :                   ustar,ram1in,ram1,state%t(:,pver),state%pmid(:,pver),&
         456           0 :                   state%pdel(:,pver),fvin,fv)
         457             :
         458           0 :     call outfld( 'airFV', fv(:), pcols, lchnk )
         459           0 :     call outfld( 'RAM1', ram1(:), pcols, lchnk )
         460             :
         461             :     ! note that tendencies are not only in sfc layer (because of sedimentation)
         462             :     ! and that ptend is updated within each subroutine for different species
         463             :
         464           0 :     call physics_ptend_init(ptend, state%psetcols, 'aero_model_drydep', lq=drydep_lq)
         465             :
         466           0 :     aeronames(:sslt_nbin)   = sslt_names(:)
         467           0 :     aeronames(sslt_nbin+1:) = dust_names(:)
         468             :
         469           0 :     lchnk = state%lchnk
         470           0 :     ncol  = state%ncol
         471             :
         472           0 :     tvs(:ncol,:) = state%t(:ncol,:)
         473           0 :     rho(:ncol,:) = state%pmid(:ncol,:)/(rair*state%t(:ncol,:))
         474             :
         475             :     ! compute dep velocities for sea salt and dust...
         476           0 :     if (sslt_active) then
         477             :        call sslt_depvel( state%t(:,:), state%pmid(:,:), state%q(:,:,1), ram1, fv, ncol, lchnk, &
         478           0 :                          vlc_dry(:,:,begslt:endslt), vlc_trb(:,begslt:endslt), vlc_grv(:,:,begslt:endslt))
         479             :     endif
         480           0 :     if (dust_active) then
         481             :        call dust_depvel( state%t(:,:), state%pmid(:,:),                 ram1, fv, ncol, &
         482           0 :                          vlc_dry(:,:,begdst:enddst), vlc_trb(:,begdst:enddst), vlc_grv(:,:,begdst:enddst) )
         483             :     endif
         484             :
         485           0 :     tsflx_dst(:)=0._r8
         486           0 :     tsflx_slt(:)=0._r8
         487             :
         488             :     ! do drydep for each of the bins of dust and seasalt
         489           0 :     do m=1,ndrydep
         490             :
         491           0 :        mm = drydep_indices(m)
         492           0 :        findindex: do im = 1,naero
         493           0 :          if (trim(cnst_name(mm))==trim(aeronames(im))) exit findindex
         494             :        enddo findindex
         495             :
         496           0 :        pvaeros(:ncol,1)=0._r8
         497           0 :        pvaeros(:ncol,2:pverp) = vlc_dry(:ncol,:,im)
         498             :
         499           0 :        call outfld( trim(cnst_name(mm))//'DV', pvaeros(:,2:pverp), pcols, lchnk )
         500             :
         501             :        if(.true.) then ! use phil's method
         502             :           !      convert from meters/sec to pascals/sec
         503             :           !      pvaeros(:,1) is assumed zero, use density from layer above in conversion
         504           0 :           pvaeros(:ncol,2:pverp) = pvaeros(:ncol,2:pverp) * rho(:ncol,:)*gravit
         505             :
         506             :           !      calculate the tendencies and sfc fluxes from the above velocities
         507             :           call dust_sediment_tend( &
         508             :                ncol,             dt,       state%pint(:,:), state%pmid, state%pdel, state%t , &
         509           0 :                state%q(:,:,mm) , pvaeros  , ptend%q(:,:,mm), sflx  )
         510             :        else   !use charlie's method
         511             :           call d3ddflux(ncol, vlc_dry(:,:,im), state%q(:,:,mm),state%pmid,state%pdel, tvs,sflx,ptend%q(:,:,mm),dt)
         512             :        endif
         513             :        ! apportion dry deposition into turb and gravitational settling for tapes
         514           0 :        do i=1,ncol
         515           0 :           dep_trb(i)=sflx(i)*vlc_trb(i,im)/vlc_dry(i,pver,im)
         516           0 :           dep_grv(i)=sflx(i)*vlc_grv(i,pver,im)/vlc_dry(i,pver,im)
         517             :        enddo
         518             :
         519           0 :        if ( any( sslt_names(:)==trim(cnst_name(mm)) ) ) &
         520           0 :             tsflx_slt(:ncol)=tsflx_slt(:ncol)+sflx(:ncol)
         521           0 :        if ( any( dust_names(:)==trim(cnst_name(mm)) ) ) &
         522           0 :             tsflx_dst(:ncol)=tsflx_dst(:ncol)+sflx(:ncol)
         523             :
         524             :        ! if the user has specified prescribed aerosol dep fluxes then
         525             :        ! do not set cam_out dep fluxes according to the prognostic aerosols
         526           0 :        if (.not. aerodep_flx_prescribed()) then
         527             :           ! set deposition in export state
         528           0 :           if (im==begdst) then
         529           0 :              cam_out%dstdry1(:ncol) = max(sflx(:ncol), 0._r8)
         530           0 :           elseif(im==begdst+1) then
         531           0 :              cam_out%dstdry2(:ncol) = max(sflx(:ncol), 0._r8)
         532           0 :           elseif(im==begdst+2) then
         533           0 :              cam_out%dstdry3(:ncol) = max(sflx(:ncol), 0._r8)
         534           0 :           elseif(im==begdst+3) then
         535           0 :              cam_out%dstdry4(:ncol) = max(sflx(:ncol), 0._r8)
         536             :           endif
         537             :        endif
         538             :
         539           0 :        call outfld( trim(cnst_name(mm))//'DD', sflx, pcols, lchnk)
         540           0 :        call outfld( trim(cnst_name(mm))//'TB', dep_trb, pcols, lchnk )
         541           0 :        call outfld( trim(cnst_name(mm))//'GV', dep_grv, pcols, lchnk )
         542           0 :        call outfld( trim(cnst_name(mm))//'DT', ptend%q(:,:,mm), pcols, lchnk)
         543             :
         544             :     end do
         545             :
         546             :     ! output the total dry deposition
         547           0 :     if (sslt_active) then
         548           0 :        call outfld( 'SSTSFDRY', tsflx_slt, pcols, lchnk)
         549             :     endif
         550           0 :     if (dust_active) then
         551           0 :        call outfld( 'DSTSFDRY', tsflx_dst, pcols, lchnk)
         552             :     endif
         553             :
         554     1489176 :   endsubroutine aero_model_drydep
         555             :
         556             :   !=============================================================================
         557             :   !=============================================================================
         558     5981472 :   subroutine aero_model_wetdep( state, dt, dlf, cam_out, ptend, pbuf)
         559             :
         560             :     use wetdep,        only : wetdepa_v1, wetdep_inputs_set, wetdep_inputs_t
         561             :     use dust_model,    only : dust_names
         562             :     use seasalt_model, only : sslt_names=>seasalt_names
         563             :
         564             :     ! args
         565             :
         566             :     type(physics_state), intent(in)    :: state       ! Physics state variables
         567             :     real(r8),            intent(in)    :: dt          ! time step
         568             :     real(r8),            intent(in)    :: dlf(:,:)    ! shallow+deep convective detrainment [kg/kg/s]
         569             :     type(cam_out_t),     intent(inout) :: cam_out     ! export state
         570             :     type(physics_ptend), intent(out)   :: ptend       ! indivdual parameterization tendencies
         571             :     type(physics_buffer_desc), pointer :: pbuf(:)
         572             :
         573             :     ! local vars
         574             :
         575             :     integer  :: ncol                     ! number of atmospheric columns
         576             :     integer  :: lchnk                    ! chunk identifier
         577             :     integer  :: m,mm, i,k
         578             :
         579             :     real(r8) :: sflx_tot_dst(pcols)
         580             :     real(r8) :: sflx_tot_slt(pcols)
         581             :
         582             :     real(r8) :: iscavt(pcols, pver)
         583             :     real(r8) :: scavt(pcols, pver)
         584             :     real(r8) :: scavcoef(pcols,pver)     ! Dana and Hales coefficient (/mm) (0.1)
         585             :     real(r8) :: sflx(pcols)              ! deposition flux
         586             :
         587             :     real(r8) :: icscavt(pcols, pver)
         588             :     real(r8) :: isscavt(pcols, pver)
         589             :     real(r8) :: bcscavt(pcols, pver)
         590             :     real(r8) :: bsscavt(pcols, pver)
         591             :
         592             :     real(r8) :: sol_factb, sol_facti
         593             :
         594             :     real(r8) :: rainmr(pcols,pver)       ! mixing ratio of rain within cloud volume
         595             :     real(r8) :: cldv(pcols,pver)         ! cloudy volume undergoing scavenging
         596             :     real(r8) :: cldvcu(pcols,pver)       ! Convective precipitation area at the top interface of current layer
         597             :     real(r8) :: cldvst(pcols,pver)       ! Stratiform precipitation area at the top interface of current layer
         598             :
         599     1495368 :     real(r8), pointer :: fracis(:,:,:)   ! fraction of transported species that are insoluble
         600             :
         601             :     type(wetdep_inputs_t) :: dep_inputs  ! obj that contains inputs to wetdepa routine
         602             :
         603     1495368 :     if (nwetdep<1) return
         604             :
         605           0 :     call pbuf_get_field(pbuf, fracis_idx, fracis, start=(/1,1,1/), kount=(/pcols, pver, pcnst/) )
         606             :
         607           0 :     call physics_ptend_init(ptend, state%psetcols, 'aero_model_wetdep', lq=wetdep_lq)
         608             :
         609           0 :     call wetdep_inputs_set( state, pbuf, dep_inputs )
         610             :
         611           0 :     lchnk = state%lchnk
         612           0 :     ncol  = state%ncol
         613             :
         614           0 :     sflx_tot_dst(:) = 0._r8
         615           0 :     sflx_tot_slt(:) = 0._r8
         616             :
         617           0 :     do m = 1, nwetdep
         618             :
         619           0 :        mm = wetdep_indices(m)
         620             :
         621           0 :        sol_factb = aer_sol_factb(m)
         622           0 :        sol_facti = aer_sol_facti(m)
         623             :
         624           0 :        scavcoef(:ncol,:) = aer_scav_coef(m)
         625             :
         626             :        call wetdepa_v1( state%t, state%pmid, state%q(:,:,1), state%pdel, &
         627             :             dep_inputs%cldt, dep_inputs%cldcu, dep_inputs%cmfdqr, &
         628             :             dep_inputs%conicw, dep_inputs%prain, dep_inputs%qme, &
         629             :             dep_inputs%evapr, dep_inputs%totcond, state%q(:,:,mm), dt, &
         630             :             scavt, iscavt, dep_inputs%cldv, &
         631             :             fracis(:,:,mm), sol_factb, ncol, &
         632             :             scavcoef, &
         633             :             sol_facti_in=sol_facti, &
         634           0 :             icscavt=icscavt, isscavt=isscavt, bcscavt=bcscavt, bsscavt=bsscavt )
         635             :
         636           0 :        ptend%q(:ncol,:,mm)=scavt(:ncol,:)
         637             :
         638           0 :        call outfld( trim(cnst_name(mm))//'WET', ptend%q(:,:,mm), pcols, lchnk)
         639           0 :        call outfld( trim(cnst_name(mm))//'SIC', icscavt , pcols, lchnk)
         640           0 :        call outfld( trim(cnst_name(mm))//'SIS', isscavt, pcols, lchnk)
         641           0 :        call outfld( trim(cnst_name(mm))//'SBC', bcscavt, pcols, lchnk)
         642           0 :        call outfld( trim(cnst_name(mm))//'SBS', bsscavt, pcols, lchnk)
         643             :
         644           0 :        sflx(:)=0._r8
         645             :
         646           0 :        do k=1,pver
         647           0 :           do i=1,ncol
         648           0 :              sflx(i)=sflx(i)+ptend%q(i,k,mm)*state%pdel(i,k)/gravit
         649             :           enddo
         650             :        enddo
         651           0 :        call outfld( trim(cnst_name(mm))//'SFWET', sflx, pcols, lchnk)
         652             :
         653           0 :        if ( any( sslt_names(:)==trim(cnst_name(mm)) ) ) &
         654           0 :             sflx_tot_slt(:ncol) = sflx_tot_slt(:ncol) + sflx(:ncol)
         655           0 :        if ( any( dust_names(:)==trim(cnst_name(mm)) ) ) &
         656           0 :             sflx_tot_dst(:ncol) = sflx_tot_dst(:ncol) + sflx(:ncol)
         657             :
         658             :        ! if the user has specified prescribed aerosol dep fluxes then
         659             :        ! do not set cam_out dep fluxes according to the prognostic aerosols
         660           0 :        if (.not.aerodep_flx_prescribed()) then
         661             :           ! export deposition fluxes to coupler ??? why "-" sign ???
         662           0 :           if (trim(cnst_name(mm))=='CB2') then
         663           0 :              cam_out%bcphiwet(:) = max(-sflx(:), 0._r8)
         664           0 :           elseif (trim(cnst_name(mm))=='OC2') then
         665           0 :              cam_out%ocphiwet(:) = max(-sflx(:), 0._r8)
         666           0 :           elseif (trim(cnst_name(mm))==trim(dust_names(1))) then
         667           0 :              cam_out%dstwet1(:) = max(-sflx(:), 0._r8)
         668           0 :           elseif (trim(cnst_name(mm))==trim(dust_names(2))) then
         669           0 :              cam_out%dstwet2(:) = max(-sflx(:), 0._r8)
         670           0 :           elseif (trim(cnst_name(mm))==trim(dust_names(3))) then
         671           0 :              cam_out%dstwet3(:) = max(-sflx(:), 0._r8)
         672           0 :           elseif (trim(cnst_name(mm))==trim(dust_names(4))) then
         673           0 :              cam_out%dstwet4(:) = max(-sflx(:), 0._r8)
         674             :           endif
         675             :        endif
         676             :
         677             :     enddo
         678             :
         679           0 :     if (sslt_active) then
         680           0 :        call outfld( 'SSTSFWET', sflx_tot_slt, pcols, lchnk)
         681             :     endif
         682           0 :     if (dust_active) then
         683           0 :        call outfld( 'DSTSFWET', sflx_tot_dst, pcols, lchnk)
         684             :     endif
         685             :
         686     1495368 :   endsubroutine aero_model_wetdep
         687             :
         688             :   !-------------------------------------------------------------------------
         689             :   ! provides aerosol surface area info for sectional aerosols
         690             :   ! called from mo_usrrxt
         691             :   !-------------------------------------------------------------------------
         692           0 :   subroutine aero_model_surfarea( &
         693           0 :                   mmr, radmean, relhum, pmid, temp, strato_sad, sulfate,  m, ltrop, &
         694           0 :                   dlat, het1_ndx, pbuf, ncol, sfc, dm_aer, sad_total, reff_trop )
         695             :
         696             :     use mo_constants, only : pi, avo => avogadro
         697             :
         698             :     ! dummy args
         699             :     real(r8), intent(in)    :: pmid(:,:)
         700             :     real(r8), intent(in)    :: temp(:,:)
         701             :     real(r8), intent(in)    :: mmr(:,:,:)
         702             :     real(r8), intent(in)    :: radmean      ! mean radii in cm
         703             :     real(r8), intent(in)    :: strato_sad(:,:)
         704             :     integer,  intent(in)    :: ncol
         705             :     integer,  intent(in)    :: ltrop(:)
         706             :     real(r8), intent(in)    :: dlat(:)                    ! degrees latitude
         707             :     integer,  intent(in)    :: het1_ndx
         708             :     real(r8), intent(in)    :: relhum(:,:)
         709             :     real(r8), intent(in)    :: m(:,:) ! total atm density (/cm^3)
         710             :     real(r8), intent(in)    :: sulfate(:,:)
         711             :     type(physics_buffer_desc), pointer :: pbuf(:)
         712             :
         713             :     real(r8), intent(inout) :: sfc(:,:,:)
         714             :     real(r8), intent(inout) :: dm_aer(:,:,:)
         715             :     real(r8), intent(inout) :: sad_total(:,:)
         716             :     real(r8), intent(out)   :: reff_trop(:,:)
         717             :
         718             :     ! local vars
         719             :
         720             :     integer  :: i,k
         721             :     real(r8) :: rho_air
         722             :     real(r8) :: v, n, n_exp, r_rd, r_sd
         723             :     real(r8) :: dm_sulf, dm_sulf_wet, log_sd_sulf, sfc_sulf, sfc_nit
         724             :     real(r8) :: dm_orgc, dm_orgc_wet, log_sd_orgc, sfc_oc, sfc_soa
         725             :     real(r8) :: sfc_soai, sfc_soam, sfc_soab, sfc_soat, sfc_soax
         726             :     real(r8) :: dm_bc, dm_bc_wet, log_sd_bc, sfc_bc
         727             :     real(r8) :: rxt_sulf, rxt_nit, rxt_oc, rxt_soa
         728             :     real(r8) :: c_n2o5, c_ho2, c_no2, c_no3
         729             :     real(r8) :: s_exp
         730             :
         731             :     !-----------------------------------------------------------------
         732             :     !   ... parameters for log-normal distribution by number
         733             :     ! references:
         734             :     !   Chin et al., JAS, 59, 461, 2003
         735             :     !   Liao et al., JGR, 108(D1), 4001, 2003
         736             :     !   Martin et al., JGR, 108(D3), 4097, 2003
         737             :     !-----------------------------------------------------------------
         738             :     real(r8), parameter :: rm_sulf  = 6.95e-6_r8        ! mean radius of sulfate particles (cm) (Chin)
         739             :     real(r8), parameter :: sd_sulf  = 2.03_r8           ! standard deviation of radius for sulfate (Chin)
         740             :     real(r8), parameter :: rho_sulf = 1.7e3_r8          ! density of sulfate aerosols (kg/m3) (Chin)
         741             :
         742             :     real(r8), parameter :: rm_orgc  = 2.12e-6_r8        ! mean radius of organic carbon particles (cm) (Chin)
         743             :     real(r8), parameter :: sd_orgc  = 2.20_r8           ! standard deviation of radius for OC (Chin)
         744             :     real(r8), parameter :: rho_orgc = 1.8e3_r8          ! density of OC aerosols (kg/m3) (Chin)
         745             :
         746             :     real(r8), parameter :: rm_bc    = 1.18e-6_r8        ! mean radius of soot/BC particles (cm) (Chin)
         747             :     real(r8), parameter :: sd_bc    = 2.00_r8           ! standard deviation of radius for BC (Chin)
         748             :     real(r8), parameter :: rho_bc   = 1.0e3_r8          ! density of BC aerosols (kg/m3) (Chin)
         749             :
         750             :     real(r8), parameter :: mw_so4 = 98.e-3_r8     ! so4 molecular wt (kg/mole)
         751             :
         752             :     integer  ::  irh, rh_l, rh_u
         753             :     real(r8) ::  factor, rfac_sulf, rfac_oc, rfac_bc, rfac_ss
         754             :     logical :: zero_aerosols
         755             :
         756             :     !-----------------------------------------------------------------
         757             :     !   ... table for hygroscopic growth effect on radius (Chin et al)
         758             :     !           (no growth effect for mineral dust)
         759             :     !-----------------------------------------------------------------
         760             :     real(r8), dimension(7) :: table_rh, table_rfac_sulf, table_rfac_bc, table_rfac_oc, table_rfac_ss
         761             :
         762             :     data table_rh(1:7)        / 0.0_r8, 0.5_r8, 0.7_r8, 0.8_r8, 0.9_r8, 0.95_r8, 0.99_r8/
         763             :     data table_rfac_sulf(1:7) / 1.0_r8, 1.4_r8, 1.5_r8, 1.6_r8, 1.8_r8, 1.9_r8,  2.2_r8/
         764             :     data table_rfac_oc(1:7)   / 1.0_r8, 1.2_r8, 1.4_r8, 1.5_r8, 1.6_r8, 1.8_r8,  2.2_r8/
         765             :     data table_rfac_bc(1:7)   / 1.0_r8, 1.0_r8, 1.0_r8, 1.2_r8, 1.4_r8, 1.5_r8,  1.9_r8/
         766             :     data table_rfac_ss(1:7)   / 1.0_r8, 1.6_r8, 1.8_r8, 2.0_r8, 2.4_r8, 2.9_r8,  4.8_r8/
         767             :
         768             :     !-----------------------------------------------------------------
         769             :     !   ... exponent for calculating number density
         770             :     !-----------------------------------------------------------------
         771           0 :     n_exp = exp( -4.5_r8*log(sd_sulf)*log(sd_sulf) )
         772             :
         773           0 :     dm_sulf = 2._r8 * rm_sulf
         774           0 :     dm_orgc = 2._r8 * rm_orgc
         775           0 :     dm_bc   = 2._r8 * rm_bc
         776             :
         777           0 :     log_sd_sulf = log(sd_sulf)
         778           0 :     log_sd_orgc = log(sd_orgc)
         779           0 :     log_sd_bc   = log(sd_bc)
         780             :
         781           0 :     reff_trop(:,:) = 0._r8
         782             :
         783           0 :     ver_loop: do k = 1,pver
         784           0 :        col_loop: do i = 1,ncol
         785             :           !-------------------------------------------------------------------------
         786             :           !     ... air density (kg/m3)
         787             :           !-------------------------------------------------------------------------
         788           0 :           rho_air = pmid(i,k)/(temp(i,k)*287.04_r8)
         789             :           !-------------------------------------------------------------------------
         790             :           !       ... aerosol growth interpolated from M.Chin's table
         791             :           !-------------------------------------------------------------------------
         792           0 :           if (relhum(i,k) >= table_rh(7)) then
         793           0 :              rfac_sulf = table_rfac_sulf(7)
         794           0 :              rfac_oc = table_rfac_oc(7)
         795           0 :              rfac_bc = table_rfac_bc(7)
         796             :           else
         797           0 :              do irh = 2,7
         798           0 :                 if (relhum(i,k) <= table_rh(irh)) then
         799             :                    exit
         800             :                 end if
         801             :              end do
         802           0 :              rh_l = irh-1
         803           0 :              rh_u = irh
         804             :
         805           0 :              factor = (relhum(i,k) - table_rh(rh_l))/(table_rh(rh_u) - table_rh(rh_l))
         806             :
         807           0 :              rfac_sulf = table_rfac_sulf(rh_l) + factor*(table_rfac_sulf(rh_u) - table_rfac_sulf(rh_l))
         808           0 :              rfac_oc = table_rfac_oc(rh_u) + factor*(table_rfac_oc(rh_u) - table_rfac_oc(rh_l))
         809           0 :              rfac_bc = table_rfac_bc(rh_u) + factor*(table_rfac_bc(rh_u) - table_rfac_bc(rh_l))
         810             :           end if
         811             :
         812           0 :           dm_sulf_wet = dm_sulf * rfac_sulf
         813           0 :           dm_orgc_wet = dm_orgc * rfac_oc
         814           0 :           dm_bc_wet = dm_bc * rfac_bc
         815             :
         816           0 :           dm_bc_wet   = min(dm_bc_wet  ,50.e-6_r8) ! maximum size is 0.5 micron (Chin)
         817           0 :           dm_orgc_wet = min(dm_orgc_wet,50.e-6_r8) ! maximum size is 0.5 micron (Chin)
         818             :
         819             :
         820             :           !-------------------------------------------------------------------------
         821             :           !     ... sulfate aerosols
         822             :           !-------------------------------------------------------------------------
         823           0 :           zero_aerosols = k < ltrop(i)
         824           0 :           if ( abs( dlat(i) ) > 50._r8 ) then
         825           0 :              zero_aerosols = pmid(i,k) < 30000._r8
         826             :           endif
         827             :           !-------------------------------------------------------------------------
         828             :           !       ... use ubvals climatology for stratospheric sulfate surface area density
         829             :           !-------------------------------------------------------------------------
         830           0 :           if( zero_aerosols ) then
         831           0 :              sfc_sulf = strato_sad(i,k)
         832           0 :              if ( het1_ndx > 0 ) then
         833           0 :                 sfc_sulf = 0._r8        ! reaction already taken into account in mo_strato_rates.F90
         834             :              end if
         835             :              sfc_nit = 0._r8
         836             :              sfc_soa = 0._r8
         837             :              sfc_oc  = 0._r8
         838             :              sfc_bc  = 0._r8
         839             :           else
         840             :
         841           0 :              if( so4_ndx > 0 ) then
         842             :                 !-------------------------------------------------------------------------
         843             :                 ! convert mass mixing ratio of aerosol to cm3/cm3 (cm^3_aerosol/cm^3_air)
         844             :                 ! v=volume density (m^3/m^3)
         845             :                 ! rho_aer=density of aerosol (kg/m^3)
         846             :                 ! v=m*rho_air/rho_aer   [kg/kg * (kg/m3)_air/(kg/m3)_aer]
         847             :                 !-------------------------------------------------------------------------
         848           0 :                 v = mmr(i,k,so4_ndx) * rho_air/rho_sulf
         849             :                 !-------------------------------------------------------------------------
         850             :                 ! calculate the number density of aerosol (aerosols/cm3)
         851             :                 ! assuming a lognormal distribution
         852             :                 ! n  = (aerosols/cm3)
         853             :                 ! dm = geometric mean diameter
         854             :                 !
         855             :                 ! because only the dry mass of the aerosols is known, we
         856             :                 ! use the mean dry radius
         857             :                 !-------------------------------------------------------------------------
         858           0 :                 n  = v * (6._r8/pi)*(1._r8/(dm_sulf**3._r8))*n_exp
         859             :                 !-------------------------------------------------------------------------
         860             :                 ! find surface area of aerosols using dm_wet, log_sd
         861             :                 !  (increase of sd due to RH is negligible)
         862             :                 ! and number density calculated above as distribution
         863             :                 ! parameters
         864             :                 ! sfc = surface area of wet aerosols (cm^2/cm^3)
         865             :                 !-------------------------------------------------------------------------
         866           0 :                 s_exp    = exp(2._r8*log_sd_sulf*log_sd_sulf)
         867           0 :                 sfc_sulf = n * pi * (dm_sulf_wet**2._r8) * s_exp
         868             :
         869             :              else
         870             :                 !-------------------------------------------------------------------------
         871             :                 !  if so4 not simulated, use off-line sulfate and calculate as above
         872             :                 !  convert sulfate vmr to volume density of aerosol (cm^3_aerosol/cm^3_air)
         873             :                 !-------------------------------------------------------------------------
         874           0 :                 v = sulfate(i,k) * m(i,k) * mw_so4 / (avo * rho_sulf) *1.e6_r8
         875           0 :                 n  = v * (6._r8/pi)*(1._r8/(dm_sulf**3._r8))*n_exp
         876           0 :                 s_exp    = exp(2._r8*log_sd_sulf*log_sd_sulf)
         877           0 :                 sfc_sulf = n * pi * (dm_sulf_wet**2._r8) * s_exp
         878             :
         879             :              end if
         880             :
         881             :              !-------------------------------------------------------------------------
         882             :              ! ammonium nitrate (follow same procedure as sulfate, using size and density of sulfate)
         883             :              !-------------------------------------------------------------------------
         884           0 :              if( nit_ndx > 0 ) then
         885           0 :                 v = mmr(i,k,nit_ndx) * rho_air/rho_sulf
         886           0 :                 n  = v * (6._r8/pi)*(1._r8/(dm_sulf**3._r8))*n_exp
         887           0 :                 s_exp   = exp(2._r8*log_sd_sulf*log_sd_sulf)
         888           0 :                 sfc_nit = n * pi * (dm_sulf_wet**2._r8) * s_exp
         889             :              else
         890             :                 sfc_nit = 0._r8
         891             :              end if
         892             :
         893             :              !-------------------------------------------------------------------------
         894             :              ! hydrophylic organic carbon (follow same procedure as sulfate)
         895             :              !-------------------------------------------------------------------------
         896           0 :              if( oc2_ndx > 0 ) then
         897           0 :                 v = mmr(i,k,oc2_ndx) * rho_air/rho_orgc
         898           0 :                 n  = v * (6._r8/pi)*(1._r8/(dm_orgc**3))*n_exp
         899           0 :                 s_exp    = exp(2._r8*log_sd_orgc*log_sd_orgc)
         900           0 :                 sfc_oc   = n * pi * (dm_orgc_wet**2._r8) * s_exp
         901             :              else
         902             :                 sfc_oc = 0._r8
         903             :              end if
         904             :
         905             :              !-------------------------------------------------------------------------
         906             :              ! secondary organic carbon (follow same procedure as sulfate)
         907             :              !-------------------------------------------------------------------------
         908           0 :              if( soa_ndx > 0 ) then
         909           0 :                 v = mmr(i,k,soa_ndx) * rho_air/rho_orgc
         910           0 :                 n  = v * (6._r8/pi)*(1._r8/(dm_orgc**3._r8))*n_exp
         911           0 :                 s_exp     = exp(2._r8*log_sd_orgc*log_sd_orgc)
         912           0 :                 sfc_soa   = n * pi * (dm_orgc_wet**2._r8) * s_exp
         913             :              else
         914             :                 sfc_soa = 0._r8
         915             :              end if
         916             :
         917             :              !-------------------------------------------------------------------------
         918             :              ! black carbon (follow same procedure as sulfate)
         919             :              !-------------------------------------------------------------------------
         920           0 :              if( cb2_ndx > 0 ) then
         921           0 :                 v = mmr(i,k,cb2_ndx) * rho_air/rho_bc
         922           0 :                 n  = v * (6._r8/pi)*(1._r8/(dm_bc**3._r8))*n_exp
         923           0 :                 s_exp     = exp(2._r8*log_sd_bc*log_sd_bc)
         924           0 :                 sfc_bc   = n * pi * (dm_bc_wet**2._r8) * s_exp
         925             :              else
         926             :                 sfc_bc = 0._r8
         927             :              end if
         928           0 :              if( soai_ndx > 0 ) then
         929           0 :                 v = mmr(i,k,soai_ndx) * rho_air/rho_orgc
         930           0 :                 n  = v * (6._r8/pi)*(1._r8/(dm_orgc**3._r8))*n_exp
         931           0 :                 s_exp     = exp(2._r8*log_sd_orgc*log_sd_orgc)
         932           0 :                 sfc_soai   = n * pi * (dm_orgc_wet**2._r8) * s_exp
         933             :              else
         934             :                 sfc_soai = 0._r8
         935             :              end if
         936           0 :              if( soam_ndx > 0 ) then
         937           0 :                 v = mmr(i,k,soam_ndx) * rho_air/rho_orgc
         938           0 :                 n  = v * (6._r8/pi)*(1._r8/(dm_orgc**3._r8))*n_exp
         939           0 :                 s_exp     = exp(2._r8*log_sd_orgc*log_sd_orgc)
         940           0 :                 sfc_soam   = n * pi * (dm_orgc_wet**2._r8) * s_exp
         941             :              else
         942             :                 sfc_soam = 0._r8
         943             :              end if
         944           0 :              if( soab_ndx > 0 ) then
         945           0 :                 v = mmr(i,k,soab_ndx) * rho_air/rho_orgc
         946           0 :                 n  = v * (6._r8/pi)*(1._r8/(dm_orgc**3._r8))*n_exp
         947           0 :                 s_exp     = exp(2._r8*log_sd_orgc*log_sd_orgc)
         948           0 :                 sfc_soab   = n * pi * (dm_orgc_wet**2._r8) * s_exp
         949             :              else
         950             :                 sfc_soab = 0._r8
         951             :              end if
         952           0 :              if( soat_ndx > 0 ) then
         953           0 :                 v = mmr(i,k,soat_ndx) * rho_air/rho_orgc
         954           0 :                 n  = v * (6._r8/pi)*(1._r8/(dm_orgc**3._r8))*n_exp
         955           0 :                 s_exp     = exp(2._r8*log_sd_orgc*log_sd_orgc)
         956           0 :                 sfc_soat   = n * pi * (dm_orgc_wet**2._r8) * s_exp
         957             :              else
         958             :                 sfc_soat = 0._r8
         959             :              end if
         960           0 :              if( soax_ndx > 0 ) then
         961           0 :                 v = mmr(i,k,soax_ndx) * rho_air/rho_orgc
         962           0 :                 n  = v * (6._r8/pi)*(1._r8/(dm_orgc**3._r8))*n_exp
         963           0 :                 s_exp     = exp(2._r8*log_sd_orgc*log_sd_orgc)
         964           0 :                 sfc_soax   = n * pi * (dm_orgc_wet**2._r8) * s_exp
         965             :              else
         966             :                 sfc_soax = 0._r8
         967             :              end if
         968           0 :              sfc_soa = sfc_soa + sfc_soai + sfc_soam + sfc_soab + sfc_soat + sfc_soax
         969             :
         970             :           end if
         971             :
         972           0 :           sfc(i,k,:) = (/ sfc_sulf, sfc_nit, sfc_oc, sfc_soa, sfc_bc /)
         973           0 :           dm_aer(i,k,:) = (/ dm_sulf_wet,dm_sulf_wet,dm_orgc_wet,dm_orgc_wet,dm_bc_wet /)
         974             :
         975             :           !-------------------------------------------------------------------------
         976             :           !     ... add up total surface area density for output
         977             :           !-------------------------------------------------------------------------
         978           0 :           sad_total(i,k) = sfc_sulf + sfc_nit + sfc_oc + sfc_soa + sfc_bc
         979             :
         980             :        enddo col_loop
         981             :     enddo ver_loop
         982             :
         983           0 :   end subroutine aero_model_surfarea
         984             :
         985             :   !-------------------------------------------------------------------------
         986             :   ! stub
         987             :   !-------------------------------------------------------------------------
         988           0 :   subroutine aero_model_strat_surfarea( ncol, mmr, pmid, temp, ltrop, pbuf, strato_sad, reff_strat )
         989             :
         990             :     ! dummy args
         991             :     integer,  intent(in)    :: ncol
         992             :     real(r8), intent(in)    :: mmr(:,:,:)
         993             :     real(r8), intent(in)    :: pmid(:,:)
         994             :     real(r8), intent(in)    :: temp(:,:)
         995             :     integer,  intent(in)    :: ltrop(:) ! tropopause level indices
         996             :     type(physics_buffer_desc), pointer :: pbuf(:)
         997             :     real(r8), intent(out)   :: strato_sad(:,:)
         998             :     real(r8), intent(out)   :: reff_strat(:,:)
         999             :
        1000           0 :     strato_sad(:,:) = 0._r8
        1001           0 :     reff_strat(:,:) = 0._r8
        1002             :
        1003           0 :   end subroutine aero_model_strat_surfarea
        1004             :
        1005             :   !=============================================================================
        1006             :   !=============================================================================
        1007           0 :   subroutine aero_model_gasaerexch( loffset, ncol, lchnk, troplev, delt, reaction_rates, &
        1008           0 :                                     tfld, pmid, pdel, mbar, relhum, &
        1009           0 :                                     zm,  qh2o, cwat, cldfr, cldnum, &
        1010           0 :                                     airdens, invariants, del_h2so4_gasprod,  &
        1011           0 :                                     vmr0, vmr, pbuf )
        1012             :
        1013             :     use chem_mods,   only : gas_pcnst
        1014             :     use mo_aerosols, only : aerosols_formation, has_aerosols
        1015             :     use mo_setsox,   only : setsox, has_sox
        1016             :     use mo_setsoa,   only : setsoa, has_soa
        1017             :
        1018             :     !-----------------------------------------------------------------------
        1019             :     !      ... dummy arguments
        1020             :     !-----------------------------------------------------------------------
        1021             :     integer,  intent(in) :: loffset                ! offset applied to modal aero "pointers"
        1022             :     integer,  intent(in) :: ncol                   ! number columns in chunk
        1023             :     integer,  intent(in) :: lchnk                  ! chunk index
        1024             :     integer,  intent(in) :: troplev(:)
        1025             :     real(r8), intent(in) :: delt                   ! time step size (sec)
        1026             :     real(r8), intent(in) :: reaction_rates(:,:,:)  ! reaction rates
        1027             :     real(r8), intent(in) :: tfld(:,:)              ! temperature (K)
        1028             :     real(r8), intent(in) :: pmid(:,:)              ! pressure at model levels (Pa)
        1029             :     real(r8), intent(in) :: pdel(:,:)              ! pressure thickness of levels (Pa)
        1030             :     real(r8), intent(in) :: mbar(:,:)              ! mean wet atmospheric mass ( amu )
        1031             :     real(r8), intent(in) :: relhum(:,:)            ! relative humidity
        1032             :     real(r8), intent(in) :: airdens(:,:)           ! total atms density (molec/cm**3)
        1033             :     real(r8), intent(in) :: invariants(:,:,:)
        1034             :     real(r8), intent(in) :: del_h2so4_gasprod(:,:)
        1035             :     real(r8), intent(in) :: zm(:,:)
        1036             :     real(r8), intent(in) :: qh2o(:,:)
        1037             :     real(r8), intent(in) :: cwat(:,:)          ! cloud liquid water content (kg/kg)
        1038             :     real(r8), intent(in) :: cldfr(:,:)
        1039             :     real(r8), intent(in) :: cldnum(:,:)       ! droplet number concentration (#/kg)
        1040             :     real(r8), intent(in) :: vmr0(:,:,:)       ! initial mixing ratios (before gas-phase chem changes)
        1041             :     real(r8), intent(inout) :: vmr(:,:,:)         ! mixing ratios ( vmr )
        1042             :
        1043             :     type(physics_buffer_desc), pointer :: pbuf(:)
        1044             :
        1045             :     ! local vars
        1046             :
        1047           0 :     real(r8) :: vmrcw(ncol,pver,gas_pcnst)            ! cloud-borne aerosol (vmr)
        1048             :
        1049           0 :     real(r8) ::  aqso4(ncol,1)               ! aqueous phase chemistry
        1050           0 :     real(r8) ::  aqh2so4(ncol,1)             ! aqueous phase chemistry
        1051           0 :     real(r8) ::  aqso4_h2o2(ncol)            ! SO4 aqueous phase chemistry due to H2O2
        1052           0 :     real(r8) ::  aqso4_o3(ncol)              ! SO4 aqueous phase chemistry due to O3
        1053           0 :     real(r8) ::  xphlwc(ncol,pver)           ! pH value multiplied by lwc
        1054             :
        1055             :
        1056             :   ! aqueous chemistry ...
        1057             :
        1058           0 :     if( has_sox ) then
        1059             :        call setsox(   &
        1060             :             ncol,     &
        1061             :             lchnk,    &
        1062             :             loffset,  &
        1063             :             delt,     &
        1064             :             pmid,     &
        1065             :             pdel,     &
        1066             :             tfld,     &
        1067             :             mbar,     &
        1068             :             cwat,     &
        1069             :             cldfr,    &
        1070             :             cldnum,   &
        1071             :             airdens,  &
        1072             :             invariants, &
        1073             :             vmrcw,    &
        1074             :             vmr,      &
        1075             :             xphlwc,   &
        1076             :             aqso4,    &
        1077             :             aqh2so4,  &
        1078             :             aqso4_h2o2,&
        1079             :             aqso4_o3  &
        1080           0 :             )
        1081           0 :         call outfld( 'XPH_LWC',xphlwc(:ncol,:), ncol , lchnk )
        1082             :     endif
        1083             :
        1084           0 :     if( has_soa ) then
        1085           0 :        call setsoa( ncol, lchnk, delt, reaction_rates, tfld, airdens, vmr, pbuf)
        1086             :     endif
        1087             :
        1088           0 :     if( has_aerosols ) then
        1089           0 :        call aerosols_formation( ncol, lchnk, tfld, relhum, vmr )
        1090             :     endif
        1091             :
        1092             :
        1093           0 :   end subroutine aero_model_gasaerexch
        1094             :
        1095             :   !=============================================================================
        1096             :   !=============================================================================
        1097           0 :   subroutine aero_model_emissions( state, cam_in )
        1098             :     use seasalt_model, only: seasalt_emis, seasalt_indices
        1099             :     use dust_model,    only: dust_emis, dust_indices
        1100             :     use physics_types, only: physics_state
        1101             :
        1102             :     ! Arguments:
        1103             :
        1104             :     type(physics_state),    intent(in)    :: state   ! Physics state variables
        1105             :     type(cam_in_t),         intent(inout) :: cam_in  ! import state
        1106             :
        1107             :     ! local vars
        1108             :
        1109             :     integer :: lchnk, ncol
        1110             :     integer :: m, mm
        1111             :     real(r8) :: soil_erod_tmp(pcols)
        1112             :     real(r8) :: sflx(pcols)   ! accumulate over all bins for output
        1113             :     real(r8) :: u10cubed(pcols)
        1114             :     real (r8), parameter :: z0=0.0001_r8  ! m roughness length over oceans--from ocean model
        1115             :
        1116           0 :     lchnk = state%lchnk
        1117           0 :     ncol = state%ncol
        1118             :
        1119           0 :     if (dust_active) then
        1120             :
        1121           0 :        call dust_emis( ncol, lchnk, cam_in%dstflx, cam_in%cflx, soil_erod_tmp )
        1122             :
        1123             :        ! some dust emis diagnostics ...
        1124           0 :        sflx(:)=0._r8
        1125           0 :        do m=1,dust_nbin
        1126           0 :           mm = dust_indices(m)
        1127           0 :           sflx(:ncol)=sflx(:ncol)+cam_in%cflx(:ncol,mm)
        1128           0 :           call outfld(trim(dust_names(m))//'SF',cam_in%cflx(:,mm),pcols, lchnk)
        1129             :        enddo
        1130           0 :        call outfld('DSTSFMBL',sflx(:),pcols,lchnk)
        1131           0 :        call outfld('LND_MBL',soil_erod_tmp(:),pcols, lchnk )
        1132             :     endif
        1133             :
        1134           0 :     if (sslt_active) then
        1135           0 :        u10cubed(:ncol)=sqrt(state%u(:ncol,pver)**2+state%v(:ncol,pver)**2)
        1136             :        ! move the winds to 10m high from the midpoint of the gridbox:
        1137             :        ! follows Tie and Seinfeld and Pandis, p.859 with math.
        1138             :
        1139           0 :        u10cubed(:ncol)=u10cubed(:ncol)*log(10._r8/z0)/log(state%zm(:ncol,pver)/z0)
        1140             :
        1141             :        ! we need them to the 3.41 power, according to Gong et al., 1997:
        1142           0 :        u10cubed(:ncol)=u10cubed(:ncol)**3.41_r8
        1143             :
        1144           0 :        sflx(:)=0._r8
        1145             :
        1146           0 :        call seasalt_emis( u10cubed, cam_in%sst, cam_in%ocnfrac, ncol, cam_in%cflx )
        1147             :
        1148           0 :        do m=1,seasalt_nbin
        1149           0 :           mm = seasalt_indices(m)
        1150           0 :           sflx(:ncol)=sflx(:ncol)+cam_in%cflx(:ncol,mm)
        1151           0 :           call outfld(trim(seasalt_names(m))//'SF',cam_in%cflx(:,mm),pcols,lchnk)
        1152             :        enddo
        1153           0 :        call outfld('SSTSFMBL',sflx(:),pcols,lchnk)
        1154             :     endif
        1155             :
        1156           0 :   end subroutine aero_model_emissions
        1157             :
        1158             : end module aero_model

Generated by: LCOV version 1.14