LCOV - code coverage report
Current view: | top level - chemistry/utils - modal_aero_deposition.F90 (source / functions) |  |  | Hit | Total | Coverage
Test: | coverage.info |  | Lines: | 0 | 115 | 0.0 %
Date: | 2025-01-13 21:54:50 |  | Functions: | 0 | 4 | 0.0 %

              Line data    Source code
           1             : module modal_aero_deposition
           2             :
           3             : !------------------------------------------------------------------------------------------------
           4             : ! Purpose:
           5             : !
           6             : ! Partition the contributions from modal components of wet and dry
           7             : ! deposition at the surface into the fields passed to the coupler.
           8             : !
           9             : ! *** N.B. *** Currently only a simple scheme for the 3-mode version
          10             : !              of MAM has been implemented.
          11             : !
          12             : ! Revision history:
          13             : ! Feb 2009  M. Flanner, B. Eaton   Original version for trop_mam3.
          14             : ! Jul 2011  F Vitt -- made avaliable to be used in a prescribed modal aerosol mode (no prognostic MAM)
          15             : ! Mar 2012  F Vitt -- made changes for to prevent abort when 7-mode aeroslol model is used
          16             : !                     some of the needed consituents do not exist in 7-mode so bin_fluxes will be false
          17             : ! May 2014  F Vitt -- included contributions from MAM4 aerosols and added soa_a2 to the ocphiwet fluxes
          18             : !------------------------------------------------------------------------------------------------
          19             :
          20             : use shr_kind_mod,     only: r8 => shr_kind_r8
          21             : use camsrfexch,       only: cam_out_t
          22             : use constituents,     only: cnst_get_ind, pcnst
          23             : use cam_abortutils,   only: endrun
          24             : use rad_constituents, only: rad_cnst_get_info
          25             :
          26             : implicit none
          27             : private
          28             : save
          29             :
          30             : public :: &
          31             :    modal_aero_deposition_init, &
          32             :    set_srf_drydep,             &
          33             :    set_srf_wetdep
          34             :
          35             : ! Private module data
          36             :
          37             : logical :: initialized = .false.
          38             : integer :: bcphi_ndx( pcnst ) = -1
          39             : integer :: bcpho_ndx( pcnst ) = -1
          40             : integer :: ocphi_ndx( pcnst ) = -1
          41             : integer :: ocpho_ndx( pcnst ) = -1
          42             : integer :: crse_dust_ndx( pcnst ) = -1
          43             : integer :: fine_dust_ndx( pcnst ) = -1
          44             : integer :: bcphi_cnt = 0
          45             : integer :: ocphi_cnt = 0
          46             : integer :: bcpho_cnt = 0
          47             : integer :: ocpho_cnt = 0
          48             : integer :: crse_dust_cnt = 0
          49             : integer :: fine_dust_cnt = 0
          50             :
          51             : !==============================================================================
          52             : contains
          53             : !==============================================================================
          54             :
          55           0 : subroutine modal_aero_deposition_init( bcphi_indices, bcpho_indices, ocphi_indices, &
          56           0 :                                 ocpho_indices, fine_dust_indices, crse_dust_indices )
          57             :
          58             :   ! set aerosol indices for re-mapping surface deposition fluxes:
          59             :   ! *_a1 = accumulation mode
          60             :   ! *_a2 = aitken mode
          61             :   ! *_a3 = coarse mode
          62             :
          63             :   ! can be initialized with user specified indices
          64             :   ! if called from aerodep_flx module (for prescribed modal aerosol fluxes) then these indices are specified
          65             :   integer, optional, intent(in) :: bcphi_indices(:)     ! hydrophilic black carbon
          66             :   integer, optional, intent(in) :: bcpho_indices(:)     ! hydrophobic black carbon
          67             :   integer, optional, intent(in) :: ocphi_indices(:)     ! hydrophilic organic carbon
          68             :   integer, optional, intent(in) :: ocpho_indices(:)     ! hydrophobic organic carbon
          69             :   integer, optional, intent(in) :: fine_dust_indices(:) ! fine dust
          70             :   integer, optional, intent(in) :: crse_dust_indices(:) ! coarse dust
          71             :
          72             :   ! local vars
          73             :   integer :: i, pcnt, scnt
          74             :
          75             :   character(len=16), parameter :: fine_dust_modes(2) =  (/ 'accum           ', 'fine_dust       '/)
          76             :   character(len=16), parameter :: crse_dust_modes(2) =  (/ 'coarse          ', 'coarse_dust     '/)
          77             :   character(len=16), parameter :: hydrophilic_carbon_modes(1) = (/'accum           '/)
          78             :   character(len=16), parameter :: hydrophobic_carbon_modes(3) = (/'aitken          ',  'coarse          ', 'primary_carbon  '/)
          79             :
          80             :   ! if already initialized abort the run
          81           0 :   if (initialized) then
          82           0 :      call endrun('modal_aero_deposition is already initialized')
          83             :   endif
          84             :
          85           0 :   if (present(bcphi_indices)) then
          86           0 :      bcphi_cnt = size(bcphi_indices)
          87           0 :      bcphi_ndx(1:bcphi_cnt) = bcphi_indices (1:bcphi_cnt)
          88             :   else
          89           0 :      call get_indices( type='black-c', modes=hydrophilic_carbon_modes, indices=bcphi_ndx, count=bcphi_cnt )
          90             :   endif
          91           0 :   if (present(bcpho_indices)) then
          92           0 :      bcpho_cnt = size(bcpho_indices)
          93           0 :      bcpho_ndx(1:bcpho_cnt) = bcpho_indices (1:bcpho_cnt)
          94             :   else
          95           0 :      call get_indices( type='black-c', modes=hydrophobic_carbon_modes, indices=bcpho_ndx, count=bcpho_cnt )
          96             :   endif
          97             :
          98           0 :   if (present(ocphi_indices)) then
          99           0 :      ocphi_cnt = size(ocphi_indices)
         100           0 :      ocphi_ndx(1:ocphi_cnt) = ocphi_indices (1:ocphi_cnt)
         101             :   else
         102           0 :      call get_indices( type='s-organic', modes=hydrophilic_carbon_modes, indices=ocphi_ndx, count=pcnt )
         103           0 :      call get_indices( type='p-organic', modes=hydrophilic_carbon_modes, indices=ocphi_ndx(pcnt+1:), count=scnt )
         104           0 :      ocphi_cnt = pcnt+scnt
         105             :   endif
         106           0 :   if (present(ocpho_indices)) then
         107           0 :      ocpho_cnt = size(ocpho_indices)
         108           0 :      ocpho_ndx(1:ocpho_cnt) = ocpho_indices (1:ocpho_cnt)
         109             :   else
         110           0 :      call get_indices( type='s-organic', modes=hydrophobic_carbon_modes, indices=ocpho_ndx, count=pcnt )
         111           0 :      call get_indices( type='p-organic', modes=hydrophobic_carbon_modes, indices=ocpho_ndx(pcnt+1:), count=scnt )
         112           0 :      ocpho_cnt = pcnt+scnt
         113             :   endif
         114             :
         115           0 :   if (present(fine_dust_indices)) then
         116           0 :      fine_dust_cnt = size(fine_dust_indices)
         117           0 :      fine_dust_ndx(1:fine_dust_cnt) = fine_dust_indices(1:fine_dust_cnt)
         118             :   else
         119           0 :      call get_indices( type='dust', modes=fine_dust_modes, indices=fine_dust_ndx, count=fine_dust_cnt )
         120             :   endif
         121           0 :   if (present(crse_dust_indices)) then
         122           0 :      crse_dust_cnt = size(crse_dust_indices)
         123           0 :      crse_dust_ndx(1:crse_dust_cnt) = crse_dust_indices(1:crse_dust_cnt)
         124             :   else
         125           0 :      call get_indices( type='dust', modes=crse_dust_modes, indices=crse_dust_ndx, count=crse_dust_cnt )
         126             :   endif
         127             :
         128           0 :   initialized = .true.
         129             :
         130           0 : end subroutine modal_aero_deposition_init
         131             :
         132             : !==============================================================================
         133           0 : subroutine set_srf_wetdep(aerdepwetis, aerdepwetcw, cam_out)
         134             :
         135             : ! Set surface wet deposition fluxes passed to coupler.
         136             :
         137             :    ! Arguments:
         138             :    real(r8), intent(in) :: aerdepwetis(:,:)  ! aerosol wet deposition (interstitial)
         139             :    real(r8), intent(in) :: aerdepwetcw(:,:)  ! aerosol wet deposition (cloud water)
         140             :    type(cam_out_t), intent(inout) :: cam_out     ! cam export state
         141             :
         142             :    ! Local variables:
         143             :    integer :: i, ispec, idx
         144             :    integer :: ncol                      ! number of columns
         145             :
         146             :    real(r8) :: bcphiwet_sum, ocphiwet_sum
         147             :    !----------------------------------------------------------------------------
         148             :
         149           0 :   if (.not.initialized) call endrun('set_srf_wetdep: modal_aero_deposition has not been initialized')
         150             :
         151           0 :    ncol = cam_out%ncol
         152             :
         153           0 :    cam_out%bcphiwet(:) = 0._r8
         154           0 :    cam_out%ocphiwet(:) = 0._r8
         155             :
         156             :    ! derive cam_out variables from deposition fluxes
         157             :    !  note: wet deposition fluxes are negative into surface,
         158             :    !        dry deposition fluxes are positive into surface.
         159             :    !        srf models want positive definite fluxes.
         160           0 :    do i = 1, ncol
         161             :
         162             :       ! black carbon fluxes
         163           0 :       do ispec=1,bcphi_cnt
         164           0 :          cam_out%bcphiwet(i) = cam_out%bcphiwet(i) &
         165           0 :                              - (aerdepwetis(i,bcphi_ndx(ispec))+aerdepwetcw(i,bcphi_ndx(ispec)))
         166             :       enddo
         167           0 :       do ispec=1,bcpho_cnt
         168           0 :          cam_out%bcphiwet(i) = cam_out%bcphiwet(i) &
         169           0 :                              - (aerdepwetis(i,bcpho_ndx(ispec))+aerdepwetcw(i,bcpho_ndx(ispec)))
         170             :       enddo
         171             :
         172             :       ! organic carbon fluxes
         173           0 :       do ispec=1,ocphi_cnt
         174           0 :          cam_out%ocphiwet(i) = cam_out%ocphiwet(i) &
         175           0 :                              - (aerdepwetis(i,ocphi_ndx(ispec))+aerdepwetcw(i,ocphi_ndx(ispec)))
         176             :       enddo
         177           0 :       do ispec=1,ocpho_cnt
         178           0 :          cam_out%ocphiwet(i) = cam_out%ocphiwet(i) &
         179           0 :                              - (aerdepwetis(i,ocpho_ndx(ispec))+aerdepwetcw(i,ocpho_ndx(ispec)))
         180             :       enddo
         181             :
         182             :       ! dust fluxes
         183           0 :       cam_out%dstwet1(i) = 0._r8
         184           0 :       cam_out%dstwet2(i) = 0._r8
         185           0 :       cam_out%dstwet3(i) = 0._r8
         186           0 :       cam_out%dstwet4(i) = 0._r8
         187             :
         188             :       ! bulk bin1 (fine) dust deposition equals accumulation mode deposition:
         189           0 :       do ispec=1,fine_dust_cnt
         190             :          cam_out%dstwet1(i) = cam_out%dstwet1(i) &
         191           0 :                             -(aerdepwetis(i,fine_dust_ndx(ispec))+aerdepwetcw(i,fine_dust_ndx(ispec)))
         192             :       enddo
         193             :
         194             :       !  Assign all coarse-mode dust to bulk size bin 3:
         195           0 :       do ispec=1,crse_dust_cnt
         196             :          cam_out%dstwet3(i) = cam_out%dstwet3(i) &
         197           0 :                             -(aerdepwetis(i,crse_dust_ndx(ispec))+aerdepwetcw(i,crse_dust_ndx(ispec)))
         198             :       enddo
         199             :
         200             :       ! in rare cases, integrated deposition tendency is upward
         201           0 :       if (cam_out%bcphiwet(i) .lt. 0._r8) cam_out%bcphiwet(i) = 0._r8
         202           0 :       if (cam_out%ocphiwet(i) .lt. 0._r8) cam_out%ocphiwet(i) = 0._r8
         203           0 :       if (cam_out%dstwet1(i)  .lt. 0._r8) cam_out%dstwet1(i)  = 0._r8
         204           0 :       if (cam_out%dstwet3(i)  .lt. 0._r8) cam_out%dstwet3(i)  = 0._r8
         205             :    enddo
         206             :
         207           0 : end subroutine set_srf_wetdep
         208             :
         209             : !==============================================================================
         210             :
         211           0 : subroutine set_srf_drydep(aerdepdryis, aerdepdrycw, cam_out)
         212             :
         213             : ! Set surface dry deposition fluxes passed to coupler.
         214             :
         215             :    ! Arguments:
         216             :    real(r8), intent(in) :: aerdepdryis(:,:)  ! aerosol dry deposition (interstitial)
         217             :    real(r8), intent(in) :: aerdepdrycw(:,:)  ! aerosol dry deposition (cloud water)
         218             :    type(cam_out_t), intent(inout) :: cam_out     ! cam export state
         219             :
         220             :    ! Local variables:
         221             :    integer :: i, ispec, idx
         222             :    integer :: ncol                      ! number of columns
         223             :    real(r8):: bcphidry_sum, ocphidry_sum, ocphodry_sum
         224             :    !----------------------------------------------------------------------------
         225             :
         226           0 :    if (.not.initialized) call endrun('set_srf_drydep: modal_aero_deposition has not been initialized')
         227             :
         228           0 :    ncol = cam_out%ncol
         229             :
         230           0 :    cam_out%bcphidry(:) = 0._r8
         231           0 :    cam_out%bcphodry(:) = 0._r8
         232           0 :    cam_out%ocphidry(:) = 0._r8
         233           0 :    cam_out%ocphodry(:) = 0._r8
         234             :
         235             :    ! derive cam_out variables from deposition fluxes
         236             :    !  note: wet deposition fluxes are negative into surface,
         237             :    !        dry deposition fluxes are positive into surface.
         238             :    !        srf models want positive definite fluxes.
         239           0 :    do i = 1, ncol
         240             :
         241             :       ! black carbon fluxes
         242           0 :       do ispec=1,bcphi_cnt
         243           0 :          cam_out%bcphidry(i) = cam_out%bcphidry(i) &
         244           0 :                              + (aerdepdryis(i,bcphi_ndx(ispec))+aerdepdrycw(i,bcphi_ndx(ispec)))
         245             :       enddo
         246           0 :       do ispec=1,bcpho_cnt
         247           0 :          cam_out%bcphodry(i) = cam_out%bcphodry(i) &
         248           0 :                              + (aerdepdryis(i,bcpho_ndx(ispec))+aerdepdrycw(i,bcpho_ndx(ispec)))
         249             :       enddo
         250             :
         251             :       ! organic carbon fluxes
         252           0 :       do ispec=1,ocphi_cnt
         253           0 :          cam_out%ocphidry(i) = cam_out%ocphidry(i) &
         254           0 :                              + (aerdepdryis(i,ocphi_ndx(ispec))+aerdepdrycw(i,ocphi_ndx(ispec)))
         255             :       enddo
         256           0 :       do ispec=1,ocpho_cnt
         257           0 :          cam_out%ocphodry(i) = cam_out%ocphodry(i) &
         258           0 :                              + (aerdepdryis(i,ocpho_ndx(ispec))+aerdepdrycw(i,ocpho_ndx(ispec)))
         259             :       enddo
         260             :
         261             :       ! dust fluxes
         262           0 :       cam_out%dstdry1(i) = 0._r8
         263           0 :       cam_out%dstdry2(i) = 0._r8
         264           0 :       cam_out%dstdry3(i) = 0._r8
         265           0 :       cam_out%dstdry4(i) = 0._r8
         266             :       ! bulk bin1 (fine) dust deposition equals accumulation mode deposition:
         267           0 :       do ispec=1,fine_dust_cnt
         268             :          cam_out%dstdry1(i) = cam_out%dstdry1(i) &
         269           0 :                             + (aerdepdryis(i,fine_dust_ndx(ispec))+aerdepdrycw(i,fine_dust_ndx(ispec)))
         270             :       enddo
         271             :       !  Assign all coarse-mode dust to bulk size bin 3:
         272           0 :       do ispec=1,crse_dust_cnt
         273             :          cam_out%dstdry3(i) = cam_out%dstdry3(i) &
         274           0 :                             + (aerdepdryis(i,crse_dust_ndx(ispec))+aerdepdrycw(i,crse_dust_ndx(ispec)))
         275             :       enddo
         276             :
         277             :       ! in rare cases, integrated deposition tendency is upward
         278           0 :       if (cam_out%bcphidry(i) .lt. 0._r8) cam_out%bcphidry(i) = 0._r8
         279           0 :       if (cam_out%bcphodry(i) .lt. 0._r8) cam_out%bcphodry(i) = 0._r8
         280           0 :       if (cam_out%ocphidry(i) .lt. 0._r8) cam_out%ocphidry(i) = 0._r8
         281           0 :       if (cam_out%ocphodry(i) .lt. 0._r8) cam_out%ocphodry(i) = 0._r8
         282           0 :       if (cam_out%dstdry1(i)  .lt. 0._r8) cam_out%dstdry1(i)  = 0._r8
         283           0 :       if (cam_out%dstdry3(i)  .lt. 0._r8) cam_out%dstdry3(i)  = 0._r8
         284             :    enddo
         285             :
         286           0 : end subroutine set_srf_drydep
         287             :
         288             : !==============================================================================
         289           0 : subroutine get_indices( type, modes, indices, count )
         290             :
         291             :   character(len=*), intent(in) :: type
         292             :   character(len=*), intent(in) :: modes(:)
         293             :   integer, intent(out) :: indices(:)
         294             :   integer, intent(out) :: count
         295             :
         296             :   integer :: l, n, ndx, nmodes, nspec
         297             :   character(len=32) :: spec_type, spec_name, mode_type
         298             :
         299           0 :   call rad_cnst_get_info(0, nmodes=nmodes)
         300             :
         301           0 :   count = 0
         302           0 :   indices(:) = -1
         303             :
         304           0 :   if (nmodes==7) return ! historically turned off for mam7
         305             :
         306           0 :   do n = 1, nmodes
         307             :
         308           0 :      call rad_cnst_get_info(0, n, mode_type=mode_type, nspec=nspec)
         309             :
         310           0 :      if ( any(modes==trim(mode_type)) ) then
         311             :
         312           0 :         do l = 1,nspec
         313           0 :            call rad_cnst_get_info(0, n, l, spec_type=spec_type, spec_name=spec_name)
         314           0 :            call cnst_get_ind(spec_name, ndx, abort=.false.)
         315           0 :            if (ndx>0) then
         316           0 :               if (trim(spec_type) == trim(type)) then
         317           0 :                  count = count+1
         318           0 :                  indices(count) = ndx
         319             :               endif
         320             :            endif
         321             :         enddo
         322             :
         323             :      endif
         324             :
         325             :   enddo
         326             :
         327             : end subroutine get_indices
         328             : !==============================================================================
         329             :
         330             : end module modal_aero_deposition

Generated by: LCOV version 1.14