Statistiques
| Révision :

root / src / Step_GDIIS_Simple_Err.f90

Historique | Voir | Annoter | Télécharger (11,41 ko)

1
!C  HEAT is never used, not even in call of Space(...)
2
!C  Geom = input parameter vector (Geometry).
3
!C  Grad = input gradient vector.
4
      SUBROUTINE Step_GDIIS_Simple_Err(NewGeom,Geom,NewGrad,GRAD,HP,HEAT,NCoord,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) :: NCoord
49
      REAL(KREAL) :: NewGeom(NCoord), Geom(NCoord), NewGrad(NCoord), GRAD(NCoord)
50
      REAL(KREAL) :: HEAT, HP
51
      LOGICAL :: FRST
52
    
53
!************************************************************************
54
!*                                                                      *
55
!*     DIIS PERFORMS DIRECT INVERSION IN THE ITERATIVE SUBSPACE         *
56
!*                                                                      *
57
!*     THIS INVOLVES SOLVING FOR C IN Geom(NEW) = Geom' - HG'           *
58
!*                                                                      *
59
!*  WHERE Geom' = SUM(C(I)Geom(I), THE C COEFFICIENTES COMING FROM      *
60
!*                                                                      *
61
!*                   | B   1 | . | C | = | 0 |                          *
62
!*                   | 1   0 |   |-L |   | 1 |                          *
63
!*                                                                      *
64
!* WHERE B(I,J) =GRAD(I)H(T)HGRAD(J)  GRAD(I) = GRADIENT ON CYCLE I     *
65
!*                              Hess    = INVERSE HESSIAN               *
66
!*                                                                      *
67
!*                          REFERENCE                                   *
68
!*                                                                      *
69
!*  P. CSASZAR, P. PULAY, J. MOL. STRUCT. (THEOCHEM), 114, 31 (1984)    *
70
!*                                                                      *
71
!************************************************************************
72
!************************************************************************
73
!*                                                                      *
74
!*     GEOMETRY OPTIMIZATION USING THE METHOD OF DIRECT INVERSION IN    *
75
!*     THE ITERATIVE SUBSPACE (GDIIS), COMBINED WITH THE BFGS OPTIMIZER *
76
!*     (A VARIABLE METRIC METHOD)                                       *
77
!*                                                                      *
78
!*     WRITTEN BY PETER L. CUMMINS, UNIVERSITY OF SYDNEY, AUSTRALIA     *
79
!*                                                                      *
80
!*                              REFERENCE                               *
81
!*                                                                      *
82
!*      "COMPUTATIONAL STRATEGIES FOR THE OPTIMIZATION OF EQUILIBRIUM   *
83
!*     GEOMETRIES AND TRANSITION-STATE STRUCTURES AT THE SEMIEMPIRICAL  *
84
!*     LEVEL", PETER L. CUMMINS, JILL E. GREADY, J. COMP. CHEM., 10,    *
85
!*     939-950 (1989).                                                  *
86
!*                                                                      *
87
!*     MODIFIED BY JJPS TO CONFORM TO EXISTING MOPAC CONVENTIONS        *
88
!*                                                                      *
89
!************************************************************************
90

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

    
103
      DEBUG=.TRUE.
104
      PRINT=.TRUE.
105

    
106
      IF (PRINT)  WRITE(*,'(/,''      BEGIN Step_GDIIS_Simple_Err   '')')
107

    
108
      ! Initialization
109
      IF (FRST) THEN
110
       ! FRST will be set to False in Space, so no need to modify it here
111
         IF (ALLOCATED(GeomSet)) THEN
112
            IF (PRINT)  WRITE(*,'(/,''    In FRST, Step_GDIIS_Simple_Err Dealloc  '')')
113
            DEALLOCATE(GeomSet,GradSet,ERR,DX,GSave)
114
            RETURN
115
         ELSE
116
            IF (PRINT)  WRITE(*,'(/,''     In FRST,  Step_GDIIS_Simple_Err alloc  '')')
117
            ALLOCATE(GeomSet(MRESET*NCoord), GradSet(MRESET*NCoord), ERR(MRESET*NCoord))
118
            ALLOCATE(DX(NCoord),GSAVE(NCoord))
119
         END IF
120
      END IF
121

    
122
      ! SPACE SIMPLY LOADS THE CURRENT VALUES OF Geom AND GRAD INTO THE ARRAYS GeomSet AND GradSet
123
      ! HEAT is never used, not even in Space(...)
124
      CALL SPACE(MRESET,MSET,Geom,Grad,HEAT,NCoord,GeomSet,GradSet,ESET,FRST)
125

    
126
      IF (PRINT)  WRITE(*,'(/,''       Step_GDIIS_Simple_Err after Space  '')')
127

    
128
      ! INITIALIZE SOME VARIABLES AND CONSTANTS:
129
      NDIIS = MSET
130
      MPLUS = MSET + 1
131
      MM = MPLUS * MPLUS
132

    
133
      ! CONSTRUCT THE GDIIS MATRIX:
134
      ! B_ij calculations from <B_ij=(g_i-g_j)(R_i-R_j)>
135
      JJ=0
136
      INV=-NCoord
137
      DO I=1,MSET
138
         INV=INV+NCoord
139
         JNV=-NCoord
140
         DO J=1,MSET
141
            JNV=JNV+NCoord
142
            JJ = JJ + 1
143
            B(JJ)=0.D0
144
      DO K=1, NCoord
145
         B(JJ) = B(JJ) + (((GradSet(INV+K)-GradSet(JNV+K))*(GeomSet(INV+K)-GeomSet(JNV+K)))/2.D0)
146
      END DO
147
         END DO
148
      END DO   
149

    
150
     ! The following shifting is required to correct indices of B_ij elements in the GDIIS matrix.
151
   ! The correction is needed because the last coloumn of the matrix contains all 1 and one zero.
152
      DO 60 I=MSET-1,1,-1
153
         DO 60 J=MSET,1,-1
154
   60 B(I*MSET+J+I) = B(I*MSET+J)
155
   
156
      ! for last row and last column of GDIIS matrix 
157
      DO 70 I=1,MPLUS
158
         B(MPLUS*I) = 1.D0
159
   70 B(MPLUS*MSET+I) = 1.D0
160
      B(MM) = 0.D0
161

    
162
      ! ELIMINATE ERROR VECTORS WITH THE LARGEST NORM:
163
   80 CONTINUE
164
      DO 90 I=1,MM
165
   90 BS(I) = B(I)
166
      IF (NDIIS .EQ. MSET) GO TO 140
167
      DO 130 II=1,MSET-NDIIS
168
         XMAX = -1.D10
169
         ITERA = 0
170
         DO 110 I=1,MSET
171
            XNORM = 0.D0
172
            INV = (I-1) * MPLUS
173
            DO 100 J=1,MSET
174
  100       XNORM = XNORM + ABS(B(INV + J))
175
            IF (XMAX.LT.XNORM .AND. XNORM.NE.1.0D0) THEN
176
               XMAX = XNORM
177
               ITERA = I
178
               IONE = INV + I
179
            ENDIF
180
  110    CONTINUE
181
         DO 120 I=1,MPLUS
182
            INV = (I-1) * MPLUS
183
            DO 120 J=1,MPLUS
184
               JNV = (J-1) * MPLUS
185
               IF (J.EQ.ITERA) B(INV + J) = 0.D0
186
               B(JNV + I) = B(INV + J)
187
  120    CONTINUE
188
         B(IONE) = 1.0D0
189
  130 CONTINUE
190
  140 CONTINUE
191
  
192
      IF (DEBUG) THEN
193

    
194
      ! OUTPUT THE GDIIS MATRIX:
195
         WRITE(*,'(/5X,'' Step_GDIIS_Simple_Err MATRIX'')')
196
         ITmp=min(12,MPLUS)
197
         DO IJ=1,MPLUS
198
            WRITE(*,'(12(F10.4,1X))') B((IJ-1)*MPLUS+1:(IJ-1)*MPLUS+ITmp)
199
         END DO
200
      ENDIF
201

    
202
      ! SCALE DIIS MATRIX BEFORE INVERSION:
203
      DO 160 I=1,MPLUS
204
         II = MPLUS * (I-1) + I
205
  160 GSAVE(I) = 1.D0 / DSQRT(1.D-20+DABS(B(II)))
206
      GSAVE(MPLUS) = 1.D0
207
      DO 170 I=1,MPLUS
208
         DO 170 J=1,MPLUS
209
            IJ = MPLUS * (I-1) + J
210
  170 B(IJ) = B(IJ) * GSAVE(I) * GSAVE(J)
211
  
212
      IF (DEBUG) THEN
213

    
214
      ! OUTPUT SCALED GDIIS MATRIX:
215
         WRITE(*,'(/5X,'' Step_GDIIS_Simple_Err MATRIX (SCALED)'')')
216
         ITmp=min(12,MPLUS)
217
         DO IJ=1,MPLUS
218
            WRITE(*,'(12(F10.4,1X))') B((IJ-1)*MPLUS+1:(IJ-1)*MPLUS+ITmp)
219
         END DO
220
            
221
      ENDIF ! matches IF (DEBUG) THEN
222

    
223
      ! INVERT THE GDIIS MATRIX B:
224
      CALL MINV(B,MPLUS,DET) ! matrix inversion.
225

    
226
      DO 190 I=1,MPLUS
227
         DO 190 J=1,MPLUS
228
            IJ = MPLUS * (I-1) + J
229
  190 B(IJ) = B(IJ) * GSAVE(I) * GSAVE(J)
230
  
231
      ! COMPUTE THE INTERMEDIATE INTERPOLATED PARAMETER AND GRADIENT VECTORS:
232
      DO 200 K=1,NCoord
233
         NewGeom(K) = 0.D0
234
         NewGrad(K) = 0.D0
235
         DO 200 I=1,MSET
236
            INK = (I-1) * NCoord + K
237
      !Print *, 'B(',MPLUS*MSET+I,')=', B(MPLUS*MSET+I)
238
            NewGeom(K) = NewGeom(K) + B(MPLUS*MSET+I) * GeomSet(INK)
239
  200 NewGrad(K) = NewGrad(K) + B(MPLUS*MSET+I) * GradSet(INK)
240
      HP=0.D0
241
      DO 210 I=1,MSET
242
  210 HP=HP+B(MPLUS*MSET+I)*ESET(I)
243
      
244
      DO 220 K=1,NCoord
245
  220 DX(K) = Geom(K) - NewGeom(K)
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,''Step_GDIIS_Simple_Err 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**(-NCoord), 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 230 K=1,MM
262
  230    B(K) = BS(K)
263
         NDIIS = NDIIS - 1
264
         IF (NDIIS .GT. 0) GO TO 80
265
         IF (PRINT) WRITE(*,'(10X,''NEWTON-RAPHSON STEP TAKEN'')')
266
         DO 240 K=1,NCoord
267
            NewGeom(K) = Geom(K)
268
  240       NewGrad(K) = GRAD(K)  
269
      ENDIF ! matches IF (XNORM.GT.2.D0 .OR. DABS(DET).LT. THRES) THEN
270
    
271
      !    q_{m+1} = q'_{m+1} - H^{-1}g'_{m+1}
272
     ! Hess is a symmetric matrix.
273
     !Hess_inv = 1.d0 ! to be deleted.
274
     !Call GenInv(NCoord,Reshape(Hess,(/NCoord,NCoord/)),Hess_inv,NCoord) ! Implemented in Mat_util.f90
275
     ! H^{-1}g'_{m+1}
276
     !Print *, 'Hess_inv='
277
    ! Print *, Hess_inv
278
     !Geom=0.d0
279
     !DO I=1, NCoord
280
      !  Geom(:) = Geom(:) + Hess_inv(:,I)*NewGrad(I)
281
     !END DO
282
     !Geom(:) = NewGeom(:) - Geom(:) ! now Geom is a new geometry.
283
     
284
     ! STEP is the difference between the new and old geometry and thus "step":
285
         !STEP = Geom - Geom_old
286
         
287
      IF (PRINT)  WRITE(*,'(/,''       END Step_GDIIS_Simple_Err  '',/)')
288

    
289
      END SUBROUTINE Step_GDIIS_Simple_Err