C CCC  CCCCCCCCCCCCCCCCCCCCCCC
C W.Quapp  24.12.2009    
c GRADIENT to scratchfile
c for GamessUS output of Ala2 
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
      Real*8 En,Um,Gr(60),He(60,60),Bmat(60,66),gmat(60,60),
     1 ginv(60,60),XX(58,58),YY(58,58),ZZ(58)
      Integer NAT,I,J,K,Ivar(60),Jnum(6),istatus
      Logical omat_inv
      Character*5 Z5
      Character*6 Z6
      Character*7 Z7
      Character*2 Z2
      Character*18 Z18
      Character*80 Z80
      OPEN(71,FILE='Energyfile')
      OPEN(72,FILE='Gradfile')
      OPEN(73,FILE='Hessfile')
      OPEN(74,FILE='Bmatfile')
      OPEN(75,FILE='Gmatfile')
      OPEN(13,FILE='a22Vener.dat',status='unknown',access='append')
      OPEN(14,FILE='a22Vgrad.dat',status='unknown',access='append')
      OPEN(15,FILE='a22Vhesse.dat',status='unknown',access='append')
      OPEN(18,FILE='a22Vistat.dat')
      OPEN(48,FILE='a22Vgmatr.dat',status='unknown',access='append')
      OPEN(44,FILE='a22Vprotocol.txt',status='unknown',access='append')
c 
c ! Note: DimensionReduktion um DoF 6 and 60 !!!
c
       NAT=59
       read(18,*) istatus
ccccccccccccccccccccccccccccccccccccccccccccccccccccc
       read(71,*,END=91) Z5, Z6, Z2, En
81     FORMAT(1X,A18,F18.10)
       if(istatus.eq.2) rewind 13
       write(13,523) En 
523    FORMAT(1X,F18.10)
cccccccccccccccccccccccccccccccccccccccccccccccccccccc 
c   Gradient:
       Do I=1,3
        read(72,*) 
       enddo
       Do I=1,NAT  
        read(72,82,END=92) Ivar(I), Z7, (Jnum(J),J=1,6), En, Gr(I)
c        write(*,82)        Ivar(I), Z7, (Jnum(J),J=1,6), En, Gr(I)
       enddo 
82     FORMAT(1X,I5,1X,A7,1X,6I5,2F16.7)
       if(istatus.eq.2) rewind 14 
       write(14,52) (Gr(I),I=1,3)
       write(14,52) Gr(4),Gr(5),Gr(7)
       write(14,52) (Gr(I),I=8,NAT)
52     FORMAT(1X, 3F15.11)
cccccccccccccccccccccccccccccccccccccccccccccccccccccc 
c Hesse matrix
       Do I=1,10
        read(73,*)
       enddo
       Do 23 k=1,12       
       Do I=1,NAT
        read(73,83,END=93) Ivar(I), (He(I,J),J=(K-1)*5+1,(K-1)*5+5)
        enddo
C  !  beachte:  hessian output bis 60         
        Do I=1,4
         read(73,*)
        enddo
23     continue                        
83     FORMAT(1X,I4,1X,5(1X,F11.7))
       if(istatus.eq.2) rewind 15
       Do  I=1,5
        WRITE(15,53) (He(I,J),J=1,3)
        WRITE(15,53) (He(I,J),J=4,5),He(I,7)
        WRITE(15,53) (He(I,J),J=8,NAT)
       enddo
       Do  I=7,NAT
        WRITE(15,53) (He(I,J),J=1,3)
        WRITE(15,53) (He(I,J),J=4,5),He(I,7)
        WRITE(15,53) (He(I,J),J=8,NAT)
       enddo
53     FORMAT(1X,3F15.10)
c            
cc alt       goto 123
ccccccccccccccccccccccccccccccccccccccccccccccccccccccc
c B matrix 
      Do I=1,5
       read(74,*)
      enddo
c               13= [ (Nat+6) : 5 ] 
      Do 22 k=1,13
      Do I=1,NAT
       read(74,84,END=94) Ivar(I), (Bmat(I,J),J=(K-1)*5+1,(K-1)*5+5)
      enddo
      read(74,*)
      read(74,*)  ! beachte dim-reduction
      read(74,80) Z80
      read(74,*)
22    continue 
80    FORMAT(A80)
      Do I=1,NAT
       read(74,844,END=94) Ivar(I), Bmat(I,66)
      enddo
84     FORMAT(1X,I4,1X,5(1X,F11.7))
844    FORMAT(1X,I4,1X,1(1X,F11.7))
cccccc Make Metric G=B*B^T 
      DO 16  I=1,NAT
      DO 16  J=1,NAT
        UM=0.0d0
       DO K=1,NAT+6
        UM=UM+Bmat(I,K)*Bmat(J,K)
       enddo                                                                                                                 17      CONTINUE
16     Ginv(I,J)=UM                                                                                                                

C CCC  CCCCCCCCCCCCCCCCCCCC
C W.Quapp  09.11.2007 for Ala
c inverse Metric Matrix to scratchfile
CCCCCCCCCCCCCCCCCCCCCCCCCCC
c also dih6 fixed :
      do 371, I=1,5
       do 371, J=1,5
371    XX(I,J)=Ginv(I,J)
      Do 377, I=6,NAT-1
       Do 378, J=6,NAT-1
378    XX(I,J)=Ginv(I+1,J+1)
377   continue
 
      if(istatus.eq.2) rewind 48
      Do 37, I=1,NAT-1
37    WRITE(48,50) (XX(I,J),J=1,NAT-1)
      WRITE(48,*)
50    FORMAT(1X,3F20.10)
cccccccccccccccccccccccccccccccccccccccccccc
        call SVDCMP(XX,NAT-1,NAT-1,NAT-1,NAT-1,ZZ,YY) 
        Um=10.1d0**10
        Do J=1,NAT-1
        IF(ZZ(J).lt.Um) Um=ZZ(J)
        enddo
        if(istatus.eq.2) then
         WRITE(44,*) ' smallest SVD of gmat(i,j) is ', Um
        endif
        Um=1.0d0
        Do J=1,NAT-1
          Um=Um*ZZ(J)
        enddo
        if(istatus.eq.2) then
          WRITE(44,*) ' Product of SVD of gmat(i,i) is ', Um 
          WRITE(44,*) ' vector of singular values ' 
          WRITE(44,50) (ZZ(J),J=1,NAT-1)
        endif 
       Do 55 K=1,NAT-1
       ZZ(K)=1.0d0/ZZ(K)
55     continue
       Do 111 I=1,NAT-1
           Do K=1,NAT-1
              XX(I,K)=XX(I,K)*ZZ(K)
           enddo
111    continue       
c
        Do 112 I=1,NAT-1
           Do 110 J=1,NAT-1
              gmat(I,J)=0.0d0
              Do 109 K=1,NAT-1
109           gmat(I,J)= gmat(I,J)+XX(I,K)*YY(J,K)
110        continue
112     continue
        Do 3382, J=1,NAT-1
3382    WRITE(48,50) (gmat(J,I),I=1,NAT-1)
        WRITE(48,*)
        goto 11
ccccccccccccccccccccccccccccccccccccccccccccccccccccccc
123   continue       
c ginv + gmat direct matrix from GamessUS
      Do I=1,4
       read(75,*)
      enddo
c               12= [ Nat : 5 ]
      Do 222 k=1,NAT/5
      Do I=1,NAT
       read(75,84,END=94) Ivar(I), (ginv(I,J),J=(K-1)*5+1,(K-1)*5+5)
      enddo
      read(75,*)
      read(75,80) Z80
      read(75,*)
222    continue
85     FORMAT(1X,I4,2X,5(F12.7))
cc      Do I=1,NAT
cc       read(75,844,END=94) Ivar(I), ginv(I,66)
cc       write(52,844)       Ivar(I), ginv(I,66)
cc      enddo
cc844    FORMAT(1X,I4,1X,1(1X,F11.7))
      Do I=1,3
        read(75,*)
      enddo
c               12= [ Nat : 5 ]
      Do 2121 k=1,NAT/5
      Do I=1,NAT
       read(75,84,END=94) Ivar(I), (gmat(I,J),J=(K-1)*5+1,(K-1)*5+5)
      enddo
      read(75,*)
      read(75,80) Z80
      read(75,*)
2121  continue
c      Do I=1,NAT
c       read(75,844,END=94) Ivar(I), gmat(I,66)
c      enddo
      Do 313, J=1,NAT
313     WRITE(18,50) (ginv(J,I),I=1,NAT)
        write(18,*)
      Do 323, J=1,NAT
323     WRITE(18,50) (gmat(J,I),I=1,NAT)
        write(18,*)
       goto 11
ccccccccccccccccccccccccccccccccccccccccccccccccccccccc
91     continue
      write(6,*) 'Stop ohne Energy '
      write(44,*) ' ERROR !!! Energy is missing !!! '
       goto1
92    continue
       write(6,*) 'Stop ohne Gradient '
       write(44,*) ' ERROR !!! Gradient is missing !!! '
       goto1
93    continue
       write(6,*) 'Stop ohne Hessian '
       write(44,*) ' ERROR !!! Hessian is missing !!! '
       goto1
94    continue
       write(6,*) 'Stop ohne Metric '
       write(44,*) ' ERROR !!! Metric is missing !!! '
1     continue
      istatus=10
      WRITE(*,*)' Exit-Status DATEN ', istatus
      WRITE(44,*)' Exit-Status DATEN ', istatus
11    continue
      call exit(istatus)
      STOP      
      End
c ------------------------------------------------------------------------
      subroutine ginvers(in,NAT,out,omat_inv)
c    calculates the inverse matrix of IN
      real*8 in,out
      logical omat_inv
      integer NAT,i,j,k
      dimension in(NAT,NAT),out(NAT,NAT)
      do 1,k=1,NAT
      do 1,j=1,NAT
  1   out(j,k)=in(j,k)
c
      do 10,k=1,NAT
         if (out(k,k).eq.0.0d0) then
            omat_inv=.false.
            return
         endif
         out(k,k)=1.0d0/out(k,k)
         do 20,i=1,NAT
             if (i.ne.k) out(i,k)=-(out(i,k)*out(k,k))
   20    continue
         do 30,j=1,NAT
             if (j.ne.k) then
                do 40,i=1,NAT
                      if (i.ne.k) out(i,j)=out(i,j)+out(i,k)*out(k,j)
   40           continue
                out(k,j)=out(k,j)*out(k,k)
             endif
   30    continue
   10 continue
      omat_inv=.true.
      return
      end
C ccccccccccccccccccccccccccccccccccccccccc                   
      SUBROUTINE SVDCMP(A,M,N,Mp,Np,W,V)
      IMPLICIT NONE
      INTEGER M, N, Mp, Np
      DOUBLE PRECISION A(Mp, Np), W(Np), V(Np,Np)
c Routine to do singular value decomposition of the matrix A.
c Based on the Press et.al routine (Numerical Recipes)
      INTEGER NMAX
      PARAMETER (NMAX=100)
      DOUBLE PRECISION rv1(NMAX)
      DOUBLE PRECISION anorm, c, f, g, h, s, scale, x, y, z
      INTEGER i, its, j, k, l, nm, jj, l1

      g = 0.0d0
      scale = 0.0d0
      anorm = 0.0d0
      DO i = 1 , N
         l = i + 1
         rv1(i) = scale*g
         g = 0.0d0
         s = 0.0d0
         scale = 0.0d0
         IF ( i.LE.M ) THEN
            DO k = i , M
               scale = scale + ABS(A(k,i))
            ENDDO
            IF ( scale .NE. 0.0d0 ) THEN
               DO k = i , M
                  A(k,i) = A(k,i)/scale
                  s = s + A(k,i)*A(k,i)
               ENDDO
               f = A(i,i)
               g = -SIGN(SQRT(s),f)
               h = f*g - s
               A(i,i) = f - g
               IF ( i.NE.N ) THEN
                  DO j = l , N
                     s = 0.0d0
                     DO k = i , M
                        s = s + A(k,i)*A(k,j)
                     ENDDO
                     f = s/h
                     DO k = i , M
                        A(k,j) = A(k,j) + f*A(k,i)
                     ENDDO
                  ENDDO
               ENDIF
               DO k = i , M
                  A(k,i) = scale*A(k,i)
               ENDDO
            ENDIF
         ENDIF
         W(i) = scale*g
         g = 0.0d0
         s = 0.0d0
         scale = 0.0d0
         IF ( (i.LE.M) .AND. (i.NE.N) ) THEN
            DO k = l , N
               scale = scale + ABS(A(i,k))
            ENDDO
            IF ( scale .NE. 0.0d0 ) THEN
               DO k = l , N
                  A(i,k) = A(i,k)/scale
                  s = s + A(i,k)*A(i,k)
               ENDDO
               f = A(i,l)
               g = -SIGN(SQRT(s),f)
               h = f*g - s
               A(i,l) = f - g
               DO k = l , N
                  rv1(k) = A(i,k)/h
               ENDDO
               IF ( i.NE.M ) THEN
                  DO j = l , M
                     s = 0.0d0
                     DO k = l , N
                        s = s + A(j,k)*A(i,k)
                     ENDDO
                     DO k = l , N
                        A(j,k) = A(j,k) + s*rv1(k)
                     ENDDO
                  ENDDO
               ENDIF
               DO k = l , N
                  A(i,k) = scale*A(i,k)
               ENDDO
            ENDIF
         ENDIF
         anorm = MAX(anorm,(ABS(W(i))+ABS(rv1(i))))
      ENDDO

      DO i = N , 1 , -1
         IF ( i.LT.N ) THEN
            IF ( g .NE. 0.0d0 ) THEN
               DO j = l , N
                  V(j,i) = (A(i,j)/A(i,l))/g
               ENDDO
               DO j = l , N
                  s = 0.0d0
                  DO k = l , N
                     s = s + A(i,k)*V(k,j)
                  ENDDO
                  DO k = l , N
                     V(k,j) = V(k,j) + s*V(k,i)
                  ENDDO
               ENDDO
            ENDIF
            DO j = l , N
               V(i,j) = 0.0d0
               V(j,i) = 0.0d0
            ENDDO
         ENDIF
         V(i,i) = 1.0
         g = rv1(i)
         l = i
      ENDDO

      DO i = N , 1 , -1
         l = i + 1
         g = W(i)
         IF ( i.LT.N ) THEN
            DO j = l , N
               A(i,j) = 0.0d0
            ENDDO
         ENDIF
         IF ( g .NE. 0.0d0 ) THEN
            g = 1.0/g
            IF ( i.NE.N ) THEN
               DO j = l , N
                  s = 0.0d0
                  DO k = l , M
                     s = s + A(k,i)*A(k,j)
                  ENDDO
                  f = (s/A(i,i))*g
                  DO k = i , M
                     A(k,j) = A(k,j) + f*A(k,i)
                  ENDDO
               ENDDO
            ENDIF
            DO j = i , M
               A(j,i) = A(j,i)*g
            ENDDO
         ELSE
            DO j = i , M
               A(j,i) = 0.0d0
            ENDDO
         ENDIF
         A(i,i) = A(i,i) + 1.0
      ENDDO

      DO k = N , 1 , -1
         DO its = 1 , 30
            DO l = k , 1 , -1
               l1 = l
               nm = l - 1
               IF ( (ABS(rv1(l))+anorm).EQ.anorm ) GOTO 380
               IF ( (ABS(W(nm))+anorm).EQ.anorm ) GOTO 340
            ENDDO
 340        CONTINUE
            l = l1
            c = 0.0d0
            s = 1.0d0
            DO i = l , k
               f = s*rv1(i)
               rv1(i) = c*rv1(i)
               IF ( (ABS(f)+anorm).NE.anorm ) THEN
                  g = W(i)
                  h = SQRT(f*f+g*g)
                  W(i) = h
                  h = 1.0d0/h
                  c = (g*h)
                  s = -(f*h)
                  DO j = 1 , M
                     y = A(j,nm)
                     z = A(j,i)
                     A(j,nm) = (y*c) + (z*s)
                     A(j,i) = -(y*s) + (z*c)
                  ENDDO
               ENDIF
 360        ENDDO
 380        CONTINUE
            z = W(k)
            IF ( l.EQ.k ) THEN
               IF ( z .LT. 0.0d0 ) THEN
                  W(k) = -z
                  DO j = 1 , N
                     V(j,k) = -V(j,k)
                  ENDDO
               ENDIF
               GOTO 500
            ENDIF
            IF ( its .EQ. 30 ) write(*,*)
     &        'SVDCMP: No convergence in 30 iterations'
            x = W(l)
            nm = k - 1
            y = W(nm)
            g = rv1(nm)
            h = rv1(k)
            f = ((y-z)*(y+z)+(g-h)*(g+h))/(2.0d0*h*y)
            g = SQRT(f*f+1.0d0)
            f = ((x-z)*(x+z)+h*((y/(f+SIGN(g,f)))-h))/x
            c = 1.0d0
            s = 1.0d0
            DO j = l , nm
               i = j + 1
               g = rv1(i)
               y = W(i)
               h = s*g
               g = c*g
               z = SQRT(f*f+h*h)
               rv1(j) = z
               c = f/z
               s = h/z
               f = (x*c) + (g*s)
               g = -(x*s) + (g*c)
               h = y*s
               y = y*c
               DO jj = 1 , N
                  x = V(jj,j)
                  z = V(jj,i)
                  V(jj,j) = (x*c) + (z*s)
                  V(jj,i) = -(x*s) + (z*c)
               ENDDO
               z = SQRT(f*f+h*h)
               W(j) = z
               IF ( z .NE. 0.0d0 ) THEN
                  z = 1.0d0/z
                  c = f*z
                  s = h*z
               ENDIF
               f = (c*g) + (s*y)
               x = -(s*g) + (c*y)
               DO jj = 1 , M
                  y = A(jj,j)
                  z = A(jj,i)
                  A(jj,j) = (y*c) + (z*s)
                  A(jj,i) = -(y*s) + (z*c)
               ENDDO
            ENDDO
            rv1(l) = 0.0d0
            rv1(k) = f
            W(k) = x
         ENDDO
 500     CONTINUE
      ENDDO
      RETURN
      END
