      SUBROUTINE puv_driver(NumMinVols,lu,ld,fcerr,aquan,asdae,
     &                  data,nobs)
      include '/usr/include/cm/CMF_defs.h'
      include 'params.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
      INTEGER nreps (NumMinVols,50), augment
      LOGICAL first, final, onestage, qobs, offlev, solved
      logical unislp
      EXTERNAL cov
      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 aquan (im, jnp, mlev + 1, nq), asdae (im, jnp, mlev + 1), 
     &clam (144), datalist (NumMinVols,150,50),data (nobs,NRECORDS),
     & fcerr (im , jnp ), slam (144), weights (150, 600, 3), 
     &delta (150), symat (12000),
     &force (150, 600, 3), gp (600), force2 (270000), 
     &npd_mark, aug (3), symat_temp (12000)
      CHARACTER * 8 dataname, obsname
      logical mv_done
      integer mv_start
      real crscov
      COMMON /PUV/ CRSCOV


!hpf$ distribute aquan(block,block,block,block)
!hpf$ distribute datalist(block,block,block)
!hpf$ distribute asdae(block,block,block)
!hpf$ distribute aug(block)
!hpf$ distribute clam(block)
!hpf$ distribute data(block,block)
!hpf$ distribute delta(block)
!hpf$ distribute fcerr(block,block)
!hpf$ distribute force(block,block,block)
!hpf$ distribute force2(block)
!hpf$ distribute glatup(block)
!hpf$ distribute glonup(block)
!hpf$ distribute gp(block)
!hpf$ distribute kq(block)
!hpf$ distribute nh(block)
!hpf$ distribute nreps(block,block)
!hpf$ distribute obserr(block,block,block)
!hpf$ distribute offlev(block)
!hpf$ distribute qobs(block,block)
!hpf$ distribute reg(block)
!hpf$ distribute slam(block)
!hpf$ distribute symat(block)
!hpf$ distribute symat_temp(block)
!hpf$ distribute vcorox(block,block,block)
!hpf$ distribute vhc(block,block,block)
!hpf$ distribute volcentre_x(block)
!hpf$ distribute volcentre_y(block)
!hpf$ distribute weights(block,block,block)
!hpf$ distribute ww(block,block,block)
      DATA aug / 1.01, 1.1, 10. /
      integer nfact

      COMMON / gridxx / im, jnp, mlev
      COMMON / region / reg (13104)
      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)

      integer,dimension(NumMinVols,600):: gplat,gplon
!hpf$ distribute gplat(block,block),gplon(block,block)

      real,dimension(NumMinVols,70):: plat,plon,pstd,
     &     gstd,pdel,pkx,wlat,wlon,wstd,wkx,plst,wlst,glat,
     &     glon

      real,dimension(NumMinVols,150):: type
!hpf$ distribute     type(block,block)

!hpf$ distribute     plat(block,block),plon(block,block)
!hpf$ distribute     pstd(block,block),gstd(block,block)
!hpf$ distribute     pdel(block,block)
!hpf$ distribute     pkx(block,block),wlat(block,block)
!hpf$ distribute     wlon(block,block),wstd(block,block)
!hpf$ distribute     wkx(block,block),plst(block,block)
!hpf$ distribute     wlst(block,block)
!hpf$ distribute     glat(block,block),glon(block,block)

      integer,dimension(NumMinVols)::np,nw
!hpf$ distribute np(block),nw(block)

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

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

      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)

         IF(     UNISLP) THEN
            CRSCOV = ZERO
         ELSE
            CRSCOV = ONE
         END IF


      do levels = lu, ld, nv

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

           call puv_prep_cov(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,wkx,
     &             glat,glon,np,nw)
        endif

!  Call a local driver to compute and solve covariance matrices
!        call solvedrvl(levels)
!  Store covariance matrices locally
!        call storel()

      end do

      write(6,'("...matrix solutions complete.")')
      write(6,'(//)')

!  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

      RETURN
      END
