      LOGICAL FUNCTION CONVRG (A,NX,B,SHIFTS,SIGUWT)

*** UPDATE THE UNKNOWNS AND TEST FOR CONVERGENCE

      IMPLICIT DOUBLE PRECISION (A-H,O-Z)
      IMPLICIT INTEGER (I-N)
      PARAMETER (MXSSN = 9999)
      CHARACTER*30 NAME1,NAMES
      LOGICAL GETA
      LOGICAL ELFLAG,DFFLAG,FLAGCD
      LOGICAL LMSL,LSS,LUP
      LOGICAL LBB,LGF,LCS,LVD,LVA,LVZ,LVS,
     &        LVR,LVG,LVC,LIS,LPS,LPG,LDR,LOS,LAP
      DIMENSION A(*),NX(*),B(*),SHIFTS(*)

      COMMON /STRUCT/ NSTA,NAUX,NUNK,IDIM,NSTAS,NOBS,NCON,NZ,NCD
      COMMON /STUFF/ ITER
      COMMON /NAMTAB/ NAMES(MXSSN)
      COMMON /OPT/ AX,E2,DMSL,DGH,VM,VP,CTOL,ITMAX,ITMIN,IMODE,
     &             LMSL,LSS,LUP
      COMMON /FLAGS/ ELFLAG(MXSSN),DFFLAG(MXSSN)
      COMMON /OPRINT/ CRIT,LBB,LGF,LCS,LVD,LVA,LVZ,LVS,
     &                LVR,LVG,LVC,LIS,LPS,LPG,LDR,LOS,LAP
      COMMON /CONST/ PI,PI2,RAD,RADSEC,TWOPI
      COMMON /ALICE/ IPRSZ

      SAVE ISNX,GLAT,GLON,EHT,RX,RY
      SAVE SHFMX,ISHFMX,IISN

      SSQ = 0.D0
      N1 = NUNK + 1
      SHFMX = -1.D0
      IISN = 0
      ISHFMX = 0
      ICDPX = 0
      FLAGCD = .FALSE.

*** LOOP OVER ALL UNKNOWNS

      ISNX = 0
      DO 2 I = 1,NUNK
        IF ( .NOT.GETA(I,N1,VAL,A,NX) ) THEN
          WRITE (6,1)
    1     FORMAT ('0PROGRAMMER ERROR IN CONVRG')
          CALL ABORT2
        ELSE
          CALL INVIUN (I,ISN,ITYPE,IUCODE)
          IF (IUCODE.EQ.0) THEN

*** GET COORDINATES AND RADII

            IF (ISN.NE.ISNX) THEN
              ISNX = ISN
              CALL GETGLA (GLAT,ISN,B)
              CALL GETGLO (GLON,ISN,B)
              CALL GETMSL (GMSL,ISN,B)
              CALL GETGH (GHT,ISN,B)
              EHT = GMSL + GHT
              CALL RADCUR (GLAT,RMER,RPV) 
              RX = RMER + EHT
              RY = (RPV + EHT) * DCOS(GLAT)
            ENDIF

*** UPDATE LATITUDE

            IF ( ITYPE.EQ.1 ) THEN
              VALRAD = VAL / RADSEC
              VALMET = VALRAD * RX
              IF (LPS) THEN
                J = IUNSHF(ISN,ITYPE)
                SHIFTS(J) = SHIFTS(J) + VALMET
              ENDIF
              SSQ = SSQ + VALMET * VALMET
              GLAT = GLAT + VALRAD
              CALL PUTGLA (GLAT,ISN,B)
              IF ( .NOT.DFFLAG(ISN) ) CALL PUTALA (GLAT,ISN,B)

*** UPDATE LONGITUDE

            ELSEIF ( ITYPE.EQ.2 ) THEN
              VALRAD = VAL / RADSEC
              VALMET = VALRAD * RY
              IF (LPS) THEN
                J = IUNSHF(ISN,ITYPE)
                SHIFTS(J) = SHIFTS(J) + VALMET
              ENDIF
              SSQ = SSQ + VALMET * VALMET
              GLON = GLON + VALRAD
              CALL PUTGLO (GLON,ISN,B)
              IF ( .NOT.DFFLAG(ISN) ) CALL PUTALO (GLON,ISN,B)

*** UPDATE HEIGHT

            ELSEIF ( ITYPE.EQ.3 ) THEN
              VALMET = VAL
              IF (LPS) THEN
                J = IUNSHF(ISN,ITYPE)
                SHIFTS(J) = SHIFTS(J) + VALMET
              ENDIF
              SSQ = SSQ + VALMET * VALMET
              IF ( .NOT.ELFLAG(ISN) ) THEN
                GHT = GHT + VALMET
                CALL PUTGH (GHT,ISN,B)
              ELSE
                GMSL = GMSL + VALMET
                CALL PUTMSL (GMSL,ISN,B)
              ENDIF
            ENDIF

*** LOCATE THE MAXIMUM SHIFT

            IF (LPS) THEN
              IF (DABS(VALMET).GT.SHFMX) THEN
                SHFMX = DABS(VALMET)
                ISHFMX = I
                IISN = ISN
              ENDIF
            ENDIF

*** AUXILIARY PARAMETER TYPES

          ELSEIF (IUCODE.EQ.1) THEN
            IAUX = ISN
            CALL GETAUX (AUX,IAUX,B)
            AUX = AUX + VAL
            CALL PUTAUX (AUX,IAUX,B)

*** CRUSTAL VELOCITY PARAMETER TYPES

          ELSEIF (IUCODE.EQ.2) THEN
            IF(ITYPE .EQ. 3) THEN
               B(ISN) = B(ISN) + VAL
            ELSE
               B(ISN) = B(ISN) + VAL/RADSEC
            ENDIF

*** ROTATION PARAMETER TYPES

          ELSEIF (IUCODE.EQ.3) THEN
            IZ = ISN
            CALL GETROT (AUX,IZ,B)
            AUX = AUX + VAL
            CALL PUTROT (AUX,IZ,B)

          ELSE
            WRITE (6,666) IUCODE
  666       FORMAT ('0ERROR - ILLEGAL PARAMETER CODE IN CONVRG--',I5)
            CALL ABORT2
          ENDIF

        ENDIF
    2 CONTINUE

*** TEST FOR CONVERGENCE

      VAL = DSQRT( SSQ / (NSTA * 3) )
      IF (VAL.LE.CTOL) THEN
        CONVRG = .TRUE.
      ELSE
        CONVRG = .FALSE.
      ENDIF

*** PRINT RMS SHIFT AND V'PV

      IF ( .NOT.GETA(N1,N1,VTPV,A,NX) ) THEN
        WRITE (6,667) N1
  667   FORMAT ('0BASEMENT WINDOW ERROR--',I5)
        CALL ABORT2
      ENDIF
      IDOF = NOBS + NCON - NUNK
      IF (VTPV.LT.0.0) THEN
        WRITE (6,5)
   5    FORMAT ('0*** WARNING: NEGATIVE VTPV ***')
        VARUWT = DIVIDE( DABS(VTPV),IDOF )
      ELSE
        VARUWT = DIVIDE(VTPV,IDOF)
      ENDIF
      SIGUWT = DSQRT(VARUWT)
      CALL LINE (2)
      WRITE (6,3) ITER,VAL,VTPV,IDOF,VARUWT
*AD 3 FORMAT ('0ITERATION #',I2,' THE RMS CORRECTION IS ',F10.3,
*AD  &        ' METERS --- VTPV  =  ',F15.3,'  DF=',I6,
*AD  &        '  VARIANCE = ',F15.2)
    3 FORMAT ('0ITERATION #',I2,' THE RMS CORRECTION IS',G15.8,
     &        ' METERS --- VTPV  =',G20.8,'  DF=',I6,
     &        '  VARIANCE =',G20.7)
      IF (LPS) THEN
        CALL LINE (2)
        CALL INVIUN (ISHFMX,IISN,ITP,IUCODE)
        NAME1 = NAMES(IISN)
        IF (ITP.EQ.1) THEN
          WRITE (6,6) NAME1,SHFMX
   6      FORMAT ('0 MAXIMUM SHIFT - STATION: ',A30,10X,
     &            'LATITUDE SHIFT =  ',F10.3,' METERS')
        ELSEIF (ITP.EQ.2) THEN
          WRITE (6,7) NAME1,SHFMX
   7      FORMAT ('0 MAXIMUM SHIFT - STATION: ',A30,10X,
     &            'LONGITUDE SHIFT= ',F10.3,' METERS')
        ELSEIF (ITP.EQ.3) THEN
          WRITE (6,8) NAME1,SHFMX
   8      FORMAT ('0 MAXIMUM SHIFT - STATION: ',A30,10X,
     &            'VERTICAL SHIFT= ',F10.3,' METERS')
        ENDIF
      ENDIF
      RETURN
      END
