Statistiques
| Révision :

root / src / Step_DIIS.f90 @ 1

Historique | Voir | Annoter | Télécharger (10,29 ko)

1 1 equemene
!C  HEAT is never used, not even in call of Space(...)
2 1 equemene
!C  XPARAM = input parameter vector (Geometry).
3 1 equemene
!C  Grad = input gradient vector.
4 1 equemene
      SUBROUTINE Step_DIIS(XP,XPARAM,GP,GRAD,HP,HEAT,Hess,NVAR,FRST)
5 1 equemene
	  !SUBROUTINE DIIS(XPARAM,STEP,GRAD,HP,HEAT,Hess,NVAR,FRST)
6 1 equemene
!      IMPLICIT DOUBLE PRECISION (A-H,O-Z)
7 1 equemene
      IMPLICIT NONE
8 1 equemene
      integer, parameter :: KINT = kind(1)
9 1 equemene
      integer, parameter :: KREAL = kind(1.0d0)
10 1 equemene
11 1 equemene
!      INCLUDE 'SIZES'
12 1 equemene
13 1 equemene
      INTEGER(KINT) :: NVAR
14 1 equemene
      REAL(KREAL) :: XP(NVAR), XPARAM(NVAR), GP(NVAR), GRAD(NVAR), Hess(NVAR*NVAR)
15 1 equemene
	  !REAL(KREAL) :: Hess_inv(NVAR,NVAR),XPARAM_old(NVAR),STEP(NVAR)
16 1 equemene
      REAL(KREAL) :: HEAT, HP
17 1 equemene
      LOGICAL :: FRST
18 1 equemene
19 1 equemene
!************************************************************************
20 1 equemene
!*                                                                      *
21 1 equemene
!*     DIIS PERFORMS DIRECT INVERSION IN THE ITERATIVE SUBSPACE         *
22 1 equemene
!*                                                                      *
23 1 equemene
!*     THIS INVOLVES SOLVING FOR C IN XPARAM(NEW) = XPARAM' - HG'       *
24 1 equemene
!*                                                                      *
25 1 equemene
!*  WHERE XPARAM' = SUM(C(I)XPARAM(I), THE C COEFFICIENTES COMING FROM  *
26 1 equemene
!*                                                                      *
27 1 equemene
!*                   | B   1 | . | C | = | 0 |                          *
28 1 equemene
!*                   | 1   0 |   |-L |   | 1 |                          *
29 1 equemene
!*                                                                      *
30 1 equemene
!* WHERE B(I,J) =GRAD(I)H(T)HGRAD(J)  GRAD(I) = GRADIENT ON CYCLE I     *
31 1 equemene
!*                              Hess    = INVERSE HESSIAN                 *
32 1 equemene
!*                                                                      *
33 1 equemene
!*                          REFERENCE                                   *
34 1 equemene
!*                                                                      *
35 1 equemene
!*  P. CSASZAR, P. PULAY, J. MOL. STRUCT. (THEOCHEM), 114, 31 (1984)    *
36 1 equemene
!*                                                                      *
37 1 equemene
!************************************************************************
38 1 equemene
!************************************************************************
39 1 equemene
!*                                                                      *
40 1 equemene
!*     GEOMETRY OPTIMIZATION USING THE METHOD OF DIRECT INVERSION IN    *
41 1 equemene
!*     THE ITERATIVE SUBSPACE (GDIIS), COMBINED WITH THE BFGS OPTIMIZER *
42 1 equemene
!*     (A VARIABLE METRIC METHOD)                                       *
43 1 equemene
!*                                                                      *
44 1 equemene
!*     WRITTEN BY PETER L. CUMMINS, UNIVERSITY OF SYDNEY, AUSTRALIA     *
45 1 equemene
!*                                                                      *
46 1 equemene
!*                              REFERENCE                               *
47 1 equemene
!*                                                                      *
48 1 equemene
!*      "COMPUTATIONAL STRATEGIES FOR THE OPTIMIZATION OF EQUILIBRIUM   *
49 1 equemene
!*     GEOMETRIES AND TRANSITION-STATE STRUCTURES AT THE SEMIEMPIRICAL  *
50 1 equemene
!*     LEVEL", PETER L. CUMMINS, JILL E. GREADY, J. COMP. CHEM., 10,    *
51 1 equemene
!*     939-950 (1989).                                                  *
52 1 equemene
!*                                                                      *
53 1 equemene
!*     MODIFIED BY JJPS TO CONFORM TO EXISTING MOPAC CONVENTIONS        *
54 1 equemene
!*                                                                      *
55 1 equemene
!************************************************************************
56 1 equemene
57 1 equemene
      ! MRESET = number of iterations.
58 1 equemene
      INTEGER(KINT), PARAMETER :: MRESET=15, M2=(MRESET+1)*(MRESET+1) !M2 = 256
59 1 equemene
      REAL(KREAL), ALLOCATABLE, SAVE :: XSET(:),GSET(:),ERR(:) ! MRESET*NVAR
60 1 equemene
      REAL(KREAL) :: ESET(MRESET)
61 1 equemene
      REAL(KREAL), ALLOCATABLE, SAVE :: DX(:),GSAVE(:) !NVAR
62 1 equemene
      REAL(KREAL) :: B(M2),BS(M2),BST(M2)
63 1 equemene
      LOGICAL DEBUG, PRINT
64 1 equemene
      INTEGER(KINT), SAVE :: MSET
65 1 equemene
      INTEGER(KINT) :: NDIIS, MPLUS, INV, ITERA, MM
66 1 equemene
      INTEGER(KINT) :: I,J,K, JJ, KJ, JNV, II, IONE, IJ, INK,ITmp
67 1 equemene
      REAL(KREAL) :: XMax, XNorm, S, DET, THRES
68 1 equemene
69 1 equemene
      DEBUG=.TRUE.
70 1 equemene
      PRINT=.TRUE.
71 1 equemene
72 1 equemene
      IF (PRINT)  WRITE(*,'(/,''      BEGIN GDIIS   '')')
73 1 equemene
74 1 equemene
	  !XPARAM_old = XPARAM
75 1 equemene
76 1 equemene
! Initialization
77 1 equemene
      IF (FRST) THEN
78 1 equemene
! FRST will be set to False in Space, so no need to modify it here
79 1 equemene
         IF (ALLOCATED(XSET)) THEN
80 1 equemene
            IF (PRINT)  WRITE(*,'(/,''    In FRST, GDIIS Dealloc  '')')
81 1 equemene
            DEALLOCATE(XSet,GSET,ERR,DX,GSave)
82 1 equemene
            RETURN
83 1 equemene
         ELSE
84 1 equemene
            IF (PRINT)  WRITE(*,'(/,''     In FRST,  GDIIS alloc  '')')
85 1 equemene
            ALLOCATE(XSet(MRESET*NVAR), GSet(MRESET*NVAR), ERR(MRESET*NVAR))
86 1 equemene
            ALLOCATE(DX(NVAR),GSAVE(NVAR))
87 1 equemene
         END IF
88 1 equemene
      END IF
89 1 equemene
!C
90 1 equemene
!C  SPACE SIMPLY LOADS THE CURRENT VALUES OF XPARAM AND GRAD INTO
91 1 equemene
!C  THE ARRAYS XSET AND GSET
92 1 equemene
!C
93 1 equemene
!C  HEAT is never used, not even in Space(...)
94 1 equemene
      CALL SPACE(MRESET,MSET,XPARAM,GRAD,HEAT,NVAR,XSET,GSET,ESET,FRST)
95 1 equemene
96 1 equemene
      IF (PRINT)  WRITE(*,'(/,''       GDIIS after Space  '')')
97 1 equemene
98 1 equemene
   ! INITIALIZE SOME VARIABLES AND CONSTANTS:
99 1 equemene
      NDIIS = MSET
100 1 equemene
      MPLUS = MSET + 1
101 1 equemene
      MM = MPLUS * MPLUS
102 1 equemene
103 1 equemene
   ! COMPUTE THE APPROXIMATE ERROR VECTORS:
104 1 equemene
      INV=-NVAR
105 1 equemene
      DO 30 I=1,MSET
106 1 equemene
         INV = INV + NVAR
107 1 equemene
         DO 30 J=1,NVAR
108 1 equemene
            S = 0.D0
109 1 equemene
            KJ=(J*(J-1))/2
110 1 equemene
            DO 10 K=1,J
111 1 equemene
               KJ = KJ+1
112 1 equemene
   10       S = S - Hess(KJ) * GSET(INV+K)
113 1 equemene
            DO 20 K=J+1,NVAR
114 1 equemene
               KJ = (K*(K-1))/2+J
115 1 equemene
   20       S = S - Hess(KJ) * GSET(INV+K)
116 1 equemene
   30 ERR(INV+J) = S
117 1 equemene
118 1 equemene
119 1 equemene
120 1 equemene
    ! CONSTRUCT THE GDIIS MATRIX:
121 1 equemene
      ! initialization (not really needed)
122 1 equemene
      DO I=1,MM
123 1 equemene
         B(I) = 1.D0
124 1 equemene
      END DO
125 1 equemene
126 1 equemene
      ! B_ij calculations from <e_i|e_j>
127 1 equemene
      JJ=0
128 1 equemene
      INV=-NVAR
129 1 equemene
      DO 50 I=1,MSET
130 1 equemene
         INV=INV+NVAR
131 1 equemene
         JNV=-NVAR
132 1 equemene
         DO 50 J=1,MSET
133 1 equemene
            JNV=JNV+NVAR
134 1 equemene
            JJ = JJ + 1
135 1 equemene
            B(JJ)=0.D0
136 1 equemene
            DO 50 K=1,NVAR
137 1 equemene
   50 B(JJ) = B(JJ) + ERR(INV+K) * ERR(JNV+K)
138 1 equemene
139 1 equemene
     ! The following shifting is required to correct indices of B_ij elements in the GDIIS matrix.
140 1 equemene
	 ! The correction is needed because the last coloumn of the matrix contains all 1 and one zero.
141 1 equemene
      DO 60 I=MSET-1,1,-1
142 1 equemene
         DO 60 J=MSET,1,-1
143 1 equemene
   60 B(I*MSET+J+I) = B(I*MSET+J)
144 1 equemene
145 1 equemene
      ! For last row and last column of GDIIS matrix
146 1 equemene
      DO 70 I=1,MPLUS
147 1 equemene
         B(MPLUS*I) = 1.D0
148 1 equemene
   70 B(MPLUS*MSET+I) = 1.D0
149 1 equemene
      B(MM) = 0.D0
150 1 equemene
151 1 equemene
   ! ELIMINATE ERROR VECTORS WITH THE LARGEST NORM:
152 1 equemene
   80 CONTINUE
153 1 equemene
      DO 90 I=1,MM
154 1 equemene
   90 BS(I) = B(I)
155 1 equemene
      IF (NDIIS .EQ. MSET) GO TO 140
156 1 equemene
      DO 130 II=1,MSET-NDIIS
157 1 equemene
         XMAX = -1.D10
158 1 equemene
         ITERA = 0
159 1 equemene
         DO 110 I=1,MSET
160 1 equemene
            XNORM = 0.D0
161 1 equemene
            INV = (I-1) * MPLUS
162 1 equemene
            DO 100 J=1,MSET
163 1 equemene
  100       XNORM = XNORM + ABS(B(INV + J))
164 1 equemene
            IF (XMAX.LT.XNORM .AND. XNORM.NE.1.0D0) THEN
165 1 equemene
               XMAX = XNORM
166 1 equemene
               ITERA = I
167 1 equemene
               IONE = INV + I
168 1 equemene
            ENDIF
169 1 equemene
  110    CONTINUE
170 1 equemene
         DO 120 I=1,MPLUS
171 1 equemene
            INV = (I-1) * MPLUS
172 1 equemene
            DO 120 J=1,MPLUS
173 1 equemene
               JNV = (J-1) * MPLUS
174 1 equemene
               IF (J.EQ.ITERA) B(INV + J) = 0.D0
175 1 equemene
               B(JNV + I) = B(INV + J)
176 1 equemene
  120    CONTINUE
177 1 equemene
         B(IONE) = 1.0D0
178 1 equemene
  130 CONTINUE
179 1 equemene
  140 CONTINUE
180 1 equemene
181 1 equemene
      IF (DEBUG) THEN
182 1 equemene
183 1 equemene
      ! OUTPUT THE GDIIS MATRIX:
184 1 equemene
         WRITE(*,'(/5X,'' GDIIS MATRIX'')')
185 1 equemene
         ITmp=min(12,MPLUS)
186 1 equemene
         DO IJ=1,MPLUS
187 1 equemene
            WRITE(*,'(12(F10.4,1X))') B((IJ-1)*MPLUS+1:(IJ-1)*MPLUS+ITmp)
188 1 equemene
         END DO
189 1 equemene
      ENDIF
190 1 equemene
191 1 equemene
     ! SCALE DIIS MATRIX BEFORE INVERSION:
192 1 equemene
193 1 equemene
      DO I=1,MPLUS
194 1 equemene
         II = MPLUS * (I-1) + I
195 1 equemene
         GSAVE(I) = 1.D0 / DSQRT(1.D-20+DABS(B(II)))
196 1 equemene
      END DO
197 1 equemene
198 1 equemene
      GSAVE(MPLUS) = 1.D0
199 1 equemene
      DO I=1,MPLUS
200 1 equemene
         DO J=1,MPLUS
201 1 equemene
            IJ = MPLUS * (I-1) + J
202 1 equemene
            B(IJ) = B(IJ) * GSAVE(I) * GSAVE(J)
203 1 equemene
         END DO
204 1 equemene
      END DO
205 1 equemene
206 1 equemene
      IF (DEBUG) THEN
207 1 equemene
     ! OUTPUT SCALED GDIIS MATRIX:
208 1 equemene
         WRITE(*,'(/5X,'' GDIIS MATRIX (SCALED)'')')
209 1 equemene
         ITmp=min(12,MPLUS)
210 1 equemene
         DO IJ=1,MPLUS
211 1 equemene
            WRITE(*,'(12(F10.4,1X))') B((IJ-1)*MPLUS+1:(IJ-1)*MPLUS+ITmp)
212 1 equemene
         END DO
213 1 equemene
214 1 equemene
      ENDIF ! matches IF (DEBUG) THEN
215 1 equemene
216 1 equemene
     ! INVERT THE GDIIS MATRIX B:
217 1 equemene
      CALL MINV(B,MPLUS,DET) ! matrix inversion.
218 1 equemene
219 1 equemene
      DO I=1,MPLUS
220 1 equemene
         DO J=1,MPLUS
221 1 equemene
            IJ = MPLUS * (I-1) + J
222 1 equemene
            B(IJ) = B(IJ) * GSAVE(I) * GSAVE(J)
223 1 equemene
         END DO
224 1 equemene
      END DO
225 1 equemene
226 1 equemene
      ! COMPUTE THE INTERMEDIATE INTERPOLATED PARAMETER AND GRADIENT VECTORS:
227 1 equemene
      DO K=1,NVAR
228 1 equemene
         XP(K) = 0.D0
229 1 equemene
         GP(K) = 0.D0
230 1 equemene
         DO I=1,MSET
231 1 equemene
            INK = (I-1) * NVAR + K
232 1 equemene
			!Print *, 'B(',MPLUS*MSET+I,')=', B(MPLUS*MSET+I)
233 1 equemene
            XP(K) = XP(K) + B(MPLUS*MSET+I) * XSET(INK)
234 1 equemene
            GP(K) = GP(K) + B(MPLUS*MSET+I) * GSET(INK)
235 1 equemene
         END DO
236 1 equemene
	  END DO
237 1 equemene
238 1 equemene
      HP=0.D0
239 1 equemene
      DO I=1,MSET
240 1 equemene
         HP=HP+B(MPLUS*MSET+I)*ESET(I)
241 1 equemene
      END DO
242 1 equemene
243 1 equemene
      DO K=1,NVAR
244 1 equemene
         DX(K) = XPARAM(K) - XP(K)
245 1 equemene
      END DO
246 1 equemene
      XNORM = SQRT(DOT_PRODUCT(DX,DX))
247 1 equemene
      IF (PRINT) THEN
248 1 equemene
         WRITE (6,'(/10X,''DEVIATION IN X '',F7.4,8X,''DETERMINANT '',G9.3)') XNORM,DET
249 1 equemene
         WRITE(*,'(10X,''GDIIS COEFFICIENTS'')')
250 1 equemene
         WRITE(*,'(10X,5F12.5)') (B(MPLUS*MSET+I),I=1,MSET)
251 1 equemene
      ENDIF
252 1 equemene
253 1 equemene
      ! THE FOLLOWING TOLERENCES FOR XNORM AND DET ARE SOMEWHAT ARBITRARY!
254 1 equemene
      THRES = MAX(10.D0**(-NVAR), 1.D-25)
255 1 equemene
      IF (XNORM.GT.2.D0 .OR. DABS(DET).LT. THRES) THEN
256 1 equemene
         IF (PRINT)THEN
257 1 equemene
            WRITE(*,*) "THE DIIS MATRIX IS ILL CONDITIONED"
258 1 equemene
            WRITE(*,*) " - PROBABLY, VECTORS ARE LINEARLY DEPENDENT - "
259 1 equemene
            WRITE(*,*) "THE DIIS STEP WILL BE REPEATED WITH A SMALLER SPACE"
260 1 equemene
         END IF
261 1 equemene
         DO K=1,MM
262 1 equemene
	        B(K) = BS(K)
263 1 equemene
         END DO
264 1 equemene
         NDIIS = NDIIS - 1
265 1 equemene
         IF (NDIIS .GT. 0) GO TO 80
266 1 equemene
         IF (PRINT) WRITE(*,'(10X,''NEWTON-RAPHSON STEP TAKEN'')')
267 1 equemene
         DO K=1,NVAR
268 1 equemene
            XP(K) = XPARAM(K)
269 1 equemene
            GP(K) = GRAD(K)
270 1 equemene
         END DO
271 1 equemene
      ENDIF ! matches IF (XNORM.GT.2.D0 .OR. DABS(DET).LT. THRES) THEN
272 1 equemene
273 1 equemene
         ! q_{m+1} = q'_{m+1} - H^{-1}g'_{m+1}
274 1 equemene
		 ! Hess is a symmetric matrix.
275 1 equemene
		 !Hess_inv = 1.d0 ! to be deleted.
276 1 equemene
		 !Call GenInv(NVAR,Reshape(Hess,(/NVAR,NVAR/)),Hess_inv,NVAR) ! Implemented in Mat_util.f90
277 1 equemene
		 ! H^{-1}g'_{m+1}
278 1 equemene
		 !Print *, 'Hess_inv='
279 1 equemene
		 !Print *, Hess_inv
280 1 equemene
		 !XPARAM=0.d0
281 1 equemene
		 !DO I=1, NVAR
282 1 equemene
		 !XPARAM(:) = XPARAM(:) + Hess_inv(:,I)*GP(I)
283 1 equemene
		 !END DO
284 1 equemene
		 !XPARAM(:) = XP(:) - XPARAM(:) ! now XPARAM is a new geometry.
285 1 equemene
286 1 equemene
		 !STEP is the difference between the new and old geometry and thus "step":
287 1 equemene
         !STEP = XPARAM - XPARAM_old
288 1 equemene
289 1 equemene
      IF (PRINT)  WRITE(*,'(/,''       END GDIIS  '',/)')
290 1 equemene
291 1 equemene
      END SUBROUTINE Step_DIIS