Statistiques
| Révision :

root / src / Step_DIIS.f90 @ 6

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

1
!C  HEAT is never used, not even in call of Space(...)
2
!C  XPARAM = input parameter vector (Geometry).
3
!C  Grad = input gradient vector.
4
      SUBROUTINE Step_DIIS(XP,XPARAM,GP,GRAD,HP,HEAT,Hess,NVAR,FRST)
5
    !SUBROUTINE DIIS(XPARAM,STEP,GRAD,HP,HEAT,Hess,NVAR,FRST)
6
!      IMPLICIT DOUBLE PRECISION (A-H,O-Z)
7
      IMPLICIT NONE
8
      integer, parameter :: KINT = kind(1)
9
      integer, parameter :: KREAL = kind(1.0d0)
10

    
11
!      INCLUDE 'SIZES'
12

    
13
      INTEGER(KINT) :: NVAR
14
      REAL(KREAL) :: XP(NVAR), XPARAM(NVAR), GP(NVAR), GRAD(NVAR), Hess(NVAR*NVAR)
15
    !REAL(KREAL) :: Hess_inv(NVAR,NVAR),XPARAM_old(NVAR),STEP(NVAR)
16
      REAL(KREAL) :: HEAT, HP
17
      LOGICAL :: FRST
18
    
19
!************************************************************************
20
!*                                                                      *
21
!*     DIIS PERFORMS DIRECT INVERSION IN THE ITERATIVE SUBSPACE         *
22
!*                                                                      *
23
!*     THIS INVOLVES SOLVING FOR C IN XPARAM(NEW) = XPARAM' - HG'       *
24
!*                                                                      *
25
!*  WHERE XPARAM' = SUM(C(I)XPARAM(I), THE C COEFFICIENTES COMING FROM  *
26
!*                                                                      *
27
!*                   | B   1 | . | C | = | 0 |                          *
28
!*                   | 1   0 |   |-L |   | 1 |                          *
29
!*                                                                      *
30
!* WHERE B(I,J) =GRAD(I)H(T)HGRAD(J)  GRAD(I) = GRADIENT ON CYCLE I     *
31
!*                              Hess    = INVERSE HESSIAN                 *
32
!*                                                                      *
33
!*                          REFERENCE                                   *
34
!*                                                                      *
35
!*  P. CSASZAR, P. PULAY, J. MOL. STRUCT. (THEOCHEM), 114, 31 (1984)    *
36
!*                                                                      *
37
!************************************************************************
38
!************************************************************************
39
!*                                                                      *
40
!*     GEOMETRY OPTIMIZATION USING THE METHOD OF DIRECT INVERSION IN    *
41
!*     THE ITERATIVE SUBSPACE (GDIIS), COMBINED WITH THE BFGS OPTIMIZER *
42
!*     (A VARIABLE METRIC METHOD)                                       *
43
!*                                                                      *
44
!*     WRITTEN BY PETER L. CUMMINS, UNIVERSITY OF SYDNEY, AUSTRALIA     *
45
!*                                                                      *
46
!*                              REFERENCE                               *
47
!*                                                                      *
48
!*      "COMPUTATIONAL STRATEGIES FOR THE OPTIMIZATION OF EQUILIBRIUM   *
49
!*     GEOMETRIES AND TRANSITION-STATE STRUCTURES AT THE SEMIEMPIRICAL  *
50
!*     LEVEL", PETER L. CUMMINS, JILL E. GREADY, J. COMP. CHEM., 10,    *
51
!*     939-950 (1989).                                                  *
52
!*                                                                      *
53
!*     MODIFIED BY JJPS TO CONFORM TO EXISTING MOPAC CONVENTIONS        *
54
!*                                                                      *
55
!************************************************************************
56

    
57
      ! MRESET = number of iterations.
58
      INTEGER(KINT), PARAMETER :: MRESET=15, M2=(MRESET+1)*(MRESET+1) !M2 = 256
59
      REAL(KREAL), ALLOCATABLE, SAVE :: XSET(:),GSET(:),ERR(:) ! MRESET*NVAR
60
      REAL(KREAL) :: ESET(MRESET)
61
      REAL(KREAL), ALLOCATABLE, SAVE :: DX(:),GSAVE(:) !NVAR
62
      REAL(KREAL) :: B(M2),BS(M2),BST(M2)
63
      LOGICAL DEBUG, PRINT
64
      INTEGER(KINT), SAVE :: MSET
65
      INTEGER(KINT) :: NDIIS, MPLUS, INV, ITERA, MM
66
      INTEGER(KINT) :: I,J,K, JJ, KJ, JNV, II, IONE, IJ, INK,ITmp
67
      REAL(KREAL) :: XMax, XNorm, S, DET, THRES
68

    
69
      DEBUG=.TRUE.
70
      PRINT=.TRUE.
71

    
72
      IF (PRINT)  WRITE(*,'(/,''      BEGIN GDIIS   '')')
73
           
74
    !XPARAM_old = XPARAM
75
    
76
! Initialization
77
      IF (FRST) THEN
78
! FRST will be set to False in Space, so no need to modify it here
79
         IF (ALLOCATED(XSET)) THEN
80
            IF (PRINT)  WRITE(*,'(/,''    In FRST, GDIIS Dealloc  '')')
81
            DEALLOCATE(XSet,GSET,ERR,DX,GSave)
82
            RETURN
83
         ELSE
84
            IF (PRINT)  WRITE(*,'(/,''     In FRST,  GDIIS alloc  '')')
85
            ALLOCATE(XSet(MRESET*NVAR), GSet(MRESET*NVAR), ERR(MRESET*NVAR))
86
            ALLOCATE(DX(NVAR),GSAVE(NVAR))
87
         END IF
88
      END IF
89
!C
90
!C  SPACE SIMPLY LOADS THE CURRENT VALUES OF XPARAM AND GRAD INTO
91
!C  THE ARRAYS XSET AND GSET
92
!C
93
!C  HEAT is never used, not even in Space(...)
94
      CALL SPACE(MRESET,MSET,XPARAM,GRAD,HEAT,NVAR,XSET,GSET,ESET,FRST)
95

    
96
      IF (PRINT)  WRITE(*,'(/,''       GDIIS after Space  '')')
97

    
98
   ! INITIALIZE SOME VARIABLES AND CONSTANTS:
99
      NDIIS = MSET
100
      MPLUS = MSET + 1
101
      MM = MPLUS * MPLUS
102

    
103
   ! COMPUTE THE APPROXIMATE ERROR VECTORS:
104
      INV=-NVAR
105
      DO 30 I=1,MSET
106
         INV = INV + NVAR
107
         DO 30 J=1,NVAR
108
            S = 0.D0
109
            KJ=(J*(J-1))/2
110
            DO 10 K=1,J
111
               KJ = KJ+1
112
   10       S = S - Hess(KJ) * GSET(INV+K)
113
            DO 20 K=J+1,NVAR
114
               KJ = (K*(K-1))/2+J
115
   20       S = S - Hess(KJ) * GSET(INV+K)
116
   30 ERR(INV+J) = S
117
   
118
   
119

    
120
    ! CONSTRUCT THE GDIIS MATRIX:
121
      ! initialization (not really needed)
122
      DO I=1,MM
123
         B(I) = 1.D0
124
      END DO
125
       
126
      ! B_ij calculations from <e_i|e_j>  
127
      JJ=0
128
      INV=-NVAR
129
      DO 50 I=1,MSET
130
         INV=INV+NVAR
131
         JNV=-NVAR
132
         DO 50 J=1,MSET
133
            JNV=JNV+NVAR
134
            JJ = JJ + 1
135
            B(JJ)=0.D0
136
            DO 50 K=1,NVAR
137
   50 B(JJ) = B(JJ) + ERR(INV+K) * ERR(JNV+K)
138

    
139
     ! The following shifting is required to correct indices of B_ij elements in the GDIIS matrix.
140
   ! The correction is needed because the last coloumn of the matrix contains all 1 and one zero.
141
      DO 60 I=MSET-1,1,-1
142
         DO 60 J=MSET,1,-1
143
   60 B(I*MSET+J+I) = B(I*MSET+J)
144
   
145
      ! For last row and last column of GDIIS matrix 
146
      DO 70 I=1,MPLUS
147
         B(MPLUS*I) = 1.D0
148
   70 B(MPLUS*MSET+I) = 1.D0
149
      B(MM) = 0.D0
150

    
151
   ! ELIMINATE ERROR VECTORS WITH THE LARGEST NORM:
152
   80 CONTINUE
153
      DO 90 I=1,MM
154
   90 BS(I) = B(I)
155
      IF (NDIIS .EQ. MSET) GO TO 140
156
      DO 130 II=1,MSET-NDIIS
157
         XMAX = -1.D10
158
         ITERA = 0
159
         DO 110 I=1,MSET
160
            XNORM = 0.D0
161
            INV = (I-1) * MPLUS
162
            DO 100 J=1,MSET
163
  100       XNORM = XNORM + ABS(B(INV + J))
164
            IF (XMAX.LT.XNORM .AND. XNORM.NE.1.0D0) THEN
165
               XMAX = XNORM
166
               ITERA = I
167
               IONE = INV + I
168
            ENDIF
169
  110    CONTINUE
170
         DO 120 I=1,MPLUS
171
            INV = (I-1) * MPLUS
172
            DO 120 J=1,MPLUS
173
               JNV = (J-1) * MPLUS
174
               IF (J.EQ.ITERA) B(INV + J) = 0.D0
175
               B(JNV + I) = B(INV + J)
176
  120    CONTINUE
177
         B(IONE) = 1.0D0
178
  130 CONTINUE
179
  140 CONTINUE
180

    
181
      IF (DEBUG) THEN
182

    
183
      ! OUTPUT THE GDIIS MATRIX:
184
         WRITE(*,'(/5X,'' GDIIS MATRIX'')')
185
         ITmp=min(12,MPLUS)
186
         DO IJ=1,MPLUS
187
            WRITE(*,'(12(F10.4,1X))') B((IJ-1)*MPLUS+1:(IJ-1)*MPLUS+ITmp)
188
         END DO
189
      ENDIF
190

    
191
     ! SCALE DIIS MATRIX BEFORE INVERSION:
192
 
193
      DO I=1,MPLUS
194
         II = MPLUS * (I-1) + I
195
         GSAVE(I) = 1.D0 / DSQRT(1.D-20+DABS(B(II)))
196
      END DO
197
    
198
      GSAVE(MPLUS) = 1.D0
199
      DO I=1,MPLUS
200
         DO J=1,MPLUS
201
            IJ = MPLUS * (I-1) + J
202
            B(IJ) = B(IJ) * GSAVE(I) * GSAVE(J)
203
         END DO
204
      END DO
205
    
206
      IF (DEBUG) THEN
207
     ! OUTPUT SCALED GDIIS MATRIX:
208
         WRITE(*,'(/5X,'' GDIIS MATRIX (SCALED)'')')
209
         ITmp=min(12,MPLUS)
210
         DO IJ=1,MPLUS
211
            WRITE(*,'(12(F10.4,1X))') B((IJ-1)*MPLUS+1:(IJ-1)*MPLUS+ITmp)
212
         END DO
213
            
214
      ENDIF ! matches IF (DEBUG) THEN
215

    
216
     ! INVERT THE GDIIS MATRIX B:
217
      CALL MINV(B,MPLUS,DET) ! matrix inversion.
218

    
219
      DO I=1,MPLUS
220
         DO J=1,MPLUS
221
            IJ = MPLUS * (I-1) + J
222
            B(IJ) = B(IJ) * GSAVE(I) * GSAVE(J)
223
         END DO
224
      END DO
225

    
226
      ! COMPUTE THE INTERMEDIATE INTERPOLATED PARAMETER AND GRADIENT VECTORS:
227
      DO K=1,NVAR
228
         XP(K) = 0.D0
229
         GP(K) = 0.D0
230
         DO I=1,MSET
231
            INK = (I-1) * NVAR + K
232
      !Print *, 'B(',MPLUS*MSET+I,')=', B(MPLUS*MSET+I)
233
            XP(K) = XP(K) + B(MPLUS*MSET+I) * XSET(INK)
234
            GP(K) = GP(K) + B(MPLUS*MSET+I) * GSET(INK)
235
         END DO
236
    END DO
237
    
238
      HP=0.D0
239
      DO I=1,MSET
240
         HP=HP+B(MPLUS*MSET+I)*ESET(I)
241
      END DO
242
        
243
      DO K=1,NVAR
244
         DX(K) = XPARAM(K) - XP(K)
245
      END DO
246
      XNORM = SQRT(DOT_PRODUCT(DX,DX))
247
      IF (PRINT) THEN
248
         WRITE (6,'(/10X,''DEVIATION IN X '',F7.4,8X,''DETERMINANT '',G9.3)') XNORM,DET
249
         WRITE(*,'(10X,''GDIIS COEFFICIENTS'')')
250
         WRITE(*,'(10X,5F12.5)') (B(MPLUS*MSET+I),I=1,MSET)
251
      ENDIF
252

    
253
      ! THE FOLLOWING TOLERENCES FOR XNORM AND DET ARE SOMEWHAT ARBITRARY!
254
      THRES = MAX(10.D0**(-NVAR), 1.D-25)
255
      IF (XNORM.GT.2.D0 .OR. DABS(DET).LT. THRES) THEN
256
         IF (PRINT)THEN
257
            WRITE(*,*) "THE DIIS MATRIX IS ILL CONDITIONED"
258
            WRITE(*,*) " - PROBABLY, VECTORS ARE LINEARLY DEPENDENT - "
259
            WRITE(*,*) "THE DIIS STEP WILL BE REPEATED WITH A SMALLER SPACE"
260
         END IF
261
         DO K=1,MM
262
          B(K) = BS(K)
263
         END DO
264
         NDIIS = NDIIS - 1
265
         IF (NDIIS .GT. 0) GO TO 80
266
         IF (PRINT) WRITE(*,'(10X,''NEWTON-RAPHSON STEP TAKEN'')')
267
         DO K=1,NVAR
268
            XP(K) = XPARAM(K)
269
            GP(K) = GRAD(K)  
270
         END DO
271
      ENDIF ! matches IF (XNORM.GT.2.D0 .OR. DABS(DET).LT. THRES) THEN
272
    
273
         ! q_{m+1} = q'_{m+1} - H^{-1}g'_{m+1}
274
     ! Hess is a symmetric matrix.
275
     !Hess_inv = 1.d0 ! to be deleted.
276
     !Call GenInv(NVAR,Reshape(Hess,(/NVAR,NVAR/)),Hess_inv,NVAR) ! Implemented in Mat_util.f90
277
     ! H^{-1}g'_{m+1}
278
     !Print *, 'Hess_inv='
279
     !Print *, Hess_inv
280
     !XPARAM=0.d0
281
     !DO I=1, NVAR
282
     !XPARAM(:) = XPARAM(:) + Hess_inv(:,I)*GP(I)
283
     !END DO
284
     !XPARAM(:) = XP(:) - XPARAM(:) ! now XPARAM is a new geometry.
285
     
286
     !STEP is the difference between the new and old geometry and thus "step":
287
         !STEP = XPARAM - XPARAM_old
288
         
289
      IF (PRINT)  WRITE(*,'(/,''       END GDIIS  '',/)')
290

    
291
      END SUBROUTINE Step_DIIS