#include <misc.h> #include <preproc.h> module filterMod 5,3 !----------------------------------------------------------------------- !BOP ! ! !MODULE: filterMod ! ! !DESCRIPTION: ! Module of filters used for processing columns and pfts of particular ! types, including lake, non-lake, urban, soil, snow, non-snow, and ! naturally-vegetated patches. ! ! !USES: use shr_kind_mod, only: r8 => shr_kind_r8 use abortutils, only : endrun use clm_varctl, only : iulog ! ! !PUBLIC TYPES: implicit none save private type clumpfilter #if (defined CNDV) integer, pointer :: natvegp(:) ! CNDV nat-vegetated (present) filter (pfts) integer :: num_natvegp ! number of pfts in nat-vegetated filter #endif integer, pointer :: lakep(:) ! lake filter (pfts) integer :: num_lakep ! number of pfts in lake filter integer, pointer :: nolakep(:) ! non-lake filter (pfts) integer :: num_nolakep ! number of pfts in non-lake filter integer, pointer :: lakec(:) ! lake filter (columns) integer :: num_lakec ! number of columns in lake filter integer, pointer :: nolakec(:) ! non-lake filter (columns) integer :: num_nolakec ! number of columns in non-lake filter integer, pointer :: soilc(:) ! soil filter (columns) integer :: num_soilc ! number of columns in soil filter integer, pointer :: soilp(:) ! soil filter (pfts) integer :: num_soilp ! number of pfts in soil filter integer, pointer :: snowc(:) ! snow filter (columns) integer :: num_snowc ! number of columns in snow filter integer, pointer :: nosnowc(:) ! non-snow filter (columns) integer :: num_nosnowc ! number of columns in non-snow filter integer, pointer :: hydrologyc(:) ! hydrology filter (columns) integer :: num_hydrologyc ! number of columns in hydrology filter integer, pointer :: urbanl(:) ! urban filter (landunits) integer :: num_urbanl ! number of landunits in urban filter integer, pointer :: nourbanl(:) ! non-urban filter (landunits) integer :: num_nourbanl ! number of landunits in non-urban filter integer, pointer :: urbanc(:) ! urban filter (columns) integer :: num_urbanc ! number of columns in urban filter integer, pointer :: nourbanc(:) ! non-urban filter (columns) integer :: num_nourbanc ! number of columns in non-urban filter integer, pointer :: urbanp(:) ! urban filter (pfts) integer :: num_urbanp ! number of pfts in urban filter integer, pointer :: nourbanp(:) ! non-urban filter (pfts) integer :: num_nourbanp ! number of pfts in non-urban filter integer, pointer :: nolakeurbanp(:) ! non-lake, non-urban filter (pfts) integer :: num_nolakeurbanp ! number of pfts in non-lake, non-urban filter end type clumpfilter public clumpfilter type(clumpfilter), allocatable, public :: filter(:) ! public allocFilters ! allocate memory for filters public setFilters ! set filters ! ! !REVISION HISTORY: ! Created by Mariana Vertenstein ! 11/13/03, Peter Thornton: Added soilp and num_soilp ! Jan/08, S. Levis: Added crop-related filters ! !EOP !----------------------------------------------------------------------- contains !------------------------------------------------------------------------ !BOP ! ! !IROUTINE: allocFilters ! ! !INTERFACE: subroutine allocFilters() 1,5 ! ! !DESCRIPTION: ! Allocate CLM filters. ! ! !USES: use clmtype use decompMod , only : get_proc_clumps, get_clump_bounds ! ! !ARGUMENTS: implicit none ! ! !REVISION HISTORY: ! Created by Mariana Vertenstein ! 2004.04.27 DGVM naturally-vegetated filter added by Forrest Hoffman ! !EOP ! ! LOCAL VARAIBLES: integer :: nc ! clump index integer :: nclumps ! total number of clumps on this processor integer :: begp, endp ! per-clump beginning and ending pft indices integer :: begc, endc ! per-clump beginning and ending column indices integer :: begl, endl ! per-clump beginning and ending landunit indices integer :: begg, endg ! per-clump beginning and ending gridcell indices integer :: ier ! error status !------------------------------------------------------------------------ ! Determine clump variables for this processor nclumps = get_proc_clumps() ier = 0 if( .not. allocated(filter)) then allocate(filter(nclumps), stat=ier) end if if (ier /= 0) then write(iulog,*) 'allocFilters(): allocation error for clumpsfilters' call endrun end if ! Loop over clumps on this processor !$OMP PARALLEL DO PRIVATE (nc,begg,endg,begl,endl,begc,endc,begp,endp) do nc = 1, nclumps call get_clump_bounds(nc, begg, endg, begl, endl, begc, endc, begp, endp) allocate(filter(nc)%lakep(endp-begp+1)) allocate(filter(nc)%nolakep(endp-begp+1)) allocate(filter(nc)%nolakeurbanp(endp-begp+1)) allocate(filter(nc)%lakec(endc-begc+1)) allocate(filter(nc)%nolakec(endc-begc+1)) allocate(filter(nc)%soilc(endc-begc+1)) allocate(filter(nc)%soilp(endp-begp+1)) allocate(filter(nc)%snowc(endc-begc+1)) allocate(filter(nc)%nosnowc(endc-begc+1)) #if (defined CNDV) allocate(filter(nc)%natvegp(endp-begp+1)) #endif allocate(filter(nc)%hydrologyc(endc-begc+1)) allocate(filter(nc)%urbanp(endp-begp+1)) allocate(filter(nc)%nourbanp(endp-begp+1)) allocate(filter(nc)%urbanc(endc-begc+1)) allocate(filter(nc)%nourbanc(endc-begc+1)) allocate(filter(nc)%urbanl(endl-begl+1)) allocate(filter(nc)%nourbanl(endl-begl+1)) end do !$OMP END PARALLEL DO end subroutine allocFilters !------------------------------------------------------------------------ !BOP ! ! !IROUTINE: setFilters ! ! !INTERFACE: subroutine setFilters() 3,5 ! ! !DESCRIPTION: ! Set CLM filters. ! ! !USES: use clmtype use decompMod , only : get_proc_clumps, get_clump_bounds use clm_varcon, only : istsoil, isturb, icol_road_perv, istice_mec ! ! !ARGUMENTS: implicit none ! ! !REVISION HISTORY: ! Created by Mariana Vertenstein ! 2004.04.27 DGVM naturally-vegetated filter added by Forrest Hoffman ! 2005.09.12 Urban related filters added by Mariana Vertenstein ! !EOP ! ! LOCAL VARAIBLES: integer , pointer :: ctype(:) ! column type integer :: nc ! clump index integer :: c,l,p ! column, landunit, pft indices integer :: nclumps ! total number of clumps on this processor integer :: fl ! lake filter index integer :: fnl,fnlu ! non-lake filter index integer :: fs ! soil filter index integer :: f, fn ! general indices integer :: begp, endp ! per-clump beginning and ending pft indices integer :: begc, endc ! per-clump beginning and ending column indices integer :: begl, endl ! per-clump beginning and ending landunit indices integer :: begg, endg ! per-clump beginning and ending gridcell indices !------------------------------------------------------------------------ ctype => clm3%g%l%c%itype ! Loop over clumps on this processor nclumps = get_proc_clumps() !$OMP PARALLEL DO PRIVATE (nc,begg,endg,begl,endl,begc,endc,begp,endp,f,fn,fl,fnl,fnlu,fs,p,c,l) do nc = 1,nclumps ! Determine clump boundaries call get_clump_bounds(nc, begg, endg, begl, endl, begc, endc, begp, endp) ! Create lake and non-lake filters at column-level fl = 0 fnl = 0 do c = begc,endc l = clm3%g%l%c%landunit(c) if (clm3%g%l%lakpoi(l)) then fl = fl + 1 filter(nc)%lakec(fl) = c else fnl = fnl + 1 filter(nc)%nolakec(fnl) = c end if end do filter(nc)%num_lakec = fl filter(nc)%num_nolakec = fnl ! Create lake and non-lake filters at pft-level ! Filter will only be active if weight of pft wrt gcell is nonzero fl = 0 fnl = 0 fnlu = 0 do p = begp,endp l = clm3%g%l%c%p%landunit(p) if (clm3%g%l%c%p%wtgcell(p) > 0._r8 & .or. & clm3%g%l%itype(l)==istice_mec) then ! some glacier_mec columns have zero weight l = clm3%g%l%c%p%landunit(p) if (clm3%g%l%lakpoi(l) ) then fl = fl + 1 filter(nc)%lakep(fl) = p else fnl = fnl + 1 filter(nc)%nolakep(fnl) = p if (clm3%g%l%itype(l) /= isturb) then fnlu = fnlu + 1 filter(nc)%nolakeurbanp(fnlu) = p end if end if end if end do filter(nc)%num_lakep = fl filter(nc)%num_nolakep = fnl filter(nc)%num_nolakeurbanp = fnlu ! Create soil filter at column-level fs = 0 do c = begc,endc l = clm3%g%l%c%landunit(c) if (clm3%g%l%itype(l) == istsoil) then fs = fs + 1 filter(nc)%soilc(fs) = c end if end do filter(nc)%num_soilc = fs ! Create soil filter at pft-level ! Filter will only be active if weight of pft wrt gcell is nonzero fs = 0 do p = begp,endp if (clm3%g%l%c%p%wtgcell(p) > 0._r8) then l = clm3%g%l%c%p%landunit(p) if (clm3%g%l%itype(l) == istsoil) then fs = fs + 1 filter(nc)%soilp(fs) = p end if end if end do filter(nc)%num_soilp = fs ! Create column-level hydrology filter (soil and Urban pervious road cols) f = 0 do c = begc,endc l = clm3%g%l%c%landunit(c) if (clm3%g%l%itype(l) == istsoil .or. ctype(c) == icol_road_perv ) then f = f + 1 filter(nc)%hydrologyc(f) = c end if end do filter(nc)%num_hydrologyc = f ! Create landunit-level urban and non-urban filters f = 0 fn = 0 do l = begl,endl if (clm3%g%l%itype(l) == isturb) then f = f + 1 filter(nc)%urbanl(f) = l else fn = fn + 1 filter(nc)%nourbanl(fn) = l end if end do filter(nc)%num_urbanl = f filter(nc)%num_nourbanl = fn ! Create column-level urban and non-urban filters f = 0 fn = 0 do c = begc,endc l = clm3%g%l%c%landunit(c) if (clm3%g%l%itype(l) == isturb) then f = f + 1 filter(nc)%urbanc(f) = c else fn = fn + 1 filter(nc)%nourbanc(fn) = c end if end do filter(nc)%num_urbanc = f filter(nc)%num_nourbanc = fn ! Create pft-level urban and non-urban filters f = 0 fn = 0 do p = begp,endp l = clm3%g%l%c%p%landunit(p) if (clm3%g%l%itype(l) == isturb .and. clm3%g%l%c%p%wtgcell(p) > 0._r8) then f = f + 1 filter(nc)%urbanp(f) = p else fn = fn + 1 filter(nc)%nourbanp(fn) = p end if end do filter(nc)%num_urbanp = f filter(nc)%num_nourbanp = fn ! Note: snow filters are reconstructed each time step in Hydrology2 ! Note: CNDV "pft present" filter is reconstructed each time CNDV is run end do !$OMP END PARALLEL DO end subroutine setFilters end module filterMod