Statistiques
| Révision :

root / src / Step_GDIIS_Simple_Err.f90 @ 5

Historique | Voir | Annoter | Télécharger (9,95 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,Hess,NCoord,FRST)
5
!      IMPLICIT DOUBLE PRECISION (A-H,O-Z)
6
      IMPLICIT NONE
7
      integer, parameter :: KINT = kind(1)
8
      integer, parameter :: KREAL = kind(1.0d0)
9

    
10
!      INCLUDE 'SIZES'
11

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

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

    
67
      DEBUG=.TRUE.
68
      PRINT=.TRUE.
69

    
70
      IF (PRINT)  WRITE(*,'(/,''      BEGIN Step_GDIIS_Simple_Err   '')')
71

    
72
      ! Initialization
73
      IF (FRST) THEN
74
       ! FRST will be set to False in Space, so no need to modify it here
75
         IF (ALLOCATED(GeomSet)) THEN
76
            IF (PRINT)  WRITE(*,'(/,''    In FRST, Step_GDIIS_Simple_Err Dealloc  '')')
77
            DEALLOCATE(GeomSet,GradSet,ERR,DX,GSave)
78
            RETURN
79
         ELSE
80
            IF (PRINT)  WRITE(*,'(/,''     In FRST,  Step_GDIIS_Simple_Err alloc  '')')
81
            ALLOCATE(GeomSet(MRESET*NCoord), GradSet(MRESET*NCoord), ERR(MRESET*NCoord))
82
            ALLOCATE(DX(NCoord),GSAVE(NCoord))
83
         END IF
84
      END IF
85

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

    
90
      IF (PRINT)  WRITE(*,'(/,''       Step_GDIIS_Simple_Err after Space  '')')
91

    
92
      ! INITIALIZE SOME VARIABLES AND CONSTANTS:
93
      NDIIS = MSET
94
      MPLUS = MSET + 1
95
      MM = MPLUS * MPLUS
96

    
97
      ! CONSTRUCT THE GDIIS MATRIX:
98
      ! B_ij calculations from <B_ij=(g_i-g_j)(R_i-R_j)>
99
      JJ=0
100
      INV=-NCoord
101
      DO I=1,MSET
102
         INV=INV+NCoord
103
         JNV=-NCoord
104
         DO J=1,MSET
105
            JNV=JNV+NCoord
106
            JJ = JJ + 1
107
            B(JJ)=0.D0
108
      DO K=1, NCoord
109
         B(JJ) = B(JJ) + (((GradSet(INV+K)-GradSet(JNV+K))*(GeomSet(INV+K)-GeomSet(JNV+K)))/2.D0)
110
      END DO
111
         END DO
112
      END DO   
113

    
114
     ! The following shifting is required to correct indices of B_ij elements in the GDIIS matrix.
115
   ! The correction is needed because the last coloumn of the matrix contains all 1 and one zero.
116
      DO 60 I=MSET-1,1,-1
117
         DO 60 J=MSET,1,-1
118
   60 B(I*MSET+J+I) = B(I*MSET+J)
119
   
120
      ! for last row and last column of GDIIS matrix 
121
      DO 70 I=1,MPLUS
122
         B(MPLUS*I) = 1.D0
123
   70 B(MPLUS*MSET+I) = 1.D0
124
      B(MM) = 0.D0
125

    
126
      ! ELIMINATE ERROR VECTORS WITH THE LARGEST NORM:
127
   80 CONTINUE
128
      DO 90 I=1,MM
129
   90 BS(I) = B(I)
130
      IF (NDIIS .EQ. MSET) GO TO 140
131
      DO 130 II=1,MSET-NDIIS
132
         XMAX = -1.D10
133
         ITERA = 0
134
         DO 110 I=1,MSET
135
            XNORM = 0.D0
136
            INV = (I-1) * MPLUS
137
            DO 100 J=1,MSET
138
  100       XNORM = XNORM + ABS(B(INV + J))
139
            IF (XMAX.LT.XNORM .AND. XNORM.NE.1.0D0) THEN
140
               XMAX = XNORM
141
               ITERA = I
142
               IONE = INV + I
143
            ENDIF
144
  110    CONTINUE
145
         DO 120 I=1,MPLUS
146
            INV = (I-1) * MPLUS
147
            DO 120 J=1,MPLUS
148
               JNV = (J-1) * MPLUS
149
               IF (J.EQ.ITERA) B(INV + J) = 0.D0
150
               B(JNV + I) = B(INV + J)
151
  120    CONTINUE
152
         B(IONE) = 1.0D0
153
  130 CONTINUE
154
  140 CONTINUE
155
  
156
      IF (DEBUG) THEN
157

    
158
      ! OUTPUT THE GDIIS MATRIX:
159
         WRITE(*,'(/5X,'' Step_GDIIS_Simple_Err MATRIX'')')
160
         ITmp=min(12,MPLUS)
161
         DO IJ=1,MPLUS
162
            WRITE(*,'(12(F10.4,1X))') B((IJ-1)*MPLUS+1:(IJ-1)*MPLUS+ITmp)
163
         END DO
164
      ENDIF
165

    
166
      ! SCALE DIIS MATRIX BEFORE INVERSION:
167
      DO 160 I=1,MPLUS
168
         II = MPLUS * (I-1) + I
169
  160 GSAVE(I) = 1.D0 / DSQRT(1.D-20+DABS(B(II)))
170
      GSAVE(MPLUS) = 1.D0
171
      DO 170 I=1,MPLUS
172
         DO 170 J=1,MPLUS
173
            IJ = MPLUS * (I-1) + J
174
  170 B(IJ) = B(IJ) * GSAVE(I) * GSAVE(J)
175
  
176
      IF (DEBUG) THEN
177

    
178
      ! OUTPUT SCALED GDIIS MATRIX:
179
         WRITE(*,'(/5X,'' Step_GDIIS_Simple_Err MATRIX (SCALED)'')')
180
         ITmp=min(12,MPLUS)
181
         DO IJ=1,MPLUS
182
            WRITE(*,'(12(F10.4,1X))') B((IJ-1)*MPLUS+1:(IJ-1)*MPLUS+ITmp)
183
         END DO
184
            
185
      ENDIF ! matches IF (DEBUG) THEN
186

    
187
      ! INVERT THE GDIIS MATRIX B:
188
      CALL MINV(B,MPLUS,DET) ! matrix inversion.
189

    
190
      DO 190 I=1,MPLUS
191
         DO 190 J=1,MPLUS
192
            IJ = MPLUS * (I-1) + J
193
  190 B(IJ) = B(IJ) * GSAVE(I) * GSAVE(J)
194
  
195
      ! COMPUTE THE INTERMEDIATE INTERPOLATED PARAMETER AND GRADIENT VECTORS:
196
      DO 200 K=1,NCoord
197
         NewGeom(K) = 0.D0
198
         NewGrad(K) = 0.D0
199
         DO 200 I=1,MSET
200
            INK = (I-1) * NCoord + K
201
      !Print *, 'B(',MPLUS*MSET+I,')=', B(MPLUS*MSET+I)
202
            NewGeom(K) = NewGeom(K) + B(MPLUS*MSET+I) * GeomSet(INK)
203
  200 NewGrad(K) = NewGrad(K) + B(MPLUS*MSET+I) * GradSet(INK)
204
      HP=0.D0
205
      DO 210 I=1,MSET
206
  210 HP=HP+B(MPLUS*MSET+I)*ESET(I)
207
      
208
      DO 220 K=1,NCoord
209
  220 DX(K) = Geom(K) - NewGeom(K)
210
      XNORM = SQRT(DOT_PRODUCT(DX,DX))
211
      IF (PRINT) THEN
212
         WRITE (6,'(/10X,''DEVIATION IN X '',F7.4,8X,''DETERMINANT '',G9.3)') XNORM,DET
213
         WRITE(*,'(10X,''Step_GDIIS_Simple_Err COEFFICIENTS'')')
214
         WRITE(*,'(10X,5F12.5)') (B(MPLUS*MSET+I),I=1,MSET)
215
      ENDIF
216

    
217
      ! THE FOLLOWING TOLERENCES FOR XNORM AND DET ARE SOMEWHAT ARBITRARY:
218
      THRES = MAX(10.D0**(-NCoord), 1.D-25)
219
      IF (XNORM.GT.2.D0 .OR. DABS(DET).LT. THRES) THEN
220
         IF (PRINT)THEN
221
            WRITE(*,*) "THE DIIS MATRIX IS ILL CONDITIONED"     
222
            WRITE(*,*) " - PROBABLY, VECTORS ARE LINEARLY DEPENDENT - "
223
            WRITE(*,*) "THE DIIS STEP WILL BE REPEATED WITH A SMALLER SPACE"
224
         END IF
225
         DO 230 K=1,MM
226
  230    B(K) = BS(K)
227
         NDIIS = NDIIS - 1
228
         IF (NDIIS .GT. 0) GO TO 80
229
         IF (PRINT) WRITE(*,'(10X,''NEWTON-RAPHSON STEP TAKEN'')')
230
         DO 240 K=1,NCoord
231
            NewGeom(K) = Geom(K)
232
  240       NewGrad(K) = GRAD(K)  
233
      ENDIF ! matches IF (XNORM.GT.2.D0 .OR. DABS(DET).LT. THRES) THEN
234
    
235
      !    q_{m+1} = q'_{m+1} - H^{-1}g'_{m+1}
236
     ! Hess is a symmetric matrix.
237
     !Hess_inv = 1.d0 ! to be deleted.
238
     !Call GenInv(NCoord,Reshape(Hess,(/NCoord,NCoord/)),Hess_inv,NCoord) ! Implemented in Mat_util.f90
239
     ! H^{-1}g'_{m+1}
240
     !Print *, 'Hess_inv='
241
    ! Print *, Hess_inv
242
     !Geom=0.d0
243
     !DO I=1, NCoord
244
      !  Geom(:) = Geom(:) + Hess_inv(:,I)*NewGrad(I)
245
     !END DO
246
     !Geom(:) = NewGeom(:) - Geom(:) ! now Geom is a new geometry.
247
     
248
     ! STEP is the difference between the new and old geometry and thus "step":
249
         !STEP = Geom - Geom_old
250
         
251
      IF (PRINT)  WRITE(*,'(/,''       END Step_GDIIS_Simple_Err  '',/)')
252

    
253
      END SUBROUTINE Step_GDIIS_Simple_Err