      SUBROUTINE puv_driver(mv_begin,mv_end,NumMinVols,
     &                      lu,ld,fcerr,data,nobs)
      include 'params.h'
      include 'processors.h'
c.....................................................................c
C     NASA/DAO OPTIMUM INTERPOLATION ANALYSIS  -  VERSION 1.4         :
c.....................................................................c
C**********************************************************************
C  This is a new driver interface for the data parallel version       *
C  It includes SEARCH routine, which stores its results in arrays     *
C  indexed by mini-volume label (igp). These are then passed to       *
C  local drivers via SOLVEDRV.                                        *
C**********************************************************************
C  Data parallel implementation (CM Fortran) : M. Makivic (NPAC)      *
C  Date:       4/94                                                   *
C**********************************************************************
c
c
c
      integer max_batch_size
      integer NumMinVols,mv_begin,mv_end
      INTEGER nreps (NumMinVols,50), augment
      LOGICAL first, final, onestage, qobs, offlev, solved
      logical unislp
      common /obs/      maxdex,  nfgge,   lun,
     &                  vhc(13,13,20),    vcorox(18,18,4),
     &                  obserr(200,4,19), ww(13,13,20),
     &                  qobs(200,5),  offlev(200)
      common / obschar / dataname (5), obsname(200)


      REAL 
     &clam (144), datalist (NumMinVols,150,50),data (nobs,NRECORDS),
     & fcerr (im , jnp ), slam (144), 
     &delta (150),
     &gp (600), 
     &npd_mark, aug (3)
      CHARACTER * 8 dataname, obsname
      logical mv_done
      integer mv_start
      real crscov
      COMMON /PUV/ CRSCOV

!hpf$ distribute data(block,*) onto PROC_ARRAY_1D
!hpf$ distribute fcerr(*,block) onto PROC_ARRAY_1D

!hpf$ distribute datalist(block,*,*) onto PROC_ARRAY_1D
!hpf$ distribute nreps(block,*) onto PROC_ARRAY_1D

      DATA aug / 1.01, 1.1, 10. /
      integer nfact

      COMMON / gridxx / im, jnp, mlev
      COMMON / region / reg (13104)
!hpf$ distribute reg(block) onto PROC_ARRAY_1D
      COMMON / scan / maxobs, rscan, onestage, MaxData
      COMMON / sparam / lsolve, ns, nr, nv, nh (13104), nq, kq (3), volc
     &entre_x (13104), ngv, volcentre_y (13104), glatup (13104), glonup 
     &(13104)

!hpf$ distribute glatup(block) onto PROC_ARRAY_1D
!hpf$ distribute glonup(block) onto PROC_ARRAY_1D
!hpf$ distribute nh(block) onto PROC_ARRAY_1D
!hpf$ distribute volcentre_x(block) onto PROC_ARRAY_1D
!hpf$ distribute volcentre_y(block) onto PROC_ARRAY_1D


      COMMON / CORTABS / HCORFE (1000, 3, 20, 2)
      COMMON / sfcdrag / drag (imr,jmr+1), iwater(13104)
!hpf$ distribute drag(*,block) onto PROC_ARRAY_1D
!hpf$ distribute iwater(block) onto PROC_ARRAY_1D

      integer,dimension(NumMinVols,700):: gplat,gplon
      integer,dimension(NumMinVols,50):: npd_flag

      real,dimension(NumMinVols,700):: plat,plon,pstd,
     &     gstd,pdel,pkx,wlat,wlon,wstd,wkx,plst,wlst,glat,
     &     glon, udel,vdel,wdrg
      integer,dimension(NumMinVols)::np,nw,nhgp,nreports
      real,dimension(NumMinVols)::region,water


!hpf$ distribute np(block) onto PROC_ARRAY_1D
!hpf$ distribute nhgp(block) onto PROC_ARRAY_1D
!hpf$ distribute nreports(block) onto PROC_ARRAY_1D
!hpf$ distribute region(block) onto PROC_ARRAY_1D
!hpf$ distribute water(block) onto PROC_ARRAY_1D
!hpf$ distribute npd_flag(block,*) onto PROC_ARRAY_1D
!hpf$ distribute gplat(block,*) onto PROC_ARRAY_1D
!hpf$ align with gplat:: gplon
!hpf$ align with gplat:: plat,plon,pstd
!hpf$ align with gplat:: gstd,pdel,pkx,wlat,wlon,wstd
!hpf$ align with gplat:: wkx,plst,wlst,glat
!hpf$ align with gplat:: glon, udel,vdel,wdrg

      if(mv_end.ne.(mv_begin+NumMinVols-1)) then
         print *, 'MV indices messed up!'
         stop
      end if

      WRITE( 6,'(" Now beginning the search.....")' ) 
      mv_start=1
c      write(6,*) 'Enter batch factor..'
c      read(5,*) nfact
       nfact=1000
c      max_batch_size=ngv*nfact
      max_batch_size=100*nfact
      write(6,*) 'from driver.. ',max_batch_size

111   continue
      CALL search(mv_begin,mv_end,NumMinVols,
     &     mv_start,max_batch_size,lu,ld,datalist,
     &     nreps,data,nobs,mv_done)
      if(.not.mv_done) goto 111

      print *, 'finished search'
      call getconh('PI180   ', pi180 )
      call getconh('DLAT    ',dlat)
      call getconh('DLON    ',dlon)
      CALL GETCONH('RADE    ',RADE  )
      CALL GETCONH('RADEI   ',RADEI )
      CALL GETCONH('RADEI2  ',RADEI2)
      cALL GETCONH('OMEGA2  ',OMEGA2)
      CALL GETCONH('RHOBAR  ',RHOBAR)
      CALL GETCONI('MAXREP  ',MAXREP)
      CALL GETCONL('SLP     ',UNISLP)
      zero=0.0
      one=1.0
         IF(     UNISLP) THEN
            CRSCOV = ZERO
         ELSE
            CRSCOV = ONE
         END IF


      nhgp(1:NumMinVols)=nh(mv_begin:mv_end)
      water(1:NumMinVols)=iwater(mv_begin:mv_end)
      region(1:NumMinVols)=reg(mv_begin:mv_end)
    
      do levels = lu, ld, nv

!  Prepare arrays needed to compute covariance matrices.
        if( any(nreps(:,levels).ne.0) ) then

        print *, 'ready to call puv_prep_cov'
           call puv_prep_cov(mv_begin,mv_end,NumMinVols,
     &             nobs,datalist(:,:,levels),
     &             nreps(:,levels),data,fcerr,
     &             glatup,glonup,nh,volcentre_x,volcentre_y,
     &             gplat,gplon,plat,plon,pstd,gstd,pdel,pkx,wlat,wlon,
     &             wstd,udel,vdel,wkx,glat,glon,np,nw)
        endif
        nreports(1:NumMinVols)=nreps(1:NumMinVols,levels)

        print *, 'ready to call solvedrvl'
c          call solvedrvl ( mv_begin,mv_end,NumMinVols,
c     &              im,jnp,mlev,levels,dlon,nq,nr,nv,region,
c     &              nreports,nhgp,np,nw, water,crscov,
c     &              obserr,hcorfemm,
c     &              radei, pi180, rhobar, omega2, plon,
c     &              plat, pstd, wlat, wlon, wstd, wdrg, udel,
c     &              vdel, pdel, pkx, wkx, testing_loc1, npd_flag)
c
!  Store covariance matrices locally
!        call storel()

      end do

      write(6,'("...matrix solutions complete.")')
      write(6,'(//)')
c      write(6,*) 'testing_loc1'
c      write(6,*) testing_loc1
      write(6,*) 'nreports'
      write(6,*) nreports

!  Average the wind increments at the poles.

!      if( nq.eq.3 ) then

!        do levels = lu, ld

!         call avguvinc ( im, clam, slam,
!     &        aquan(1,jnp,levels,2), aquan(1,jnp,levels,3),
!     &        aquan(1,  1,levels,2), aquan(1,  1,levels,3)    )
!
!        end do

!      endif

c      clam=1.0
      RETURN
      END
