module modal_aero_deposition !------------------------------------------------------------------------------------------------ ! Purpose: ! ! Partition the contributions from modal components of wet and dry ! deposition at the surface into the fields passed to the coupler. ! ! *** N.B. *** Currently only a simple scheme for the 3-mode version ! of MAM has been implemented. ! ! Revision history: ! Feb 2009 M. Flanner, B. Eaton Original version for trop_mam3. ! Jul 2011 F Vitt -- made avaliable to be used in a prescribed modal aerosol mode (no prognostic MAM) ! Mar 2012 F Vitt -- made changes for to prevent abort when 7-mode aeroslol model is used ! some of the needed consituents do not exist in 7-mode so bin_fluxes will be false ! May 2014 F Vitt -- included contributions from MAM4 aerosols and added soa_a2 to the ocphiwet fluxes !------------------------------------------------------------------------------------------------ use shr_kind_mod, only: r8 => shr_kind_r8 use camsrfexch, only: cam_out_t use constituents, only: pcnst, cnst_get_ind use ppgrid, only: pcols use cam_abortutils, only: endrun use modal_aero_data, only: nsoa, npoa, nbc, soaSpecName, poaSpecName, bcSpecName, & nnvsoa, nvsoaSpecName implicit none private save public :: & modal_aero_deposition_init, & set_srf_drydep, & set_srf_wetdep ! Private module data !BSINGH - indices needed for extended version of MAM integer :: idx_bc1(1:nbc) = -1 integer :: idx_pom1(1:npoa) = -1 integer :: idx_soa1(1:nsoa) = -1 integer :: idx_soa2(1:nsoa) = -1 integer :: idx_nvsoa1(1:nnvsoa) = -1 integer :: idx_nvsoa2(1:nnvsoa) = -1 !BSINGH - Common species integer :: idx_dst1 = -1 integer :: idx_dst3 = -1 integer :: idx_ncl3 = -1 integer :: idx_so43 = -1 integer :: idx_num3 = -1 !logical :: bin_fluxes = .false. !logical :: initialized = .false. !============================================================================== contains !============================================================================== !subroutine modal_aero_deposition_init(bc1_ndx,pom1_ndx,soa1_ndx,soa2_ndx,dst1_ndx, & !dst3_ndx,ncl3_ndx,so43_ndx,num3_ndx,bc4_ndx,pom4_ndx) subroutine modal_aero_deposition_init() !Local variables integer :: i character(len = 1000) :: msg !BSINGH - msg string for endrun calls ! set aerosol indices for re-mapping surface deposition fluxes: ! *_a1 = accumulation mode ! *_a2 = aitken mode ! *_a3 = coarse mode ! can be initialized with user specified indices ! if called from aerodep_flx module (for prescribed modal aerosol fluxes) then these indices are specified ! Currently only trop_mam3 scheme is implemented. #ifndef MODAL_AERO_3MODE return #endif !BSINGH - checks for bounds of NBC and NPOA exist in the configure file do i = 1, nbc call cnst_get_ind(trim(bcSpecName(i))//'_a1', idx_bc1(i)) enddo do i = 1, npoa call cnst_get_ind(trim(poaSpecName(i))//'_a1', idx_pom1(i)) enddo do i = 1, nsoa call cnst_get_ind(trim(soaSpecName(i))//'_a1', idx_soa1(i)) call cnst_get_ind(trim(soaSpecName(i))//'_a2', idx_soa2(i)) enddo do i = 1, nnvsoa call cnst_get_ind(trim(nvsoaSpecName(i))//'_a1', idx_nvsoa1(i)) call cnst_get_ind(trim(nvsoaSpecName(i))//'_a2', idx_nvsoa2(i)) enddo call cnst_get_ind('dst_a1', idx_dst1) call cnst_get_ind('dst_a3', idx_dst3) call cnst_get_ind('ncl_a3', idx_ncl3) call cnst_get_ind('so4_a3', idx_so43) call cnst_get_ind('num_a3', idx_num3) ! integer, optional, intent(in) :: bc1_ndx,pom1_ndx,soa1_ndx,soa2_ndx,dst1_ndx,dst3_ndx,ncl3_ndx,so43_ndx,num3_ndx ! integer, optional, intent(in) :: bc4_ndx,pom4_ndx ! ! ! if already initialized abort the run ! if (initialized) then ! call endrun('modal_aero_deposition_init is already initialized') ! endif ! ! if (present(bc1_ndx)) then ! idx_bc1 = bc1_ndx ! else ! call cnst_get_ind('bc_a1', idx_bc1) ! endif ! if (present(pom1_ndx)) then ! idx_pom1 = pom1_ndx ! else ! call cnst_get_ind('pom_a1', idx_pom1) ! endif ! if (present(soa1_ndx)) then ! idx_soa1 = soa1_ndx ! else ! call cnst_get_ind('soa_a1', idx_soa1) ! endif ! if (present(soa2_ndx)) then ! idx_soa2 = soa2_ndx ! else ! call cnst_get_ind('soa_a2', idx_soa2) ! endif ! if (present(dst1_ndx)) then ! idx_dst1 = dst1_ndx ! else ! call cnst_get_ind('dst_a1', idx_dst1,abort=.false.) ! endif ! if (present(dst3_ndx)) then ! idx_dst3 = dst3_ndx ! else ! call cnst_get_ind('dst_a3', idx_dst3,abort=.false.) ! endif ! if (present(ncl3_ndx)) then ! idx_ncl3 = ncl3_ndx ! else ! call cnst_get_ind('ncl_a3', idx_ncl3,abort=.false.) ! endif ! if (present(so43_ndx)) then ! idx_so43 = so43_ndx ! else ! call cnst_get_ind('so4_a3', idx_so43,abort=.false.) ! endif ! if (present(bc4_ndx)) then ! idx_bc4 = bc4_ndx ! else ! call cnst_get_ind('bc_a4', idx_bc4,abort=.false.) ! endif ! if (present(pom4_ndx)) then ! idx_pom4 = pom4_ndx ! else ! call cnst_get_ind('pom_a4', idx_pom4,abort=.false.) ! endif ! !! for 7 mode bin_fluxes will be false ! bin_fluxes = idx_dst1>0 .and. idx_dst3>0 .and.idx_ncl3>0 .and. idx_so43>0 ! initialized = .true. end subroutine modal_aero_deposition_init !============================================================================== subroutine set_srf_wetdep(aerdepwetis, aerdepwetcw, cam_out) ! Set surface wet deposition fluxes passed to coupler. ! Arguments: real(r8), intent(in) :: aerdepwetis(:,:) ! aerosol wet deposition (interstitial) real(r8), intent(in) :: aerdepwetcw(:,:) ! aerosol wet deposition (cloud water) type(cam_out_t), intent(inout) :: cam_out ! cam export state ! Local variables: integer :: i, ispec integer :: ncol ! number of columns real(r8) :: bcphiwet_sum, ocphiwet_sum !---------------------------------------------------------------------------- ! Currently only trop_mam3 scheme is implemented. #ifndef MODAL_AERO_3MODE return #endif ncol = cam_out%ncol ! derive cam_out variables from deposition fluxes ! note: wet deposition fluxes are negative into surface, ! dry deposition fluxes are positive into surface. ! CLM wants positive definite fluxes. do i = 1, ncol ! black carbon fluxes bcphiwet_sum = 0.0_r8 do ispec = 1, nbc bcphiwet_sum = bcphiwet_sum + aerdepwetis(i,idx_bc1(ispec))+aerdepwetcw(i,idx_bc1(ispec)) enddo cam_out%bcphiwet(i) = -(bcphiwet_sum) ! organic carbon fluxes ocphiwet_sum = 0.0_r8 do ispec = 1, npoa ocphiwet_sum = ocphiwet_sum + aerdepwetis(i,idx_pom1(ispec))+aerdepwetcw(i,idx_pom1(ispec)) enddo do ispec = 1, nsoa ocphiwet_sum = ocphiwet_sum + aerdepwetis(i,idx_soa1(ispec))+aerdepwetcw(i,idx_soa1(ispec)) enddo do ispec = 1, nnvsoa ocphiwet_sum = ocphiwet_sum + aerdepwetis(i,idx_nvsoa1(ispec))+aerdepwetcw(i,idx_nvsoa1(ispec)) enddo cam_out%ocphiwet(i)= - (ocphiwet_sum) ! dust fluxes ! ! bulk bin1 (fine) dust deposition equals accumulation mode deposition: cam_out%dstwet1(i) = -(aerdepwetis(i,idx_dst1)+aerdepwetcw(i,idx_dst1)) ! A. Simple: Assign all coarse-mode dust to bulk size bin 3: cam_out%dstwet2(i) = 0._r8 cam_out%dstwet3(i) = -(aerdepwetis(i,idx_dst3)+aerdepwetcw(i,idx_dst3)) cam_out%dstwet4(i) = 0._r8 ! in rare cases, integrated deposition tendency is upward if (cam_out%bcphiwet(i) .lt. 0._r8) cam_out%bcphiwet(i) = 0._r8 if (cam_out%ocphiwet(i) .lt. 0._r8) cam_out%ocphiwet(i) = 0._r8 if (cam_out%dstwet1(i) .lt. 0._r8) cam_out%dstwet1(i) = 0._r8 if (cam_out%dstwet3(i) .lt. 0._r8) cam_out%dstwet3(i) = 0._r8 enddo ! if (.not.bin_fluxes) return ! ! ncol = cam_out%ncol ! ! cam_out%bcphiwet(:) = 0._r8 ! cam_out%ocphiwet(:) = 0._r8 ! ! ! derive cam_out variables from deposition fluxes ! ! note: wet deposition fluxes are negative into surface, ! ! dry deposition fluxes are positive into surface. ! ! srf models want positive definite fluxes. ! do i = 1, ncol ! ! ! black carbon fluxes ! if (idx_bc1>0) & ! cam_out%bcphiwet(i) = cam_out%bcphiwet(i) -(aerdepwetis(i,idx_bc1)+aerdepwetcw(i,idx_bc1)) ! if (idx_bc4>0) & ! cam_out%bcphiwet(i) = cam_out%bcphiwet(i) -(aerdepwetis(i,idx_bc4)+aerdepwetcw(i,idx_bc4)) ! ! ! organic carbon fluxes ! if (idx_soa1>0) & ! cam_out%ocphiwet(i) = cam_out%ocphiwet(i) -(aerdepwetis(i,idx_soa1)+aerdepwetcw(i,idx_soa1)) ! if (idx_soa2>0) & ! cam_out%ocphiwet(i) = cam_out%ocphiwet(i) -(aerdepwetis(i,idx_soa2)+aerdepwetcw(i,idx_soa2)) ! if (idx_pom1>0) & ! cam_out%ocphiwet(i) = cam_out%ocphiwet(i) -(aerdepwetis(i,idx_pom1)+aerdepwetcw(i,idx_pom1)) ! if (idx_pom4>0) & ! cam_out%ocphiwet(i) = cam_out%ocphiwet(i) -(aerdepwetis(i,idx_pom4)+aerdepwetcw(i,idx_pom4)) ! ! ! dust fluxes ! ! ! ! bulk bin1 (fine) dust deposition equals accumulation mode deposition: ! cam_out%dstwet1(i) = -(aerdepwetis(i,idx_dst1)+aerdepwetcw(i,idx_dst1)) ! ! ! A. Simple: Assign all coarse-mode dust to bulk size bin 3: ! cam_out%dstwet2(i) = 0._r8 ! cam_out%dstwet3(i) = -(aerdepwetis(i,idx_dst3)+aerdepwetcw(i,idx_dst3)) ! cam_out%dstwet4(i) = 0._r8 ! ! ! in rare cases, integrated deposition tendency is upward ! if (cam_out%bcphiwet(i) .lt. 0._r8) cam_out%bcphiwet(i) = 0._r8 ! if (cam_out%ocphiwet(i) .lt. 0._r8) cam_out%ocphiwet(i) = 0._r8 ! if (cam_out%dstwet1(i) .lt. 0._r8) cam_out%dstwet1(i) = 0._r8 ! if (cam_out%dstwet3(i) .lt. 0._r8) cam_out%dstwet3(i) = 0._r8 ! enddo end subroutine set_srf_wetdep !============================================================================== subroutine set_srf_drydep(aerdepdryis, aerdepdrycw, cam_out) ! Set surface dry deposition fluxes passed to coupler. ! Arguments: real(r8), intent(in) :: aerdepdryis(:,:) ! aerosol dry deposition (interstitial) real(r8), intent(in) :: aerdepdrycw(:,:) ! aerosol dry deposition (cloud water) type(cam_out_t), intent(inout) :: cam_out ! cam export state ! Local variables: integer :: i, ispec integer :: ncol ! number of columns real(r8):: bcphidry_sum, ocphidry_sum, ocphodry_sum !---------------------------------------------------------------------------- ! if (.not.bin_fluxes) return ! ncol = cam_out%ncol ! ! cam_out%bcphidry(:) = 0._r8 ! cam_out%bcphodry(:) = 0._r8 ! cam_out%ocphidry(:) = 0._r8 ! cam_out%ocphodry(:) = 0._r8 ! ! ! derive cam_out variables from deposition fluxes ! ! note: wet deposition fluxes are negative into surface, ! ! dry deposition fluxes are positive into surface. ! ! srf models want positive definite fluxes. ! do i = 1, ncol ! ! ! black carbon fluxes ! if (idx_bc1>0) & ! cam_out%bcphidry(i) = cam_out%bcphidry(i) + aerdepdryis(i,idx_bc1)+aerdepdrycw(i,idx_bc1) ! if (idx_bc4>0) & ! cam_out%bcphodry(i) = cam_out%bcphodry(i) + aerdepdryis(i,idx_bc4)+aerdepdrycw(i,idx_bc4) ! ! ! organic carbon fluxes ! if (idx_pom1>0) & ! cam_out%ocphidry(i) = cam_out%ocphidry(i) + aerdepdryis(i,idx_pom1)+aerdepdrycw(i,idx_pom1) ! if( idx_pom4>0) & ! cam_out%ocphodry(i) = cam_out%ocphodry(i) + aerdepdryis(i,idx_pom4)+aerdepdrycw(i,idx_pom4) ! if (idx_soa1>0) & ! cam_out%ocphidry(i) = cam_out%ocphidry(i) + aerdepdryis(i,idx_soa1)+aerdepdrycw(i,idx_soa1) ! if (idx_soa2>0) & ! cam_out%ocphodry(i) = cam_out%ocphodry(i) + aerdepdryis(i,idx_soa2)+aerdepdrycw(i,idx_soa2) ! ! ! dust fluxes ! ! ! ! bulk bin1 (fine) dust deposition equals accumulation mode deposition: ! cam_out%dstdry1(i) = aerdepdryis(i,idx_dst1)+aerdepdrycw(i,idx_dst1) ! ! ! Two options for partitioning deposition into bins 2-4: ! ! A. Simple: Assign all coarse-mode dust to bulk size bin 3: ! cam_out%dstdry2(i) = 0._r8 ! cam_out%dstdry3(i) = aerdepdryis(i,idx_dst3)+aerdepdrycw(i,idx_dst3) ! cam_out%dstdry4(i) = 0._r8 ! ! ! in rare cases, integrated deposition tendency is upward ! if (cam_out%bcphidry(i) .lt. 0._r8) cam_out%bcphidry(i) = 0._r8 ! if (cam_out%bcphodry(i) .lt. 0._r8) cam_out%bcphodry(i) = 0._r8 ! if (cam_out%ocphidry(i) .lt. 0._r8) cam_out%ocphidry(i) = 0._r8 ! if (cam_out%ocphodry(i) .lt. 0._r8) cam_out%ocphodry(i) = 0._r8 ! if (cam_out%dstdry1(i) .lt. 0._r8) cam_out%dstdry1(i) = 0._r8 ! if (cam_out%dstdry3(i) .lt. 0._r8) cam_out%dstdry3(i) = 0._r8 ! enddo #ifndef MODAL_AERO_3MODE return #endif ncol = cam_out%ncol ! derive cam_out variables from deposition fluxes ! note: wet deposition fluxes are negative into surface, ! dry deposition fluxes are positive into surface. ! CLM wants positive definite fluxes. do i = 1, ncol ! black carbon fluxes cam_out%bcphodry(i) = 0._r8 bcphidry_sum = 0.0_r8 do ispec = 1, nbc bcphidry_sum = bcphidry_sum + aerdepdryis(i,idx_bc1(ispec))+aerdepdrycw(i,idx_bc1(ispec)) enddo cam_out%bcphidry(i) = bcphidry_sum ! organic carbon fluxes ocphidry_sum = 0.0_r8 do ispec = 1, npoa ocphidry_sum = ocphidry_sum + aerdepdryis(i,idx_pom1(ispec))+aerdepdrycw(i,idx_pom1(ispec)) enddo do ispec = 1, nsoa ocphidry_sum = ocphidry_sum + aerdepdryis(i,idx_soa1(ispec)) + aerdepdrycw(i,idx_soa1(ispec)) enddo do ispec = 1, nnvsoa ocphidry_sum = ocphidry_sum + aerdepdryis(i,idx_nvsoa1(ispec)) + aerdepdrycw(i,idx_nvsoa1(ispec)) enddo cam_out%ocphidry(i) = ocphidry_sum ocphodry_sum = 0.0_r8 do ispec = 1, nsoa ocphodry_sum = ocphodry_sum + aerdepdryis(i,idx_soa2(ispec))+aerdepdrycw(i,idx_soa2(ispec)) enddo do ispec = 1, nnvsoa ocphodry_sum = ocphodry_sum + aerdepdryis(i,idx_nvsoa2(ispec))+aerdepdrycw(i,idx_nvsoa2(ispec)) enddo cam_out%ocphodry(i) = ocphodry_sum ! dust fluxes ! ! bulk bin1 (fine) dust deposition equals accumulation mode deposition: cam_out%dstdry1(i) = aerdepdryis(i,idx_dst1)+aerdepdrycw(i,idx_dst1) ! Two options for partitioning deposition into bins 2-4: ! A. Simple: Assign all coarse-mode dust to bulk size bin 3: cam_out%dstdry2(i) = 0._r8 cam_out%dstdry3(i) = aerdepdryis(i,idx_dst3)+aerdepdrycw(i,idx_dst3) cam_out%dstdry4(i) = 0._r8 ! in rare cases, integrated deposition tendency is upward if (cam_out%bcphidry(i) .lt. 0._r8) cam_out%bcphidry(i) = 0._r8 if (cam_out%bcphodry(i) .lt. 0._r8) cam_out%bcphodry(i) = 0._r8 if (cam_out%ocphidry(i) .lt. 0._r8) cam_out%ocphidry(i) = 0._r8 if (cam_out%ocphodry(i) .lt. 0._r8) cam_out%ocphodry(i) = 0._r8 if (cam_out%dstdry1(i) .lt. 0._r8) cam_out%dstdry1(i) = 0._r8 if (cam_out%dstdry3(i) .lt. 0._r8) cam_out%dstdry3(i) = 0._r8 enddo end subroutine set_srf_drydep !============================================================================== end module modal_aero_deposition