#include <misc.h>
#include <preproc.h>
module domainMod 45,5
!-----------------------------------------------------------------------
!BOP
!
! !MODULE: domainMod
!
! !DESCRIPTION:
! Module containing 2-d global surface boundary data information
!
! !USES:
use shr_kind_mod
, only : r8 => shr_kind_r8
use nanMod
use spmdMod
, only : masterproc
use abortutils
, only : endrun
use clm_varctl
, only : iulog
!
! !PUBLIC TYPES:
implicit none
private
!
public :: domain_type
public :: latlon_type
!--- this typically contains local domain info with arrays dim begg:endg ---
type domain_type
integer :: ns ! global size of domain
integer :: ni,nj ! global axis if 2d (nj=1 if unstructured)
integer :: nbeg,nend ! local beg/end indices
character(len=8) :: clmlevel ! grid type
logical :: decomped ! decomposed locally or global copy
logical :: regional ! regional or global grid
logical :: areaset ! has area been set
integer ,pointer :: mask(:) ! land mask: 1 = land, 0 = ocean
real(r8),pointer :: frac(:) ! fractional land
real(r8),pointer :: topo(:) ! topography
real(r8),pointer :: latc(:) ! latitude of grid cell (deg)
real(r8),pointer :: lonc(:) ! longitude of grid cell (deg)
real(r8),pointer :: area(:) ! grid cell area (km**2)
real(r8),pointer :: asca(:) ! area scaling from CCSM driver
character*16 :: set ! flag to check if domain is set
integer ,pointer :: glcmask(:) ! glc mask: 1=sfc mass balance required by GLC component
! 0=SMB not required (default)
!--- following are valid only for land domain ---
integer ,pointer :: pftm(:) ! pft mask: 1=real, 0=fake, -1=notset
real(r8),pointer :: nara(:) ! normalized area in upscaling (km**2),
real(r8),pointer :: ntop(:) ! normalized topo for downscaling (m)
end type domain_type
!--- this contains global info about a grid, lats and lons are 1d
!--- global arrays of size ni or nj which assume regular lat/lon grids only
type latlon_type
integer :: ns ! global size of domain
integer :: ni,nj ! global axis if 2d (nj=1 if unstructured)
character*16 :: set ! flag to check if domain is set
logical :: regional ! regional or global grid
real(r8) :: edges(4) ! global edges (N,E,S,W)
real(r8),pointer :: latc(:) ! latitude of 1d grid cell (deg)
real(r8),pointer :: lonc(:) ! longitude of 1d grid cell (deg)
real(r8),pointer :: lats(:) ! latitude of 1d south grid cell edge (deg)
real(r8),pointer :: latn(:) ! latitude of 1d north grid cell edge (deg)
real(r8),pointer :: lonw(:) ! longitude of 1d west grid cell edge (deg)
real(r8),pointer :: lone(:) ! longitude of 1d east grid cell edge (deg)
end type latlon_type
type(domain_type),public :: adomain
type(domain_type),public :: ldomain
type(latlon_type),public :: alatlon
type(latlon_type),public :: llatlon
integer ,pointer,public :: gatm(:) ! gatm pulled out of domain
integer ,pointer,public :: amask(:) ! global atm mask
integer, pointer,public :: pftm(:) ! pft mask for lnd grid
!
! !PUBLIC MEMBER FUNCTIONS:
public domain_init ! allocates/nans domain types
public domain_clean ! deallocates domain types
public domain_setsame ! copy one domain to another
public domain_setptrs ! sets external pointer arrays into domain
public domain_check ! write out domain info
public latlon_init ! allocates/nans domain types
public latlon_check ! write out domain info
public latlon_clean ! deallocate domain info
public latlon_setsame ! copy one domain to another
!
!
! !REVISION HISTORY:
! Originally clm_varsur by Mariana Vertenstein
! Migrated from clm_varsur to domainMod by T Craig
!
character*16,parameter :: set = 'domain_set '
character*16,parameter :: unset = 'NOdomain_unsetNO'
!
!EOP
!------------------------------------------------------------------------------
contains
!------------------------------------------------------------------------------
!BOP
!
! !IROUTINE: domain_init
!
! !INTERFACE:
subroutine domain_init(domain,ni,nj,nbeg,nend,clmlevel) 1,2
!
! !DESCRIPTION:
! This subroutine allocates and nans the domain type
!
! !USES:
!
! !ARGUMENTS:
implicit none
type(domain_type) :: domain ! domain datatype
integer :: ni,nj ! grid size, 2d
integer,optional :: nbeg,nend ! beg/end indices
character(len=*),optional:: clmlevel ! grid type
!
! !REVISION HISTORY:
! Created by T Craig
!
!
! !LOCAL VARIABLES:
!EOP
integer ier
integer nb,ne
!
!------------------------------------------------------------------------------
nb = 1
ne = ni*nj
if (present(nbeg)) then
if (present(nend)) then
nb = nbeg
ne = nend
endif
endif
if (domain%set == set) then
call domain_clean
(domain)
endif
allocate(domain%mask(nb:ne),domain%frac(nb:ne),domain%latc(nb:ne), &
domain%pftm(nb:ne),domain%area(nb:ne),domain%lonc(nb:ne), &
domain%nara(nb:ne),domain%topo(nb:ne),domain%ntop(nb:ne), &
domain%asca(nb:ne),domain%glcmask(nb:ne),stat=ier)
if (ier /= 0) then
write(iulog,*) 'domain_init ERROR: allocate mask, frac, lat, lon, area '
call endrun
()
endif
if (present(clmlevel)) then
domain%clmlevel = clmlevel
endif
domain%ns = ni*nj
domain%ni = ni
domain%nj = nj
domain%nbeg = nb
domain%nend = ne
domain%mask = -9999
domain%frac = -1.0e36
domain%topo = 0._r8
domain%latc = nan
domain%lonc = nan
domain%area = nan
domain%set = set
domain%regional = .false.
domain%areaset = .false.
if (domain%nbeg == 1 .and. domain%nend == domain%ns) then
domain%decomped = .false.
else
domain%decomped = .true.
endif
domain%pftm = -9999
domain%glcmask = 0
domain%nara = 0._r8
domain%ntop = -1.0e36
domain%asca = 1._r8
end subroutine domain_init
!------------------------------------------------------------------------------
!BOP
!
! !IROUTINE: domain_clean
!
! !INTERFACE:
subroutine domain_clean(domain) 1,1
!
! !DESCRIPTION:
! This subroutine deallocates the domain type
!
! !USES:
!
! !ARGUMENTS:
implicit none
type(domain_type) :: domain ! domain datatype
!
! !REVISION HISTORY:
! Created by T Craig
!
!
! !LOCAL VARIABLES:
!EOP
integer ier
!
!------------------------------------------------------------------------------
if (domain%set == set) then
if (masterproc) then
write(iulog,*) 'domain_clean: cleaning ',domain%ni,domain%nj
endif
deallocate(domain%mask,domain%frac,domain%latc, &
domain%lonc,domain%area,domain%pftm, &
domain%nara,domain%topo,domain%ntop, &
domain%asca,domain%glcmask,stat=ier)
if (ier /= 0) then
write(iulog,*) 'domain_clean ERROR: deallocate mask, frac, lat, lon, area '
call endrun
()
endif
else
if (masterproc) then
write(iulog,*) 'domain_clean WARN: clean domain unecessary '
endif
endif
domain%clmlevel = unset
domain%ns = bigint
domain%ni = bigint
domain%nj = bigint
domain%nbeg = bigint
domain%nend = bigint
domain%set = unset
domain%decomped = .true.
domain%regional = .false.
domain%areaset = .false.
end subroutine domain_clean
!------------------------------------------------------------------------------
!BOP
!
! !IROUTINE: domain_setsame
!
! !INTERFACE:
subroutine domain_setsame(domain1,domain2) 1,1
!
! !DESCRIPTION:
! This subroutine copies parts of domain2 = domain1 specifically for
! setting a finemesh lats/lons to coarsemesh grid
!
! !USES:
!
! !ARGUMENTS:
implicit none
type(domain_type),intent(in) :: domain1 ! domain datatype
type(domain_type),intent(inout) :: domain2 ! domain datatype
!
! !REVISION HISTORY:
! Created by T Craig
!
!
! !LOCAL VARIABLES:
!EOP
integer ier
!
!------------------------------------------------------------------------------
if (domain1%ni /= domain2%ni .or. domain1%nj /= domain2%nj) then
write(iulog,*) 'domain_setsame: error on size',domain1%ni,domain1%nj,domain2%ni,domain2%nj
call endrun
()
endif
if (masterproc) then
write(iulog,*) 'domain_setsame: copying ',domain1%ni,domain1%nj
endif
!!! Don't copy mask, frac, topo, pftm, nara, ntop or gatm
! domain2%mask = domain1%mask
! domain2%frac = domain1%frac
! domain2%topo = domain1%topo
! domain2%pftm = domain1%pftm
! domain2%nara = domain1%nara
! domain2%ntop = domain1%ntop
! domain2%asca = domain1%asca
! domain2%gatm = domain1%gatm
domain2%latc = domain1%latc
domain2%lonc = domain1%lonc
domain2%area = domain1%area
domain2%set = domain1%set
domain2%regional = domain1%regional
domain2%areaset = domain1%areaset
domain2%decomped = domain1%decomped
domain2%glcmask = domain1%glcmask
end subroutine domain_setsame
!------------------------------------------------------------------------------
!BOP
!
! !IROUTINE: domain_setptrs
!
! !INTERFACE:
subroutine domain_setptrs(domain,ns,ni,nj,nbeg,nend,decomped,regional, & 2
mask,pftm,glcmask,clmlevel, &
frac,topo,latc,lonc,area,nara,ntop,asca)
!
! !DESCRIPTION:
! This subroutine sets external pointer arrays to arrays in domain
!
! !USES:
!
! !ARGUMENTS:
implicit none
type(domain_type),intent(in) :: domain ! domain datatype
integer ,optional :: ns,ni,nj,nbeg,nend ! grid size, 2d, beg/end
character(len=*),optional :: clmlevel ! grid type
logical, optional :: decomped ! decomped or global
logical, optional :: regional ! regional or global
integer ,optional,pointer :: mask(:)
integer ,optional,pointer :: pftm(:)
integer ,optional,pointer :: glcmask(:)
real(r8),optional,pointer :: frac(:)
real(r8),optional,pointer :: topo(:)
real(r8),optional,pointer :: latc(:)
real(r8),optional,pointer :: lonc(:)
real(r8),optional,pointer :: area(:)
real(r8),optional,pointer :: nara(:)
real(r8),optional,pointer :: ntop(:)
real(r8),optional,pointer :: asca(:)
!
! !REVISION HISTORY:
! Created by T Craig
!
!
! !LOCAL VARIABLES:
!
!EOP
!------------------------------------------------------------------------------
if (present(ns)) then
ns = domain%ns
endif
if (present(ni)) then
ni = domain%ni
endif
if (present(nj)) then
nj = domain%nj
endif
if (present(nbeg)) then
nbeg = domain%nbeg
endif
if (present(nend)) then
nend = domain%nend
endif
if (present(clmlevel)) then
clmlevel = domain%clmlevel
endif
if (present(decomped)) then
decomped = domain%decomped
endif
if (present(regional)) then
regional = domain%regional
endif
if (present(mask)) then
mask => domain%mask
endif
if (present(pftm)) then
pftm => domain%pftm
endif
if (present(glcmask)) then
glcmask => domain%glcmask
endif
if (present(frac)) then
frac => domain%frac
endif
if (present(topo)) then
topo => domain%topo
endif
if (present(latc)) then
latc => domain%latc
endif
if (present(lonc)) then
lonc => domain%lonc
endif
if (present(area)) then
area => domain%area
endif
if (present(nara)) then
nara => domain%nara
endif
if (present(ntop)) then
ntop => domain%ntop
endif
if (present(asca)) then
asca => domain%asca
endif
end subroutine domain_setptrs
!------------------------------------------------------------------------------
!BOP
!
! !IROUTINE: domain_check
!
! !INTERFACE:
subroutine domain_check(domain) 2
!
! !DESCRIPTION:
! This subroutine write domain info
!
! !USES:
!
! !ARGUMENTS:
implicit none
type(domain_type),intent(in) :: domain ! domain datatype
!
! !REVISION HISTORY:
! Created by T Craig
!
!
! !LOCAL VARIABLES:
!
!EOP
!------------------------------------------------------------------------------
if (masterproc) then
write(iulog,*) ' domain_check set = ',trim(domain%set)
write(iulog,*) ' domain_check decomped = ',domain%decomped
write(iulog,*) ' domain_check regional = ',domain%regional
write(iulog,*) ' domain_check areaset = ',domain%areaset
write(iulog,*) ' domain_check ns = ',domain%ns
write(iulog,*) ' domain_check ni,nj = ',domain%ni,domain%nj
write(iulog,*) ' domain_check clmlevel = ',trim(domain%clmlevel)
write(iulog,*) ' domain_check nbeg,nend = ',domain%nbeg,domain%nend
write(iulog,*) ' domain_check lonc = ',minval(domain%lonc),maxval(domain%lonc)
write(iulog,*) ' domain_check latc = ',minval(domain%latc),maxval(domain%latc)
write(iulog,*) ' domain_check mask = ',minval(domain%mask),maxval(domain%mask)
write(iulog,*) ' domain_check frac = ',minval(domain%frac),maxval(domain%frac)
write(iulog,*) ' domain_check topo = ',minval(domain%topo),maxval(domain%topo)
write(iulog,*) ' domain_check area = ',minval(domain%area),maxval(domain%area)
write(iulog,*) ' domain_check pftm = ',minval(domain%pftm),maxval(domain%pftm)
write(iulog,*) ' domain_check nara = ',minval(domain%nara),maxval(domain%nara)
write(iulog,*) ' domain_check ntop = ',minval(domain%ntop),maxval(domain%ntop)
write(iulog,*) ' domain_check asca = ',minval(domain%asca),maxval(domain%asca)
write(iulog,*) ' domain_check glcmask = ',minval(domain%glcmask),maxval(domain%glcmask)
write(iulog,*) ' '
endif
end subroutine domain_check
!------------------------------------------------------------------------------
!BOP
!
! !IROUTINE: latlon_init
!
! !INTERFACE:
subroutine latlon_init(latlon,ni,nj) 2,2
!
! !DESCRIPTION:
! This subroutine allocates and nans the latlon type
!
! !USES:
!
! !ARGUMENTS:
implicit none
type(latlon_type) :: latlon ! latlon datatype
integer :: ni,nj ! grid size, 2d
!
! !REVISION HISTORY:
! Created by T Craig
!
!
! !LOCAL VARIABLES:
integer ier
!
!EOP
!------------------------------------------------------------------------------
if (latlon%set == set) then
call latlon_clean
(latlon)
endif
allocate(latlon%latc(nj),latlon%lonc(ni), &
latlon%lats(nj),latlon%latn(nj), &
latlon%lonw(ni),latlon%lone(ni), &
stat=ier)
if (ier /= 0) then
write(iulog,*) 'latlon_init ERROR: allocate '
call endrun
()
endif
latlon%ns = ni*nj
latlon%ni = ni
latlon%nj = nj
latlon%latc = nan
latlon%lonc = nan
latlon%lats = nan
latlon%latn = nan
latlon%lonw = nan
latlon%lone = nan
latlon%edges = nan
latlon%set = set
latlon%regional = .false.
end subroutine latlon_init
!------------------------------------------------------------------------------
!BOP
!
! !IROUTINE: latlon_clean
!
! !INTERFACE:
subroutine latlon_clean(latlon) 2,1
!
! !DESCRIPTION:
! This subroutine allocates and nans the latlon type
!
! !USES:
!
! !ARGUMENTS:
implicit none
type(latlon_type) :: latlon ! latlon datatype
!
! !REVISION HISTORY:
! Created by T Craig
!
!
! !LOCAL VARIABLES:
integer ier
!
!EOP
!------------------------------------------------------------------------------
if (latlon%set == unset) then
return
endif
deallocate(latlon%latc,latlon%lonc, &
latlon%lats,latlon%latn, &
latlon%lonw,latlon%lone, &
stat=ier)
if (ier /= 0) then
write(iulog,*) 'latlon_clean ERROR: deallocate '
call endrun
()
endif
latlon%ns = bigint
latlon%ni = bigint
latlon%nj = bigint
latlon%edges = nan
latlon%set = unset
latlon%regional = .false.
end subroutine latlon_clean
!------------------------------------------------------------------------------
!BOP
!
! !IROUTINE: latlon_setsame
!
! !INTERFACE:
subroutine latlon_setsame(latlon1,latlon2) 1,1
!
! !DESCRIPTION:
! This subroutine copies parts of latlon2 = latlon1 specifically for
! setting a finemesh lats/lons to coarsemesh grid
!
! !USES:
!
! !ARGUMENTS:
implicit none
type(latlon_type),intent(in) :: latlon1 ! latlon datatype
type(latlon_type),intent(inout) :: latlon2 ! latlon datatype
!
! !REVISION HISTORY:
! Created by T Craig
!
!
! !LOCAL VARIABLES:
integer ier
!
!EOP
!------------------------------------------------------------------------------
if (latlon1%ni /= latlon2%ni .or. latlon1%nj /= latlon2%nj) then
write(iulog,*) 'latlon_setsame: error on size',latlon1%ni,latlon1%nj,latlon2%ni,latlon2%nj
call endrun
()
endif
if (masterproc) then
write(iulog,*) 'latlon_setsame: copying ',latlon1%ni,latlon1%nj
endif
latlon2%edges = latlon1%edges
latlon2%latc = latlon1%latc
latlon2%lonc = latlon1%lonc
latlon2%lats = latlon1%lats
latlon2%latn = latlon1%latn
latlon2%lonw = latlon1%lonw
latlon2%lone = latlon1%lone
latlon2%set = latlon1%set
latlon2%regional = latlon1%regional
end subroutine latlon_setsame
!------------------------------------------------------------------------------
!BOP
!
! !IROUTINE: latlon_check
!
! !INTERFACE:
subroutine latlon_check(latlon) 2
!
! !DESCRIPTION:
! This subroutine write latlon info
!
! !USES:
!
! !ARGUMENTS:
implicit none
type(latlon_type),intent(in) :: latlon ! latlon datatype
!
! !REVISION HISTORY:
! Created by T Craig
!
!
! !LOCAL VARIABLES:
!
!EOP
!------------------------------------------------------------------------------
if (masterproc .and. latlon%set == set) then
write(iulog,*) ' latlon_check ns = ',latlon%ns
write(iulog,*) ' latlon_check ni,nj = ',latlon%ni,latlon%nj
write(iulog,*) ' latlon_check set = ',latlon%set
write(iulog,*) ' latlon_check regional = ',latlon%regional
write(iulog,*) ' latlon_check edgeNESW = ',latlon%edges
write(iulog,*) ' latlon_check lonc = ',minval(latlon%lonc),maxval(latlon%lonc)
write(iulog,*) ' latlon_check latc = ',minval(latlon%latc),maxval(latlon%latc)
write(iulog,*) ' latlon_check lonw = ',minval(latlon%lonw),maxval(latlon%lonw)
write(iulog,*) ' latlon_check lone = ',minval(latlon%lone),maxval(latlon%lone)
write(iulog,*) ' latlon_check lats = ',minval(latlon%lats),maxval(latlon%lats)
write(iulog,*) ' latlon_check latn = ',minval(latlon%latn),maxval(latlon%latn)
write(iulog,*) ' '
endif
end subroutine latlon_check
!------------------------------------------------------------------------------
end module domainMod