    module split_defs
! SPLIT_DEFS - utility routines.
!  Modification history:
!  11/20/04 - added routines to support distribution of actual observations
!             among the processors
!  08/18/03 - split along latitudes instead of longitudes.
!
    implicit none
    contains
!----------------------
    subroutine imod(iproc,iwidth,nstrips,ywin,startlat,endlat,psouth,pnorth)
! IMOD - given the patch width, number of available processors,
! and the number NSTRIPS of latitudes, determine
! a splitting of the data and decide how many processors to use.
!  IPROC  :=: on input, the number of available processors; on return,
!             the number of processors on which to run.
!  IWIDTH :=  Kth entry is the width of each latitude strip (i.e., number
!             of vertical grid points) that the Kth processor should handle.
!  NSTRIPS :  the number of latitudes to use.
!  YWIN  : minimum Y (latitude) radius that can be centered at each point
!      between each latitude strip defined by STARTLAT and ENDLAT.
!  STARTLAT := the starting latitude for the model grid for processor K.
!  ENDLAT := the stopping latitude for the model grid for processor K.
!  The splitting is determined so that the width of the strips is as least
!  as great as the latitude width (YWIN) of a patch.
!  PSOUTH, PNORTH := Kth entries are the southern- and northernmost
!  latitudes at which patches can be centered for the data assimilation.
!
    use resolution,only:LATG
    use grid_indexing
    use ferror
    implicit none
    integer,intent(inout)::iproc
    integer,allocatable,intent(out)::iwidth(:),startlat(:),endlat(:)
    integer,allocatable,intent(out)::psouth(:),pnorth(:)
    integer,intent(in)::nstrips,ywin
!
!   Local variables
!
    integer::per_proc,left,j,n
!
!  First determine the number of latitude strips that each processor will
!  handle.  The lowest-numbered processors handle up to one extra strip
!  than higher-numbered ones (partially compensates for slowness of data
!  movement across the cluster).  Revise the total number of processors
!  to be used as needed.
!
    n=min(iproc,nstrips)
    per_proc=nstrips/n
    left=mod(nstrips,n)
    allocate(iwidth(n))
    iwidth(1:left)=per_proc+1  ! distribute leftovers
    iwidth(left+1:n)=per_proc
    iproc=n
!
    allocate(startlat(n),endlat(n))
    allocate(psouth(n),pnorth(n))
!
!  First determine processor assignments; processor J centers points
!  along latitudes STARTLAT(J) to ENDLAT(J) inclusive.
!
    startlat(1)=1
    endlat(1)=iwidth(1)
    do j=2,n
       startlat(j)=endlat(j-1)+1
       endlat(j)=startlat(j)+iwidth(j)-1
    enddo
    if(endlat(n).gt.LATG) call fabort('imod: processor allocation botched')
    psouth=startlat
    pnorth=endlat
!
!  Now add padding: up to YWIN latitudes to the north of ENDLAT and to the
!  south of STARTLAT so that we can center patches at each point along
!  the southernmost and northernmost latitudes.
!
    do j=1,n
       startlat(j)=max(startlat(j)-ywin,1)
       endlat(j)=min(endlat(j)+ywin,LATG)
    enddo
    return
    end subroutine imod
!----------------------
    end module split_defs
