LCOV - code coverage report
Current view: top level - chemistry/mozart - mo_drydep.F90 (source / functions) Hit Total Coverage
Test: coverage.info Lines: 341 603 56.6 %
Date: 2025-03-13 18:42:46 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        1536 :   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        4608 :     allocate(spc_ndx(nddvels))
     101        4608 :     allocate( lnd(begchunk:endchunk) )
     102             : 
     103        9216 :     do ispc = 1,nddvels
     104             : 
     105        7680 :        spc_ndx(ispc) = get_spc_ndx(drydep_list(ispc))
     106        9216 :        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        1536 :     crb = (difft/diffm)**(2._r8/3._r8) !.666666_r8
     114             : 
     115        1536 :   endsubroutine dvel_inti_fromlnd
     116             : 
     117             :   !-------------------------------------------------------------------------------------
     118             :   !-------------------------------------------------------------------------------------
     119       58824 :   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       58824 :     if (nddvels<1) return
     127             : 
     128       58824 :     lnd(state%lchnk)%dvel => cam_in%depvel
     129             : 
     130       58824 :   end subroutine drydep_update
     131             : 
     132             :   !-------------------------------------------------------------------------------------
     133             :   !-------------------------------------------------------------------------------------
     134       58824 :   subroutine drydep_fromlnd( ocnfrac, icefrac, sfc_temp, pressure_sfc,  &
     135             :                              wind_speed, spec_hum, air_temp, pressure_10m, rain, &
     136       58824 :                              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       58824 :     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      117648 :     real(r8) :: ocnice_dvel(ncol,gas_pcnst)
     177             :     real(r8) :: ocnice_dflx(pcols,gas_pcnst)
     178             : 
     179      117648 :     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     1041048 :     lndfrac(:ncol) = 1._r8 - ocnfrac(:ncol) - icefrac(:ncol)
     189             : 
     190      982224 :     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    30507768 :     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       58824 :                          ocnfrc=ocnfrac,icefrc=icefrac, beglandtype=7, endlandtype=8 )
     216             : #endif
     217      982224 :     term(:ncol) = 1.e-2_r8 * pressure_10m(:ncol) / (r*tv(:ncol))
     218             : 
     219      352944 :     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     4969944 :                                        + ocnice_dvel(:ncol,spc_ndx(ispec))
     226             :     enddo
     227             : 
     228             :     !-------------------------------------------------------------------------------------
     229             :     !        ... special adjustments
     230             :     !-------------------------------------------------------------------------------------
     231       58824 :     if( mpan_ndx>0 ) then
     232           0 :        dvelocity(:ncol,mpan_ndx) = dvelocity(:ncol,mpan_ndx)/3._r8
     233             :     endif
     234       58824 :     if( xmpan_ndx>0 ) then
     235           0 :        dvelocity(:ncol,xmpan_ndx) = dvelocity(:ncol,xmpan_ndx)/3._r8
     236             :     endif
     237       58824 :     if( hcn_ndx>0 ) then
     238           0 :        dvelocity(:ncol,hcn_ndx) = ocnice_dvel(:ncol,hcn_ndx) ! should be zero over land
     239             :     endif
     240       58824 :     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       58824 :     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       58824 :     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       58824 :     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       58824 :     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      352944 :     do ispec = 1,nddvels
     273             :        !-------------------------------------------------------------------------------------
     274             :        !        ... compute the deposition flux
     275             :        !-------------------------------------------------------------------------------------
     276     4969944 :        dflx(:ncol,spc_ndx(ispec)) = dvelocity(:ncol,spc_ndx(ispec)) * term(:ncol) * mmr(:ncol,plev,spc_ndx(ispec))
     277             :     end do
     278             : 
     279       58824 :   end subroutine drydep_fromlnd
     280             : 
     281             :   !-------------------------------------------------------------------------------------
     282             :   !-------------------------------------------------------------------------------------
     283        1536 :   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        1536 :     real(r8), allocatable :: vegetation_map(:,:,:)
     308        1536 :     real(r8), allocatable :: work(:,:)
     309        1536 :     real(r8), allocatable :: landmask(:,:)
     310        1536 :     real(r8), allocatable :: urban(:,:)
     311        1536 :     real(r8), allocatable :: lake(:,:)
     312        1536 :     real(r8), allocatable :: wetland(:,:)
     313        1536 :     real(r8), allocatable :: lon_veg_edge(:)
     314        1536 :     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        1536 :     call phys_getopts(prog_modal_aero_out=prog_modal_aero)
     326             : 
     327        1536 :     call dvel_inti_fromlnd()
     328             : 
     329        1536 :     if( masterproc ) then
     330           2 :        write(iulog,*) 'drydep_inti: following species have dry deposition'
     331          12 :        do i=1,nddvels
     332          12 :           if( len_trim(drydep_list(i)) > 0 ) then
     333          10 :              write(iulog,*) 'drydep_inti: '//trim(drydep_list(i))//' is requested to have dry dep'
     334             :           endif
     335             :        enddo
     336           2 :        write(iulog,*) 'drydep_inti:'
     337             :     endif
     338             : 
     339             :     !-------------------------------------------------------------------------------------
     340             :     !   ... get species indices
     341             :     !-------------------------------------------------------------------------------------
     342        1536 :     xpan_ndx      = get_spc_ndx( 'XPAN' )
     343        1536 :     xmpan_ndx     = get_spc_ndx( 'XMPAN' )
     344        1536 :     o3a_ndx       = get_spc_ndx( 'O3A' )
     345             : 
     346        1536 :     ch4_ndx      = get_spc_ndx( 'CH4' )
     347        1536 :     h2_ndx       = get_spc_ndx( 'H2' )
     348        1536 :     co_ndx       = get_spc_ndx( 'CO' )
     349        1536 :     pan_ndx      = get_spc_ndx( 'PAN' )
     350        1536 :     mpan_ndx     = get_spc_ndx( 'MPAN' )
     351        1536 :     o3_ndx       = get_spc_ndx( 'OX' )
     352        1536 :     if( o3_ndx < 0 ) then
     353        1536 :        o3_ndx  = get_spc_ndx( 'O3' )
     354             :     end if
     355        1536 :     so2_ndx     = get_spc_ndx( 'SO2' )
     356        1536 :     ch3cooh_ndx = get_spc_ndx( 'CH3COOH')
     357             : 
     358        1536 :     sogm_ndx   = get_spc_ndx( 'SOGM' )
     359        1536 :     sogi_ndx   = get_spc_ndx( 'SOGI' )
     360        1536 :     sogt_ndx   = get_spc_ndx( 'SOGT' )
     361        1536 :     sogb_ndx   = get_spc_ndx( 'SOGB' )
     362        1536 :     sogx_ndx   = get_spc_ndx( 'SOGX' )
     363             : 
     364        1536 :     hcn_ndx     = get_spc_ndx( 'HCN')
     365        1536 :     ch3cn_ndx   = get_spc_ndx( 'CH3CN')
     366             : 
     367        1536 :     cohc_ndx     = get_spc_ndx( 'COhc' )
     368        1536 :     come_ndx     = get_spc_ndx( 'COme' )
     369             : 
     370        1536 :     tag_cnt=0
     371       78336 :     cotag_ndx(:)=-1
     372       78336 :     do i = 1,NTAGS
     373       76800 :        write(tag_name,'(a2,i2.2)') 'CO',i
     374       76800 :        ndx = get_spc_ndx(tag_name)
     375       78336 :        if (ndx>0) then
     376           0 :           tag_cnt = tag_cnt+1
     377           0 :           cotag_ndx(tag_cnt) = ndx
     378             :        endif
     379             :     enddo
     380             : 
     381        9216 :     do i=1,nddvels
     382        9216 :        if ( mapping(i) > 0 ) then
     383        7680 :           test_name = drydep_list(i)
     384        7680 :           m = get_spc_ndx( test_name )
     385        7680 :           has_dvel(m) = .true.
     386        7680 :           map_dvel(m) = i
     387             :        endif
     388             :     enddo
     389             : 
     390       10752 :     if( all( .not. has_dvel(:) ) ) then
     391             :        return
     392             :     end if
     393             : 
     394             :     !---------------------------------------------------------------------------
     395             :     !   ... allocate module variables
     396             :     !---------------------------------------------------------------------------
     397        4608 :     allocate( dep_ra(pcols,n_land_type,begchunk:endchunk),stat=astat )
     398        1536 :     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        4608 :     allocate( dep_rb(pcols,n_land_type,begchunk:endchunk),stat=astat )
     403        1536 :     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        1536 :     if (.not.prog_modal_aero) then
     409             :        return
     410             :     endif
     411             : 
     412        4608 :     allocate( fraction_landuse(pcols,n_land_type, begchunk:endchunk),stat=astat )
     413        1536 :     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        1536 :     fraction_landuse = nan
     418             : 
     419        1536 :     plon = get_dyn_grid_parm('plon')
     420        1536 :     plat = get_dyn_grid_parm('plat')
     421             : 
     422        1536 :     if(dycore_is('UNSTRUCTURED') ) then
     423        1536 :        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        3072 :   end subroutine dvel_inti_xactive
     511             : 
     512             :   !-------------------------------------------------------------------------------------
     513        1536 :   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        1536 :     call getfil (drydep_srf_file, locfn, 1, lexist)
     523        1536 :     if(lexist) then
     524        1536 :        call cam_pio_openfile(piofile, locfn, PIO_NOWRITE)
     525             : 
     526             :        call infld('fraction_landuse', piofile, 'ncol','class',1,pcols,1,n_land_type, begchunk,endchunk, &
     527        1536 :             fraction_landuse, readvar, gridname='physgrid')
     528        1536 :        if (.not. readvar) then
     529           0 :           write(iulog,*)'**************************************'
     530           0 :           write(iulog,*)'get_landuse_and_soilw_from_file: INFO:'
     531           0 :           write(iulog,*)' fraction_landuse not read from file: '
     532           0 :           write(iulog,*)' ', trim(locfn)
     533           0 :           write(iulog,*)' setting all values to zero'
     534           0 :           write(iulog,*)'**************************************'
     535           0 :           fraction_landuse = 0._r8
     536             :        end if
     537             : 
     538        1536 :        call cam_pio_closefile(piofile)
     539             :     else
     540           0 :        call endrun('Unstructured grids require drydep_srf_file ')
     541             :     end if
     542             : 
     543             : 
     544        1536 :   end subroutine get_landuse_and_soilw_from_file
     545             : 
     546             :   !-------------------------------------------------------------------------------------
     547           0 :   subroutine interp_map( plon, plat, nlon_veg, nlat_veg, npft_veg, lat_veg_edge, &
     548           0 :                          lon_veg_edge, landmask, urban, lake, &
     549           0 :                          wetland, vegetation_map )
     550             : 
     551             :     use mo_constants, only : r2d
     552             :     use scamMod, only : latiop,loniop,scmlat,scmlon,scm_cambfb_mode
     553             :     use shr_scam_mod  , only: shr_scam_getCloseLatLon  ! Standardized system subroutines
     554             :     use cam_initfiles, only: initial_file_get_id
     555             :     use dycore, only : dycore_is
     556             :     use phys_grid,     only : get_rlat_all_p, get_rlon_all_p, get_ncols_p
     557             : 
     558             :     !-------------------------------------------------------------------------------------
     559             :     !   ... dummy arguments
     560             :     !-------------------------------------------------------------------------------------
     561             :     integer,  intent(in)         :: plon, plat, nlon_veg, nlat_veg, npft_veg
     562             :     real(r8), intent(in)         :: landmask(nlon_veg,nlat_veg)
     563             :     real(r8), intent(in)         :: urban(nlon_veg,nlat_veg)
     564             :     real(r8), intent(in)         :: lake(nlon_veg,nlat_veg)
     565             :     real(r8), intent(in)         :: wetland(nlon_veg,nlat_veg)
     566             :     real(r8), intent(in)         :: vegetation_map(nlon_veg,nlat_veg,npft_veg)
     567             :     real(r8), intent(in)         :: lon_veg_edge(nlon_veg+1)
     568             :     real(r8), intent(in)         :: lat_veg_edge(nlat_veg+1)
     569             : 
     570             :     !-------------------------------------------------------------------------------------
     571             :     !   ... local variables
     572             :     !-------------------------------------------------------------------------------------
     573             :     real(r8) :: closelat,closelon
     574             :     integer :: latidx,lonidx
     575             : 
     576             :     integer, parameter           :: veg_ext = 20
     577             :     type(file_desc_t), pointer   :: piofile
     578             :     integer                      :: i, j, ii, jj, i_ndx, n
     579           0 :     integer, dimension(plon+1)   :: ind_lon
     580           0 :     integer, dimension(plat+1)  :: ind_lat
     581             :     real(r8)                         :: total_land
     582           0 :     real(r8), dimension(plon+1)      :: lon_edge
     583           0 :     real(r8), dimension(plat+1)     :: lat_edge
     584             :     real(r8)                         :: lat1, lon1
     585             :     real(r8)                         :: x1, x2, y1, y2, dx, dy
     586             :     real(r8)                         :: area, total_area
     587           0 :     real(r8), dimension(npft_veg+3)  :: fraction
     588           0 :     real(r8), dimension(-veg_ext:nlon_veg+veg_ext) :: lon_veg_edge_ext
     589           0 :     integer, dimension(-veg_ext:nlon_veg+veg_ext) :: mapping_ext
     590             : 
     591           0 :     real(r8), allocatable :: lam(:), phi(:)
     592             : 
     593             :     logical, parameter :: has_npole = .true.
     594             :     integer :: ploniop,platiop
     595           0 :     real(r8) :: tmp_frac_lu(plon,n_land_type,plat)
     596             : 
     597             :     real(r8):: rlats(pcols), rlons(pcols)
     598             :     integer :: lchnk, ncol, icol
     599             :     logical :: found
     600             : 
     601           0 :     if(dycore_is('UNSTRUCTURED') ) then
     602           0 :        call endrun('mo_drydep::interp_map called for UNSTRUCTURED grid')
     603             :     endif
     604             : 
     605           0 :     allocate(lam(plon), phi(plat))
     606           0 :     call get_horiz_grid_d(plat, clat_d_out=phi)
     607           0 :     call get_horiz_grid_d(plon, clon_d_out=lam)
     608             : 
     609           0 :     if (single_column) then
     610           0 :        if (scm_cambfb_mode) then
     611           0 :           piofile => initial_file_get_id()
     612           0 :           call shr_scam_getCloseLatLon(piofile,scmlat,scmlon,closelat,closelon,latidx,lonidx)
     613           0 :           ploniop=size(loniop)
     614           0 :           platiop=size(latiop)
     615             :        else
     616           0 :           latidx=1
     617           0 :           lonidx=1
     618           0 :           ploniop=1
     619           0 :           platiop=1
     620             :        end if
     621             : 
     622           0 :        lon_edge(1) = loniop(lonidx) * r2d - .5_r8*(loniop(2) - loniop(1)) * r2d
     623             : 
     624           0 :        if (lonidx.lt.ploniop) then
     625           0 :           lon_edge(2) = loniop(lonidx+1) * r2d - .5_r8*(loniop(2) - loniop(1)) * r2d
     626             :        else
     627           0 :           lon_edge(2) = lon_edge(1) + (loniop(2) - loniop(1)) * r2d
     628             :        end if
     629             : 
     630           0 :        lat_edge(1) = latiop(latidx) * r2d - .5_r8*(latiop(2) - latiop(1)) * r2d
     631             : 
     632           0 :        if (latidx.lt.platiop) then
     633           0 :           lat_edge(2) = latiop(latidx+1) * r2d - .5_r8*(latiop(2) - latiop(1)) * r2d
     634             :        else
     635           0 :           lat_edge(2) = lat_edge(1) + (latiop(2) - latiop(1)) * r2d
     636             :        end if
     637             :     else
     638           0 :        do i = 1,plon
     639           0 :           lon_edge(i) = lam(i) * r2d - .5_r8*(lam(2) - lam(1)) * r2d
     640             :        end do
     641           0 :        lon_edge(plon+1) = lon_edge(plon) + (lam(2) - lam(1)) * r2d
     642             :        if( .not. has_npole ) then
     643             :           do j = 1,plat+1
     644             :              lat_edge(j) = phi(j) * r2d - .5_r8*(phi(2) - phi(1)) * r2d
     645             :           end do
     646             :        else
     647           0 :           do j = 1,plat
     648           0 :              lat_edge(j) = phi(j) * r2d - .5_r8*(phi(2) - phi(1)) * r2d
     649             :           end do
     650           0 :           lat_edge(plat+1) = lat_edge(plat) + (phi(2) - phi(1)) * r2d
     651             :        end if
     652             :     end if
     653           0 :     do j = 1,plat+1
     654           0 :        lat_edge(j) = min( lat_edge(j), 90._r8 )
     655           0 :        lat_edge(j) = max( lat_edge(j),-90._r8 )
     656             :     end do
     657             : 
     658             :     !-------------------------------------------------------------------------------------
     659             :     ! wrap around the longitudes
     660             :     !-------------------------------------------------------------------------------------
     661           0 :     do i = -veg_ext,0
     662           0 :        lon_veg_edge_ext(i) = lon_veg_edge(nlon_veg+i) - 360._r8
     663           0 :        mapping_ext     (i) =              nlon_veg+i
     664             :     end do
     665           0 :     do i = 1,nlon_veg
     666           0 :        lon_veg_edge_ext(i) = lon_veg_edge(i)
     667           0 :        mapping_ext     (i) =              i
     668             :     end do
     669           0 :     do i = nlon_veg+1,nlon_veg+veg_ext
     670           0 :        lon_veg_edge_ext(i) = lon_veg_edge(i-nlon_veg) + 360._r8
     671           0 :        mapping_ext     (i) =              i-nlon_veg
     672             :     end do
     673             : #ifdef DEBUG
     674           0 :     write(iulog,*) 'interp_map : lon_edge ',lon_edge
     675           0 :     write(iulog,*) 'interp_map : lat_edge ',lat_edge
     676           0 :     write(iulog,*) 'interp_map : mapping_ext ',mapping_ext
     677             : #endif
     678           0 :     do j = 1,plon+1
     679           0 :        lon1 = lon_edge(j)
     680           0 :        do i = -veg_ext,nlon_veg+veg_ext
     681           0 :           dx = lon_veg_edge_ext(i  ) - lon1
     682           0 :           dy = lon_veg_edge_ext(i+1) - lon1
     683           0 :           if( dx*dy <= 0._r8 ) then
     684           0 :              ind_lon(j) = i
     685           0 :              exit
     686             :           end if
     687             :        end do
     688             :     end do
     689             : 
     690           0 :     do j = 1,plat+1
     691           0 :        lat1 = lat_edge(j)
     692           0 :        do i = 1,nlat_veg
     693           0 :           dx = lat_veg_edge(i  ) - lat1
     694           0 :           dy = lat_veg_edge(i+1) - lat1
     695           0 :           if( dx*dy <= 0._r8 ) then
     696           0 :              ind_lat(j) = i
     697           0 :              exit
     698             :           end if
     699             :        end do
     700             :     end do
     701             : #ifdef DEBUG
     702           0 :     write(iulog,*) 'interp_map : ind_lon ',ind_lon
     703           0 :     write(iulog,*) 'interp_map : ind_lat ',ind_lat
     704             : #endif
     705           0 :     lat_loop : do j = 1,plat
     706           0 :        lon_loop : do i = 1,plon
     707           0 :           total_area       = 0._r8
     708           0 :           fraction         = 0._r8
     709           0 :           do jj = ind_lat(j),ind_lat(j+1)
     710           0 :              y1 = max( lat_edge(j),lat_veg_edge(jj) )
     711           0 :              y2 = min( lat_edge(j+1),lat_veg_edge(jj+1) )
     712           0 :              dy = (y2 - y1)/(lat_veg_edge(jj+1) - lat_veg_edge(jj))
     713           0 :              do ii =ind_lon(i),ind_lon(i+1)
     714           0 :                 i_ndx = mapping_ext(ii)
     715           0 :                 x1 = max( lon_edge(i),lon_veg_edge_ext(ii) )
     716           0 :                 x2 = min( lon_edge(i+1),lon_veg_edge_ext(ii+1) )
     717           0 :                 dx = (x2 - x1)/(lon_veg_edge_ext(ii+1) - lon_veg_edge_ext(ii))
     718           0 :                 area = dx * dy
     719           0 :                 total_area = total_area + area
     720             :                 !-----------------------------------------------------------------
     721             :                 !       ... special case for ocean grid point
     722             :                 !-----------------------------------------------------------------
     723           0 :                 if( nint(landmask(i_ndx,jj)) == 0 ) then
     724           0 :                    fraction(npft_veg+1) = fraction(npft_veg+1) + area
     725             :                 else
     726           0 :                    do n = 1,npft_veg
     727           0 :                       fraction(n) = fraction(n) + vegetation_map(i_ndx,jj,n) * area
     728             :                    end do
     729           0 :                    fraction(npft_veg+1) = fraction(npft_veg+1) + area * lake   (i_ndx,jj)
     730           0 :                    fraction(npft_veg+2) = fraction(npft_veg+2) + area * wetland(i_ndx,jj)
     731           0 :                    fraction(npft_veg+3) = fraction(npft_veg+3) + area * urban  (i_ndx,jj)
     732             :                    !-----------------------------------------------------------------
     733             :                    !    ... check if land accounts for the whole area.
     734             :                    !           If not, the remaining area is in the ocean
     735             :                    !-----------------------------------------------------------------
     736             :                    total_land = sum(vegetation_map(i_ndx,jj,:)) &
     737             :                               + urban  (i_ndx,jj) &
     738             :                               + lake   (i_ndx,jj) &
     739           0 :                               + wetland(i_ndx,jj)
     740           0 :                    if( total_land < 1._r8 ) then
     741           0 :                       fraction(npft_veg+1) = fraction(npft_veg+1) + (1._r8 - total_land) * area
     742             :                    end if
     743             :                 end if
     744             :              end do
     745             :           end do
     746             :           !-------------------------------------------------------------------------------------
     747             :           !     ... divide by total area of grid box
     748             :           !-------------------------------------------------------------------------------------
     749           0 :           fraction(:) = fraction(:)/total_area
     750             :           !-------------------------------------------------------------------------------------
     751             :           !     ... make sure we don't have too much or too little
     752             :           !-------------------------------------------------------------------------------------
     753           0 :           if( abs( sum(fraction) - 1._r8) > .001_r8 ) then
     754           0 :              fraction(:) = fraction(:)/sum(fraction)
     755             :           end if
     756             :           !-------------------------------------------------------------------------------------
     757             :           !     ... map to Wesely land classification
     758             :           !-------------------------------------------------------------------------------------
     759           0 :           tmp_frac_lu(i, 1, j) =     fraction(20)
     760           0 :           tmp_frac_lu(i, 2, j) = sum(fraction(16:17))
     761           0 :           tmp_frac_lu(i, 3, j) = sum(fraction(13:15))
     762           0 :           tmp_frac_lu(i, 4, j) = sum(fraction( 5: 9))
     763           0 :           tmp_frac_lu(i, 5, j) = sum(fraction( 2: 4))
     764           0 :           tmp_frac_lu(i, 6, j) =     fraction(19)
     765           0 :           tmp_frac_lu(i, 7, j) =     fraction(18)
     766           0 :           tmp_frac_lu(i, 8, j) =     fraction( 1)
     767           0 :           tmp_frac_lu(i, 9, j) = 0._r8
     768           0 :           tmp_frac_lu(i,10, j) = 0._r8
     769           0 :           tmp_frac_lu(i,11, j) = sum(fraction(10:12))
     770             :        end do lon_loop
     771             :     end do lat_loop
     772             : 
     773           0 :     do lchnk = begchunk, endchunk
     774           0 :        ncol = get_ncols_p(lchnk)
     775           0 :        call get_rlat_all_p(lchnk, ncol, rlats(:ncol))
     776           0 :        call get_rlon_all_p(lchnk, ncol, rlons(:ncol))
     777           0 :        do icol= 1,ncol
     778           0 :           found=.false.
     779           0 :           find_col: do j = 1,plat
     780           0 :              do i = 1,plon
     781           0 :                 if (rlats(icol)==phi(j) .and. rlons(icol)==lam(i)) then
     782             :                    found=.true.
     783             :                    exit find_col
     784             :                 endif
     785             :              enddo
     786             :           enddo find_col
     787             : 
     788           0 :           if (.not.found) call endrun('mo_drydep::interp_map not able find physics column coordinate')
     789           0 :           fraction_landuse(icol,1:n_land_type,lchnk) =  tmp_frac_lu(i,1:n_land_type,j)
     790             : 
     791             :        end do
     792             : 
     793             :        !-------------------------------------------------------------------------------------
     794             :        !        ... make sure there are no out of range values
     795             :        !-------------------------------------------------------------------------------------
     796           0 :        where (fraction_landuse(:ncol,:n_land_type,lchnk) < 0._r8) fraction_landuse(:ncol,:n_land_type,lchnk) = 0._r8
     797           0 :        where (fraction_landuse(:ncol,:n_land_type,lchnk) > 1._r8) fraction_landuse(:ncol,:n_land_type,lchnk) = 1._r8
     798             :     end do
     799             : 
     800           0 :   end subroutine interp_map
     801             : 
     802             :   !-------------------------------------------------------------------------------------
     803             :   !-------------------------------------------------------------------------------------
     804       58824 :   subroutine drydep_xactive( sfc_temp, pressure_sfc,  &
     805             :                              wind_speed, spec_hum, air_temp, pressure_10m, rain, &
     806       58824 :                              snow, solar_flux, dvel, dflx, mmr, &
     807             :                              tv, ncol, lchnk, &
     808             :                              ocnfrc, icefrc, beglandtype, endlandtype )
     809             :     !-------------------------------------------------------------------------------------
     810             :     !   code based on wesely (atmospheric environment, 1989, vol 23, p. 1293-1304) for
     811             :     !   calculation of r_c, and on walcek et. al. (atmospheric enviroment, 1986,
     812             :     !   vol. 20, p. 949-964) for calculation of r_a and r_b
     813             :     !
     814             :     !   as suggested in walcek (u_i)(u*_i) = (u_a)(u*_a)
     815             :     !   is kept constant where i represents a subgrid environment and a the
     816             :     !   grid average environment. thus the calculation proceeds as follows:
     817             :     !   va the grid averaged wind is calculated on dots
     818             :     !   z0(i) the grid averaged roughness coefficient is calculated
     819             :     !   ri(i) the grid averaged richardson number is calculated
     820             :     !   --> the grid averaged (u_a)(u*_a) is calculated
     821             :     !   --> subgrid scale u*_i is calculated assuming (u_i) given as above
     822             :     !   --> final deposotion velocity is weighted average of subgrid scale velocities
     823             :     !
     824             :     ! code written by P. Hess, rewritten in fortran 90 by JFL (August 2000)
     825             :     ! modified by JFL to be used in MOZART-2 (October 2002)
     826             :     !-------------------------------------------------------------------------------------
     827             : 
     828           0 :     use shr_drydep_mod, only: z0, rgso, rgss, ri, rclo, rcls, rlu, rac
     829             :     use shr_drydep_mod, only: shr_drydep_setHCoeff, foxd, drat
     830             :     use physconst,      only: tmelt
     831             : 
     832             :     !-------------------------------------------------------------------------------------
     833             :     !   ... dummy arguments
     834             :     !-------------------------------------------------------------------------------------
     835             :     integer, intent(in)   :: ncol
     836             :     real(r8), intent(in)      :: sfc_temp(pcols)          ! surface temperature (K)
     837             :     real(r8), intent(in)      :: pressure_sfc(pcols)      ! surface pressure (Pa)
     838             :     real(r8), intent(in)      :: wind_speed(pcols)        ! 10 meter wind speed (m/s)
     839             :     real(r8), intent(in)      :: spec_hum(pcols)          ! specific humidity (kg/kg)
     840             :     real(r8), intent(in)      :: air_temp(pcols)          ! surface air temperature (K)
     841             :     real(r8), intent(in)      :: pressure_10m(pcols)      ! 10 meter pressure (Pa)
     842             :     real(r8), intent(in)      :: rain(pcols)
     843             :     real(r8), intent(in)      :: snow(pcols)              ! snow height (m)
     844             : 
     845             :     real(r8), intent(in)      :: solar_flux(pcols)        ! direct shortwave radiation at surface (W/m^2)
     846             :     real(r8), intent(in)      :: tv(pcols)                ! potential temperature
     847             :     real(r8), intent(in)      :: mmr(pcols,plev,gas_pcnst)    ! constituent concentration (kg/kg)
     848             :     real(r8), intent(out)     :: dvel(ncol,gas_pcnst)        ! deposition velocity (cm/s)
     849             :     real(r8), intent(inout)   :: dflx(pcols,gas_pcnst)        ! deposition flux (/cm^2/s)
     850             : 
     851             :     integer, intent(in)     ::   lchnk                   ! chunk number
     852             : 
     853             :     integer, intent(in), optional     ::  beglandtype
     854             :     integer, intent(in), optional     ::  endlandtype
     855             : 
     856             :     real(r8), intent(in), optional      :: ocnfrc(pcols)
     857             :     real(r8), intent(in), optional      :: icefrc(pcols)
     858             : 
     859             :     !-------------------------------------------------------------------------------------
     860             :     !   ... local variables
     861             :     !-------------------------------------------------------------------------------------
     862             :     real(r8), parameter :: scaling_to_cm_per_s = 100._r8
     863             :     real(r8), parameter :: rain_threshold      = 1.e-7_r8  ! of the order of 1cm/day expressed in m/s
     864             : 
     865             :     integer :: i, ispec, lt, m
     866             :     integer :: sndx
     867             : 
     868             :     real(r8) :: slope = 0._r8
     869             :     real(r8) :: z0water ! revised z0 over water
     870             :     real(r8) :: p       ! pressure at midpoint first layer
     871             :     real(r8) :: pg      ! surface pressure
     872             :     real(r8) :: es      ! saturation vapor pressure
     873             :     real(r8) :: ws      ! saturation mixing ratio
     874             :     real(r8) :: hvar    ! constant to compute xmol
     875             :     real(r8) :: h       ! constant to compute xmol
     876             :     real(r8) :: psih    ! stability correction factor
     877             :     real(r8) :: rs      ! constant for calculating rsmx
     878             :     real(r8) :: rmx     ! resistance by vegetation
     879             :     real(r8) :: zovl    ! ratio of z to  m-o length
     880             :     real(r8) :: cvarb   ! cvar averaged over landtypes
     881             :     real(r8) :: bb      ! b averaged over landtypes
     882             :     real(r8) :: ustarb  ! ustar averaged over landtypes
     883      117648 :     real(r8) :: tc(ncol)  ! temperature in celsius
     884      117648 :     real(r8) :: cts(ncol) ! correction to rlu rcl and rgs for frost
     885             : 
     886             :     !-------------------------------------------------------------------------------------
     887             :     ! local arrays: dependent on location and species
     888             :     !-------------------------------------------------------------------------------------
     889      117648 :     real(r8), dimension(ncol,nddvels) :: heff
     890             : 
     891             :     !-------------------------------------------------------------------------------------
     892             :     ! local arrays: dependent on location only
     893             :     !-------------------------------------------------------------------------------------
     894      117648 :     integer                :: index_season(ncol,n_land_type)
     895      117648 :     real(r8), dimension(ncol) :: tha     ! atmospheric virtual potential temperature
     896      117648 :     real(r8), dimension(ncol) :: thg     ! ground virtual potential temperature
     897      117648 :     real(r8), dimension(ncol) :: z       ! height of lowest level
     898      117648 :     real(r8), dimension(ncol) :: va      ! magnitude of v on cross points
     899      117648 :     real(r8), dimension(ncol) :: ribn    ! richardson number
     900      117648 :     real(r8), dimension(ncol) :: qs      ! saturation specific humidity
     901      117648 :     real(r8), dimension(ncol) :: crs     ! multiplier to calculate crs
     902      117648 :     real(r8), dimension(ncol) :: rdc     ! part of lower canopy resistance
     903      117648 :     real(r8), dimension(ncol) :: uustar  ! u*ustar (assumed constant over grid)
     904      117648 :     real(r8), dimension(ncol) :: z0b     ! average roughness length over grid
     905      117648 :     real(r8), dimension(ncol) :: wrk     ! work array
     906      117648 :     real(r8), dimension(ncol) :: term    ! work array
     907      117648 :     real(r8), dimension(ncol) :: resc    ! work array
     908      117648 :     real(r8), dimension(ncol) :: lnd_frc ! work array
     909      117648 :     logical,  dimension(ncol) :: unstable
     910      117648 :     logical,  dimension(ncol) :: has_rain
     911      117648 :     logical,  dimension(ncol) :: has_dew
     912             : 
     913             :     !-------------------------------------------------------------------------------------
     914             :     ! local arrays: dependent on location and landtype
     915             :     !-------------------------------------------------------------------------------------
     916      117648 :     real(r8), dimension(ncol,n_land_type) :: rds   ! resistance for deposition of sulfate
     917      117648 :     real(r8), dimension(ncol,n_land_type) :: b     ! buoyancy parameter for unstable conditions
     918      117648 :     real(r8), dimension(ncol,n_land_type) :: cvar  ! height parameter
     919      117648 :     real(r8), dimension(ncol,n_land_type) :: ustar ! friction velocity
     920      117648 :     real(r8), dimension(ncol,n_land_type) :: xmol  ! monin-obukhov length
     921             : 
     922             :     !-------------------------------------------------------------------------------------
     923             :     ! local arrays: dependent on location, landtype and species
     924             :     !-------------------------------------------------------------------------------------
     925      117648 :     real(r8), dimension(ncol,n_land_type,gas_pcnst) :: rsmx  ! vegetative resistance (plant mesophyll)
     926      117648 :     real(r8), dimension(ncol,n_land_type,gas_pcnst) :: rclx  ! lower canopy resistance
     927      117648 :     real(r8), dimension(ncol,n_land_type,gas_pcnst) :: rlux  ! vegetative resistance (upper canopy)
     928      117648 :     real(r8), dimension(ncol,n_land_type) :: rlux_o3  ! vegetative resistance (upper canopy)
     929      117648 :     real(r8), dimension(ncol,n_land_type,gas_pcnst) :: rgsx  ! ground resistance
     930             :     real(r8) :: vds
     931      117648 :     logical  :: fr_lnduse(ncol,n_land_type)           ! wrking array
     932             :     real(r8) :: dewm                                  ! multiplier for rs when dew occurs
     933             : 
     934      117648 :     real(r8) :: lcl_frc_landuse(ncol,n_land_type)
     935             : 
     936             :     integer :: beglt, endlt
     937             : 
     938             :     !-------------------------------------------------------------------------------------
     939             :     ! jfl : mods for PAN
     940             :     !-------------------------------------------------------------------------------------
     941             :     real(r8) :: dv_pan
     942             :     real(r8) :: c0_pan(11) = (/ 0.000_r8, 0.006_r8, 0.002_r8, 0.009_r8, 0.015_r8, &
     943             :                                 0.006_r8, 0.000_r8, 0.000_r8, 0.000_r8, 0.002_r8, 0.002_r8 /)
     944             :     real(r8) :: k_pan (11) = (/ 0.000_r8, 0.010_r8, 0.005_r8, 0.004_r8, 0.003_r8, &
     945             :                                 0.005_r8, 0.000_r8, 0.000_r8, 0.000_r8, 0.075_r8, 0.002_r8 /)
     946             : 
     947       58824 :     if (present( beglandtype)) then
     948       58824 :       beglt = beglandtype
     949             :     else
     950             :       beglt = 1
     951             :     endif
     952       58824 :     if (present( endlandtype)) then
     953       58824 :       endlt = endlandtype
     954             :     else
     955             :       endlt = n_land_type
     956             :     endif
     957             : 
     958             :     !-------------------------------------------------------------------------------------
     959             :     ! initialize
     960             :     !-------------------------------------------------------------------------------------
     961     1882368 :     do m = 1,gas_pcnst
     962    30507768 :        dvel(:,m) = 0._r8
     963             :     end do
     964             : 
     965      411768 :     if( all( .not. has_dvel(:) ) ) then
     966             :        return
     967             :     end if
     968             : 
     969             :     !-------------------------------------------------------------------------------------
     970             :     ! define species-dependent parameters (temperature dependent)
     971             :     !-------------------------------------------------------------------------------------
     972       58824 :     call shr_drydep_setHCoeff( ncol, sfc_temp, heff )
     973             : 
     974      705888 :     do lt = 1,n_land_type
     975    11000088 :        dep_ra (:,lt,lchnk)   = 0._r8
     976    11000088 :        dep_rb (:,lt,lchnk)   = 0._r8
     977    10863288 :        rds(:,lt)   = 0._r8
     978             :     end do
     979             : 
     980             :     !-------------------------------------------------------------------------------------
     981             :     ! season index only for ocn and sea ice
     982             :     !-------------------------------------------------------------------------------------
     983    10863288 :     index_season = 4
     984             :     !-------------------------------------------------------------------------------------
     985             :     ! special case for snow covered terrain
     986             :     !-------------------------------------------------------------------------------------
     987      982224 :     do i = 1,ncol
     988      982224 :        if( snow(i) > .01_r8 ) then
     989     1355844 :           index_season(i,:) = 4
     990             :        end if
     991             :     end do
     992             :     !-------------------------------------------------------------------------------------
     993             :     ! scale rain and define logical arrays
     994             :     !-------------------------------------------------------------------------------------
     995      982224 :     has_rain(:ncol) = rain(:ncol) > rain_threshold
     996             : 
     997             :     !-------------------------------------------------------------------------------------
     998             :     ! loop over longitude points
     999             :     !-------------------------------------------------------------------------------------
    1000      982224 :     col_loop :  do i = 1,ncol
    1001      923400 :        p   = pressure_10m(i)
    1002      923400 :        pg  = pressure_sfc(i)
    1003             :        !-------------------------------------------------------------------------------------
    1004             :        ! potential temperature
    1005             :        !-------------------------------------------------------------------------------------
    1006      923400 :        tha(i) = air_temp(i) * (p00/p )**rovcp * (1._r8 + .61_r8*spec_hum(i))
    1007      923400 :        thg(i) = sfc_temp(i) * (p00/pg)**rovcp * (1._r8 + .61_r8*spec_hum(i))
    1008             :        !-------------------------------------------------------------------------------------
    1009             :        ! height of 1st level
    1010             :        !-------------------------------------------------------------------------------------
    1011      923400 :        z(i) = - r/grav * air_temp(i) * (1._r8 + .61_r8*spec_hum(i)) * log(p/pg)
    1012             :        !-------------------------------------------------------------------------------------
    1013             :        ! wind speed
    1014             :        !-------------------------------------------------------------------------------------
    1015      923400 :        va(i) = max( .01_r8,wind_speed(i) )
    1016             :        !-------------------------------------------------------------------------------------
    1017             :        ! Richardson number
    1018             :        !-------------------------------------------------------------------------------------
    1019      923400 :        ribn(i) = z(i) * grav * (tha(i) - thg(i))/thg(i) / (va(i)*va(i))
    1020      923400 :        ribn(i) = min( ribn(i),ric )
    1021      923400 :        unstable(i) = ribn(i) < 0._r8
    1022             :        !-------------------------------------------------------------------------------------
    1023             :        ! saturation vapor pressure (Pascals)
    1024             :        ! saturation mixing ratio
    1025             :        ! saturation specific humidity
    1026             :        !-------------------------------------------------------------------------------------
    1027      923400 :        es    = 611._r8*exp( 5414.77_r8*(sfc_temp(i) - tmelt)/(tmelt*sfc_temp(i)) )
    1028      923400 :        ws    = .622_r8*es/(pg - es)
    1029      923400 :        qs(i) = ws/(1._r8 + ws)
    1030      923400 :        has_dew(i) = .false.
    1031      923400 :        if( qs(i) <= spec_hum(i) ) then
    1032       80163 :           has_dew(i) = .true.
    1033             :        end if
    1034      923400 :        if( sfc_temp(i) < tmelt ) then
    1035      154965 :           has_dew(i) = .false.
    1036             :        end if
    1037             :        !-------------------------------------------------------------------------------------
    1038             :        ! constant in determining rs
    1039             :        !-------------------------------------------------------------------------------------
    1040      923400 :        tc(i) = sfc_temp(i) - tmelt
    1041      923400 :        if( sfc_temp(i) > tmelt .and. sfc_temp(i) < 313.15_r8 ) then
    1042      759224 :           crs(i) = (1._r8 + (200._r8/(solar_flux(i) + .1_r8))**2) * (400._r8/(tc(i)*(40._r8 - tc(i))))
    1043             :        else
    1044      164176 :           crs(i) = large_value
    1045             :        end if
    1046             :        !-------------------------------------------------------------------------------------
    1047             :        ! rdc (lower canopy res)
    1048             :        !-------------------------------------------------------------------------------------
    1049      982224 :        rdc(i) = 100._r8*(1._r8 + 1000._r8/(solar_flux(i) + 10._r8))/(1._r8 + 1000._r8*slope)
    1050             :     end do col_loop
    1051             : 
    1052             :     !-------------------------------------------------------------------------------------
    1053             :     !   ... form working arrays
    1054             :     !-------------------------------------------------------------------------------------
    1055    10863288 :     lcl_frc_landuse(:,:) = 0._r8
    1056             : 
    1057       58824 :     if ( present(ocnfrc) .and. present(icefrc) ) then
    1058      982224 :        do i=1,ncol
    1059             :           ! land type 7 is used for ocean
    1060             :           ! land type 8 is used for sea ice
    1061      923400 :           lcl_frc_landuse(i,7) = ocnfrc(i)
    1062      982224 :           lcl_frc_landuse(i,8) = icefrc(i)
    1063             :        enddo
    1064             :     endif
    1065      705888 :     do lt = 1,n_land_type
    1066    10863288 :        do i=1,ncol
    1067    10804464 :           fr_lnduse(i,lt) = lcl_frc_landuse(i,lt) > 0._r8
    1068             :        enddo
    1069             :     end do
    1070             : 
    1071             :     !-------------------------------------------------------------------------------------
    1072             :     ! find grid averaged z0: z0bar (the roughness length) z_o=exp[S(f_i*ln(z_oi))]
    1073             :     ! this is calculated so as to find u_i, assuming u*u=u_i*u_i
    1074             :     !-------------------------------------------------------------------------------------
    1075      982224 :     z0b(:) = 0._r8
    1076      705888 :     do lt = 1,n_land_type
    1077    10863288 :        do i = 1,ncol
    1078    10804464 :           if( fr_lnduse(i,lt) ) then
    1079      724338 :              z0b(i) = z0b(i) + lcl_frc_landuse(i,lt) * log( z0(index_season(i,lt),lt) )
    1080             :           end if
    1081             :        end do
    1082             :     end do
    1083             : 
    1084             :     !-------------------------------------------------------------------------------------
    1085             :     ! find the constant velocity uu*=(u_i)(u*_i)
    1086             :     !-------------------------------------------------------------------------------------
    1087      982224 :     do i = 1,ncol
    1088      923400 :        z0b(i) = exp( z0b(i) )
    1089      923400 :        cvarb  = vonkar/log( z(i)/z0b(i) )
    1090             :        !-------------------------------------------------------------------------------------
    1091             :        ! unstable and stable cases
    1092             :        !-------------------------------------------------------------------------------------
    1093      923400 :        if( unstable(i) ) then
    1094      617660 :           bb = 9.4_r8*(cvarb**2)*sqrt( abs(ribn(i))*z(i)/z0b(i) )
    1095      617660 :           ustarb = cvarb * va(i) * sqrt( 1._r8 - (9.4_r8*ribn(i)/(1._r8 + 7.4_r8*bb)) )
    1096             :        else
    1097      305740 :           ustarb = cvarb * va(i)/(1._r8 + 4.7_r8*ribn(i))
    1098             :        end if
    1099      982224 :        uustar(i) = va(i)*ustarb
    1100             :     end do
    1101             : 
    1102             :     !-------------------------------------------------------------------------------------
    1103             :     ! calculate the friction velocity for each land type u_i=uustar/u*_i
    1104             :     !-------------------------------------------------------------------------------------
    1105      176472 :     do lt = beglt,endlt
    1106     2023272 :        do i = 1,ncol
    1107     1964448 :           if( fr_lnduse(i,lt) ) then
    1108      724338 :              if( unstable(i) ) then
    1109      533541 :                 cvar(i,lt)  = vonkar/log( z(i)/z0(index_season(i,lt),lt) )
    1110      533541 :                 b(i,lt)     = 9.4_r8*(cvar(i,lt)**2)* sqrt( abs(ribn(i))*z(i)/z0(index_season(i,lt),lt) )
    1111      533541 :                 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))) ) )
    1112             :              else
    1113      190797 :                 cvar(i,lt)  = vonkar/log( z(i)/z0(index_season(i,lt),lt) )
    1114      190797 :                 ustar(i,lt) = sqrt( cvar(i,lt)*uustar(i)/(1._r8 + 4.7_r8*ribn(i)) )
    1115             :              end if
    1116             :           end if
    1117             :        end do
    1118             :     end do
    1119             : 
    1120             :     !-------------------------------------------------------------------------------------
    1121             :     ! revise calculation of friction velocity and z0 over water
    1122             :     !-------------------------------------------------------------------------------------
    1123      982224 :     lt = 7
    1124      982224 :     do i = 1,ncol
    1125      982224 :        if( fr_lnduse(i,lt) ) then
    1126      679175 :           if( unstable(i) ) then
    1127      517948 :              z0water     = (.016_r8*(ustar(i,lt)**2)/grav) + diffk/(9.1_r8*ustar(i,lt))
    1128      517948 :              cvar(i,lt)  = vonkar/(log( z(i)/z0water ))
    1129      517948 :              b(i,lt)     = 9.4_r8*(cvar(i,lt)**2)*sqrt( abs(ribn(i))*z(i)/z0water )
    1130      517948 :              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))) ) )
    1131             :           else
    1132      161227 :              z0water     = (.016_r8*(ustar(i,lt)**2)/grav) + diffk/(9.1_r8*ustar(i,lt))
    1133      161227 :              cvar(i,lt)  = vonkar/(log(z(i)/z0water))
    1134      161227 :              ustar(i,lt) = sqrt( cvar(i,lt)*uustar(i)/(1._r8 + 4.7_r8*ribn(i)) )
    1135             :           end if
    1136             :        end if
    1137             :     end do
    1138             : 
    1139             :     !-------------------------------------------------------------------------------------
    1140             :     ! compute monin-obukhov length for unstable and stable conditions/ sublayer resistance
    1141             :     !-------------------------------------------------------------------------------------
    1142      176472 :     do lt = beglt,endlt
    1143     2023272 :        do i = 1,ncol
    1144     1964448 :           if( fr_lnduse(i,lt) ) then
    1145      724338 :              hvar = (va(i)/0.74_r8) * (tha(i) - thg(i)) * (cvar(i,lt)**2)
    1146      724338 :              if( unstable(i) ) then                      ! unstable
    1147      533541 :                 h = hvar*(1._r8 - (9.4_r8*ribn(i)/(1._r8 + 5.3_r8*b(i,lt))))
    1148             :              else
    1149      190797 :                 h = hvar/((1._r8+4.7_r8*ribn(i))**2)
    1150             :              end if
    1151      724338 :              xmol(i,lt) = thg(i) * ustar(i,lt) * ustar(i,lt) / (vonkar * grav * h)
    1152             :           end if
    1153             :        end do
    1154             :     end do
    1155             : 
    1156             :     !-------------------------------------------------------------------------------------
    1157             :     ! psih
    1158             :     !-------------------------------------------------------------------------------------
    1159      176472 :     do lt = beglt,endlt
    1160     2023272 :        do i = 1,ncol
    1161     1964448 :           if( fr_lnduse(i,lt) ) then
    1162      724338 :              if( xmol(i,lt) < 0._r8 ) then
    1163      533541 :                 zovl = z(i)/xmol(i,lt)
    1164      533541 :                 zovl = max( -1._r8,zovl )
    1165      533541 :                 psih = exp( .598_r8 + .39_r8*log( -zovl ) - .09_r8*(log( -zovl ))**2 )
    1166      533541 :                 vds  = 2.e-3_r8*ustar(i,lt) * (1._r8 + (300/(-xmol(i,lt)))**0.666_r8)
    1167             :              else
    1168      190797 :                 zovl = z(i)/xmol(i,lt)
    1169      190797 :                 zovl = min( 1._r8,zovl )
    1170      190797 :                 psih = -5._r8 * zovl
    1171      190797 :                 vds  = 2.e-3_r8*ustar(i,lt)
    1172             :              end if
    1173      724338 :              dep_ra (i,lt,lchnk) = (vonkar - psih*cvar(i,lt))/(ustar(i,lt)*vonkar*cvar(i,lt))
    1174      724338 :              dep_rb (i,lt,lchnk) = (2._r8/(vonkar*ustar(i,lt))) * crb
    1175      724338 :              rds(i,lt) = 1._r8/vds
    1176             :           end if
    1177             :        end do
    1178             :     end do
    1179             : 
    1180             :     !-------------------------------------------------------------------------------------
    1181             :     ! surface resistance : depends on both land type and species
    1182             :     ! land types are computed seperately, then resistance is computed as average of values
    1183             :     ! following wesely rc=(1/(rs+rm) + 1/rlu +1/(rdc+rcl) + 1/(rac+rgs))**-1
    1184             :     !
    1185             :     ! compute rsmx = 1/(rs+rm) : multiply by 3 if surface is wet
    1186             :     !-------------------------------------------------------------------------------------
    1187     1882368 :     species_loop1 :  do ispec = 1,gas_pcnst
    1188     1882368 :        if( has_dvel(ispec) ) then
    1189      294120 :           m = map_dvel(ispec)
    1190      882360 :           do lt = beglt,endlt
    1191    10116360 :              do i = 1,ncol
    1192     9822240 :                 if( fr_lnduse(i,lt) ) then
    1193     3621690 :                    sndx = index_season(i,lt)
    1194     3621690 :                    if( ispec == o3_ndx .or. ispec == o3a_ndx .or. ispec == so2_ndx ) then
    1195             :                       rmx = 0._r8
    1196             :                    else
    1197     2897352 :                       rmx = 1._r8/(heff(i,m)/3000._r8 + 100._r8*foxd(m))
    1198             :                    end if
    1199     3621690 :                    cts(i) = 1000._r8*exp( - tc(i) - 4._r8 )                 ! correction for frost
    1200     3621690 :                    rgsx(i,lt,ispec) = cts(i) + 1._r8/((heff(i,m)/(1.e5_r8*rgss(sndx,lt))) + (foxd(m)/rgso(sndx,lt)))
    1201             :                    !-------------------------------------------------------------------------------------
    1202             :                    ! special case for H2 and CO;; CH4 is set ot a fraction of dv(H2)
    1203             :                    !-------------------------------------------------------------------------------------
    1204     3621690 :                    if( ispec == h2_ndx .or. ispec == co_ndx .or. ispec == ch4_ndx ) then
    1205             :                       !-------------------------------------------------------------------------------------
    1206             :                       ! no deposition on snow, ice, desert, and water
    1207             :                       !-------------------------------------------------------------------------------------
    1208           0 :                       if( lt == 1 .or. lt == 7 .or. lt == 8 .or. sndx == 4 ) then
    1209           0 :                          rgsx(i,lt,ispec) = large_value
    1210             :                       end if
    1211             :                    end if
    1212     3621690 :                    if( lt == 7 ) then
    1213     3395875 :                       rclx(i,lt,ispec) = large_value
    1214     3395875 :                       rsmx(i,lt,ispec) = large_value
    1215     3395875 :                       rlux(i,lt,ispec) = large_value
    1216             :                    else
    1217      225815 :                       rs = ri(sndx,lt)*crs(i)
    1218      225815 :                       if ( has_dew(i) .or. has_rain(i) ) then
    1219             :                          dewm = 3._r8
    1220             :                       else
    1221      213525 :                          dewm = 1._r8
    1222             :                       end if
    1223      225815 :                       rsmx(i,lt,ispec) = (dewm*rs*drat(m) + rmx)
    1224             :                       !-------------------------------------------------------------------------------------
    1225             :                       ! jfl : special case for PAN
    1226             :                       !-------------------------------------------------------------------------------------
    1227      225815 :                       if( ispec == pan_ndx .or. ispec == xpan_ndx ) then
    1228           0 :                          dv_pan =  c0_pan(lt) * (1._r8 - exp( -k_pan(lt)*(dewm*rs*drat(m))*1.e-2_r8 ))
    1229           0 :                          if( dv_pan > 0._r8 .and. sndx /= 4 ) then
    1230           0 :                             rsmx(i,lt,ispec) = ( 1._r8/dv_pan )
    1231             :                          end if
    1232             :                       end if
    1233      225815 :                       rclx(i,lt,ispec) = cts(i) + 1._r8/((heff(i,m)/(1.e5_r8*rcls(sndx,lt))) + (foxd(m)/rclo(sndx,lt)))
    1234      225815 :                       rlux(i,lt,ispec) = cts(i) + rlu(sndx,lt)/(1.e-5_r8*heff(i,m) + foxd(m))
    1235             :                    end if
    1236             :                 end if
    1237             :              end do
    1238             :           end do
    1239             :        end if
    1240             :     end do species_loop1
    1241             : 
    1242      176472 :     do lt = beglt,endlt
    1243      176472 :        if( lt /= 7 ) then
    1244      982224 :           do i = 1,ncol
    1245      982224 :              if( fr_lnduse(i,lt) ) then
    1246       45163 :                 sndx = index_season(i,lt)
    1247             :                 !-------------------------------------------------------------------------------------
    1248             :                 !       ... no effect if sfc_temp < O C
    1249             :                 !-------------------------------------------------------------------------------------
    1250       45163 :                 if( sfc_temp(i) > tmelt ) then
    1251        2218 :                    if( has_dew(i) ) then
    1252         631 :                       rlux_o3(i,lt)     = 3000._r8*rlu(sndx,lt)/(1000._r8 + rlu(sndx,lt))
    1253         631 :                       if( o3_ndx > 0 ) then
    1254           0 :                          rlux(i,lt,o3_ndx) = rlux_o3(i,lt)
    1255             :                       endif
    1256         631 :                       if( o3a_ndx > 0 ) then
    1257           0 :                          rlux(i,lt,o3a_ndx) = rlux_o3(i,lt)
    1258             :                       endif
    1259             :                    end if
    1260        2218 :                    if( has_rain(i) ) then
    1261             :                       ! rlux(i,lt,o3_ndx) = 1./(1.e-3 + (1./(3.*rlu(sndx,lt))))
    1262         476 :                       rlux_o3(i,lt)     = 3000._r8*rlu(sndx,lt)/(1000._r8 + 3._r8*rlu(sndx,lt))
    1263         476 :                       if( o3_ndx > 0 ) then
    1264           0 :                          rlux(i,lt,o3_ndx) = rlux_o3(i,lt)
    1265             :                       endif
    1266         476 :                       if( o3a_ndx > 0 ) then
    1267           0 :                          rlux(i,lt,o3a_ndx) = rlux_o3(i,lt)
    1268             :                       endif
    1269             :                    end if
    1270             :                 end if
    1271             : 
    1272       45163 :                 if ( o3_ndx > 0 ) then
    1273           0 :                    rclx(i,lt,o3_ndx) = cts(i) + rclo(index_season(i,lt),lt)
    1274           0 :                    rlux(i,lt,o3_ndx) = cts(i) + rlux(i,lt,o3_ndx)
    1275             :                 end if
    1276       45163 :                 if ( o3a_ndx > 0 ) then
    1277           0 :                    rclx(i,lt,o3a_ndx) = cts(i) + rclo(index_season(i,lt),lt)
    1278           0 :                    rlux(i,lt,o3a_ndx) = cts(i) + rlux(i,lt,o3a_ndx)
    1279             :                 end if
    1280             : 
    1281             :              end if
    1282             :           end do
    1283             :        end if
    1284             :     end do
    1285             : 
    1286     1882368 :     species_loop2 : do ispec = 1,gas_pcnst
    1287     1823544 :        m = map_dvel(ispec)
    1288     1882368 :        if( has_dvel(ispec) ) then
    1289      294120 :           if( ispec /= o3_ndx .and. ispec /= o3a_ndx .and. ispec /= so2_ndx ) then
    1290      705888 :              do lt = beglt,endlt
    1291      705888 :                 if( lt /= 7 ) then
    1292     3928896 :                    do i = 1,ncol
    1293     3928896 :                       if( fr_lnduse(i,lt) ) then
    1294             :                          !-------------------------------------------------------------------------------------
    1295             :                          ! no effect if sfc_temp < O C
    1296             :                          !-------------------------------------------------------------------------------------
    1297      180652 :                          if( sfc_temp(i) > tmelt ) then
    1298        8872 :                             if( has_dew(i) ) then
    1299             :                                rlux(i,lt,ispec) = 1._r8/((1._r8/(3._r8*rlux(i,lt,ispec))) &
    1300        2524 :                                     + 1.e-7_r8*heff(i,m) + foxd(m)/rlux_o3(i,lt))
    1301             :                             end if
    1302             :                          end if
    1303             : 
    1304             :                       end if
    1305             :                    end do
    1306             :                 end if
    1307             :              end do
    1308       58824 :           else if( ispec == so2_ndx ) then
    1309      176472 :              do lt = beglt,endlt
    1310      176472 :                 if( lt /= 7 ) then
    1311      982224 :                    do i = 1,ncol
    1312      982224 :                       if( fr_lnduse(i,lt) ) then
    1313             :                          !-------------------------------------------------------------------------------------
    1314             :                          ! no effect if sfc_temp < O C
    1315             :                          !-------------------------------------------------------------------------------------
    1316       45163 :                          if( sfc_temp(i) > tmelt ) then
    1317        2218 :                             if( qs(i) <= spec_hum(i) ) then
    1318         631 :                                rlux(i,lt,ispec) = 100._r8
    1319             :                             end if
    1320        2218 :                             if( has_rain(i) ) then
    1321             :                                !                               rlux(i,lt,ispec) = 1./(2.e-4 + (1./(3.*rlu(index_season(i,lt),lt))))
    1322         476 :                                rlux(i,lt,ispec) = 15._r8*rlu(index_season(i,lt),lt)/(5._r8 + 3.e-3_r8*rlu(index_season(i,lt),lt))
    1323             :                             end if
    1324             :                          end if
    1325       45163 :                          rclx(i,lt,ispec) = cts(i) + rcls(index_season(i,lt),lt)
    1326       45163 :                          rlux(i,lt,ispec) = cts(i) + rlux(i,lt,ispec)
    1327             : 
    1328             :                       end if
    1329             :                    end do
    1330             :                 end if
    1331             :              end do
    1332      982224 :              do i = 1,ncol
    1333      982224 :                 if( fr_lnduse(i,1) .and. (has_dew(i) .or. has_rain(i)) ) then
    1334           0 :                    rlux(i,1,ispec) = 50._r8
    1335             :                 end if
    1336             :              end do
    1337             :           end if
    1338             :        end if
    1339             :     end do species_loop2
    1340             : 
    1341             :     !-------------------------------------------------------------------------------------
    1342             :     ! compute rc
    1343             :     !-------------------------------------------------------------------------------------
    1344      982224 :     term(:ncol) = 1.e-2_r8 * pressure_10m(:ncol) / (r*tv(:ncol))
    1345     1882368 :     species_loop3 : do ispec = 1,gas_pcnst
    1346     1882368 :        if( has_dvel(ispec) ) then
    1347     4911120 :           wrk(:) = 0._r8
    1348      882360 :           lt_loop: do lt = beglt,endlt
    1349     9822240 :              do i = 1,ncol
    1350     9822240 :                 if (fr_lnduse(i,lt)) then
    1351             :                    resc(i) = 1._r8/( 1._r8/rsmx(i,lt,ispec) + 1._r8/rlux(i,lt,ispec) &
    1352             :                                    + 1._r8/(rdc(i) + rclx(i,lt,ispec)) &
    1353     3621690 :                                    + 1._r8/(rac(index_season(i,lt),lt) + rgsx(i,lt,ispec)))
    1354             : 
    1355     3621690 :                    resc(i) = max( 10._r8,resc(i) )
    1356             : 
    1357     3621690 :                    lnd_frc(i) = lcl_frc_landuse(i,lt)
    1358             :                 endif
    1359             :              enddo
    1360             :              !-------------------------------------------------------------------------------------
    1361             :              !  ... compute average deposition velocity
    1362             :              !-------------------------------------------------------------------------------------
    1363      294120 :              select case( solsym(ispec) )
    1364             :              case( 'SO2' )
    1365      117648 :                 if( lt == 7 ) then
    1366      982224 :                    where( fr_lnduse(:ncol,lt) )
    1367             :                       ! assume no surface resistance for SO2 over water`
    1368       58824 :                       wrk(:) = wrk(:) + lnd_frc(:)/(dep_ra(:ncol,lt,lchnk) + dep_rb(:ncol,lt,lchnk))
    1369             :                    endwhere
    1370             :                 else
    1371      982224 :                    where( fr_lnduse(:ncol,lt) )
    1372       58824 :                       wrk(:) = wrk(:) + lnd_frc(:)/(dep_ra(:ncol,lt,lchnk) + dep_rb(:ncol,lt,lchnk) + resc(:))
    1373             :                    endwhere
    1374             :                 end if
    1375             : 
    1376             :                 !  JFL - increase in dry deposition of SO2 to improve bias over US/Europe
    1377     1964448 :                 wrk(:) = wrk(:) * 2._r8
    1378             : 
    1379             :              case( 'SO4' )
    1380           0 :                 where( fr_lnduse(:ncol,lt) )
    1381           0 :                    wrk(:) = wrk(:) + lnd_frc(:)/(dep_ra(:ncol,lt,lchnk) + rds(:,lt))
    1382             :                 endwhere
    1383             :              case( 'NH4', 'NH4NO3', 'XNH4NO3' )
    1384           0 :                 where( fr_lnduse(:ncol,lt) )
    1385           0 :                    wrk(:) = wrk(:) + lnd_frc(:)/(dep_ra(:ncol,lt,lchnk) + 0.5_r8*rds(:,lt))
    1386             :                 endwhere
    1387             : 
    1388             :              !-------------------------------------------------------------------------------------
    1389             :              !  ... special case for Pb (for consistency with offline code)
    1390             :              !-------------------------------------------------------------------------------------
    1391             :              case( 'Pb' )
    1392           0 :                 if( lt == 7 ) then
    1393           0 :                    where( fr_lnduse(:ncol,lt) )
    1394             :                       wrk(:) = wrk(:) + lnd_frc(:) * 0.05e-2_r8
    1395             :                    endwhere
    1396             :                 else
    1397           0 :                    where( fr_lnduse(:ncol,lt) )
    1398             :                       wrk(:ncol) = wrk(:ncol) + lnd_frc(:ncol) * 0.2e-2_r8
    1399             :                    endwhere
    1400             :                 end if
    1401             : 
    1402             :              !-------------------------------------------------------------------------------------
    1403             :              !  ... special case for carbon aerosols
    1404             :              !-------------------------------------------------------------------------------------
    1405             :              case( 'CB1', 'CB2', 'OC1', 'OC2', 'SOAM', 'SOAI', 'SOAT', 'SOAB','SOAX' )
    1406           0 :                 where( fr_lnduse(:ncol,lt) )
    1407             :                    wrk(:ncol) = wrk(:ncol) + lnd_frc(:ncol) * 0.10e-2_r8
    1408             :                 endwhere
    1409             : 
    1410             :              !-------------------------------------------------------------------------------------
    1411             :              ! deposition over ocean for HCN, CH3CN
    1412             :              !    velocity estimated from aircraft measurements (E.Apel, INTEX-B)
    1413             :              !-------------------------------------------------------------------------------------
    1414             :              case( 'HCN','CH3CN' )
    1415           0 :                 if( lt == 7 ) then ! over ocean only
    1416           0 :                    where( fr_lnduse(:ncol,lt) .and. snow(:ncol) < 0.01_r8  )
    1417             :                       wrk(:ncol) = wrk(:ncol) + lnd_frc(:ncol) * 0.2e-2_r8
    1418             :                    endwhere
    1419             :                 end if
    1420             :              case default
    1421     8446032 :                 where( fr_lnduse(:ncol,lt) )
    1422      470592 :                    wrk(:ncol) = wrk(:ncol) + lnd_frc(:ncol)/(dep_ra(:ncol,lt,lchnk) + dep_rb(:ncol,lt,lchnk) + resc(:ncol))
    1423             :                 endwhere
    1424             :              end select
    1425             :           end do lt_loop
    1426     4911120 :           dvel(:ncol,ispec) = wrk(:ncol) * scaling_to_cm_per_s
    1427     4911120 :           dflx(:ncol,ispec) = term(:ncol) * dvel(:ncol,ispec) * mmr(:ncol,plev,ispec)
    1428             :        end if
    1429             : 
    1430             :     end do species_loop3
    1431             : 
    1432       58824 :     if ( beglt > 1 ) return
    1433             : 
    1434             :     !-------------------------------------------------------------------------------------
    1435             :     !   ... special adjustments
    1436             :     !-------------------------------------------------------------------------------------
    1437           0 :     if( mpan_ndx > 0 ) then
    1438           0 :        if( has_dvel(mpan_ndx) ) then
    1439           0 :           dvel(:ncol,mpan_ndx) = dvel(:ncol,mpan_ndx)/3._r8
    1440           0 :           dflx(:ncol,mpan_ndx) = term(:ncol) * dvel(:ncol,mpan_ndx) * mmr(:ncol,plev,mpan_ndx)
    1441             :        end if
    1442             :     end if
    1443           0 :     if( xmpan_ndx > 0 ) then
    1444           0 :        if( has_dvel(xmpan_ndx) ) then
    1445           0 :           dvel(:ncol,xmpan_ndx) = dvel(:ncol,xmpan_ndx)/3._r8
    1446           0 :           dflx(:ncol,xmpan_ndx) = term(:ncol) * dvel(:ncol,xmpan_ndx) * mmr(:ncol,plev,xmpan_ndx)
    1447             :        end if
    1448             :     end if
    1449             : 
    1450             :     ! HCOOH, use CH3COOH dep.vel
    1451           0 :     if( hcooh_ndx > 0) then
    1452           0 :        if( has_dvel(hcooh_ndx) ) then
    1453           0 :           dvel(:ncol,hcooh_ndx) = dvel(:ncol,ch3cooh_ndx)
    1454           0 :           dflx(:ncol,hcooh_ndx) = term(:ncol) * dvel(:ncol,hcooh_ndx) * mmr(:ncol,plev,hcooh_ndx)
    1455             :        end if
    1456             :     end if
    1457             : !
    1458             : ! SOG species
    1459             : !
    1460           0 :     if( sogm_ndx > 0) then
    1461           0 :        if( has_dvel(sogm_ndx) ) then
    1462           0 :           dvel(:ncol,sogm_ndx) = dvel(:ncol,ch3cooh_ndx)
    1463           0 :           dflx(:ncol,sogm_ndx) = term(:ncol) * dvel(:ncol,sogm_ndx) * mmr(:ncol,plev,sogm_ndx)
    1464             :        end if
    1465             :     end if
    1466           0 :     if( sogi_ndx > 0) then
    1467           0 :        if( has_dvel(sogi_ndx) ) then
    1468           0 :           dvel(:ncol,sogi_ndx) = dvel(:ncol,ch3cooh_ndx)
    1469           0 :           dflx(:ncol,sogi_ndx) = term(:ncol) * dvel(:ncol,sogi_ndx) * mmr(:ncol,plev,sogi_ndx)
    1470             :        end if
    1471             :     end if
    1472           0 :     if( sogt_ndx > 0) then
    1473           0 :        if( has_dvel(sogt_ndx) ) then
    1474           0 :           dvel(:ncol,sogt_ndx) = dvel(:ncol,ch3cooh_ndx)
    1475           0 :           dflx(:ncol,sogt_ndx) = term(:ncol) * dvel(:ncol,sogt_ndx) * mmr(:ncol,plev,sogt_ndx)
    1476             :        end if
    1477             :     end if
    1478           0 :     if( sogb_ndx > 0) then
    1479           0 :        if( has_dvel(sogb_ndx) ) then
    1480           0 :           dvel(:ncol,sogb_ndx) = dvel(:ncol,ch3cooh_ndx)
    1481           0 :           dflx(:ncol,sogb_ndx) = term(:ncol) * dvel(:ncol,sogb_ndx) * mmr(:ncol,plev,sogb_ndx)
    1482             :        end if
    1483             :     end if
    1484           0 :     if( sogx_ndx > 0) then
    1485           0 :        if( has_dvel(sogx_ndx) ) then
    1486           0 :           dvel(:ncol,sogx_ndx) = dvel(:ncol,ch3cooh_ndx)
    1487           0 :           dflx(:ncol,sogx_ndx) = term(:ncol) * dvel(:ncol,sogx_ndx) * mmr(:ncol,plev,sogx_ndx)
    1488             :        end if
    1489             :     end if
    1490             : 
    1491       58824 :   end subroutine drydep_xactive
    1492             : 
    1493             :   !-------------------------------------------------------------------------------------
    1494             :   !-------------------------------------------------------------------------------------
    1495     1871160 :   function has_drydep( name )
    1496             : 
    1497             :     character(len=*), intent(in) :: name
    1498             : 
    1499             :     logical :: has_drydep
    1500             :     integer :: i
    1501             : 
    1502     1871160 :     has_drydep = .false.
    1503             : 
    1504    10321560 :     do i=1,nddvels
    1505    10321560 :        if ( trim(name) == trim(drydep_list(i)) ) then
    1506      301800 :          has_drydep = .true.
    1507      301800 :          exit
    1508             :        endif
    1509             :     enddo
    1510             : 
    1511       58824 :   endfunction has_drydep
    1512             : 
    1513           0 : end module mo_drydep

Generated by: LCOV version 1.14