LCOV - code coverage report
Current view: top level - chemistry/mozart - mo_drydep.F90 (source / functions) Hit Total Coverage
Test: coverage.info Lines: 343 613 56.0 %
Date: 2025-03-13 19:18:33 Functions: 7 9 77.8 %

          Line data    Source code
       1             : module mo_drydep
       2             : 
       3             :   !---------------------------------------------------------------------
       4             :   !       ... Dry deposition
       5             :   !---------------------------------------------------------------------
       6             : 
       7             :   use shr_kind_mod,     only : r8 => shr_kind_r8, shr_kind_cl
       8             :   use chem_mods,        only : gas_pcnst
       9             :   use pmgrid,           only : plev
      10             :   use spmd_utils,       only : masterproc
      11             :   use ppgrid,           only : pcols, begchunk, endchunk
      12             :   use mo_tracname,      only : solsym
      13             :   use cam_abortutils,   only : endrun
      14             :   use ioFileMod,        only : getfil
      15             :   use pio
      16             :   use cam_pio_utils,    only : cam_pio_openfile, cam_pio_closefile
      17             :   use cam_logfile,      only : iulog
      18             :   use dyn_grid,         only : get_dyn_grid_parm, get_horiz_grid_d
      19             :   use scamMod,          only : single_column
      20             : 
      21             :   use shr_drydep_mod,   only : nddvels =>  n_drydep, drydep_list, mapping
      22             :   use physconst,        only : karman
      23             : 
      24             :   use infnan,                only : nan, assignment(=)
      25             : 
      26             :   implicit none
      27             : 
      28             :   save
      29             : 
      30             :   interface drydep_inti
      31             :      module procedure dvel_inti_xactive
      32             :   end interface
      33             : 
      34             :   interface drydep
      35             :      module procedure drydep_fromlnd
      36             :   end interface
      37             : 
      38             :   private
      39             : 
      40             :   public :: drydep_inti, drydep, has_drydep
      41             :   public :: drydep_update
      42             :   public :: n_land_type, fraction_landuse, drydep_srf_file
      43             : 
      44             :   integer :: pan_ndx, mpan_ndx, o3_ndx, ch4_ndx, co_ndx, h2_ndx, ch3cooh_ndx
      45             :   integer :: sogm_ndx, sogi_ndx, sogt_ndx, sogb_ndx, sogx_ndx
      46             : 
      47             :   integer :: so2_ndx, ch3cn_ndx, hcn_ndx, hcooh_ndx
      48             : 
      49             :   integer :: o3a_ndx,xpan_ndx,xmpan_ndx
      50             : 
      51             :   integer :: cohc_ndx=-1, come_ndx=-1
      52             :   integer, parameter :: NTAGS = 50
      53             :   integer :: cotag_ndx(NTAGS)
      54             :   integer :: tag_cnt
      55             : 
      56             :   real(r8), parameter    :: small_value = 1.e-36_r8
      57             :   real(r8), parameter    :: large_value = 1.e36_r8
      58             :   real(r8), parameter    :: diffm       = 1.789e-5_r8
      59             :   real(r8), parameter    :: diffk       = 1.461e-5_r8
      60             :   real(r8), parameter    :: difft       = 2.060e-5_r8
      61             :   real(r8), parameter    :: vonkar      = karman
      62             :   real(r8), parameter    :: ric         = 0.2_r8
      63             :   real(r8), parameter    :: r           = 287.04_r8
      64             :   real(r8), parameter    :: cp          = 1004._r8
      65             :   real(r8), parameter    :: grav        = 9.81_r8
      66             :   real(r8), parameter    :: p00         = 100000._r8
      67             :   real(r8), parameter    :: wh2o        = 18.0153_r8
      68             :   real(r8), parameter    :: ph          = 1.e-5_r8
      69             :   real(r8), parameter    :: ph_inv      = 1._r8/ph
      70             :   real(r8), parameter    :: rovcp = r/cp
      71             : 
      72             :   logical, public :: has_dvel(gas_pcnst) = .false.
      73             :   integer         :: map_dvel(gas_pcnst) = 0
      74             : 
      75             :   real(r8), protected, allocatable  :: fraction_landuse(:,:,:)
      76             :   real(r8), allocatable, dimension(:,:,:) :: dep_ra ! [s/m] aerodynamic resistance
      77             :   real(r8), allocatable, dimension(:,:,:) :: dep_rb ! [s/m] resistance across sublayer
      78             :   integer, parameter :: n_land_type = 11
      79             : 
      80             :   integer, allocatable :: spc_ndx(:) ! nddvels
      81             :   real(r8), public :: crb
      82             : 
      83             :   type lnd_dvel_type
      84             :      real(r8), pointer :: dvel(:,:)   ! deposition velocity over land (cm/s)
      85             :   end type lnd_dvel_type
      86             : 
      87             :   type(lnd_dvel_type), allocatable :: lnd(:)
      88             :   character(len=SHR_KIND_CL) :: drydep_srf_file
      89             : 
      90             : contains
      91             : 
      92             :   !---------------------------------------------------------------------------
      93             :   !---------------------------------------------------------------------------
      94        2304 :   subroutine dvel_inti_fromlnd
      95             :     use mo_chem_utls,         only : get_spc_ndx
      96             :     use cam_abortutils,       only : endrun
      97             : 
      98             :     integer :: ispc
      99             : 
     100        6912 :     allocate(spc_ndx(nddvels))
     101        6912 :     allocate( lnd(begchunk:endchunk) )
     102             : 
     103       13824 :     do ispc = 1,nddvels
     104             : 
     105       11520 :        spc_ndx(ispc) = get_spc_ndx(drydep_list(ispc))
     106       13824 :        if (spc_ndx(ispc) < 1) then
     107           0 :           write(*,*) 'drydep_inti: '//trim(drydep_list(ispc))//' is not included in species set'
     108           0 :           call endrun('drydep_init: invalid dry deposition species')
     109             :        endif
     110             : 
     111             :     enddo
     112             : 
     113        2304 :     crb = (difft/diffm)**(2._r8/3._r8) !.666666_r8
     114             : 
     115        2304 :   endsubroutine dvel_inti_fromlnd
     116             : 
     117             :   !-------------------------------------------------------------------------------------
     118             :   !-------------------------------------------------------------------------------------
     119       89784 :   subroutine drydep_update( state, cam_in )
     120             :     use physics_types,   only : physics_state
     121             :     use camsrfexch,      only : cam_in_t
     122             : 
     123             :     type(physics_state), intent(in) :: state           ! Physics state variables
     124             :     type(cam_in_t),  intent(in) :: cam_in
     125             : 
     126       89784 :     if (nddvels<1) return
     127             : 
     128       89784 :     lnd(state%lchnk)%dvel => cam_in%depvel
     129             : 
     130       89784 :   end subroutine drydep_update
     131             : 
     132             :   !-------------------------------------------------------------------------------------
     133             :   !-------------------------------------------------------------------------------------
     134       89784 :   subroutine drydep_fromlnd( ocnfrac, icefrac, sfc_temp, pressure_sfc,  &
     135             :                              wind_speed, spec_hum, air_temp, pressure_10m, rain, &
     136       89784 :                              snow, solar_flux, dvelocity, dflx, mmr, &
     137             :                              tv, ncol, lchnk )
     138             : 
     139             :     !-------------------------------------------------------------------------------------
     140             :     ! combines the deposition velocities provided by the land model with deposition
     141             :     ! velocities over ocean and sea ice
     142             :     !-------------------------------------------------------------------------------------
     143             : 
     144       89784 :     use ppgrid,         only : pcols
     145             :     use chem_mods,      only : gas_pcnst
     146             : 
     147             : #if (defined OFFLINE_DYN)
     148             :     use metdata, only: get_met_fields
     149             : #endif
     150             : 
     151             :     !-------------------------------------------------------------------------------------
     152             :     !   ... dummy arguments
     153             :     !-------------------------------------------------------------------------------------
     154             : 
     155             :     real(r8), intent(in)      :: icefrac(pcols)
     156             :     real(r8), intent(in)      :: ocnfrac(pcols)
     157             :     integer,  intent(in)      :: ncol
     158             :     integer,  intent(in)      :: lchnk                    ! chunk number
     159             :     real(r8), intent(in)      :: sfc_temp(pcols)          ! surface temperature (K)
     160             :     real(r8), intent(in)      :: pressure_sfc(pcols)      ! surface pressure (Pa)
     161             :     real(r8), intent(in)      :: wind_speed(pcols)        ! 10 meter wind speed (m/s)
     162             :     real(r8), intent(in)      :: spec_hum(pcols)          ! specific humidity (kg/kg)
     163             :     real(r8), intent(in)      :: air_temp(pcols)          ! surface air temperature (K)
     164             :     real(r8), intent(in)      :: pressure_10m(pcols)      ! 10 meter pressure (Pa)
     165             :     real(r8), intent(in)      :: rain(pcols)
     166             :     real(r8), intent(in)      :: snow(pcols)              ! snow height (m)
     167             :     real(r8), intent(in)      :: solar_flux(pcols)        ! direct shortwave radiation at surface (W/m^2)
     168             :     real(r8), intent(in)      :: tv(pcols)                ! potential temperature
     169             :     real(r8), intent(in)      :: mmr(pcols,plev,gas_pcnst)    ! constituent concentration (kg/kg)
     170             :     real(r8), intent(out)     :: dvelocity(ncol,gas_pcnst)    ! deposition velocity (cm/s)
     171             :     real(r8), intent(inout)   :: dflx(pcols,gas_pcnst)        ! deposition flux (/cm^2/s)
     172             : 
     173             :     !-------------------------------------------------------------------------------------
     174             :     !   ... local variables
     175             :     !-------------------------------------------------------------------------------------
     176      179568 :     real(r8) :: ocnice_dvel(ncol,gas_pcnst)
     177             :     real(r8) :: ocnice_dflx(pcols,gas_pcnst)
     178             : 
     179      179568 :     real(r8), dimension(ncol) :: term    ! work array
     180             :     integer  :: ispec
     181             :     real(r8)  :: lndfrac(pcols)
     182             : #if (defined OFFLINE_DYN)
     183             :     real(r8)  :: met_ocnfrac(pcols)
     184             :     real(r8)  :: met_icefrac(pcols)
     185             : #endif
     186             :     integer :: i
     187             : 
     188     1588968 :     lndfrac(:ncol) = 1._r8 - ocnfrac(:ncol) - icefrac(:ncol)
     189             : 
     190     1499184 :     where( lndfrac(:ncol) < 0._r8 )
     191             :        lndfrac(:ncol) = 0._r8
     192             :     endwhere
     193             : 
     194             : #if (defined OFFLINE_DYN)
     195             :     call get_met_fields(lndfrac, met_ocnfrac, met_icefrac, lchnk, ncol)
     196             : #endif
     197             : 
     198             :     !-------------------------------------------------------------------------------------
     199             :     !   ... initialize
     200             :     !-------------------------------------------------------------------------------------
     201    46564488 :     dvelocity(:,:) = 0._r8
     202             : 
     203             :     !-------------------------------------------------------------------------------------
     204             :     !   ... compute the dep velocities over ocean and sea ice
     205             :     !       land type 7 is used for ocean
     206             :     !       land type 8 is used for sea ice
     207             :     !-------------------------------------------------------------------------------------
     208             :     call drydep_xactive( sfc_temp, pressure_sfc,  &
     209             :                          wind_speed, spec_hum, air_temp, pressure_10m, rain, &
     210             :                          snow, solar_flux, ocnice_dvel, ocnice_dflx, mmr, &
     211             :                          tv, ncol, lchnk, &
     212             : #if (defined OFFLINE_DYN)
     213             :                          ocnfrc=met_ocnfrac,icefrc=met_icefrac, beglandtype=7, endlandtype=8 )
     214             : #else
     215       89784 :                          ocnfrc=ocnfrac,icefrc=icefrac, beglandtype=7, endlandtype=8 )
     216             : #endif
     217     1499184 :     term(:ncol) = 1.e-2_r8 * pressure_10m(:ncol) / (r*tv(:ncol))
     218             : 
     219      538704 :     do ispec = 1,nddvels
     220             :        !-------------------------------------------------------------------------------------
     221             :        !        ... merge the land component with the non-land component
     222             :        !            ocn and ice already have fractions factored in
     223             :        !-------------------------------------------------------------------------------------
     224           0 :        dvelocity(:ncol,spc_ndx(ispec)) = lnd(lchnk)%dvel(:ncol,ispec)*lndfrac(:ncol) &
     225     7585704 :                                        + ocnice_dvel(:ncol,spc_ndx(ispec))
     226             :     enddo
     227             : 
     228             :     !-------------------------------------------------------------------------------------
     229             :     !        ... special adjustments
     230             :     !-------------------------------------------------------------------------------------
     231       89784 :     if( mpan_ndx>0 ) then
     232           0 :        dvelocity(:ncol,mpan_ndx) = dvelocity(:ncol,mpan_ndx)/3._r8
     233             :     endif
     234       89784 :     if( xmpan_ndx>0 ) then
     235           0 :        dvelocity(:ncol,xmpan_ndx) = dvelocity(:ncol,xmpan_ndx)/3._r8
     236             :     endif
     237       89784 :     if( hcn_ndx>0 ) then
     238           0 :        dvelocity(:ncol,hcn_ndx) = ocnice_dvel(:ncol,hcn_ndx) ! should be zero over land
     239             :     endif
     240       89784 :     if( ch3cn_ndx>0 ) then
     241           0 :        dvelocity(:ncol,ch3cn_ndx) = ocnice_dvel(:ncol,ch3cn_ndx) ! should be zero over land
     242             :     endif
     243             : 
     244             :     ! HCOOH, use CH3COOH dep.vel
     245       89784 :     if( hcooh_ndx > 0 .and. ch3cooh_ndx > 0 ) then
     246           0 :        if( has_dvel(hcooh_ndx) ) then
     247           0 :           dvelocity(:ncol,hcooh_ndx) = dvelocity(:ncol,ch3cooh_ndx)
     248             :        end if
     249             :     end if
     250             : 
     251             :     !-------------------------------------------------------------------------------------
     252             :     !        ... assign CO tags to CO
     253             :     ! put this kludge in for now ...
     254             :     !  -- should be able to set all these via the table mapping in shr_drydep_mod
     255             :     !-------------------------------------------------------------------------------------
     256       89784 :     if( cohc_ndx>0 .and. co_ndx>0 ) then
     257           0 :        dvelocity(:ncol,cohc_ndx) = dvelocity(:ncol,co_ndx)
     258           0 :        dflx(:ncol,cohc_ndx) = dvelocity(:ncol,co_ndx) * term(:ncol) * mmr(:ncol,plev,cohc_ndx)
     259             :     endif
     260       89784 :     if( come_ndx>0 .and. co_ndx>0 ) then
     261           0 :        dvelocity(:ncol,come_ndx) = dvelocity(:ncol,co_ndx)
     262           0 :        dflx(:ncol,come_ndx) = dvelocity(:ncol,co_ndx) * term(:ncol) * mmr(:ncol,plev,come_ndx)
     263             :     endif
     264             : 
     265       89784 :     if ( co_ndx>0 ) then
     266           0 :        do i=1,tag_cnt
     267           0 :           dvelocity(:ncol,cotag_ndx(i)) = dvelocity(:ncol,co_ndx)
     268           0 :           dflx(:ncol,cotag_ndx(i)) = dvelocity(:ncol,co_ndx) * term(:ncol) * mmr(:ncol,plev,cotag_ndx(i))
     269             :        enddo
     270             :     endif
     271             : 
     272      538704 :     do ispec = 1,nddvels
     273             :        !-------------------------------------------------------------------------------------
     274             :        !        ... compute the deposition flux
     275             :        !-------------------------------------------------------------------------------------
     276     7585704 :        dflx(:ncol,spc_ndx(ispec)) = dvelocity(:ncol,spc_ndx(ispec)) * term(:ncol) * mmr(:ncol,plev,spc_ndx(ispec))
     277             :     end do
     278             : 
     279       89784 :   end subroutine drydep_fromlnd
     280             : 
     281             :   !-------------------------------------------------------------------------------------
     282             :   !-------------------------------------------------------------------------------------
     283        2304 :   subroutine dvel_inti_xactive( depvel_lnd_file )
     284             :     !-------------------------------------------------------------------------------------
     285             :     !   ... intialize interactive drydep
     286             :     !-------------------------------------------------------------------------------------
     287             :     use dycore,        only : dycore_is
     288             :     use mo_chem_utls,  only : get_spc_ndx
     289             :     use phys_control,  only : phys_getopts
     290             : 
     291             :     !-------------------------------------------------------------------------------------
     292             :     !   ... dummy arguments
     293             :     !-------------------------------------------------------------------------------------
     294             :     character(len=*), intent(in) :: depvel_lnd_file
     295             : 
     296             :     !-------------------------------------------------------------------------------------
     297             :     !   ... local variables
     298             :     !-------------------------------------------------------------------------------------
     299             :     integer :: i
     300             :     integer :: nlon_veg, nlat_veg, npft_veg
     301             :     integer :: dimid
     302             :     integer :: m
     303             :     integer :: astat
     304             :     integer :: plon, plat
     305             :     integer :: ierr, ndx
     306             : 
     307        2304 :     real(r8), allocatable :: vegetation_map(:,:,:)
     308        2304 :     real(r8), allocatable :: work(:,:)
     309        2304 :     real(r8), allocatable :: landmask(:,:)
     310        2304 :     real(r8), allocatable :: urban(:,:)
     311        2304 :     real(r8), allocatable :: lake(:,:)
     312        2304 :     real(r8), allocatable :: wetland(:,:)
     313        2304 :     real(r8), allocatable :: lon_veg_edge(:)
     314        2304 :     real(r8), allocatable :: lat_veg_edge(:)
     315             : 
     316             :     character(len=32) :: test_name
     317             :     character(len=4) :: tag_name
     318             :     type(file_desc_t) :: piofile
     319             :     type(var_desc_t) :: vid
     320             : 
     321             :     character(len=shr_kind_cl) :: locfn
     322             :     logical :: prog_modal_aero
     323             : 
     324             :     ! determine if modal aerosols are active so that fraction_landuse array is initialized for modal aerosal dry dep
     325        2304 :     call phys_getopts(prog_modal_aero_out=prog_modal_aero)
     326             : 
     327        2304 :     call dvel_inti_fromlnd()
     328             : 
     329        2304 :     if( masterproc ) then
     330           3 :        write(iulog,*) 'drydep_inti: following species have dry deposition'
     331          18 :        do i=1,nddvels
     332          18 :           if( len_trim(drydep_list(i)) > 0 ) then
     333          15 :              write(iulog,*) 'drydep_inti: '//trim(drydep_list(i))//' is requested to have dry dep'
     334             :           endif
     335             :        enddo
     336           3 :        write(iulog,*) 'drydep_inti:'
     337             :     endif
     338             : 
     339             :     !-------------------------------------------------------------------------------------
     340             :     !   ... get species indices
     341             :     !-------------------------------------------------------------------------------------
     342        2304 :     xpan_ndx      = get_spc_ndx( 'XPAN' )
     343        2304 :     xmpan_ndx     = get_spc_ndx( 'XMPAN' )
     344        2304 :     o3a_ndx       = get_spc_ndx( 'O3A' )
     345             : 
     346        2304 :     ch4_ndx      = get_spc_ndx( 'CH4' )
     347        2304 :     h2_ndx       = get_spc_ndx( 'H2' )
     348        2304 :     co_ndx       = get_spc_ndx( 'CO' )
     349        2304 :     pan_ndx      = get_spc_ndx( 'PAN' )
     350        2304 :     mpan_ndx     = get_spc_ndx( 'MPAN' )
     351        2304 :     o3_ndx       = get_spc_ndx( 'OX' )
     352        2304 :     if( o3_ndx < 0 ) then
     353        2304 :        o3_ndx  = get_spc_ndx( 'O3' )
     354             :     end if
     355        2304 :     so2_ndx     = get_spc_ndx( 'SO2' )
     356        2304 :     ch3cooh_ndx = get_spc_ndx( 'CH3COOH')
     357             : 
     358        2304 :     sogm_ndx   = get_spc_ndx( 'SOGM' )
     359        2304 :     sogi_ndx   = get_spc_ndx( 'SOGI' )
     360        2304 :     sogt_ndx   = get_spc_ndx( 'SOGT' )
     361        2304 :     sogb_ndx   = get_spc_ndx( 'SOGB' )
     362        2304 :     sogx_ndx   = get_spc_ndx( 'SOGX' )
     363             : 
     364        2304 :     hcn_ndx     = get_spc_ndx( 'HCN')
     365        2304 :     ch3cn_ndx   = get_spc_ndx( 'CH3CN')
     366             : 
     367        2304 :     cohc_ndx     = get_spc_ndx( 'COhc' )
     368        2304 :     come_ndx     = get_spc_ndx( 'COme' )
     369             : 
     370        2304 :     tag_cnt=0
     371      117504 :     cotag_ndx(:)=-1
     372      117504 :     do i = 1,NTAGS
     373      115200 :        write(tag_name,'(a2,i2.2)') 'CO',i
     374      115200 :        ndx = get_spc_ndx(tag_name)
     375      117504 :        if (ndx>0) then
     376           0 :           tag_cnt = tag_cnt+1
     377           0 :           cotag_ndx(tag_cnt) = ndx
     378             :        endif
     379             :     enddo
     380             : 
     381       13824 :     do i=1,nddvels
     382       13824 :        if ( mapping(i) > 0 ) then
     383       11520 :           test_name = drydep_list(i)
     384       11520 :           m = get_spc_ndx( test_name )
     385       11520 :           has_dvel(m) = .true.
     386       11520 :           map_dvel(m) = i
     387             :        endif
     388             :     enddo
     389             : 
     390       16128 :     if( all( .not. has_dvel(:) ) ) then
     391             :        return
     392             :     end if
     393             : 
     394             :     !---------------------------------------------------------------------------
     395             :     !   ... allocate module variables
     396             :     !---------------------------------------------------------------------------
     397        6912 :     allocate( dep_ra(pcols,n_land_type,begchunk:endchunk),stat=astat )
     398        2304 :     if( astat /= 0 ) then
     399           0 :        write(iulog,*) 'dvel_inti: failed to allocate dep_ra; error = ',astat
     400           0 :        call endrun('dvel_inti: failed to allocate dep_ra')
     401             :     end if
     402        6912 :     allocate( dep_rb(pcols,n_land_type,begchunk:endchunk),stat=astat )
     403        2304 :     if( astat /= 0 ) then
     404           0 :        write(iulog,*) 'dvel_inti: failed to allocate dep_rb; error = ',astat
     405           0 :        call endrun('dvel_inti: failed to allocate dep_rb')
     406             :     end if
     407             : 
     408        2304 :     if (.not.prog_modal_aero) then
     409             :        return
     410             :     endif
     411             : 
     412        6912 :     allocate( fraction_landuse(pcols,n_land_type, begchunk:endchunk),stat=astat )
     413        2304 :     if( astat /= 0 ) then
     414           0 :        write(iulog,*) 'dvel_inti: failed to allocate fraction_landuse; error = ',astat
     415           0 :        call endrun('dvel_inti: failed to allocate fraction_landuse')
     416             :     end if
     417        2304 :     fraction_landuse = nan
     418             : 
     419        2304 :     plon = get_dyn_grid_parm('plon')
     420        2304 :     plat = get_dyn_grid_parm('plat')
     421             : 
     422        2304 :     if(dycore_is('UNSTRUCTURED') ) then
     423        2304 :        call get_landuse_and_soilw_from_file()
     424             :     else
     425             :        !---------------------------------------------------------------------------
     426             :        !        ... read landuse map
     427             :        !---------------------------------------------------------------------------
     428           0 :        call getfil (depvel_lnd_file, locfn, 0)
     429           0 :        call cam_pio_openfile (piofile, trim(locfn), PIO_NOWRITE)
     430             :        !---------------------------------------------------------------------------
     431             :        !        ... get the dimensions
     432             :        !---------------------------------------------------------------------------
     433           0 :        ierr = pio_inq_dimid( piofile, 'lon', dimid )
     434           0 :        ierr = pio_inq_dimlen( piofile, dimid, nlon_veg )
     435           0 :        ierr = pio_inq_dimid( piofile, 'lat', dimid )
     436           0 :        ierr = pio_inq_dimlen( piofile, dimid, nlat_veg )
     437           0 :        ierr = pio_inq_dimid( piofile, 'pft', dimid )
     438           0 :        ierr = pio_inq_dimlen( piofile, dimid, npft_veg )
     439             :        !---------------------------------------------------------------------------
     440             :        !        ... allocate arrays
     441             :        !---------------------------------------------------------------------------
     442           0 :        allocate( vegetation_map(nlon_veg,nlat_veg,npft_veg), work(nlon_veg,nlat_veg), stat=astat )
     443           0 :        if( astat /= 0 ) then
     444           0 :           write(iulog,*) 'dvel_inti: failed to allocate vegetation_map; error = ',astat
     445           0 :           call endrun('dvel_inti: failed to allocate vegetation_map')
     446             :        end if
     447             :        allocate( urban(nlon_veg,nlat_veg), lake(nlon_veg,nlat_veg), &
     448           0 :             landmask(nlon_veg,nlat_veg), wetland(nlon_veg,nlat_veg), stat=astat )
     449           0 :        if( astat /= 0 ) then
     450           0 :           write(iulog,*) 'dvel_inti: failed to allocate vegetation_map; error = ',astat
     451           0 :           call endrun('dvel_inti: failed to allocate vegetation_map')
     452             :        end if
     453           0 :        allocate( lon_veg_edge(nlon_veg+1), lat_veg_edge(nlat_veg+1), stat=astat )
     454           0 :        if( astat /= 0 ) then
     455           0 :           write(iulog,*) 'dvel_inti: failed to allocate vegetation lon, lat arrays; error = ',astat
     456           0 :           call endrun('dvel_inti: failed to allocate vegetation lon, lat arrays')
     457             :        end if
     458             :        !---------------------------------------------------------------------------
     459             :        !        ... read the vegetation map and landmask
     460             :        !---------------------------------------------------------------------------
     461           0 :        ierr = pio_inq_varid( piofile, 'PCT_PFT', vid )
     462           0 :        ierr = pio_get_var( piofile, vid, vegetation_map )
     463             : 
     464           0 :        ierr = pio_inq_varid( piofile, 'LANDMASK', vid )
     465           0 :        ierr = pio_get_var( piofile, vid, landmask )
     466             : 
     467           0 :        ierr = pio_inq_varid( piofile, 'PCT_URBAN', vid )
     468           0 :        ierr = pio_get_var( piofile, vid, urban )
     469             : 
     470           0 :        ierr = pio_inq_varid( piofile, 'PCT_LAKE', vid )
     471           0 :        ierr = pio_get_var( piofile, vid, lake )
     472             : 
     473           0 :        ierr = pio_inq_varid( piofile, 'PCT_WETLAND', vid )
     474           0 :        ierr = pio_get_var( piofile, vid, wetland )
     475             : 
     476           0 :        call cam_pio_closefile( piofile )
     477             : 
     478             :        !---------------------------------------------------------------------------
     479             :        ! scale vegetation, urban, lake, and wetland to fraction
     480             :        !---------------------------------------------------------------------------
     481           0 :        vegetation_map(:,:,:) = .01_r8 * vegetation_map(:,:,:)
     482           0 :        wetland(:,:)          = .01_r8 * wetland(:,:)
     483           0 :        lake(:,:)             = .01_r8 * lake(:,:)
     484           0 :        urban(:,:)            = .01_r8 * urban(:,:)
     485             : #ifdef DEBUG
     486           0 :        if(masterproc) then
     487           0 :           write(iulog,*) 'minmax vegetation_map ',minval(vegetation_map),maxval(vegetation_map)
     488           0 :           write(iulog,*) 'minmax wetland        ',minval(wetland),maxval(wetland)
     489           0 :           write(iulog,*) 'minmax landmask       ',minval(landmask),maxval(landmask)
     490             :        end if
     491             : #endif
     492             :        !---------------------------------------------------------------------------
     493             :        !        ... define lat-lon of vegetation map (1x1)
     494             :        !---------------------------------------------------------------------------
     495           0 :        lat_veg_edge(:) = (/ (-90.0_r8 + (i-1),i=1,nlat_veg+1) /)
     496           0 :        lon_veg_edge(:) = (/ (  0.0_r8 + (i-1),i=1,nlon_veg+1) /)
     497             : 
     498             :        !---------------------------------------------------------------------------
     499             :        !        ... regrid to model grid
     500             :        !---------------------------------------------------------------------------
     501             :        call interp_map( plon, plat, nlon_veg, nlat_veg, npft_veg, lat_veg_edge, &
     502             :             lon_veg_edge, landmask, urban, lake, &
     503           0 :             wetland, vegetation_map )
     504             : 
     505           0 :        deallocate( vegetation_map, work, stat=astat )
     506           0 :        deallocate( lon_veg_edge, lat_veg_edge, stat=astat )
     507           0 :        deallocate( landmask, urban, lake, wetland, stat=astat )
     508             :     endif  ! Unstructured grid
     509             : 
     510        4608 :   end subroutine dvel_inti_xactive
     511             : 
     512             :   !-------------------------------------------------------------------------------------
     513        2304 :   subroutine get_landuse_and_soilw_from_file()
     514             :     use ncdio_atm, only : infld
     515             : 
     516             :     logical :: readvar
     517             : 
     518             :     type(file_desc_t) :: piofile
     519             :     character(len=shr_kind_cl) :: locfn
     520             :     logical :: lexist
     521             : 
     522        2304 :     if (len_trim(drydep_srf_file) == 0) then
     523           0 :        if (masterproc) then
     524           0 :           write(iulog,*)'**************************************'
     525           0 :           write(iulog,*)' get_landuse_and_soilw_from_file: INFO:'
     526           0 :           write(iulog,*)' drydep_srf_file not set:'
     527           0 :           write(iulog,*)' setting fraction_landuse to zero'
     528           0 :           write(iulog,*)'**************************************'
     529             :        end if
     530           0 :        fraction_landuse = 0._r8
     531             :        return
     532             :     end if
     533             : 
     534        2304 :     call getfil (drydep_srf_file, locfn, 1, lexist)
     535        2304 :     if(lexist) then
     536        2304 :        call cam_pio_openfile(piofile, locfn, PIO_NOWRITE)
     537             : 
     538             :        call infld('fraction_landuse', piofile, 'ncol','class',1,pcols,1,n_land_type, begchunk,endchunk, &
     539        2304 :             fraction_landuse, readvar, gridname='physgrid')
     540        2304 :        if (.not. readvar) then
     541           0 :           if (masterproc) then
     542           0 :              write(iulog,*)'**************************************'
     543           0 :              write(iulog,*)'get_landuse_and_soilw_from_file: INFO:'
     544           0 :              write(iulog,*)' fraction_landuse not read from file: '
     545           0 :              write(iulog,*)' ', trim(locfn)
     546           0 :              write(iulog,*)' setting all values to zero'
     547           0 :              write(iulog,*)'**************************************'
     548             :           end if
     549           0 :           fraction_landuse = 0._r8
     550             :        end if
     551             : 
     552        2304 :        call cam_pio_closefile(piofile)
     553             :     else
     554           0 :        call endrun('Unstructured grids require drydep_srf_file ')
     555             :     end if
     556             : 
     557             : 
     558        4608 :   end subroutine get_landuse_and_soilw_from_file
     559             : 
     560             :   !-------------------------------------------------------------------------------------
     561           0 :   subroutine interp_map( plon, plat, nlon_veg, nlat_veg, npft_veg, lat_veg_edge, &
     562           0 :                          lon_veg_edge, landmask, urban, lake, &
     563           0 :                          wetland, vegetation_map )
     564             : 
     565        2304 :     use mo_constants, only : r2d
     566             :     use scamMod, only : latiop,loniop,scmlat,scmlon,scm_cambfb_mode
     567             :     use shr_scam_mod  , only: shr_scam_getCloseLatLon  ! Standardized system subroutines
     568             :     use cam_initfiles, only: initial_file_get_id
     569             :     use dycore, only : dycore_is
     570             :     use phys_grid,     only : get_rlat_all_p, get_rlon_all_p, get_ncols_p
     571             : 
     572             :     !-------------------------------------------------------------------------------------
     573             :     !   ... dummy arguments
     574             :     !-------------------------------------------------------------------------------------
     575             :     integer,  intent(in)         :: plon, plat, nlon_veg, nlat_veg, npft_veg
     576             :     real(r8), intent(in)         :: landmask(nlon_veg,nlat_veg)
     577             :     real(r8), intent(in)         :: urban(nlon_veg,nlat_veg)
     578             :     real(r8), intent(in)         :: lake(nlon_veg,nlat_veg)
     579             :     real(r8), intent(in)         :: wetland(nlon_veg,nlat_veg)
     580             :     real(r8), intent(in)         :: vegetation_map(nlon_veg,nlat_veg,npft_veg)
     581             :     real(r8), intent(in)         :: lon_veg_edge(nlon_veg+1)
     582             :     real(r8), intent(in)         :: lat_veg_edge(nlat_veg+1)
     583             : 
     584             :     !-------------------------------------------------------------------------------------
     585             :     !   ... local variables
     586             :     !-------------------------------------------------------------------------------------
     587             :     real(r8) :: closelat,closelon
     588             :     integer :: latidx,lonidx
     589             : 
     590             :     integer, parameter           :: veg_ext = 20
     591             :     type(file_desc_t), pointer   :: piofile
     592             :     integer                      :: i, j, ii, jj, i_ndx, n
     593           0 :     integer, dimension(plon+1)   :: ind_lon
     594           0 :     integer, dimension(plat+1)  :: ind_lat
     595             :     real(r8)                         :: total_land
     596           0 :     real(r8), dimension(plon+1)      :: lon_edge
     597           0 :     real(r8), dimension(plat+1)     :: lat_edge
     598             :     real(r8)                         :: lat1, lon1
     599             :     real(r8)                         :: x1, x2, y1, y2, dx, dy
     600             :     real(r8)                         :: area, total_area
     601           0 :     real(r8), dimension(npft_veg+3)  :: fraction
     602           0 :     real(r8), dimension(-veg_ext:nlon_veg+veg_ext) :: lon_veg_edge_ext
     603           0 :     integer, dimension(-veg_ext:nlon_veg+veg_ext) :: mapping_ext
     604             : 
     605           0 :     real(r8), allocatable :: lam(:), phi(:)
     606             : 
     607             :     logical, parameter :: has_npole = .true.
     608             :     integer :: ploniop,platiop
     609           0 :     real(r8) :: tmp_frac_lu(plon,n_land_type,plat)
     610             : 
     611             :     real(r8):: rlats(pcols), rlons(pcols)
     612             :     integer :: lchnk, ncol, icol
     613             :     logical :: found
     614             : 
     615           0 :     if(dycore_is('UNSTRUCTURED') ) then
     616           0 :        call endrun('mo_drydep::interp_map called for UNSTRUCTURED grid')
     617             :     endif
     618             : 
     619           0 :     allocate(lam(plon), phi(plat))
     620           0 :     call get_horiz_grid_d(plat, clat_d_out=phi)
     621           0 :     call get_horiz_grid_d(plon, clon_d_out=lam)
     622             : 
     623           0 :     if (single_column) then
     624           0 :        if (scm_cambfb_mode) then
     625           0 :           piofile => initial_file_get_id()
     626           0 :           call shr_scam_getCloseLatLon(piofile,scmlat,scmlon,closelat,closelon,latidx,lonidx)
     627           0 :           ploniop=size(loniop)
     628           0 :           platiop=size(latiop)
     629             :        else
     630           0 :           latidx=1
     631           0 :           lonidx=1
     632           0 :           ploniop=1
     633           0 :           platiop=1
     634             :        end if
     635             : 
     636           0 :        lon_edge(1) = loniop(lonidx) * r2d - .5_r8*(loniop(2) - loniop(1)) * r2d
     637             : 
     638           0 :        if (lonidx.lt.ploniop) then
     639           0 :           lon_edge(2) = loniop(lonidx+1) * r2d - .5_r8*(loniop(2) - loniop(1)) * r2d
     640             :        else
     641           0 :           lon_edge(2) = lon_edge(1) + (loniop(2) - loniop(1)) * r2d
     642             :        end if
     643             : 
     644           0 :        lat_edge(1) = latiop(latidx) * r2d - .5_r8*(latiop(2) - latiop(1)) * r2d
     645             : 
     646           0 :        if (latidx.lt.platiop) then
     647           0 :           lat_edge(2) = latiop(latidx+1) * r2d - .5_r8*(latiop(2) - latiop(1)) * r2d
     648             :        else
     649           0 :           lat_edge(2) = lat_edge(1) + (latiop(2) - latiop(1)) * r2d
     650             :        end if
     651             :     else
     652           0 :        do i = 1,plon
     653           0 :           lon_edge(i) = lam(i) * r2d - .5_r8*(lam(2) - lam(1)) * r2d
     654             :        end do
     655           0 :        lon_edge(plon+1) = lon_edge(plon) + (lam(2) - lam(1)) * r2d
     656             :        if( .not. has_npole ) then
     657             :           do j = 1,plat+1
     658             :              lat_edge(j) = phi(j) * r2d - .5_r8*(phi(2) - phi(1)) * r2d
     659             :           end do
     660             :        else
     661           0 :           do j = 1,plat
     662           0 :              lat_edge(j) = phi(j) * r2d - .5_r8*(phi(2) - phi(1)) * r2d
     663             :           end do
     664           0 :           lat_edge(plat+1) = lat_edge(plat) + (phi(2) - phi(1)) * r2d
     665             :        end if
     666             :     end if
     667           0 :     do j = 1,plat+1
     668           0 :        lat_edge(j) = min( lat_edge(j), 90._r8 )
     669           0 :        lat_edge(j) = max( lat_edge(j),-90._r8 )
     670             :     end do
     671             : 
     672             :     !-------------------------------------------------------------------------------------
     673             :     ! wrap around the longitudes
     674             :     !-------------------------------------------------------------------------------------
     675           0 :     do i = -veg_ext,0
     676           0 :        lon_veg_edge_ext(i) = lon_veg_edge(nlon_veg+i) - 360._r8
     677           0 :        mapping_ext     (i) =              nlon_veg+i
     678             :     end do
     679           0 :     do i = 1,nlon_veg
     680           0 :        lon_veg_edge_ext(i) = lon_veg_edge(i)
     681           0 :        mapping_ext     (i) =              i
     682             :     end do
     683           0 :     do i = nlon_veg+1,nlon_veg+veg_ext
     684           0 :        lon_veg_edge_ext(i) = lon_veg_edge(i-nlon_veg) + 360._r8
     685           0 :        mapping_ext     (i) =              i-nlon_veg
     686             :     end do
     687             : #ifdef DEBUG
     688           0 :     write(iulog,*) 'interp_map : lon_edge ',lon_edge
     689           0 :     write(iulog,*) 'interp_map : lat_edge ',lat_edge
     690           0 :     write(iulog,*) 'interp_map : mapping_ext ',mapping_ext
     691             : #endif
     692           0 :     do j = 1,plon+1
     693           0 :        lon1 = lon_edge(j)
     694           0 :        do i = -veg_ext,nlon_veg+veg_ext
     695           0 :           dx = lon_veg_edge_ext(i  ) - lon1
     696           0 :           dy = lon_veg_edge_ext(i+1) - lon1
     697           0 :           if( dx*dy <= 0._r8 ) then
     698           0 :              ind_lon(j) = i
     699           0 :              exit
     700             :           end if
     701             :        end do
     702             :     end do
     703             : 
     704           0 :     do j = 1,plat+1
     705           0 :        lat1 = lat_edge(j)
     706           0 :        do i = 1,nlat_veg
     707           0 :           dx = lat_veg_edge(i  ) - lat1
     708           0 :           dy = lat_veg_edge(i+1) - lat1
     709           0 :           if( dx*dy <= 0._r8 ) then
     710           0 :              ind_lat(j) = i
     711           0 :              exit
     712             :           end if
     713             :        end do
     714             :     end do
     715             : #ifdef DEBUG
     716           0 :     write(iulog,*) 'interp_map : ind_lon ',ind_lon
     717           0 :     write(iulog,*) 'interp_map : ind_lat ',ind_lat
     718             : #endif
     719           0 :     lat_loop : do j = 1,plat
     720           0 :        lon_loop : do i = 1,plon
     721           0 :           total_area       = 0._r8
     722           0 :           fraction         = 0._r8
     723           0 :           do jj = ind_lat(j),ind_lat(j+1)
     724           0 :              y1 = max( lat_edge(j),lat_veg_edge(jj) )
     725           0 :              y2 = min( lat_edge(j+1),lat_veg_edge(jj+1) )
     726           0 :              dy = (y2 - y1)/(lat_veg_edge(jj+1) - lat_veg_edge(jj))
     727           0 :              do ii =ind_lon(i),ind_lon(i+1)
     728           0 :                 i_ndx = mapping_ext(ii)
     729           0 :                 x1 = max( lon_edge(i),lon_veg_edge_ext(ii) )
     730           0 :                 x2 = min( lon_edge(i+1),lon_veg_edge_ext(ii+1) )
     731           0 :                 dx = (x2 - x1)/(lon_veg_edge_ext(ii+1) - lon_veg_edge_ext(ii))
     732           0 :                 area = dx * dy
     733           0 :                 total_area = total_area + area
     734             :                 !-----------------------------------------------------------------
     735             :                 !       ... special case for ocean grid point
     736             :                 !-----------------------------------------------------------------
     737           0 :                 if( nint(landmask(i_ndx,jj)) == 0 ) then
     738           0 :                    fraction(npft_veg+1) = fraction(npft_veg+1) + area
     739             :                 else
     740           0 :                    do n = 1,npft_veg
     741           0 :                       fraction(n) = fraction(n) + vegetation_map(i_ndx,jj,n) * area
     742             :                    end do
     743           0 :                    fraction(npft_veg+1) = fraction(npft_veg+1) + area * lake   (i_ndx,jj)
     744           0 :                    fraction(npft_veg+2) = fraction(npft_veg+2) + area * wetland(i_ndx,jj)
     745           0 :                    fraction(npft_veg+3) = fraction(npft_veg+3) + area * urban  (i_ndx,jj)
     746             :                    !-----------------------------------------------------------------
     747             :                    !    ... check if land accounts for the whole area.
     748             :                    !           If not, the remaining area is in the ocean
     749             :                    !-----------------------------------------------------------------
     750             :                    total_land = sum(vegetation_map(i_ndx,jj,:)) &
     751             :                               + urban  (i_ndx,jj) &
     752             :                               + lake   (i_ndx,jj) &
     753           0 :                               + wetland(i_ndx,jj)
     754           0 :                    if( total_land < 1._r8 ) then
     755           0 :                       fraction(npft_veg+1) = fraction(npft_veg+1) + (1._r8 - total_land) * area
     756             :                    end if
     757             :                 end if
     758             :              end do
     759             :           end do
     760             :           !-------------------------------------------------------------------------------------
     761             :           !     ... divide by total area of grid box
     762             :           !-------------------------------------------------------------------------------------
     763           0 :           fraction(:) = fraction(:)/total_area
     764             :           !-------------------------------------------------------------------------------------
     765             :           !     ... make sure we don't have too much or too little
     766             :           !-------------------------------------------------------------------------------------
     767           0 :           if( abs( sum(fraction) - 1._r8) > .001_r8 ) then
     768           0 :              fraction(:) = fraction(:)/sum(fraction)
     769             :           end if
     770             :           !-------------------------------------------------------------------------------------
     771             :           !     ... map to Wesely land classification
     772             :           !-------------------------------------------------------------------------------------
     773           0 :           tmp_frac_lu(i, 1, j) =     fraction(20)
     774           0 :           tmp_frac_lu(i, 2, j) = sum(fraction(16:17))
     775           0 :           tmp_frac_lu(i, 3, j) = sum(fraction(13:15))
     776           0 :           tmp_frac_lu(i, 4, j) = sum(fraction( 5: 9))
     777           0 :           tmp_frac_lu(i, 5, j) = sum(fraction( 2: 4))
     778           0 :           tmp_frac_lu(i, 6, j) =     fraction(19)
     779           0 :           tmp_frac_lu(i, 7, j) =     fraction(18)
     780           0 :           tmp_frac_lu(i, 8, j) =     fraction( 1)
     781           0 :           tmp_frac_lu(i, 9, j) = 0._r8
     782           0 :           tmp_frac_lu(i,10, j) = 0._r8
     783           0 :           tmp_frac_lu(i,11, j) = sum(fraction(10:12))
     784             :        end do lon_loop
     785             :     end do lat_loop
     786             : 
     787           0 :     do lchnk = begchunk, endchunk
     788           0 :        ncol = get_ncols_p(lchnk)
     789           0 :        call get_rlat_all_p(lchnk, ncol, rlats(:ncol))
     790           0 :        call get_rlon_all_p(lchnk, ncol, rlons(:ncol))
     791           0 :        do icol= 1,ncol
     792           0 :           found=.false.
     793           0 :           find_col: do j = 1,plat
     794           0 :              do i = 1,plon
     795           0 :                 if (rlats(icol)==phi(j) .and. rlons(icol)==lam(i)) then
     796             :                    found=.true.
     797             :                    exit find_col
     798             :                 endif
     799             :              enddo
     800             :           enddo find_col
     801             : 
     802           0 :           if (.not.found) call endrun('mo_drydep::interp_map not able find physics column coordinate')
     803           0 :           fraction_landuse(icol,1:n_land_type,lchnk) =  tmp_frac_lu(i,1:n_land_type,j)
     804             : 
     805             :        end do
     806             : 
     807             :        !-------------------------------------------------------------------------------------
     808             :        !        ... make sure there are no out of range values
     809             :        !-------------------------------------------------------------------------------------
     810           0 :        where (fraction_landuse(:ncol,:n_land_type,lchnk) < 0._r8) fraction_landuse(:ncol,:n_land_type,lchnk) = 0._r8
     811           0 :        where (fraction_landuse(:ncol,:n_land_type,lchnk) > 1._r8) fraction_landuse(:ncol,:n_land_type,lchnk) = 1._r8
     812             :     end do
     813             : 
     814           0 :   end subroutine interp_map
     815             : 
     816             :   !-------------------------------------------------------------------------------------
     817             :   !-------------------------------------------------------------------------------------
     818       89784 :   subroutine drydep_xactive( sfc_temp, pressure_sfc,  &
     819             :                              wind_speed, spec_hum, air_temp, pressure_10m, rain, &
     820       89784 :                              snow, solar_flux, dvel, dflx, mmr, &
     821             :                              tv, ncol, lchnk, &
     822             :                              ocnfrc, icefrc, beglandtype, endlandtype )
     823             :     !-------------------------------------------------------------------------------------
     824             :     !   code based on wesely (atmospheric environment, 1989, vol 23, p. 1293-1304) for
     825             :     !   calculation of r_c, and on walcek et. al. (atmospheric enviroment, 1986,
     826             :     !   vol. 20, p. 949-964) for calculation of r_a and r_b
     827             :     !
     828             :     !   as suggested in walcek (u_i)(u*_i) = (u_a)(u*_a)
     829             :     !   is kept constant where i represents a subgrid environment and a the
     830             :     !   grid average environment. thus the calculation proceeds as follows:
     831             :     !   va the grid averaged wind is calculated on dots
     832             :     !   z0(i) the grid averaged roughness coefficient is calculated
     833             :     !   ri(i) the grid averaged richardson number is calculated
     834             :     !   --> the grid averaged (u_a)(u*_a) is calculated
     835             :     !   --> subgrid scale u*_i is calculated assuming (u_i) given as above
     836             :     !   --> final deposotion velocity is weighted average of subgrid scale velocities
     837             :     !
     838             :     ! code written by P. Hess, rewritten in fortran 90 by JFL (August 2000)
     839             :     ! modified by JFL to be used in MOZART-2 (October 2002)
     840             :     !-------------------------------------------------------------------------------------
     841             : 
     842           0 :     use shr_drydep_mod, only: z0, rgso, rgss, ri, rclo, rcls, rlu, rac
     843             :     use shr_drydep_mod, only: shr_drydep_setHCoeff, foxd, drat
     844             :     use physconst,      only: tmelt
     845             : 
     846             :     !-------------------------------------------------------------------------------------
     847             :     !   ... dummy arguments
     848             :     !-------------------------------------------------------------------------------------
     849             :     integer, intent(in)   :: ncol
     850             :     real(r8), intent(in)      :: sfc_temp(pcols)          ! surface temperature (K)
     851             :     real(r8), intent(in)      :: pressure_sfc(pcols)      ! surface pressure (Pa)
     852             :     real(r8), intent(in)      :: wind_speed(pcols)        ! 10 meter wind speed (m/s)
     853             :     real(r8), intent(in)      :: spec_hum(pcols)          ! specific humidity (kg/kg)
     854             :     real(r8), intent(in)      :: air_temp(pcols)          ! surface air temperature (K)
     855             :     real(r8), intent(in)      :: pressure_10m(pcols)      ! 10 meter pressure (Pa)
     856             :     real(r8), intent(in)      :: rain(pcols)
     857             :     real(r8), intent(in)      :: snow(pcols)              ! snow height (m)
     858             : 
     859             :     real(r8), intent(in)      :: solar_flux(pcols)        ! direct shortwave radiation at surface (W/m^2)
     860             :     real(r8), intent(in)      :: tv(pcols)                ! potential temperature
     861             :     real(r8), intent(in)      :: mmr(pcols,plev,gas_pcnst)    ! constituent concentration (kg/kg)
     862             :     real(r8), intent(out)     :: dvel(ncol,gas_pcnst)        ! deposition velocity (cm/s)
     863             :     real(r8), intent(inout)   :: dflx(pcols,gas_pcnst)        ! deposition flux (/cm^2/s)
     864             : 
     865             :     integer, intent(in)     ::   lchnk                   ! chunk number
     866             : 
     867             :     integer, intent(in), optional     ::  beglandtype
     868             :     integer, intent(in), optional     ::  endlandtype
     869             : 
     870             :     real(r8), intent(in), optional      :: ocnfrc(pcols)
     871             :     real(r8), intent(in), optional      :: icefrc(pcols)
     872             : 
     873             :     !-------------------------------------------------------------------------------------
     874             :     !   ... local variables
     875             :     !-------------------------------------------------------------------------------------
     876             :     real(r8), parameter :: scaling_to_cm_per_s = 100._r8
     877             :     real(r8), parameter :: rain_threshold      = 1.e-7_r8  ! of the order of 1cm/day expressed in m/s
     878             : 
     879             :     integer :: i, ispec, lt, m
     880             :     integer :: sndx
     881             : 
     882             :     real(r8) :: slope = 0._r8
     883             :     real(r8) :: z0water ! revised z0 over water
     884             :     real(r8) :: p       ! pressure at midpoint first layer
     885             :     real(r8) :: pg      ! surface pressure
     886             :     real(r8) :: es      ! saturation vapor pressure
     887             :     real(r8) :: ws      ! saturation mixing ratio
     888             :     real(r8) :: hvar    ! constant to compute xmol
     889             :     real(r8) :: h       ! constant to compute xmol
     890             :     real(r8) :: psih    ! stability correction factor
     891             :     real(r8) :: rs      ! constant for calculating rsmx
     892             :     real(r8) :: rmx     ! resistance by vegetation
     893             :     real(r8) :: zovl    ! ratio of z to  m-o length
     894             :     real(r8) :: cvarb   ! cvar averaged over landtypes
     895             :     real(r8) :: bb      ! b averaged over landtypes
     896             :     real(r8) :: ustarb  ! ustar averaged over landtypes
     897      179568 :     real(r8) :: tc(ncol)  ! temperature in celsius
     898      179568 :     real(r8) :: cts(ncol) ! correction to rlu rcl and rgs for frost
     899             : 
     900             :     !-------------------------------------------------------------------------------------
     901             :     ! local arrays: dependent on location and species
     902             :     !-------------------------------------------------------------------------------------
     903      179568 :     real(r8), dimension(ncol,nddvels) :: heff
     904             : 
     905             :     !-------------------------------------------------------------------------------------
     906             :     ! local arrays: dependent on location only
     907             :     !-------------------------------------------------------------------------------------
     908      179568 :     integer                :: index_season(ncol,n_land_type)
     909      179568 :     real(r8), dimension(ncol) :: tha     ! atmospheric virtual potential temperature
     910      179568 :     real(r8), dimension(ncol) :: thg     ! ground virtual potential temperature
     911      179568 :     real(r8), dimension(ncol) :: z       ! height of lowest level
     912      179568 :     real(r8), dimension(ncol) :: va      ! magnitude of v on cross points
     913      179568 :     real(r8), dimension(ncol) :: ribn    ! richardson number
     914      179568 :     real(r8), dimension(ncol) :: qs      ! saturation specific humidity
     915      179568 :     real(r8), dimension(ncol) :: crs     ! multiplier to calculate crs
     916      179568 :     real(r8), dimension(ncol) :: rdc     ! part of lower canopy resistance
     917      179568 :     real(r8), dimension(ncol) :: uustar  ! u*ustar (assumed constant over grid)
     918      179568 :     real(r8), dimension(ncol) :: z0b     ! average roughness length over grid
     919      179568 :     real(r8), dimension(ncol) :: wrk     ! work array
     920      179568 :     real(r8), dimension(ncol) :: term    ! work array
     921      179568 :     real(r8), dimension(ncol) :: resc    ! work array
     922      179568 :     real(r8), dimension(ncol) :: lnd_frc ! work array
     923      179568 :     logical,  dimension(ncol) :: unstable
     924      179568 :     logical,  dimension(ncol) :: has_rain
     925      179568 :     logical,  dimension(ncol) :: has_dew
     926             : 
     927             :     !-------------------------------------------------------------------------------------
     928             :     ! local arrays: dependent on location and landtype
     929             :     !-------------------------------------------------------------------------------------
     930      179568 :     real(r8), dimension(ncol,n_land_type) :: rds   ! resistance for deposition of sulfate
     931      179568 :     real(r8), dimension(ncol,n_land_type) :: b     ! buoyancy parameter for unstable conditions
     932      179568 :     real(r8), dimension(ncol,n_land_type) :: cvar  ! height parameter
     933      179568 :     real(r8), dimension(ncol,n_land_type) :: ustar ! friction velocity
     934      179568 :     real(r8), dimension(ncol,n_land_type) :: xmol  ! monin-obukhov length
     935             : 
     936             :     !-------------------------------------------------------------------------------------
     937             :     ! local arrays: dependent on location, landtype and species
     938             :     !-------------------------------------------------------------------------------------
     939      179568 :     real(r8), dimension(ncol,n_land_type,gas_pcnst) :: rsmx  ! vegetative resistance (plant mesophyll)
     940      179568 :     real(r8), dimension(ncol,n_land_type,gas_pcnst) :: rclx  ! lower canopy resistance
     941      179568 :     real(r8), dimension(ncol,n_land_type,gas_pcnst) :: rlux  ! vegetative resistance (upper canopy)
     942      179568 :     real(r8), dimension(ncol,n_land_type) :: rlux_o3  ! vegetative resistance (upper canopy)
     943      179568 :     real(r8), dimension(ncol,n_land_type,gas_pcnst) :: rgsx  ! ground resistance
     944             :     real(r8) :: vds
     945      179568 :     logical  :: fr_lnduse(ncol,n_land_type)           ! wrking array
     946             :     real(r8) :: dewm                                  ! multiplier for rs when dew occurs
     947             : 
     948      179568 :     real(r8) :: lcl_frc_landuse(ncol,n_land_type)
     949             : 
     950             :     integer :: beglt, endlt
     951             : 
     952             :     !-------------------------------------------------------------------------------------
     953             :     ! jfl : mods for PAN
     954             :     !-------------------------------------------------------------------------------------
     955             :     real(r8) :: dv_pan
     956             :     real(r8) :: c0_pan(11) = (/ 0.000_r8, 0.006_r8, 0.002_r8, 0.009_r8, 0.015_r8, &
     957             :                                 0.006_r8, 0.000_r8, 0.000_r8, 0.000_r8, 0.002_r8, 0.002_r8 /)
     958             :     real(r8) :: k_pan (11) = (/ 0.000_r8, 0.010_r8, 0.005_r8, 0.004_r8, 0.003_r8, &
     959             :                                 0.005_r8, 0.000_r8, 0.000_r8, 0.000_r8, 0.075_r8, 0.002_r8 /)
     960             : 
     961       89784 :     if (present( beglandtype)) then
     962       89784 :       beglt = beglandtype
     963             :     else
     964             :       beglt = 1
     965             :     endif
     966       89784 :     if (present( endlandtype)) then
     967       89784 :       endlt = endlandtype
     968             :     else
     969             :       endlt = n_land_type
     970             :     endif
     971             : 
     972             :     !-------------------------------------------------------------------------------------
     973             :     ! initialize
     974             :     !-------------------------------------------------------------------------------------
     975     2873088 :     do m = 1,gas_pcnst
     976    46564488 :        dvel(:,m) = 0._r8
     977             :     end do
     978             : 
     979      628488 :     if( all( .not. has_dvel(:) ) ) then
     980             :        return
     981             :     end if
     982             : 
     983             :     !-------------------------------------------------------------------------------------
     984             :     ! define species-dependent parameters (temperature dependent)
     985             :     !-------------------------------------------------------------------------------------
     986       89784 :     call shr_drydep_setHCoeff( ncol, sfc_temp, heff )
     987             : 
     988     1077408 :     do lt = 1,n_land_type
     989    16789608 :        dep_ra (:,lt,lchnk)   = 0._r8
     990    16789608 :        dep_rb (:,lt,lchnk)   = 0._r8
     991    16580808 :        rds(:,lt)   = 0._r8
     992             :     end do
     993             : 
     994             :     !-------------------------------------------------------------------------------------
     995             :     ! season index only for ocn and sea ice
     996             :     !-------------------------------------------------------------------------------------
     997    16580808 :     index_season = 4
     998             :     !-------------------------------------------------------------------------------------
     999             :     ! special case for snow covered terrain
    1000             :     !-------------------------------------------------------------------------------------
    1001     1499184 :     do i = 1,ncol
    1002     1499184 :        if( snow(i) > .01_r8 ) then
    1003     1908720 :           index_season(i,:) = 4
    1004             :        end if
    1005             :     end do
    1006             :     !-------------------------------------------------------------------------------------
    1007             :     ! scale rain and define logical arrays
    1008             :     !-------------------------------------------------------------------------------------
    1009     1499184 :     has_rain(:ncol) = rain(:ncol) > rain_threshold
    1010             : 
    1011             :     !-------------------------------------------------------------------------------------
    1012             :     ! loop over longitude points
    1013             :     !-------------------------------------------------------------------------------------
    1014     1499184 :     col_loop :  do i = 1,ncol
    1015     1409400 :        p   = pressure_10m(i)
    1016     1409400 :        pg  = pressure_sfc(i)
    1017             :        !-------------------------------------------------------------------------------------
    1018             :        ! potential temperature
    1019             :        !-------------------------------------------------------------------------------------
    1020     1409400 :        tha(i) = air_temp(i) * (p00/p )**rovcp * (1._r8 + .61_r8*spec_hum(i))
    1021     1409400 :        thg(i) = sfc_temp(i) * (p00/pg)**rovcp * (1._r8 + .61_r8*spec_hum(i))
    1022             :        !-------------------------------------------------------------------------------------
    1023             :        ! height of 1st level
    1024             :        !-------------------------------------------------------------------------------------
    1025     1409400 :        z(i) = - r/grav * air_temp(i) * (1._r8 + .61_r8*spec_hum(i)) * log(p/pg)
    1026             :        !-------------------------------------------------------------------------------------
    1027             :        ! wind speed
    1028             :        !-------------------------------------------------------------------------------------
    1029     1409400 :        va(i) = max( .01_r8,wind_speed(i) )
    1030             :        !-------------------------------------------------------------------------------------
    1031             :        ! Richardson number
    1032             :        !-------------------------------------------------------------------------------------
    1033     1409400 :        ribn(i) = z(i) * grav * (tha(i) - thg(i))/thg(i) / (va(i)*va(i))
    1034     1409400 :        ribn(i) = min( ribn(i),ric )
    1035     1409400 :        unstable(i) = ribn(i) < 0._r8
    1036             :        !-------------------------------------------------------------------------------------
    1037             :        ! saturation vapor pressure (Pascals)
    1038             :        ! saturation mixing ratio
    1039             :        ! saturation specific humidity
    1040             :        !-------------------------------------------------------------------------------------
    1041     1409400 :        es    = 611._r8*exp( 5414.77_r8*(sfc_temp(i) - tmelt)/(tmelt*sfc_temp(i)) )
    1042     1409400 :        ws    = .622_r8*es/(pg - es)
    1043     1409400 :        qs(i) = ws/(1._r8 + ws)
    1044     1409400 :        has_dew(i) = .false.
    1045     1409400 :        if( qs(i) <= spec_hum(i) ) then
    1046      172174 :           has_dew(i) = .true.
    1047             :        end if
    1048     1409400 :        if( sfc_temp(i) < tmelt ) then
    1049      225826 :           has_dew(i) = .false.
    1050             :        end if
    1051             :        !-------------------------------------------------------------------------------------
    1052             :        ! constant in determining rs
    1053             :        !-------------------------------------------------------------------------------------
    1054     1409400 :        tc(i) = sfc_temp(i) - tmelt
    1055     1409400 :        if( sfc_temp(i) > tmelt .and. sfc_temp(i) < 313.15_r8 ) then
    1056     1177795 :           crs(i) = (1._r8 + (200._r8/(solar_flux(i) + .1_r8))**2) * (400._r8/(tc(i)*(40._r8 - tc(i))))
    1057             :        else
    1058      231605 :           crs(i) = large_value
    1059             :        end if
    1060             :        !-------------------------------------------------------------------------------------
    1061             :        ! rdc (lower canopy res)
    1062             :        !-------------------------------------------------------------------------------------
    1063     1499184 :        rdc(i) = 100._r8*(1._r8 + 1000._r8/(solar_flux(i) + 10._r8))/(1._r8 + 1000._r8*slope)
    1064             :     end do col_loop
    1065             : 
    1066             :     !-------------------------------------------------------------------------------------
    1067             :     !   ... form working arrays
    1068             :     !-------------------------------------------------------------------------------------
    1069    16580808 :     lcl_frc_landuse(:,:) = 0._r8
    1070             : 
    1071       89784 :     if ( present(ocnfrc) .and. present(icefrc) ) then
    1072     1499184 :        do i=1,ncol
    1073             :           ! land type 7 is used for ocean
    1074             :           ! land type 8 is used for sea ice
    1075     1409400 :           lcl_frc_landuse(i,7) = ocnfrc(i)
    1076     1499184 :           lcl_frc_landuse(i,8) = icefrc(i)
    1077             :        enddo
    1078             :     endif
    1079     1077408 :     do lt = 1,n_land_type
    1080    16580808 :        do i=1,ncol
    1081    16491024 :           fr_lnduse(i,lt) = lcl_frc_landuse(i,lt) > 0._r8
    1082             :        enddo
    1083             :     end do
    1084             : 
    1085             :     !-------------------------------------------------------------------------------------
    1086             :     ! find grid averaged z0: z0bar (the roughness length) z_o=exp[S(f_i*ln(z_oi))]
    1087             :     ! this is calculated so as to find u_i, assuming u*u=u_i*u_i
    1088             :     !-------------------------------------------------------------------------------------
    1089     1499184 :     z0b(:) = 0._r8
    1090     1077408 :     do lt = 1,n_land_type
    1091    16580808 :        do i = 1,ncol
    1092    16491024 :           if( fr_lnduse(i,lt) ) then
    1093     1102251 :              z0b(i) = z0b(i) + lcl_frc_landuse(i,lt) * log( z0(index_season(i,lt),lt) )
    1094             :           end if
    1095             :        end do
    1096             :     end do
    1097             : 
    1098             :     !-------------------------------------------------------------------------------------
    1099             :     ! find the constant velocity uu*=(u_i)(u*_i)
    1100             :     !-------------------------------------------------------------------------------------
    1101     1499184 :     do i = 1,ncol
    1102     1409400 :        z0b(i) = exp( z0b(i) )
    1103     1409400 :        cvarb  = vonkar/log( z(i)/z0b(i) )
    1104             :        !-------------------------------------------------------------------------------------
    1105             :        ! unstable and stable cases
    1106             :        !-------------------------------------------------------------------------------------
    1107     1409400 :        if( unstable(i) ) then
    1108      796389 :           bb = 9.4_r8*(cvarb**2)*sqrt( abs(ribn(i))*z(i)/z0b(i) )
    1109      796389 :           ustarb = cvarb * va(i) * sqrt( 1._r8 - (9.4_r8*ribn(i)/(1._r8 + 7.4_r8*bb)) )
    1110             :        else
    1111      613011 :           ustarb = cvarb * va(i)/(1._r8 + 4.7_r8*ribn(i))
    1112             :        end if
    1113     1499184 :        uustar(i) = va(i)*ustarb
    1114             :     end do
    1115             : 
    1116             :     !-------------------------------------------------------------------------------------
    1117             :     ! calculate the friction velocity for each land type u_i=uustar/u*_i
    1118             :     !-------------------------------------------------------------------------------------
    1119      269352 :     do lt = beglt,endlt
    1120     3088152 :        do i = 1,ncol
    1121     2998368 :           if( fr_lnduse(i,lt) ) then
    1122     1102251 :              if( unstable(i) ) then
    1123      691102 :                 cvar(i,lt)  = vonkar/log( z(i)/z0(index_season(i,lt),lt) )
    1124      691102 :                 b(i,lt)     = 9.4_r8*(cvar(i,lt)**2)* sqrt( abs(ribn(i))*z(i)/z0(index_season(i,lt),lt) )
    1125      691102 :                 ustar(i,lt) = sqrt( cvar(i,lt)*uustar(i)*sqrt( 1._r8 - (9.4_r8*ribn(i)/(1._r8 + 7.4_r8*b(i,lt))) ) )
    1126             :              else
    1127      411149 :                 cvar(i,lt)  = vonkar/log( z(i)/z0(index_season(i,lt),lt) )
    1128      411149 :                 ustar(i,lt) = sqrt( cvar(i,lt)*uustar(i)/(1._r8 + 4.7_r8*ribn(i)) )
    1129             :              end if
    1130             :           end if
    1131             :        end do
    1132             :     end do
    1133             : 
    1134             :     !-------------------------------------------------------------------------------------
    1135             :     ! revise calculation of friction velocity and z0 over water
    1136             :     !-------------------------------------------------------------------------------------
    1137     1499184 :     lt = 7
    1138     1499184 :     do i = 1,ncol
    1139     1499184 :        if( fr_lnduse(i,lt) ) then
    1140     1027995 :           if( unstable(i) ) then
    1141      674616 :              z0water     = (.016_r8*(ustar(i,lt)**2)/grav) + diffk/(9.1_r8*ustar(i,lt))
    1142      674616 :              cvar(i,lt)  = vonkar/(log( z(i)/z0water ))
    1143      674616 :              b(i,lt)     = 9.4_r8*(cvar(i,lt)**2)*sqrt( abs(ribn(i))*z(i)/z0water )
    1144      674616 :              ustar(i,lt) = sqrt( cvar(i,lt)*uustar(i)* sqrt( 1._r8 - (9.4_r8*ribn(i)/(1._r8+ 7.4_r8*b(i,lt))) ) )
    1145             :           else
    1146      353379 :              z0water     = (.016_r8*(ustar(i,lt)**2)/grav) + diffk/(9.1_r8*ustar(i,lt))
    1147      353379 :              cvar(i,lt)  = vonkar/(log(z(i)/z0water))
    1148      353379 :              ustar(i,lt) = sqrt( cvar(i,lt)*uustar(i)/(1._r8 + 4.7_r8*ribn(i)) )
    1149             :           end if
    1150             :        end if
    1151             :     end do
    1152             : 
    1153             :     !-------------------------------------------------------------------------------------
    1154             :     ! compute monin-obukhov length for unstable and stable conditions/ sublayer resistance
    1155             :     !-------------------------------------------------------------------------------------
    1156      269352 :     do lt = beglt,endlt
    1157     3088152 :        do i = 1,ncol
    1158     2998368 :           if( fr_lnduse(i,lt) ) then
    1159     1102251 :              hvar = (va(i)/0.74_r8) * (tha(i) - thg(i)) * (cvar(i,lt)**2)
    1160     1102251 :              if( unstable(i) ) then                      ! unstable
    1161      691102 :                 h = hvar*(1._r8 - (9.4_r8*ribn(i)/(1._r8 + 5.3_r8*b(i,lt))))
    1162             :              else
    1163      411149 :                 h = hvar/((1._r8+4.7_r8*ribn(i))**2)
    1164             :              end if
    1165     1102251 :              xmol(i,lt) = thg(i) * ustar(i,lt) * ustar(i,lt) / (vonkar * grav * h)
    1166             :           end if
    1167             :        end do
    1168             :     end do
    1169             : 
    1170             :     !-------------------------------------------------------------------------------------
    1171             :     ! psih
    1172             :     !-------------------------------------------------------------------------------------
    1173      269352 :     do lt = beglt,endlt
    1174     3088152 :        do i = 1,ncol
    1175     2998368 :           if( fr_lnduse(i,lt) ) then
    1176     1102251 :              if( xmol(i,lt) < 0._r8 ) then
    1177      691102 :                 zovl = z(i)/xmol(i,lt)
    1178      691102 :                 zovl = max( -1._r8,zovl )
    1179      691102 :                 psih = exp( .598_r8 + .39_r8*log( -zovl ) - .09_r8*(log( -zovl ))**2 )
    1180      691102 :                 vds  = 2.e-3_r8*ustar(i,lt) * (1._r8 + (300/(-xmol(i,lt)))**0.666_r8)
    1181             :              else
    1182      411149 :                 zovl = z(i)/xmol(i,lt)
    1183      411149 :                 zovl = min( 1._r8,zovl )
    1184      411149 :                 psih = -5._r8 * zovl
    1185      411149 :                 vds  = 2.e-3_r8*ustar(i,lt)
    1186             :              end if
    1187     1102251 :              dep_ra (i,lt,lchnk) = (vonkar - psih*cvar(i,lt))/(ustar(i,lt)*vonkar*cvar(i,lt))
    1188     1102251 :              dep_rb (i,lt,lchnk) = (2._r8/(vonkar*ustar(i,lt))) * crb
    1189     1102251 :              rds(i,lt) = 1._r8/vds
    1190             :           end if
    1191             :        end do
    1192             :     end do
    1193             : 
    1194             :     !-------------------------------------------------------------------------------------
    1195             :     ! surface resistance : depends on both land type and species
    1196             :     ! land types are computed seperately, then resistance is computed as average of values
    1197             :     ! following wesely rc=(1/(rs+rm) + 1/rlu +1/(rdc+rcl) + 1/(rac+rgs))**-1
    1198             :     !
    1199             :     ! compute rsmx = 1/(rs+rm) : multiply by 3 if surface is wet
    1200             :     !-------------------------------------------------------------------------------------
    1201     2873088 :     species_loop1 :  do ispec = 1,gas_pcnst
    1202     2873088 :        if( has_dvel(ispec) ) then
    1203      448920 :           m = map_dvel(ispec)
    1204     1346760 :           do lt = beglt,endlt
    1205    15440760 :              do i = 1,ncol
    1206    14991840 :                 if( fr_lnduse(i,lt) ) then
    1207     5511255 :                    sndx = index_season(i,lt)
    1208     5511255 :                    if( ispec == o3_ndx .or. ispec == o3a_ndx .or. ispec == so2_ndx ) then
    1209             :                       rmx = 0._r8
    1210             :                    else
    1211     4409004 :                       rmx = 1._r8/(heff(i,m)/3000._r8 + 100._r8*foxd(m))
    1212             :                    end if
    1213     5511255 :                    cts(i) = 1000._r8*exp( - tc(i) - 4._r8 )                 ! correction for frost
    1214     5511255 :                    rgsx(i,lt,ispec) = cts(i) + 1._r8/((heff(i,m)/(1.e5_r8*rgss(sndx,lt))) + (foxd(m)/rgso(sndx,lt)))
    1215             :                    !-------------------------------------------------------------------------------------
    1216             :                    ! special case for H2 and CO;; CH4 is set ot a fraction of dv(H2)
    1217             :                    !-------------------------------------------------------------------------------------
    1218     5511255 :                    if( ispec == h2_ndx .or. ispec == co_ndx .or. ispec == ch4_ndx ) then
    1219             :                       !-------------------------------------------------------------------------------------
    1220             :                       ! no deposition on snow, ice, desert, and water
    1221             :                       !-------------------------------------------------------------------------------------
    1222           0 :                       if( lt == 1 .or. lt == 7 .or. lt == 8 .or. sndx == 4 ) then
    1223           0 :                          rgsx(i,lt,ispec) = large_value
    1224             :                       end if
    1225             :                    end if
    1226     5511255 :                    if( lt == 7 ) then
    1227     5139975 :                       rclx(i,lt,ispec) = large_value
    1228     5139975 :                       rsmx(i,lt,ispec) = large_value
    1229     5139975 :                       rlux(i,lt,ispec) = large_value
    1230             :                    else
    1231      371280 :                       rs = ri(sndx,lt)*crs(i)
    1232      371280 :                       if ( has_dew(i) .or. has_rain(i) ) then
    1233             :                          dewm = 3._r8
    1234             :                       else
    1235      309475 :                          dewm = 1._r8
    1236             :                       end if
    1237      371280 :                       rsmx(i,lt,ispec) = (dewm*rs*drat(m) + rmx)
    1238             :                       !-------------------------------------------------------------------------------------
    1239             :                       ! jfl : special case for PAN
    1240             :                       !-------------------------------------------------------------------------------------
    1241      371280 :                       if( ispec == pan_ndx .or. ispec == xpan_ndx ) then
    1242           0 :                          dv_pan =  c0_pan(lt) * (1._r8 - exp( -k_pan(lt)*(dewm*rs*drat(m))*1.e-2_r8 ))
    1243           0 :                          if( dv_pan > 0._r8 .and. sndx /= 4 ) then
    1244           0 :                             rsmx(i,lt,ispec) = ( 1._r8/dv_pan )
    1245             :                          end if
    1246             :                       end if
    1247      371280 :                       rclx(i,lt,ispec) = cts(i) + 1._r8/((heff(i,m)/(1.e5_r8*rcls(sndx,lt))) + (foxd(m)/rclo(sndx,lt)))
    1248      371280 :                       rlux(i,lt,ispec) = cts(i) + rlu(sndx,lt)/(1.e-5_r8*heff(i,m) + foxd(m))
    1249             :                    end if
    1250             :                 end if
    1251             :              end do
    1252             :           end do
    1253             :        end if
    1254             :     end do species_loop1
    1255             : 
    1256      269352 :     do lt = beglt,endlt
    1257      269352 :        if( lt /= 7 ) then
    1258     1499184 :           do i = 1,ncol
    1259     1499184 :              if( fr_lnduse(i,lt) ) then
    1260       74256 :                 sndx = index_season(i,lt)
    1261             :                 !-------------------------------------------------------------------------------------
    1262             :                 !       ... no effect if sfc_temp < O C
    1263             :                 !-------------------------------------------------------------------------------------
    1264       74256 :                 if( sfc_temp(i) > tmelt ) then
    1265         891 :                    if( has_dew(i) ) then
    1266         250 :                       rlux_o3(i,lt)     = 3000._r8*rlu(sndx,lt)/(1000._r8 + rlu(sndx,lt))
    1267         250 :                       if( o3_ndx > 0 ) then
    1268           0 :                          rlux(i,lt,o3_ndx) = rlux_o3(i,lt)
    1269             :                       endif
    1270         250 :                       if( o3a_ndx > 0 ) then
    1271           0 :                          rlux(i,lt,o3a_ndx) = rlux_o3(i,lt)
    1272             :                       endif
    1273             :                    end if
    1274         891 :                    if( has_rain(i) ) then
    1275             :                       ! rlux(i,lt,o3_ndx) = 1./(1.e-3 + (1./(3.*rlu(sndx,lt))))
    1276         137 :                       rlux_o3(i,lt)     = 3000._r8*rlu(sndx,lt)/(1000._r8 + 3._r8*rlu(sndx,lt))
    1277         137 :                       if( o3_ndx > 0 ) then
    1278           0 :                          rlux(i,lt,o3_ndx) = rlux_o3(i,lt)
    1279             :                       endif
    1280         137 :                       if( o3a_ndx > 0 ) then
    1281           0 :                          rlux(i,lt,o3a_ndx) = rlux_o3(i,lt)
    1282             :                       endif
    1283             :                    end if
    1284             :                 end if
    1285             : 
    1286       74256 :                 if ( o3_ndx > 0 ) then
    1287           0 :                    rclx(i,lt,o3_ndx) = cts(i) + rclo(index_season(i,lt),lt)
    1288           0 :                    rlux(i,lt,o3_ndx) = cts(i) + rlux(i,lt,o3_ndx)
    1289             :                 end if
    1290       74256 :                 if ( o3a_ndx > 0 ) then
    1291           0 :                    rclx(i,lt,o3a_ndx) = cts(i) + rclo(index_season(i,lt),lt)
    1292           0 :                    rlux(i,lt,o3a_ndx) = cts(i) + rlux(i,lt,o3a_ndx)
    1293             :                 end if
    1294             : 
    1295             :              end if
    1296             :           end do
    1297             :        end if
    1298             :     end do
    1299             : 
    1300     2873088 :     species_loop2 : do ispec = 1,gas_pcnst
    1301     2783304 :        m = map_dvel(ispec)
    1302     2873088 :        if( has_dvel(ispec) ) then
    1303      448920 :           if( ispec /= o3_ndx .and. ispec /= o3a_ndx .and. ispec /= so2_ndx ) then
    1304     1077408 :              do lt = beglt,endlt
    1305     1077408 :                 if( lt /= 7 ) then
    1306     5996736 :                    do i = 1,ncol
    1307     5996736 :                       if( fr_lnduse(i,lt) ) then
    1308             :                          !-------------------------------------------------------------------------------------
    1309             :                          ! no effect if sfc_temp < O C
    1310             :                          !-------------------------------------------------------------------------------------
    1311      297024 :                          if( sfc_temp(i) > tmelt ) then
    1312        3564 :                             if( has_dew(i) ) then
    1313             :                                rlux(i,lt,ispec) = 1._r8/((1._r8/(3._r8*rlux(i,lt,ispec))) &
    1314        1000 :                                     + 1.e-7_r8*heff(i,m) + foxd(m)/rlux_o3(i,lt))
    1315             :                             end if
    1316             :                          end if
    1317             : 
    1318             :                       end if
    1319             :                    end do
    1320             :                 end if
    1321             :              end do
    1322       89784 :           else if( ispec == so2_ndx ) then
    1323      269352 :              do lt = beglt,endlt
    1324      269352 :                 if( lt /= 7 ) then
    1325     1499184 :                    do i = 1,ncol
    1326     1499184 :                       if( fr_lnduse(i,lt) ) then
    1327             :                          !-------------------------------------------------------------------------------------
    1328             :                          ! no effect if sfc_temp < O C
    1329             :                          !-------------------------------------------------------------------------------------
    1330       74256 :                          if( sfc_temp(i) > tmelt ) then
    1331         891 :                             if( qs(i) <= spec_hum(i) ) then
    1332         250 :                                rlux(i,lt,ispec) = 100._r8
    1333             :                             end if
    1334         891 :                             if( has_rain(i) ) then
    1335             :                                !                               rlux(i,lt,ispec) = 1./(2.e-4 + (1./(3.*rlu(index_season(i,lt),lt))))
    1336         137 :                                rlux(i,lt,ispec) = 15._r8*rlu(index_season(i,lt),lt)/(5._r8 + 3.e-3_r8*rlu(index_season(i,lt),lt))
    1337             :                             end if
    1338             :                          end if
    1339       74256 :                          rclx(i,lt,ispec) = cts(i) + rcls(index_season(i,lt),lt)
    1340       74256 :                          rlux(i,lt,ispec) = cts(i) + rlux(i,lt,ispec)
    1341             : 
    1342             :                       end if
    1343             :                    end do
    1344             :                 end if
    1345             :              end do
    1346     1499184 :              do i = 1,ncol
    1347     1499184 :                 if( fr_lnduse(i,1) .and. (has_dew(i) .or. has_rain(i)) ) then
    1348           0 :                    rlux(i,1,ispec) = 50._r8
    1349             :                 end if
    1350             :              end do
    1351             :           end if
    1352             :        end if
    1353             :     end do species_loop2
    1354             : 
    1355             :     !-------------------------------------------------------------------------------------
    1356             :     ! compute rc
    1357             :     !-------------------------------------------------------------------------------------
    1358     1499184 :     term(:ncol) = 1.e-2_r8 * pressure_10m(:ncol) / (r*tv(:ncol))
    1359     2873088 :     species_loop3 : do ispec = 1,gas_pcnst
    1360     2873088 :        if( has_dvel(ispec) ) then
    1361     7495920 :           wrk(:) = 0._r8
    1362     1346760 :           lt_loop: do lt = beglt,endlt
    1363    14991840 :              do i = 1,ncol
    1364    14991840 :                 if (fr_lnduse(i,lt)) then
    1365             :                    resc(i) = 1._r8/( 1._r8/rsmx(i,lt,ispec) + 1._r8/rlux(i,lt,ispec) &
    1366             :                                    + 1._r8/(rdc(i) + rclx(i,lt,ispec)) &
    1367     5511255 :                                    + 1._r8/(rac(index_season(i,lt),lt) + rgsx(i,lt,ispec)))
    1368             : 
    1369     5511255 :                    resc(i) = max( 10._r8,resc(i) )
    1370             : 
    1371     5511255 :                    lnd_frc(i) = lcl_frc_landuse(i,lt)
    1372             :                 endif
    1373             :              enddo
    1374             :              !-------------------------------------------------------------------------------------
    1375             :              !  ... compute average deposition velocity
    1376             :              !-------------------------------------------------------------------------------------
    1377      448920 :              select case( solsym(ispec) )
    1378             :              case( 'SO2' )
    1379      179568 :                 if( lt == 7 ) then
    1380     1499184 :                    where( fr_lnduse(:ncol,lt) )
    1381             :                       ! assume no surface resistance for SO2 over water`
    1382       89784 :                       wrk(:) = wrk(:) + lnd_frc(:)/(dep_ra(:ncol,lt,lchnk) + dep_rb(:ncol,lt,lchnk))
    1383             :                    endwhere
    1384             :                 else
    1385     1499184 :                    where( fr_lnduse(:ncol,lt) )
    1386       89784 :                       wrk(:) = wrk(:) + lnd_frc(:)/(dep_ra(:ncol,lt,lchnk) + dep_rb(:ncol,lt,lchnk) + resc(:))
    1387             :                    endwhere
    1388             :                 end if
    1389             : 
    1390             :                 !  JFL - increase in dry deposition of SO2 to improve bias over US/Europe
    1391     2998368 :                 wrk(:) = wrk(:) * 2._r8
    1392             : 
    1393             :              case( 'SO4' )
    1394           0 :                 where( fr_lnduse(:ncol,lt) )
    1395           0 :                    wrk(:) = wrk(:) + lnd_frc(:)/(dep_ra(:ncol,lt,lchnk) + rds(:,lt))
    1396             :                 endwhere
    1397             :              case( 'NH4', 'NH4NO3', 'XNH4NO3' )
    1398           0 :                 where( fr_lnduse(:ncol,lt) )
    1399           0 :                    wrk(:) = wrk(:) + lnd_frc(:)/(dep_ra(:ncol,lt,lchnk) + 0.5_r8*rds(:,lt))
    1400             :                 endwhere
    1401             : 
    1402             :              !-------------------------------------------------------------------------------------
    1403             :              !  ... special case for Pb (for consistency with offline code)
    1404             :              !-------------------------------------------------------------------------------------
    1405             :              case( 'Pb' )
    1406           0 :                 if( lt == 7 ) then
    1407           0 :                    where( fr_lnduse(:ncol,lt) )
    1408             :                       wrk(:) = wrk(:) + lnd_frc(:) * 0.05e-2_r8
    1409             :                    endwhere
    1410             :                 else
    1411           0 :                    where( fr_lnduse(:ncol,lt) )
    1412             :                       wrk(:ncol) = wrk(:ncol) + lnd_frc(:ncol) * 0.2e-2_r8
    1413             :                    endwhere
    1414             :                 end if
    1415             : 
    1416             :              !-------------------------------------------------------------------------------------
    1417             :              !  ... special case for carbon aerosols
    1418             :              !-------------------------------------------------------------------------------------
    1419             :              case( 'CB1', 'CB2', 'OC1', 'OC2', 'SOAM', 'SOAI', 'SOAT', 'SOAB','SOAX' )
    1420           0 :                 where( fr_lnduse(:ncol,lt) )
    1421             :                    wrk(:ncol) = wrk(:ncol) + lnd_frc(:ncol) * 0.10e-2_r8
    1422             :                 endwhere
    1423             : 
    1424             :              !-------------------------------------------------------------------------------------
    1425             :              ! deposition over ocean for HCN, CH3CN
    1426             :              !    velocity estimated from aircraft measurements (E.Apel, INTEX-B)
    1427             :              !-------------------------------------------------------------------------------------
    1428             :              case( 'HCN','CH3CN' )
    1429           0 :                 if( lt == 7 ) then ! over ocean only
    1430           0 :                    where( fr_lnduse(:ncol,lt) .and. snow(:ncol) < 0.01_r8  )
    1431             :                       wrk(:ncol) = wrk(:ncol) + lnd_frc(:ncol) * 0.2e-2_r8
    1432             :                    endwhere
    1433             :                 end if
    1434             :              case default
    1435    12891312 :                 where( fr_lnduse(:ncol,lt) )
    1436      718272 :                    wrk(:ncol) = wrk(:ncol) + lnd_frc(:ncol)/(dep_ra(:ncol,lt,lchnk) + dep_rb(:ncol,lt,lchnk) + resc(:ncol))
    1437             :                 endwhere
    1438             :              end select
    1439             :           end do lt_loop
    1440     7495920 :           dvel(:ncol,ispec) = wrk(:ncol) * scaling_to_cm_per_s
    1441     7495920 :           dflx(:ncol,ispec) = term(:ncol) * dvel(:ncol,ispec) * mmr(:ncol,plev,ispec)
    1442             :        end if
    1443             : 
    1444             :     end do species_loop3
    1445             : 
    1446       89784 :     if ( beglt > 1 ) return
    1447             : 
    1448             :     !-------------------------------------------------------------------------------------
    1449             :     !   ... special adjustments
    1450             :     !-------------------------------------------------------------------------------------
    1451           0 :     if( mpan_ndx > 0 ) then
    1452           0 :        if( has_dvel(mpan_ndx) ) then
    1453           0 :           dvel(:ncol,mpan_ndx) = dvel(:ncol,mpan_ndx)/3._r8
    1454           0 :           dflx(:ncol,mpan_ndx) = term(:ncol) * dvel(:ncol,mpan_ndx) * mmr(:ncol,plev,mpan_ndx)
    1455             :        end if
    1456             :     end if
    1457           0 :     if( xmpan_ndx > 0 ) then
    1458           0 :        if( has_dvel(xmpan_ndx) ) then
    1459           0 :           dvel(:ncol,xmpan_ndx) = dvel(:ncol,xmpan_ndx)/3._r8
    1460           0 :           dflx(:ncol,xmpan_ndx) = term(:ncol) * dvel(:ncol,xmpan_ndx) * mmr(:ncol,plev,xmpan_ndx)
    1461             :        end if
    1462             :     end if
    1463             : 
    1464             :     ! HCOOH, use CH3COOH dep.vel
    1465           0 :     if( hcooh_ndx > 0) then
    1466           0 :        if( has_dvel(hcooh_ndx) ) then
    1467           0 :           dvel(:ncol,hcooh_ndx) = dvel(:ncol,ch3cooh_ndx)
    1468           0 :           dflx(:ncol,hcooh_ndx) = term(:ncol) * dvel(:ncol,hcooh_ndx) * mmr(:ncol,plev,hcooh_ndx)
    1469             :        end if
    1470             :     end if
    1471             : !
    1472             : ! SOG species
    1473             : !
    1474           0 :     if( sogm_ndx > 0) then
    1475           0 :        if( has_dvel(sogm_ndx) ) then
    1476           0 :           dvel(:ncol,sogm_ndx) = dvel(:ncol,ch3cooh_ndx)
    1477           0 :           dflx(:ncol,sogm_ndx) = term(:ncol) * dvel(:ncol,sogm_ndx) * mmr(:ncol,plev,sogm_ndx)
    1478             :        end if
    1479             :     end if
    1480           0 :     if( sogi_ndx > 0) then
    1481           0 :        if( has_dvel(sogi_ndx) ) then
    1482           0 :           dvel(:ncol,sogi_ndx) = dvel(:ncol,ch3cooh_ndx)
    1483           0 :           dflx(:ncol,sogi_ndx) = term(:ncol) * dvel(:ncol,sogi_ndx) * mmr(:ncol,plev,sogi_ndx)
    1484             :        end if
    1485             :     end if
    1486           0 :     if( sogt_ndx > 0) then
    1487           0 :        if( has_dvel(sogt_ndx) ) then
    1488           0 :           dvel(:ncol,sogt_ndx) = dvel(:ncol,ch3cooh_ndx)
    1489           0 :           dflx(:ncol,sogt_ndx) = term(:ncol) * dvel(:ncol,sogt_ndx) * mmr(:ncol,plev,sogt_ndx)
    1490             :        end if
    1491             :     end if
    1492           0 :     if( sogb_ndx > 0) then
    1493           0 :        if( has_dvel(sogb_ndx) ) then
    1494           0 :           dvel(:ncol,sogb_ndx) = dvel(:ncol,ch3cooh_ndx)
    1495           0 :           dflx(:ncol,sogb_ndx) = term(:ncol) * dvel(:ncol,sogb_ndx) * mmr(:ncol,plev,sogb_ndx)
    1496             :        end if
    1497             :     end if
    1498           0 :     if( sogx_ndx > 0) then
    1499           0 :        if( has_dvel(sogx_ndx) ) then
    1500           0 :           dvel(:ncol,sogx_ndx) = dvel(:ncol,ch3cooh_ndx)
    1501           0 :           dflx(:ncol,sogx_ndx) = term(:ncol) * dvel(:ncol,sogx_ndx) * mmr(:ncol,plev,sogx_ndx)
    1502             :        end if
    1503             :     end if
    1504             : 
    1505       89784 :   end subroutine drydep_xactive
    1506             : 
    1507             :   !-------------------------------------------------------------------------------------
    1508             :   !-------------------------------------------------------------------------------------
    1509     2854728 :   function has_drydep( name )
    1510             : 
    1511             :     character(len=*), intent(in) :: name
    1512             : 
    1513             :     logical :: has_drydep
    1514             :     integer :: i
    1515             : 
    1516     2854728 :     has_drydep = .false.
    1517             : 
    1518    15747048 :     do i=1,nddvels
    1519    15747048 :        if ( trim(name) == trim(drydep_list(i)) ) then
    1520      460440 :          has_drydep = .true.
    1521      460440 :          exit
    1522             :        endif
    1523             :     enddo
    1524             : 
    1525       89784 :   endfunction has_drydep
    1526             : 
    1527           0 : end module mo_drydep

Generated by: LCOV version 1.14