Statistiques
| Révision :

root / src / Step_DIIS.f90

Historique | Voir | Annoter | Télécharger (11,77 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

    
6
!----------------------------------------------------------------------
7
! This routine was adapted from the public domain mopac6 diis.f 
8
!  source file (c) 2009, Stewart Computational Chemistry.
9
!  <http://www.openmopac.net/Downloads/Downloads.html>
10
!
11
!----------------------------------------------------------------------
12
!  Copyright 2003-2014 Ecole Normale Supérieure de Lyon, 
13
!  Centre National de la Recherche Scientifique,
14
!  Université Claude Bernard Lyon 1. All rights reserved.
15
!
16
!  This work is registered with the Agency for the Protection of Programs 
17
!  as IDDN.FR.001.100009.000.S.P.2014.000.30625
18
!
19
!  Authors: P. Fleurat-Lessard, P. Dayal
20
!  Contact: optnpath@gmail.com
21
!
22
! This file is part of "Opt'n Path".
23
!
24
!  "Opt'n Path" is free software: you can redistribute it and/or modify
25
!  it under the terms of the GNU Affero General Public License as
26
!  published by the Free Software Foundation, either version 3 of the License,
27
!  or (at your option) any later version.
28
!
29
!  "Opt'n Path" is distributed in the hope that it will be useful,
30
!  but WITHOUT ANY WARRANTY; without even the implied warranty of
31
!
32
!  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
33
!  GNU Affero General Public License for more details.
34
!
35
!  You should have received a copy of the GNU Affero General Public License
36
!  along with "Opt'n Path". If not, see <http://www.gnu.org/licenses/>.
37
!
38
! Contact The Office of Technology Licensing, valorisation@ens-lyon.fr,
39
! for commercial licensing opportunities.
40
!----------------------------------------------------------------------
41

    
42
      IMPLICIT NONE
43
      integer, parameter :: KINT = kind(1)
44
      integer, parameter :: KREAL = kind(1.0d0)
45

    
46
!      INCLUDE 'SIZES'
47

    
48
      INTEGER(KINT) :: NVAR
49
      REAL(KREAL) :: XP(NVAR), XPARAM(NVAR), GP(NVAR), GRAD(NVAR), Hess(NVAR*NVAR)
50
    !REAL(KREAL) :: Hess_inv(NVAR,NVAR),XPARAM_old(NVAR),STEP(NVAR)
51
      REAL(KREAL) :: HEAT, HP
52
      LOGICAL :: FRST
53
    
54
!************************************************************************
55
!*                                                                      *
56
!*     DIIS PERFORMS DIRECT INVERSION IN THE ITERATIVE SUBSPACE         *
57
!*                                                                      *
58
!*     THIS INVOLVES SOLVING FOR C IN XPARAM(NEW) = XPARAM' - HG'       *
59
!*                                                                      *
60
!*  WHERE XPARAM' = SUM(C(I)XPARAM(I), THE C COEFFICIENTES COMING FROM  *
61
!*                                                                      *
62
!*                   | B   1 | . | C | = | 0 |                          *
63
!*                   | 1   0 |   |-L |   | 1 |                          *
64
!*                                                                      *
65
!* WHERE B(I,J) =GRAD(I)H(T)HGRAD(J)  GRAD(I) = GRADIENT ON CYCLE I     *
66
!*                              Hess    = INVERSE HESSIAN                 *
67
!*                                                                      *
68
!*                          REFERENCE                                   *
69
!*                                                                      *
70
!*  P. CSASZAR, P. PULAY, J. MOL. STRUCT. (THEOCHEM), 114, 31 (1984)    *
71
!*                                                                      *
72
!************************************************************************
73
!************************************************************************
74
!*                                                                      *
75
!*     GEOMETRY OPTIMIZATION USING THE METHOD OF DIRECT INVERSION IN    *
76
!*     THE ITERATIVE SUBSPACE (GDIIS), COMBINED WITH THE BFGS OPTIMIZER *
77
!*     (A VARIABLE METRIC METHOD)                                       *
78
!*                                                                      *
79
!*     WRITTEN BY PETER L. CUMMINS, UNIVERSITY OF SYDNEY, AUSTRALIA     *
80
!*                                                                      *
81
!*                              REFERENCE                               *
82
!*                                                                      *
83
!*      "COMPUTATIONAL STRATEGIES FOR THE OPTIMIZATION OF EQUILIBRIUM   *
84
!*     GEOMETRIES AND TRANSITION-STATE STRUCTURES AT THE SEMIEMPIRICAL  *
85
!*     LEVEL", PETER L. CUMMINS, JILL E. GREADY, J. COMP. CHEM., 10,    *
86
!*     939-950 (1989).                                                  *
87
!*                                                                      *
88
!*     MODIFIED BY JJPS TO CONFORM TO EXISTING MOPAC CONVENTIONS        *
89
!*                                                                      *
90
!************************************************************************
91

    
92
      ! MRESET = number of iterations.
93
      INTEGER(KINT), PARAMETER :: MRESET=15, M2=(MRESET+1)*(MRESET+1) !M2 = 256
94
      REAL(KREAL), ALLOCATABLE, SAVE :: XSET(:),GSET(:),ERR(:) ! MRESET*NVAR
95
      REAL(KREAL) :: ESET(MRESET)
96
      REAL(KREAL), ALLOCATABLE, SAVE :: DX(:),GSAVE(:) !NVAR
97
      REAL(KREAL) :: B(M2), BS(M2)
98
      LOGICAL DEBUG, PRINT
99
      INTEGER(KINT), SAVE :: MSET
100
      INTEGER(KINT) :: NDIIS, MPLUS, INV, ITERA, MM
101
      INTEGER(KINT) :: I,J,K, JJ, KJ, JNV, II, IONE, IJ, INK,ITmp
102
      REAL(KREAL) :: XMax, XNorm, S, DET, THRES
103

    
104
      DEBUG=.TRUE.
105
      PRINT=.TRUE.
106

    
107
      IF (PRINT)  WRITE(*,'(/,''      BEGIN GDIIS   '')')
108
           
109
    !XPARAM_old = XPARAM
110
    
111
! Initialization
112
      IF (FRST) THEN
113
! FRST will be set to False in Space, so no need to modify it here
114
         IF (ALLOCATED(XSET)) THEN
115
            IF (PRINT)  WRITE(*,'(/,''    In FRST, GDIIS Dealloc  '')')
116
            DEALLOCATE(XSet,GSET,ERR,DX,GSave)
117
            RETURN
118
         ELSE
119
            IF (PRINT)  WRITE(*,'(/,''     In FRST,  GDIIS alloc  '')')
120
            ALLOCATE(XSet(MRESET*NVAR), GSet(MRESET*NVAR), ERR(MRESET*NVAR))
121
            ALLOCATE(DX(NVAR),GSAVE(NVAR))
122
         END IF
123
      END IF
124
!C
125
!C  SPACE SIMPLY LOADS THE CURRENT VALUES OF XPARAM AND GRAD INTO
126
!C  THE ARRAYS XSET AND GSET
127
!C
128
!C  HEAT is never used, not even in Space(...)
129
      CALL SPACE(MRESET,MSET,XPARAM,GRAD,HEAT,NVAR,XSET,GSET,ESET,FRST)
130

    
131
      IF (PRINT)  WRITE(*,'(/,''       GDIIS after Space  '')')
132

    
133
   ! INITIALIZE SOME VARIABLES AND CONSTANTS:
134
      NDIIS = MSET
135
      MPLUS = MSET + 1
136
      MM = MPLUS * MPLUS
137

    
138
   ! COMPUTE THE APPROXIMATE ERROR VECTORS:
139
      INV=-NVAR
140
      DO 30 I=1,MSET
141
         INV = INV + NVAR
142
         DO 30 J=1,NVAR
143
            S = 0.D0
144
            KJ=(J*(J-1))/2
145
            DO 10 K=1,J
146
               KJ = KJ+1
147
   10       S = S - Hess(KJ) * GSET(INV+K)
148
            DO 20 K=J+1,NVAR
149
               KJ = (K*(K-1))/2+J
150
   20       S = S - Hess(KJ) * GSET(INV+K)
151
   30 ERR(INV+J) = S
152
   
153
   
154

    
155
    ! CONSTRUCT THE GDIIS MATRIX:
156
      ! initialization (not really needed)
157
      DO I=1,MM
158
         B(I) = 1.D0
159
      END DO
160
       
161
      ! B_ij calculations from <e_i|e_j>  
162
      JJ=0
163
      INV=-NVAR
164
      DO 50 I=1,MSET
165
         INV=INV+NVAR
166
         JNV=-NVAR
167
         DO 50 J=1,MSET
168
            JNV=JNV+NVAR
169
            JJ = JJ + 1
170
            B(JJ)=0.D0
171
            DO 50 K=1,NVAR
172
   50 B(JJ) = B(JJ) + ERR(INV+K) * ERR(JNV+K)
173

    
174
     ! The following shifting is required to correct indices of B_ij elements in the GDIIS matrix.
175
   ! The correction is needed because the last coloumn of the matrix contains all 1 and one zero.
176
      DO 60 I=MSET-1,1,-1
177
         DO 60 J=MSET,1,-1
178
   60 B(I*MSET+J+I) = B(I*MSET+J)
179
   
180
      ! For last row and last column of GDIIS matrix 
181
      DO 70 I=1,MPLUS
182
         B(MPLUS*I) = 1.D0
183
   70 B(MPLUS*MSET+I) = 1.D0
184
      B(MM) = 0.D0
185

    
186
   ! ELIMINATE ERROR VECTORS WITH THE LARGEST NORM:
187
   80 CONTINUE
188
      DO 90 I=1,MM
189
   90 BS(I) = B(I)
190
      IF (NDIIS .EQ. MSET) GO TO 140
191
      DO 130 II=1,MSET-NDIIS
192
         XMAX = -1.D10
193
         ITERA = 0
194
         DO 110 I=1,MSET
195
            XNORM = 0.D0
196
            INV = (I-1) * MPLUS
197
            DO 100 J=1,MSET
198
  100       XNORM = XNORM + ABS(B(INV + J))
199
            IF (XMAX.LT.XNORM .AND. XNORM.NE.1.0D0) THEN
200
               XMAX = XNORM
201
               ITERA = I
202
               IONE = INV + I
203
            ENDIF
204
  110    CONTINUE
205
         DO 120 I=1,MPLUS
206
            INV = (I-1) * MPLUS
207
            DO 120 J=1,MPLUS
208
               JNV = (J-1) * MPLUS
209
               IF (J.EQ.ITERA) B(INV + J) = 0.D0
210
               B(JNV + I) = B(INV + J)
211
  120    CONTINUE
212
         B(IONE) = 1.0D0
213
  130 CONTINUE
214
  140 CONTINUE
215

    
216
      IF (DEBUG) THEN
217

    
218
      ! OUTPUT THE GDIIS MATRIX:
219
         WRITE(*,'(/5X,'' GDIIS MATRIX'')')
220
         ITmp=min(12,MPLUS)
221
         DO IJ=1,MPLUS
222
            WRITE(*,'(12(F10.4,1X))') B((IJ-1)*MPLUS+1:(IJ-1)*MPLUS+ITmp)
223
         END DO
224
      ENDIF
225

    
226
     ! SCALE DIIS MATRIX BEFORE INVERSION:
227
 
228
      DO I=1,MPLUS
229
         II = MPLUS * (I-1) + I
230
         GSAVE(I) = 1.D0 / DSQRT(1.D-20+DABS(B(II)))
231
      END DO
232
    
233
      GSAVE(MPLUS) = 1.D0
234
      DO I=1,MPLUS
235
         DO J=1,MPLUS
236
            IJ = MPLUS * (I-1) + J
237
            B(IJ) = B(IJ) * GSAVE(I) * GSAVE(J)
238
         END DO
239
      END DO
240
    
241
      IF (DEBUG) THEN
242
     ! OUTPUT SCALED GDIIS MATRIX:
243
         WRITE(*,'(/5X,'' GDIIS MATRIX (SCALED)'')')
244
         ITmp=min(12,MPLUS)
245
         DO IJ=1,MPLUS
246
            WRITE(*,'(12(F10.4,1X))') B((IJ-1)*MPLUS+1:(IJ-1)*MPLUS+ITmp)
247
         END DO
248
            
249
      ENDIF ! matches IF (DEBUG) THEN
250

    
251
     ! INVERT THE GDIIS MATRIX B:
252
      CALL MINV(B,MPLUS,DET) ! matrix inversion.
253

    
254
      DO I=1,MPLUS
255
         DO J=1,MPLUS
256
            IJ = MPLUS * (I-1) + J
257
            B(IJ) = B(IJ) * GSAVE(I) * GSAVE(J)
258
         END DO
259
      END DO
260

    
261
      ! COMPUTE THE INTERMEDIATE INTERPOLATED PARAMETER AND GRADIENT VECTORS:
262
      DO K=1,NVAR
263
         XP(K) = 0.D0
264
         GP(K) = 0.D0
265
         DO I=1,MSET
266
            INK = (I-1) * NVAR + K
267
      !Print *, 'B(',MPLUS*MSET+I,')=', B(MPLUS*MSET+I)
268
            XP(K) = XP(K) + B(MPLUS*MSET+I) * XSET(INK)
269
            GP(K) = GP(K) + B(MPLUS*MSET+I) * GSET(INK)
270
         END DO
271
    END DO
272
    
273
      HP=0.D0
274
      DO I=1,MSET
275
         HP=HP+B(MPLUS*MSET+I)*ESET(I)
276
      END DO
277
        
278
      DO K=1,NVAR
279
         DX(K) = XPARAM(K) - XP(K)
280
      END DO
281
      XNORM = SQRT(DOT_PRODUCT(DX,DX))
282
      IF (PRINT) THEN
283
         WRITE (6,'(/10X,''DEVIATION IN X '',F7.4,8X,''DETERMINANT '',G9.3)') XNORM,DET
284
         WRITE(*,'(10X,''GDIIS COEFFICIENTS'')')
285
         WRITE(*,'(10X,5F12.5)') (B(MPLUS*MSET+I),I=1,MSET)
286
      ENDIF
287

    
288
      ! THE FOLLOWING TOLERENCES FOR XNORM AND DET ARE SOMEWHAT ARBITRARY!
289
      THRES = MAX(10.D0**(-NVAR), 1.D-25)
290
      IF (XNORM.GT.2.D0 .OR. DABS(DET).LT. THRES) THEN
291
         IF (PRINT)THEN
292
            WRITE(*,*) "THE DIIS MATRIX IS ILL CONDITIONED"
293
            WRITE(*,*) " - PROBABLY, VECTORS ARE LINEARLY DEPENDENT - "
294
            WRITE(*,*) "THE DIIS STEP WILL BE REPEATED WITH A SMALLER SPACE"
295
         END IF
296
         DO K=1,MM
297
          B(K) = BS(K)
298
         END DO
299
         NDIIS = NDIIS - 1
300
         IF (NDIIS .GT. 0) GO TO 80
301
         IF (PRINT) WRITE(*,'(10X,''NEWTON-RAPHSON STEP TAKEN'')')
302
         DO K=1,NVAR
303
            XP(K) = XPARAM(K)
304
            GP(K) = GRAD(K)  
305
         END DO
306
      ENDIF ! matches IF (XNORM.GT.2.D0 .OR. DABS(DET).LT. THRES) THEN
307
    
308
         ! q_{m+1} = q'_{m+1} - H^{-1}g'_{m+1}
309
     ! Hess is a symmetric matrix.
310
     !Hess_inv = 1.d0 ! to be deleted.
311
     !Call GenInv(NVAR,Reshape(Hess,(/NVAR,NVAR/)),Hess_inv,NVAR) ! Implemented in Mat_util.f90
312
     ! H^{-1}g'_{m+1}
313
     !Print *, 'Hess_inv='
314
     !Print *, Hess_inv
315
     !XPARAM=0.d0
316
     !DO I=1, NVAR
317
     !XPARAM(:) = XPARAM(:) + Hess_inv(:,I)*GP(I)
318
     !END DO
319
     !XPARAM(:) = XP(:) - XPARAM(:) ! now XPARAM is a new geometry.
320
     
321
     !STEP is the difference between the new and old geometry and thus "step":
322
         !STEP = XPARAM - XPARAM_old
323
         
324
      IF (PRINT)  WRITE(*,'(/,''       END GDIIS  '',/)')
325

    
326
      END SUBROUTINE Step_DIIS