c---------------------------------------------------------------------c
c         N A S A   /  D A O     A N A L Y S I S   G R O U P          c
c    Optimum Interpolation Analysis System   Version 1.2  Fall, 1991  c
c                                                                     c
c.....................................................................c
C                                                                     .
C  Program:    PUVANL                                                 .
C  Language:   Fortran 77 (with Fortran 90 enhancements)              .
C  Computer:   Cray YMP 864                                           .
C                                                                     .
C  Programmer: J. Pfaendtner, M. Seablom                              .
C  Date:       December, 1991                                         .
C                                                                     .
C  Program PUVANL is the driver for the surface analysis.             .
C                                                                     .
C......................................................................
C**********************************************************************
C  Data parallel implementation (CM Fortran) : M. Makivic (NPAC)      *
C  Date:       4/94                                                   *
C**********************************************************************


      SUBROUTINE puvanl(fcerr,phis,psl,usl,vsl,tsfc,aquan,asdae,t,
     &  ze,zelat,zelon,nze,fgslp,data_mm,nobs,suspect)
      include 'params.h'
      include 'processors.h'


      integer NumMinVols, mv_begin,mv_end
      real  aquan( im,jnp, mlev+1, nq ), asdae( im,jnp, mlev+1 ),
     &      fcerr( im,jnp ), fgslp( im,jnp ), phis( im,jnp ),
     &      psl( im,jnp ), t( im,jnp,mlev ), tsfc( im,jnp ),
     &      usl( im,jnp ), vsl( im,jnp ), ze(20000), zelat(20000),
     &      zelon(20000), max_value,min_value

      real,dimension(nobs,NRECORDS):: data_mm
      integer,dimension(nobs,2):: suspect
      integer i
      logical
     &      onestage, seasat, usesas, dalflg, 
     &      repack,mask(im,jnp)

      character * 60
     &      message


      COMMON /DATAPTRS/ IKX, ILAT, ILON, IPRES, ITYPE, IDELSLP, IFCER

      COMMON /DALCTL/   SEASAT, USESAS, DALFLG

      common /scan/     maxobs, rscan, onestage, max_data

      COMMON /GRIDXX/   IM, JNP, MLEV

      common /sparam/ lsolve, ns, nr, nv, nh(13104), nq,
     &                kq(3), volcentre_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


      data fill /1.e10/


      real,dimension(1:nobs):: latitude,longitude,datfcerr
!hpf$ distribute latitude(block)
!hpf$ align with latitude:: longitude,datfcerr

!hpf$ distribute data_mm(block,*) onto PROC_ARRAY_1D
!hpf$ distribute suspect(block,*) onto PROC_ARRAY_1D

!hpf$ distribute aquan(*,block,*,*) onto PROC_ARRAY_1D
!hpf$ distribute asdae(*,block,*) onto PROC_ARRAY_1D
!hpf$ distribute fcerr(*,block) onto PROC_ARRAY_1D
!hpf$ distribute phis(*,block) onto PROC_ARRAY_1D
!hpf$ distribute psl(*,block) onto PROC_ARRAY_1D
!hpf$ distribute t(*,block,*) onto PROC_ARRAY_1D
!hpf$ distribute tsfc(*,block) onto PROC_ARRAY_1D
!hpf$ distribute usl(*,block) onto PROC_ARRAY_1D
!hpf$ distribute vsl(*,block) onto PROC_ARRAY_1D
!hpf$ distribute ze(block) onto PROC_ARRAY_1D
!hpf$ distribute zelat(block) onto PROC_ARRAY_1D
!hpf$ distribute zelon(block) onto PROC_ARRAY_1D

!hpf$ align with phis:: mask

C  Initialize parameters.

      lev = mlev + 1
      kq(1) = 2
      kq(2) = 3
      kq(3) = 4

      aquan(:,:,lev,:) = 0.0
      suspect = 0
      asdae(:,:,lev) = fcerr(:,:)
      message(1:60) = ' '

      CALL getconi('NYMD    ',nymd)
      CALL getconi('NHMS    ',nhms)

      WRITE( 6,'(/,1x," Initiate sea level pressure analysis",       " f
     &or ",i7,1x,i7)' ) nymd,nhms

C  Read sea level pressure and surface wind data.
      IF (nobs .EQ. 0) THEN
        message = 'PUVANL: No data!'
        CALL flash(2,message,1)
        RETURN
      ENDIF


C  INTERPOLATE FORECAST ERROR TO DATA POINTS
      latitude=data_mm(1:nobs,ind_lat)
      longitude=data_mm(1:nobs,ind_lon)
      call terpv(latitude,longitude,datfcerr,nobs,fcerr)
      data_mm(:,ind_fcer)=datfcerr

      WRITE( 6,'(/,1x," PUVANL: Number of observations ",i10)' ) nobs

C  FORM COVARIANCE MATRICES AND SOLVE FOR ANALYSIS INCREMENTS

c      CALL puv_driver(ngv,lev,lev,fcerr,aquan,asdae,data_mm,nobs)
      do i=1,100
      mv_begin=10*i
      NumMinVols=10
      mv_end=mv_begin + NumMinVols -1
      CALL puv_driver(mv_begin,mv_end,NumMinVols,lev,
     &                lev,fcerr,data_mm,nobs)

      end do

C  ADD ANALYSIS INCREMENTS TO FIRST GUESS AND SET ANALYSIS ERRORS
      where(psl.lt.fill) psl=psl+aquan(:,:,lev,1)
      where(usl.lt.fill) usl=usl+aquan(:,:,lev,2)
      where(vsl.lt.fill) vsl=vsl+aquan(:,:,lev,3)

      max_value = -9.99E9
      min_value = 9.99E9
      mask=psl.ne.fill
      max_value=maxval(ARRAY=psl,MASK=mask)
      min_value=minval(ARRAY=psl,MASK=mask)
      WRITE( 6,'(/," PUVANL: Max slp value: ",e13.4)' ) max_value
      WRITE( 6,'(/," PUVANL: Min slp value: ",e13.4)' ) min_value

      max_value = -9.99E9
      min_value = 9.99E9
      mask=usl.ne.fill
      max_value=maxval(ARRAY=usl,MASK=mask)
      min_value=minval(ARRAY=usl,MASK=mask)
      WRITE( 6,'(/," PUVANL: Max usl value: ",e13.4)' ) max_value
      WRITE( 6,'(/," PUVANL: Min usl value: ",e13.4)' ) min_value

      max_value = -9.99E9
      min_value = 9.99E9
      mask=vsl.ne.fill
      max_value=maxval(ARRAY=vsl,MASK=mask)
      min_value=minval(ARRAY=vsl,MASK=mask)
      WRITE( 6,'(/," PUVANL: Max vsl value: ",e13.4)' ) max_value
      WRITE( 6,'(/," PUVANL: Min vsl value: ",e13.4)' ) min_value


      RETURN
      END
