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