#include <misc.h>
#include <preproc.h>
module decompInitMod 1,7
!------------------------------------------------------------------------------
!BOP
!
! !MODULE: decompInitMod
!
! !USES:
use shr_kind_mod
, only : r8 => shr_kind_r8
use spmdMod
, only : masterproc, iam, npes, mpicom, comp_id
use clm_mct_mod
use shr_sys_mod
, only : shr_sys_flush
use abortutils
, only : endrun
use clm_varctl
, only : iulog
use decompMod
!
! !PUBLIC TYPES:
implicit none
!
! !PUBLIC MEMBER FUNCTIONS:
public decompInit_atm ! initializes atm grid decomposition
! into clumps and processors
public decompInit_lnd ! initializes lnd grid decomposition
! into clumps and processors
public decompInit_glcp ! initializes g,l,c,p decomp info
!
! !DESCRIPTION:
! Module provides a descomposition into a clumped data structure which can
! be mapped back to atmosphere physics chunks.
!
! !REVISION HISTORY:
! 2002.09.11 Forrest Hoffman Creation.
! 2005.11.01 T Craig Rewrite
! 2006.06.06 T Craig Reduce memory, cleanup
!
!
! !PRIVATE TYPES:
private
integer, pointer :: acid(:) ! temporary for setting adecomp/ldecomp
!EOP
!------------------------------------------------------------------------------
contains
!------------------------------------------------------------------------------
!BOP
!
! !IROUTINE: decompInit_atm
!
! !INTERFACE:
subroutine decompInit_atm(alatlon,amask) 1,16
!
! !DESCRIPTION:
! This subroutine initializes the land surface decomposition into a clump
! data structure. This assumes each pe has the same number of clumps
! set by clump_pproc
!
! !USES:
use clm_varctl
, only : nsegspc
use domainMod
, only : latlon_type
!
! !ARGUMENTS:
implicit none
type(latlon_type),intent(in) :: alatlon
integer ,intent(in) :: amask(:)
!
! !LOCAL VARIABLES:
integer :: ani,anj ! atm domain global size
integer :: ans,ag,an,ai,aj ! indices
integer :: anumg ! atm num gridcells
integer :: anumg_tot ! precompute of anumg
logical :: seglen1 ! is segment length one
real(r8):: seglen ! average segment length
real(r8):: rcid ! real value of cid
integer :: cid,pid ! indices
integer :: n,m,np ! indices
integer :: ier ! error code
integer, parameter :: dbug=1 ! 0 = min, 1=normal, 2=much, 3=max
integer :: npmin,npmax,npint ! do loop values for printing
integer :: clmin,clmax,clint ! do loop values for printing
integer :: beg,end,lsize,gsize ! used for gsmap init
integer, pointer :: gindex(:) ! global index for gsmap init
! !CALLED FROM:
! subroutine initialize
!
! !REVISION HISTORY:
! 2002.09.11 Forrest Hoffman Creation.
! 2005.12.15 T Craig Updated for finemesh
! 2006.08.18 P Worley Performance optimizations
! 2007.01.24 T Craig Created decompInit_atm from decomp_init
!
!EOP
!------------------------------------------------------------------------------
ani = alatlon%ni
anj = alatlon%nj
ans = alatlon%ns
!--- set and verify nclumps ---
if (clump_pproc > 0) then
nclumps = clump_pproc * npes
if (nclumps < npes) then
write(iulog,*) 'decompInit_atm(): Number of gridcell clumps= ',nclumps, &
' is less than the number of processes = ', npes
call endrun
()
end if
else
write(iulog,*)'clump_pproc= ',clump_pproc,' must be greater than 0'
call endrun
()
end if
!--- allocate and initialize procinfo and clumps ---
!--- beg and end indices initialized for simple addition of cells later ---
allocate(procinfo%cid(clump_pproc), stat=ier)
if (ier /= 0) then
write(iulog,*) 'decompInit_atm(): allocation error for procinfo%cid'
call endrun
()
endif
procinfo%nclumps = clump_pproc
procinfo%cid(:) = -1
procinfo%ncells = 0
procinfo%nlunits = 0
procinfo%ncols = 0
procinfo%npfts = 0
procinfo%begg = 1
procinfo%begl = 1
procinfo%begc = 1
procinfo%begp = 1
procinfo%endg = 0
procinfo%endl = 0
procinfo%endc = 0
procinfo%endp = 0
procinfo%abegg = 1
procinfo%aendg = 0
allocate(clumps(nclumps), stat=ier)
if (ier /= 0) then
write(iulog,*) 'decompInit_atm(): allocation error for clumps'
call endrun
()
end if
clumps(:)%owner = -1
clumps(:)%ncells = 0
clumps(:)%nlunits = 0
clumps(:)%ncols = 0
clumps(:)%npfts = 0
clumps(:)%begg = 1
clumps(:)%begl = 1
clumps(:)%begc = 1
clumps(:)%begp = 1
clumps(:)%endg = 0
clumps(:)%endl = 0
clumps(:)%endc = 0
clumps(:)%endp = 0
!--- assign clumps to proc round robin ---
cid = 0
do n = 1,nclumps
pid = mod(n-1,npes)
if (pid < 0 .or. pid > npes-1) then
write(iulog,*) 'decompInit_atm(): round robin pid error ',n,pid,npes
call endrun
()
endif
clumps(n)%owner = pid
if (iam == pid) then
cid = cid + 1
if (cid < 1 .or. cid > clump_pproc) then
write(iulog,*) 'decompInit_atm(): round robin pid error ',n,pid,npes
call endrun
()
endif
procinfo%cid(cid) = n
endif
enddo
!--- count total atm gridcells
anumg_tot = 0
do an = 1,ans
if (amask(an) == 1) then
anumg_tot = anumg_tot + 1
endif
enddo
numa = anumg_tot
if (npes > numa) then
write(iulog,*) 'decompInit_atm(): Number of processes exceeds number ', &
'of atm grid cells',npes,numa
call endrun
()
end if
if (nclumps > numa) then
write(iulog,*) 'decompInit_atm(): Number of clumps exceeds number ', &
'of atm grid cells',nclumps,numa
call endrun
()
end if
if (float(anumg_tot)/float(nclumps) < float(nsegspc)) then
seglen1 = .true.
seglen = 1.0_r8
else
seglen1 = .false.
seglen = dble(anumg_tot)/(dble(nsegspc)*dble(nclumps))
endif
if (masterproc) write(iulog,*) ' atm decomp precompute anumg,nclumps,seglen1,avg_seglen,nsegspc=', &
numa,nclumps,seglen1,sngl(seglen),sngl(dble(anumg_tot)/(seglen*dble(nclumps)))
!--- assign gridcells to clumps (and thus pes) ---
allocate(acid(ans))
acid = 0
anumg = 0
do an = 1,ans
if (amask(an) == 1) then
anumg = anumg + 1
!--- give to clumps in order based on nsegspc
if (seglen1) then
cid = mod(anumg-1,nclumps) + 1
else
rcid = (dble(anumg-1)/dble(anumg_tot))*dble(nsegspc)*dble(nclumps)
cid = mod(int(rcid),nclumps) + 1
endif
acid(an) = cid
!--- give atm cell to pe that owns cid ---
if (iam > clumps(cid)%owner) then
procinfo%abegg = procinfo%abegg + 1
endif
if (iam >= clumps(cid)%owner) then
procinfo%aendg = procinfo%aendg + 1
endif
end if
enddo
! Error check on total number of gridcells
if (anumg /= numa) then
write(iulog,*) 'decompInit_atm(): Number of atm gridcells inconsistent',anumg,numa
call endrun
()
end if
! Allocate dynamic memory for adecomp, ldecomp derived type
allocate(adecomp%gdc2glo(anumg), adecomp%glo2gdc(ani*anj), &
stat=ier)
if (ier /= 0) then
write(iulog,*) 'decompInit_atm(): allocation error1 for adecomp'
call endrun
()
end if
adecomp%gdc2glo(:) = 0
adecomp%glo2gdc(:) = 0
! Set adecomp
ag = 0
do pid = 0,npes-1
do cid = 1,nclumps
if (clumps(cid)%owner == pid) then
do aj = 1,anj
do ai = 1,ani
an = (aj-1)*ani + ai
if (acid(an) == cid) then
ag = ag + 1
adecomp%gdc2glo(ag) = an
adecomp%glo2gdc(an) = ag
endif
enddo
enddo
endif
enddo
enddo
! set gsMap_atm_gdc2glo
call get_proc_bounds_atm
(beg, end)
allocate(gindex(beg:end))
do n = beg,end
gindex(n) = adecomp%gdc2glo(n)
enddo
lsize = end-beg+1
gsize = ani * anj
call mct_gsMap_init(gsMap_atm_gdc2glo, gindex, mpicom, comp_id, lsize, gsize )
deallocate(gindex)
! Diagnostic output
if (masterproc) then
write(iulog,*)' Atm Grid Characteristics'
write(iulog,*)' longitude points = ',ani
write(iulog,*)' latitude points = ',anj
write(iulog,*)' total number of gridcells = ',anumg
write(iulog,*)' Decomposition Characteristics'
write(iulog,*)' clumps per process = ',clump_pproc
write(iulog,*)' gsMap Characteristics'
write(iulog,*) ' atm gsmap glo num of segs = ',mct_gsMap_ngseg(gsMap_atm_gdc2glo)
write(iulog,*)
end if
! Write out clump and proc info, one pe at a time,
! barrier to control pes overwriting each other on stdout
#ifndef UNICOSMP
call shr_sys_flush
(iulog)
#endif
call mpi_barrier(mpicom,ier)
npmin = 0
npmax = npes-1
npint = 1
if (dbug == 0) then
npmax = 0
elseif (dbug == 1) then
npmax = min(npes-1,4)
elseif (dbug == 2) then
npint = npes/8
endif
do np = npmin,npmax,npint
pid = np
if (dbug == 1) then
if (np == 2) pid=npes/2-1
if (np == 3) pid=npes-2
if (np == 4) pid=npes-1
endif
pid = max(pid,0)
pid = min(pid,npes-1)
if (iam == pid) then
write(iulog,*)
write(iulog,*)'proc= ',pid,' beg atmcell = ',procinfo%abegg, &
' end atmcell = ',procinfo%aendg, &
' total atmcells per proc = ',procinfo%aendg-procinfo%abegg+1
write(iulog,*)'proc= ',pid,' atm ngseg = ',mct_gsMap_ngseg(gsMap_atm_gdc2glo), &
' atm nlseg = ',mct_gsMap_nlseg(gsMap_atm_gdc2glo,iam)
write(iulog,*)'proc= ',pid,' nclumps = ',procinfo%nclumps
end if
#ifndef UNICOSMP
call shr_sys_flush
(iulog)
#endif
call mpi_barrier(mpicom,ier)
end do
#ifndef UNICOSMP
call shr_sys_flush
(iulog)
#endif
end subroutine decompInit_atm
!------------------------------------------------------------------------------
!BOP
!
! !IROUTINE: decompInit_lnd
!
! !INTERFACE:
subroutine decompInit_lnd(ans,ani,anj,lns,lni,lnj) 1,5
!
! !DESCRIPTION:
! This subroutine initializes the land surface decomposition into a clump
! data structure. This assumes each pe has the same number of clumps
! set by clump_pproc
!
! !USES:
use domainMod
, only : gatm
!
! !ARGUMENTS:
implicit none
integer , intent(in) :: lns,lni,lnj ! land domain global size
integer , intent(in) :: ans,ani,anj ! atm domain global size
!
! !LOCAL VARIABLES:
integer :: lg,ln,li,lj ! indices
integer :: ag,an,ai,aj ! indices
integer :: anumg ! atm num gridcells
integer :: cid,pid ! indices
integer, pointer :: lcid(:) ! temporary for setting adecomp
integer :: n,m,np ! indices
integer :: ier ! error code
integer :: cnt ! local counter
integer :: beg,end,lsize,gsize ! used for gsmap init
integer, pointer :: gindex(:) ! global index for gsmap init
integer, pointer :: lncnt(:) ! lnd cell count per atm cell
integer, pointer :: lnoff(:) ! atm cell offset in lnmap
integer, pointer :: lnmap(:) ! map from atm cell to lnd cells
integer :: lnidx
! !CALLED FROM:
! subroutine initialize
!
! !REVISION HISTORY:
! 2002.09.11 Forrest Hoffman Creation.
! 2005.12.15 T Craig Updated for finemesh
! 2006.08.18 P Worley Performance optimizations
!
!EOP
!------------------------------------------------------------------------------
allocate(lncnt(ans),lnoff(ans),lnmap(lns))
lncnt = 0
do ln = 1,lns
an = gatm(ln)
if ((an > 0) .and. (an .le. ans)) then
lncnt(an) = lncnt(an) + 1
endif
enddo
lnoff(1) = 1
do an = 2,ans
lnoff(an) = lnoff(an-1) + lncnt(an-1)
enddo
lncnt = 0
lnmap = -1
do ln = 1,lns
an = gatm(ln)
if ((an > 0) .and. (an .le. ans)) then
lnmap(lnoff(an)+lncnt(an)) = ln
lncnt(an) = lncnt(an) + 1
endif
enddo
!--- assign gridcells to clumps (and thus pes) ---
allocate(lcid(lns))
lcid = 0
numg = 0
do anumg = 1,numa
an = adecomp%gdc2glo(anumg)
cid = acid(an)
cnt = 0
do lnidx = 0,lncnt(an)-1
ln = lnmap(lnoff(an)+lnidx)
cnt = cnt + 1
lcid(ln) = cid
!--- overall total ---
numg = numg + 1
!--- give gridcell to cid ---
!--- increment the beg and end indices ---
clumps(cid)%ncells = clumps(cid)%ncells + 1
do m = 1,nclumps
if ((clumps(m)%owner > clumps(cid)%owner) .or. &
(clumps(m)%owner == clumps(cid)%owner .and. m > cid)) then
clumps(m)%begg = clumps(m)%begg + 1
endif
if ((clumps(m)%owner > clumps(cid)%owner) .or. &
(clumps(m)%owner == clumps(cid)%owner .and. m >= cid)) then
clumps(m)%endg = clumps(m)%endg + 1
endif
enddo
!--- give gridcell to the proc that owns the cid ---
!--- increment the beg and end indices ---
if (iam == clumps(cid)%owner) then
procinfo%ncells = procinfo%ncells + 1
endif
if (iam > clumps(cid)%owner) then
procinfo%begg = procinfo%begg + 1
endif
if (iam >= clumps(cid)%owner) then
procinfo%endg = procinfo%endg + 1
endif
enddo
!--- check that atm cell has at least 1 lnd grid cell
if (cnt < 1) then
write(iulog,*) 'decompInit_lnd(): map overlap error at ',an,cnt
call endrun
()
endif
enddo
allocate(ldecomp%gdc2glo(numg), ldecomp%glo2gdc(lni*lnj), &
stat=ier)
if (ier /= 0) then
write(iulog,*) 'decompInit_lnd(): allocation error1 for ldecomp'
call endrun
()
end if
ldecomp%gdc2glo(:) = 0
ldecomp%glo2gdc(:) = 0
! Set ldecomp
lg = 0
do pid = 0,npes-1
do cid = 1,nclumps
if (clumps(cid)%owner == pid) then
do lj = 1,lnj
do li = 1,lni
ln = (lj-1)*lni + li
if (lcid(ln) == cid) then
lg = lg + 1
ldecomp%gdc2glo(lg) = ln
ldecomp%glo2gdc(ln) = lg
endif
enddo
enddo
endif
enddo
enddo
deallocate(lcid)
deallocate(lncnt,lnoff,lnmap)
! set gsMap_lnd_gdc2glo
call get_proc_bounds
(beg, end)
allocate(gindex(beg:end))
do n = beg,end
gindex(n) = ldecomp%gdc2glo(n)
enddo
lsize = end-beg+1
gsize = lni * lnj
call mct_gsMap_init(gsMap_lnd_gdc2glo, gindex, mpicom, comp_id, lsize, gsize )
deallocate(gindex)
! Diagnostic output
if (masterproc) then
write(iulog,*)' Atm Grid Characteristics'
write(iulog,*)' longitude points = ',ani
write(iulog,*)' latitude points = ',anj
write(iulog,*)' total number of gridcells = ',numa
write(iulog,*)' Surface Grid Characteristics'
write(iulog,*)' longitude points = ',lni
write(iulog,*)' latitude points = ',lnj
write(iulog,*)' total number of gridcells = ',numg
write(iulog,*)' Decomposition Characteristics'
write(iulog,*)' clumps per process = ',clump_pproc
write(iulog,*)' gsMap Characteristics'
write(iulog,*) ' lnd gsmap glo num of segs = ',mct_gsMap_ngseg(gsMap_lnd_gdc2glo)
write(iulog,*) ' atm gsmap glo num of segs = ',mct_gsMap_ngseg(gsMap_atm_gdc2glo)
write(iulog,*)
end if
#ifndef UNICOSMP
call shr_sys_flush
(iulog)
#endif
end subroutine decompInit_lnd
!------------------------------------------------------------------------------
!BOP
!
! !IROUTINE: decompInit_glcp
!
! !INTERFACE:
subroutine decompInit_glcp(ans,ani,anj,lns,lni,lnj,glcmask) 2,24
!
! !DESCRIPTION:
! This subroutine initializes the land surface decomposition into a clump
! data structure. This assumes each pe has the same number of clumps
! set by clump_pproc
!
! !USES:
use clmtype
, only : grlnd, nameg, namel, namec, namep
use spmdMod
use spmdGathScatMod
use domainMod
, only : gatm
use subgridMod
, only : subgrid_get_gcellinfo
!
! !ARGUMENTS:
implicit none
integer , intent(in) :: lns,lni,lnj ! land domain global size
integer , intent(in) :: ans,ani,anj ! atm domain global size
integer , pointer, optional :: glcmask(:) ! glc mask
!
! !LOCAL VARIABLES:
integer :: lg,ln,li,lj ! indices
integer :: ag,an,ai,aj ! indices
integer :: abegg,aendg,anumg ! atm num gridcells
integer :: begg,endg ! lnd num gridcells
integer :: begl,endl ! lnd num gridcells
integer :: begc,endc ! lnd num gridcells
integer :: begp,endp ! lnd num gridcells
integer :: cid,pid ! indices
integer :: n,m,np ! indices
integer :: icells, ilunits, icols, ipfts ! temporaries
integer :: ier ! error code
integer :: cnt ! local counter
integer, parameter :: dbug=1 ! 0 = min, 1=normal, 2=much, 3=max
integer :: npmin,npmax,npint ! do loop values for printing
integer :: clmin,clmax,clint ! do loop values for printing
integer :: lsize,gsize ! used for gsmap init
integer :: ng ! number of gridcells in gsmap
integer, pointer :: gindex(:) ! global index for gsmap init
integer, pointer :: lncnt(:) ! lnd cell count per atm cell
integer, pointer :: lnoff(:) ! atm cell offset in lnmap
integer, pointer :: lnmap(:) ! map from atm cell to lnd cells
integer, allocatable :: allvecg(:,:) ! temporary vector "global"
integer, allocatable :: allvecl(:,:) ! temporary vector "local"
integer :: lnidx
integer, pointer :: arrayg(:)
integer :: val1, val2
integer :: i,g,l,c,p,k
integer, pointer :: gstart(:),gcount(:)
integer, pointer :: lstart(:),lcount(:)
integer, pointer :: cstart(:),ccount(:)
integer, pointer :: pstart(:),pcount(:)
integer :: beg,end,num
type(mct_gsmap),pointer :: gsmap
integer, pointer :: start(:),count(:)
integer, pointer :: tarr1(:),tarr2(:)
integer :: ntest
character(len=8) :: clmlevel
character(len=32), parameter :: subname = 'decompInit_glcp'
! !CALLED FROM:
! subroutine initialize
!
! !REVISION HISTORY:
! 2002.09.11 Forrest Hoffman Creation.
! 2005.12.15 T Craig Updated for finemesh
! 2006.08.18 P Worley Performance optimizations
!
!EOP
!------------------------------------------------------------------------------
allocate(lncnt(ans),lnoff(ans),lnmap(lns))
lncnt = 0
do ln = 1,lns
an = gatm(ln)
if ((an > 0) .and. (an .le. ans)) then
lncnt(an) = lncnt(an) + 1
endif
enddo
lnoff(1) = 1
do an = 2,ans
lnoff(an) = lnoff(an-1) + lncnt(an-1)
enddo
lncnt = 0
lnmap = -1
do ln = 1,lns
an = gatm(ln)
if ((an > 0) .and. (an .le. ans)) then
lnmap(lnoff(an)+lncnt(an)) = ln
lncnt(an) = lncnt(an) + 1
endif
enddo
!--- assign gridcells to clumps (and thus pes) ---
call get_proc_bounds_atm
(abegg, aendg)
call get_proc_bounds
(begg, endg)
allocate(gstart(begg:endg),lstart(begg:endg),cstart(begg:endg),pstart(begg:endg))
allocate(gcount(begg:endg),lcount(begg:endg),ccount(begg:endg),pcount(begg:endg))
allocate(allvecg(nclumps,4),allvecl(nclumps,4)) ! 3 = gcells,lunit,cols,pfts
allvecg = 0
allvecl = 0
gcount = 0
lcount = 0
ccount = 0
pcount = 0
do anumg = abegg,aendg
an = adecomp%gdc2glo(anumg)
cid = acid(an)
do lnidx = 0,lncnt(an)-1
ln = ldecomp%glo2gdc(lnmap(lnoff(an)+lnidx))
if (present(glcmask)) then
call subgrid_get_gcellinfo
(ln, nlunits=ilunits, &
ncols=icols, npfts=ipfts, glcmask=glcmask(ln))
else
call subgrid_get_gcellinfo
(ln, nlunits=ilunits, &
ncols=icols, npfts=ipfts)
endif
allvecl(cid,1) = allvecl(cid,1) + 1
allvecl(cid,2) = allvecl(cid,2) + ilunits
allvecl(cid,3) = allvecl(cid,3) + icols
allvecl(cid,4) = allvecl(cid,4) + ipfts
gcount(ln) = 1
lcount(ln) = ilunits
ccount(ln) = icols
pcount(ln) = ipfts
enddo
enddo
call mpi_allreduce(allvecl,allvecg,size(allvecg),MPI_INTEGER,MPI_SUM,mpicom,ier)
numg = 0
numl = 0
numc = 0
nump = 0
do cid = 1,nclumps
icells = allvecg(cid,1)
ilunits = allvecg(cid,2)
icols = allvecg(cid,3)
ipfts = allvecg(cid,4)
!--- overall total ---
numg = numg + icells
numl = numl + ilunits
numc = numc + icols
nump = nump + ipfts
!--- give gridcell to cid ---
!--- increment the beg and end indices ---
! clumps(cid)%ncells = clumps(cid)%ncells + icells
clumps(cid)%nlunits = clumps(cid)%nlunits + ilunits
clumps(cid)%ncols = clumps(cid)%ncols + icols
clumps(cid)%npfts = clumps(cid)%npfts + ipfts
do m = 1,nclumps
if ((clumps(m)%owner > clumps(cid)%owner) .or. &
(clumps(m)%owner == clumps(cid)%owner .and. m > cid)) then
! clumps(m)%begg = clumps(m)%begg + icells
clumps(m)%begl = clumps(m)%begl + ilunits
clumps(m)%begc = clumps(m)%begc + icols
clumps(m)%begp = clumps(m)%begp + ipfts
endif
if ((clumps(m)%owner > clumps(cid)%owner) .or. &
(clumps(m)%owner == clumps(cid)%owner .and. m >= cid)) then
! clumps(m)%endg = clumps(m)%endg + icells
clumps(m)%endl = clumps(m)%endl + ilunits
clumps(m)%endc = clumps(m)%endc + icols
clumps(m)%endp = clumps(m)%endp + ipfts
endif
enddo
!--- give gridcell to the proc that owns the cid ---
!--- increment the beg and end indices ---
if (iam == clumps(cid)%owner) then
! procinfo%ncells = procinfo%ncells + icells
procinfo%nlunits = procinfo%nlunits + ilunits
procinfo%ncols = procinfo%ncols + icols
procinfo%npfts = procinfo%npfts + ipfts
endif
if (iam > clumps(cid)%owner) then
! procinfo%begg = procinfo%begg + icells
procinfo%begl = procinfo%begl + ilunits
procinfo%begc = procinfo%begc + icols
procinfo%begp = procinfo%begp + ipfts
endif
if (iam >= clumps(cid)%owner) then
! procinfo%endg = procinfo%endg + icells
procinfo%endl = procinfo%endl + ilunits
procinfo%endc = procinfo%endc + icols
procinfo%endp = procinfo%endp + ipfts
endif
enddo
do n = 1,nclumps
if (clumps(n)%ncells /= allvecg(n,1) .or. &
clumps(n)%nlunits /= allvecg(n,2) .or. &
clumps(n)%ncols /= allvecg(n,3) .or. &
clumps(n)%npfts /= allvecg(n,4)) then
write(iulog,*) 'decompInit_glcp(): allvecg error ncells ',iam,n,clumps(n)%ncells ,allvecg(n,1)
write(iulog,*) 'decompInit_glcp(): allvecg error lunits ',iam,n,clumps(n)%nlunits,allvecg(n,2)
write(iulog,*) 'decompInit_glcp(): allvecg error ncols ',iam,n,clumps(n)%ncols ,allvecg(n,3)
write(iulog,*) 'decompInit_glcp(): allvecg error pfts ',iam,n,clumps(n)%npfts ,allvecg(n,4)
call endrun
()
endif
enddo
deallocate(allvecg,allvecl)
deallocate(acid)
deallocate(lncnt,lnoff,lnmap)
! set gsMaps, perms for lun, col, pft
! this was just "set" above in procinfo, be careful not to move it up
call get_proc_bounds
(begg, endg, begl, endl, begc, endc, begp, endp)
ng = mct_gsmap_gsize(gsmap_lnd_gdc2glo)
allocate(arrayg(ng))
! for each subgrid gsmap (l, c, p)
! gather the gdc subgrid counts to masterproc in glo order
! compute glo ordered start indices from the counts
! scatter the subgrid start indices back out to the gdc gridcells
! set the local gindex array for the subgrid from the subgrid start and count arrays
do k = 1,4
if (k == 1) then
clmlevel = nameg
beg = begg
end = endg
num = numg
gsmap => gsmap_gce_gdc2glo
start => gstart
count => gcount
elseif (k == 2) then
clmlevel = namel
beg = begl
end = endl
num = numl
gsmap => gsmap_lun_gdc2glo
start => lstart
count => lcount
elseif (k == 3) then
clmlevel = namec
beg = begc
end = endc
num = numc
gsmap => gsmap_col_gdc2glo
start => cstart
count => ccount
elseif (k == 4) then
clmlevel = namep
beg = begp
end = endp
num = nump
gsmap => gsmap_pft_gdc2glo
start => pstart
count => pcount
else
write(iulog,*) 'decompInit_glcp error in k ',k
call endrun
()
endif
arrayg = 0
call gather_data_to_master
(count,arrayg,grlnd)
if (masterproc) then
gsize = arrayg(1)
val1 = arrayg(1)
arrayg(1) = 1
do n = 2,ng
gsize = gsize + arrayg(n)
val2 = arrayg(n)
arrayg(n) = arrayg(n-1) + val1
val1 = val2
enddo
endif
call scatter_data_from_master
(start,arrayg,grlnd)
allocate(gindex(beg:end))
i = beg-1
do g = begg,endg
if (count(g) < 1) then
write(iulog,*) 'decompInit_glcp warning count g ',k,iam,g,count(g)
endif
do l = 1,count(g)
i = i + 1
if (i < beg .or. i > end) then
write(iulog,*) 'decompInit_glcp error i ',i,beg,end
call endrun
()
endif
gindex(i) = start(g) + l-1
enddo
enddo
if (i /= end) then
write(iulog,*) 'decompInit_glcp error size ',i,beg,end
call endrun
()
endif
lsize = end-beg+1
gsize = num
call mct_gsMap_init(gsMap, gindex, mpicom, comp_id, lsize, gsize )
!--- test gsmap ---
ntest = mct_gsMap_gsize(gsMap)
allocate(tarr1(ntest),tarr2(beg:end))
call gather_data_to_master
(gindex,tarr1,clmlevel)
call scatter_data_from_master
(tarr2,tarr1,clmlevel)
!--- verify gather/scatter produces same result
do l = beg,end
if (tarr2(l) /= gindex(l)) then
write(iulog,*) 'decompInit_glcp error tarr2 ',k,l,gindex(l),tarr2(l)
call endrun
()
endif
enddo
!--- verify gather of gindex on new gsmap produces ordered indices
if (masterproc) then
if (tarr1(1) /= 1) then
write(iulog,*) 'decompInit_glcp error tarr1 ',k,1,tarr1(1)
call endrun
()
endif
do l = 2,ntest
if (tarr1(l)-tarr1(l-1) /= 1) then
write(iulog,*) 'decompInit_glcp error tarr1 ',k,l,tarr1(l-1),tarr1(l)
call endrun
()
endif
enddo
endif
deallocate(tarr1,tarr2)
if (masterproc) then
write(iulog,*) 'decompInit_glcp gsmap [l,c,p] test passes for ',k
endif
!--- end test section
deallocate(gindex)
enddo
deallocate(gstart,lstart,cstart,pstart)
deallocate(gcount,lcount,ccount,pcount)
! Diagnostic output
if (masterproc) then
write(iulog,*)' Atm Grid Characteristics'
write(iulog,*)' longitude points = ',ani
write(iulog,*)' latitude points = ',anj
write(iulog,*)' total number of gridcells = ',numa
write(iulog,*)' Surface Grid Characteristics'
write(iulog,*)' longitude points = ',lni
write(iulog,*)' latitude points = ',lnj
write(iulog,*)' total number of gridcells = ',numg
write(iulog,*)' total number of landunits = ',numl
write(iulog,*)' total number of columns = ',numc
write(iulog,*)' total number of pfts = ',nump
write(iulog,*)' Decomposition Characteristics'
write(iulog,*)' clumps per process = ',clump_pproc
write(iulog,*)' gsMap Characteristics'
write(iulog,*) ' atm gsmap glo num of segs = ',mct_gsMap_ngseg(gsMap_atm_gdc2glo)
write(iulog,*) ' lnd gsmap glo num of segs = ',mct_gsMap_ngseg(gsMap_lnd_gdc2glo)
write(iulog,*) ' gce gsmap glo num of segs = ',mct_gsMap_ngseg(gsMap_gce_gdc2glo)
write(iulog,*) ' lun gsmap glo num of segs = ',mct_gsMap_ngseg(gsMap_lun_gdc2glo)
write(iulog,*) ' col gsmap glo num of segs = ',mct_gsMap_ngseg(gsMap_col_gdc2glo)
write(iulog,*) ' pft gsmap glo num of segs = ',mct_gsMap_ngseg(gsMap_pft_gdc2glo)
write(iulog,*)
end if
! Write out clump and proc info, one pe at a time,
! barrier to control pes overwriting each other on stdout
#ifndef UNICOSMP
call shr_sys_flush
(iulog)
#endif
call mpi_barrier(mpicom,ier)
npmin = 0
npmax = npes-1
npint = 1
if (dbug == 0) then
npmax = 0
elseif (dbug == 1) then
npmax = min(npes-1,4)
elseif (dbug == 2) then
npint = npes/8
endif
do np = npmin,npmax,npint
pid = np
if (dbug == 1) then
if (np == 2) pid=npes/2-1
if (np == 3) pid=npes-2
if (np == 4) pid=npes-1
endif
pid = max(pid,0)
pid = min(pid,npes-1)
if (iam == pid) then
write(iulog,*)
write(iulog,*)'proc= ',pid,' beg atmcell = ',procinfo%abegg, &
' end atmcell = ',procinfo%aendg, &
' total atmcells per proc = ',procinfo%aendg-procinfo%abegg+1
write(iulog,*)'proc= ',pid,' beg gridcell= ',procinfo%begg, &
' end gridcell= ',procinfo%endg, &
' total gridcells per proc= ',procinfo%ncells
write(iulog,*)'proc= ',pid,' beg landunit= ',procinfo%begl, &
' end landunit= ',procinfo%endl, &
' total landunits per proc= ',procinfo%nlunits
write(iulog,*)'proc= ',pid,' beg column = ',procinfo%begc, &
' end column = ',procinfo%endc, &
' total columns per proc = ',procinfo%ncols
write(iulog,*)'proc= ',pid,' beg pft = ',procinfo%begp, &
' end pft = ',procinfo%endp, &
' total pfts per proc = ',procinfo%npfts
write(iulog,*)'proc= ',pid,' atm ngseg = ',mct_gsMap_ngseg(gsMap_atm_gdc2glo), &
' atm nlseg = ',mct_gsMap_nlseg(gsMap_atm_gdc2glo,iam)
write(iulog,*)'proc= ',pid,' lnd ngseg = ',mct_gsMap_ngseg(gsMap_lnd_gdc2glo), &
' lnd nlseg = ',mct_gsMap_nlseg(gsMap_lnd_gdc2glo,iam)
write(iulog,*)'proc= ',pid,' gce ngseg = ',mct_gsMap_ngseg(gsMap_gce_gdc2glo), &
' gce nlseg = ',mct_gsMap_nlseg(gsMap_gce_gdc2glo,iam)
write(iulog,*)'proc= ',pid,' lun ngseg = ',mct_gsMap_ngseg(gsMap_lun_gdc2glo), &
' lun nlseg = ',mct_gsMap_nlseg(gsMap_lun_gdc2glo,iam)
write(iulog,*)'proc= ',pid,' col ngseg = ',mct_gsMap_ngseg(gsMap_col_gdc2glo), &
' col nlseg = ',mct_gsMap_nlseg(gsMap_col_gdc2glo,iam)
write(iulog,*)'proc= ',pid,' pft ngseg = ',mct_gsMap_ngseg(gsMap_pft_gdc2glo), &
' pft nlseg = ',mct_gsMap_nlseg(gsMap_pft_gdc2glo,iam)
write(iulog,*)'proc= ',pid,' nclumps = ',procinfo%nclumps
clmin = 1
clmax = procinfo%nclumps
if (dbug == 1) then
clmax = 1
elseif (dbug == 0) then
clmax = -1
endif
do n = clmin,clmax
cid = procinfo%cid(n)
write(iulog,*)'proc= ',pid,' clump no = ',n, &
' clump id= ',procinfo%cid(n), &
' beg gridcell= ',clumps(cid)%begg, &
' end gridcell= ',clumps(cid)%endg, &
' total gridcells per clump= ',clumps(cid)%ncells
write(iulog,*)'proc= ',pid,' clump no = ',n, &
' clump id= ',procinfo%cid(n), &
' beg landunit= ',clumps(cid)%begl, &
' end landunit= ',clumps(cid)%endl, &
' total landunits per clump = ',clumps(cid)%nlunits
write(iulog,*)'proc= ',pid,' clump no = ',n, &
' clump id= ',procinfo%cid(n), &
' beg column = ',clumps(cid)%begc, &
' end column = ',clumps(cid)%endc, &
' total columns per clump = ',clumps(cid)%ncols
write(iulog,*)'proc= ',pid,' clump no = ',n, &
' clump id= ',procinfo%cid(n), &
' beg pft = ',clumps(cid)%begp, &
' end pft = ',clumps(cid)%endp, &
' total pfts per clump = ',clumps(cid)%npfts
end do
end if
#ifndef UNICOSMP
call shr_sys_flush
(iulog)
#endif
call mpi_barrier(mpicom,ier)
end do
#ifndef UNICOSMP
call shr_sys_flush
(iulog)
#endif
end subroutine decompInit_glcp
!------------------------------------------------------------------------------
end module decompInitMod