Statistiques
| Révision :

root / src / Step_DIIS_all.f90

Historique | Voir | Annoter | Télécharger (17,83 ko)

1 1 pfleura2
!C  HEAT is never used, not even in call of Space(...)
2 1 pfleura2
!C  Geom = input parameter vector (Geometry).
3 1 pfleura2
!C  Grad = input gradient vector.
4 1 pfleura2
!C  Geom_new = New Geometry.
5 1 pfleura2
6 1 pfleura2
    SUBROUTINE Step_diis_all(NGeomF,IGeom,Step,Geom,Grad,HP,HEAT,Hess,NCoord,allocation_flag,Tangent)
7 1 pfleura2
8 12 pfleura2
!----------------------------------------------------------------------
9 12 pfleura2
! This routine was adapted from the public domain mopac6 diis.f
10 12 pfleura2
!  source file (c) 2009, Stewart Computational Chemistry.
11 12 pfleura2
!  <http://www.openmopac.net/Downloads/Downloads.html>
12 12 pfleura2
!
13 12 pfleura2
!----------------------------------------------------------------------
14 12 pfleura2
!  Copyright 2003-2014 Ecole Normale Supérieure de Lyon,
15 12 pfleura2
!  Centre National de la Recherche Scientifique,
16 12 pfleura2
!  Université Claude Bernard Lyon 1. All rights reserved.
17 12 pfleura2
!
18 12 pfleura2
!  This work is registered with the Agency for the Protection of Programs
19 12 pfleura2
!  as IDDN.FR.001.100009.000.S.P.2014.000.30625
20 12 pfleura2
!
21 12 pfleura2
!  Authors: P. Fleurat-Lessard, P. Dayal
22 12 pfleura2
!  Contact: optnpath@gmail.com
23 12 pfleura2
!
24 12 pfleura2
! This file is part of "Opt'n Path".
25 12 pfleura2
!
26 12 pfleura2
!  "Opt'n Path" is free software: you can redistribute it and/or modify
27 12 pfleura2
!  it under the terms of the GNU Affero General Public License as
28 12 pfleura2
!  published by the Free Software Foundation, either version 3 of the License,
29 12 pfleura2
!  or (at your option) any later version.
30 12 pfleura2
!
31 12 pfleura2
!  "Opt'n Path" is distributed in the hope that it will be useful,
32 12 pfleura2
!  but WITHOUT ANY WARRANTY; without even the implied warranty of
33 12 pfleura2
!
34 12 pfleura2
!  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
35 12 pfleura2
!  GNU Affero General Public License for more details.
36 12 pfleura2
!
37 12 pfleura2
!  You should have received a copy of the GNU Affero General Public License
38 12 pfleura2
!  along with "Opt'n Path". If not, see <http://www.gnu.org/licenses/>.
39 12 pfleura2
!
40 12 pfleura2
! Contact The Office of Technology Licensing, valorisation@ens-lyon.fr,
41 12 pfleura2
! for commercial licensing opportunities.
42 12 pfleura2
!----------------------------------------------------------------------
43 12 pfleura2
44 1 pfleura2
    USE Io_module, only : IoOut
45 1 pfleura2
    USE Path_module, only : Vfree
46 1 pfleura2
47 1 pfleura2
    IMPLICIT NONE
48 1 pfleura2
    INTEGER, parameter :: KINT = kind(1)
49 1 pfleura2
    INTEGER, parameter :: KREAL = kind(1.0d0)
50 1 pfleura2
51 1 pfleura2
    !      INCLUDE 'SIZES'
52 1 pfleura2
53 1 pfleura2
    INTEGER(KINT) :: NGeomF,IGeom
54 1 pfleura2
    INTEGER(KINT), INTENT(IN) :: NCoord
55 1 pfleura2
56 2 pfleura2
    REAL(KREAL) :: Geom(NCoord), Grad(NCoord)
57 1 pfleura2
    REAL(KREAL) :: Hess(NCoord*NCoord),Step(NCoord)
58 1 pfleura2
    REAL(KREAL) :: HEAT,HP
59 1 pfleura2
    LOGICAL :: allocation_flag
60 1 pfleura2
    REAL(KREAL), INTENT(INOUT) :: Tangent(Ncoord)
61 1 pfleura2
62 1 pfleura2
!************************************************************************
63 1 pfleura2
!*                                                                      *
64 1 pfleura2
!*     DIIS PERFORMS DIRECT INVERSION IN THE ITERATIVE SUBSPACE         *
65 1 pfleura2
!*                                                                      *
66 1 pfleura2
!*     THIS INVOLVES SOLVING FOR C IN Geom(NEW) = Geom' - HG'      *
67 1 pfleura2
!*                                                                      *
68 1 pfleura2
!*  WHERE Geom' = SUM(C(I)Geom(I), THE C COEFFICIENTES COMING FROM      *
69 1 pfleura2
!*                                                                      *
70 1 pfleura2
!*                   | B   1 | . | C | = | 0 |                          *
71 1 pfleura2
!*                   | 1   0 |   |-L |   | 1 |                          *
72 1 pfleura2
!*                                                                      *
73 1 pfleura2
!*  WHERE B(I,J) =GRAD(I)H(T)HGRAD(J)  GRAD(I) = GRADIENT ON CYCLE I    *
74 1 pfleura2
!*                              Hess    = INVERSE HESSIAN        *
75 1 pfleura2
!*                                                                      *
76 1 pfleura2
!*                          REFERENCE                                   *
77 1 pfleura2
!*                                                                      *
78 1 pfleura2
!*  P. CSASZAR, P. PULAY, J. MOL. STRUCT. (THEOCHEM), 114, 31 (1984)    *
79 1 pfleura2
!*                                                                      *
80 1 pfleura2
!************************************************************************
81 1 pfleura2
!************************************************************************
82 1 pfleura2
!*                                                                      *
83 1 pfleura2
!*     GEOMETRY OPTIMIZATION USING THE METHOD OF DIRECT INVERSION IN    *
84 1 pfleura2
!*     THE ITERATIVE SUBSPACE (GDIIS), COMBINED WITH THE BFGS OPTIMIZER *
85 1 pfleura2
!*     (A VARIABLE METRIC METHOD)                                       *
86 1 pfleura2
!*                                                                      *
87 1 pfleura2
!*     WRITTEN BY PETER L. CUMMINS, UNIVERSITY OF SYDNEY, AUSTRALIA     *
88 1 pfleura2
!*                                                                      *
89 1 pfleura2
!*                              REFERENCE                               *
90 1 pfleura2
!*                                                                      *
91 1 pfleura2
!*      "COMPUTATIONAL STRATEGIES FOR THE OPTIMIZATION OF EQUILIBRIUM   *
92 1 pfleura2
!*     GEOMETRIES AND TRANSITION-STATE STRUCTURES AT THE SEMIEMPIRICAL  *
93 1 pfleura2
!*     LEVEL", PETER L. CUMMINS, JILL E. GREADY, J. COMP. CHEM., 10,    *
94 1 pfleura2
!*     939-950 (1989).                                                  *
95 1 pfleura2
!*                                                                      *
96 1 pfleura2
!*     MODIFIED BY JJPS TO CONFORM TO EXISTING MOPAC CONVENTIONS        *
97 1 pfleura2
!*                                                                      *
98 1 pfleura2
!************************************************************************
99 1 pfleura2
100 1 pfleura2
      ! MRESET = maximum number of iterations.
101 1 pfleura2
      INTEGER(KINT), PARAMETER :: MRESET=15, M2=(MRESET+1)*(MRESET+1) !M2 = 256
102 1 pfleura2
      REAL(KREAL), ALLOCATABLE, SAVE :: GeomSet(:,:),GradSet(:,:),ERR(:,:) ! MRESET*NCoord
103 1 pfleura2
      REAL(KREAL), SAVE :: ESET(MRESET)
104 1 pfleura2
    REAL(KREAL), ALLOCATABLE, SAVE :: DXTMP(:,:),GSAVE(:,:) !NCoord, why DXTMP has SAVE attribute??
105 2 pfleura2
      REAL(KREAL) :: B(M2), BS(M2)
106 1 pfleura2
      LOGICAL DEBUG, PRINT
107 1 pfleura2
      INTEGER(KINT), ALLOCATABLE, SAVE :: MSET(:)
108 1 pfleura2
    LOGICAL, ALLOCATABLE, SAVE :: FRST(:)
109 1 pfleura2
      INTEGER(KINT) :: NDIIS, MPLUS, INV, ITERA, MM, NFree, I, J, K
110 1 pfleura2
      INTEGER(KINT) :: JJ, KJ, JNV, II, IONE, IJ, INK,ITmp, Isch, Idx
111 1 pfleura2
      REAL(KREAL) :: XMax, XNorm, S, DET, THRES, Norm
112 1 pfleura2
    REAL(KREAL), PARAMETER :: eps=1e-12
113 1 pfleura2
    REAL(KREAL), PARAMETER :: crit=1e-8
114 1 pfleura2
    REAL(KREAL), ALLOCATABLE :: Tanf(:) ! NCoord
115 1 pfleura2
    REAL(KREAL), ALLOCATABLE :: HFree(:) ! NFree*NFree
116 1 pfleura2
    REAL(KREAL), ALLOCATABLE :: Htmp(:,:) ! NCoord,NFree
117 1 pfleura2
    REAL(KREAL), ALLOCATABLE :: Grad_free(:),Grad_new_free_inter(:),Step_free(:) ! NFree
118 1 pfleura2
    REAL(KREAL), ALLOCATABLE :: Geom_free(:),Geom_new_free_inter(:),Geom_new_free(:) ! NFree
119 1 pfleura2
    REAL(KREAL), ALLOCATABLE, SAVE :: GeomSet_free(:,:),GradSet_free(:,:)
120 1 pfleura2
121 1 pfleura2
      DEBUG=.TRUE.
122 1 pfleura2
      PRINT=.TRUE.
123 1 pfleura2
124 1 pfleura2
      IF (PRINT)  WRITE(*,'(/,''      BEGIN GDIIS   '')')
125 1 pfleura2
126 1 pfleura2
      ! Initialization
127 1 pfleura2
      IF (allocation_flag) THEN ! allocation_flag = .TRUE. at the begining and effective for all geometries in path.
128 1 pfleura2
      ! FRST(IGeom) will be set to False in Space, so no need to modify it here
129 1 pfleura2
         IF (ALLOCATED(GeomSet)) THEN
130 1 pfleura2
            IF (PRINT)  WRITE(*,'(/,''    In FRST, GDIIS Dealloc  '')')
131 1 pfleura2
            DEALLOCATE(GeomSet,GradSet,ERR,DXTMP,GSave,GeomSet_free,GradSet_free)
132 1 pfleura2
            RETURN
133 1 pfleura2
         ELSE
134 1 pfleura2
        ! these allocated arrays need to be properly deallocated.
135 1 pfleura2
            IF (PRINT)  WRITE(*,'(/,''     In FRST,  GDIIS Alloc  '')')
136 1 pfleura2
            ALLOCATE(GeomSet(NGeomF,MRESET*NCoord),GradSet(NGeomF,MRESET*NCoord),ERR(NGeomF,MRESET*NCoord))
137 1 pfleura2
      ALLOCATE(GeomSet_free(NGeomF,MRESET*NCoord),GradSet_free(NGeomF,MRESET*NCoord))
138 1 pfleura2
            ALLOCATE(DXTMP(NGeomF,NCoord),GSAVE(NGeomF,NCoord),MSET(NGeomF),FRST(NGeomF))
139 1 pfleura2
      DO I=1,NGeomF
140 1 pfleura2
         FRST(I) = .TRUE.
141 1 pfleura2
         GeomSet(I,:) = 0.d0
142 1 pfleura2
         GradSet(I,:) = 0.d0
143 1 pfleura2
         ERR(I,:) = 0.d0
144 1 pfleura2
         GeomSet_free(I,:) = 0.d0
145 1 pfleura2
         GradSet_free(I,:) = 0.d0
146 1 pfleura2
         DXTMP(I,:)=0.d0
147 1 pfleura2
         GSAVE(I,:)=0.d0
148 1 pfleura2
      END DO
149 1 pfleura2
      MSET(:)=0
150 1 pfleura2
         END IF
151 1 pfleura2
     allocation_flag = .FALSE.
152 1 pfleura2
      END IF
153 1 pfleura2
154 1 pfleura2
      ! Addded from here:
155 1 pfleura2
    Call FreeMv(NCoord,Vfree) ! VFree(Ncoord,Ncoord)
156 1 pfleura2
      ! we orthogonalize Vfree to the tangent vector of this geom only if Tangent/=0.d0
157 1 pfleura2
      Norm=sqrt(dot_product(Tangent,Tangent))
158 1 pfleura2
      IF (Norm.GT.eps) THEN
159 1 pfleura2
         ALLOCATE(Tanf(NCoord))
160 1 pfleura2
161 1 pfleura2
         ! We normalize Tangent
162 1 pfleura2
         Tangent=Tangent/Norm
163 1 pfleura2
164 1 pfleura2
         ! We convert Tangent into Vfree only displacements. This is useless for now (2007.Apr.23)
165 1 pfleura2
     ! as Vfree=Id matrix but it will be usefull as soon as we introduce constraints.
166 1 pfleura2
         DO I=1,NCoord
167 1 pfleura2
            Tanf(I)=dot_product(reshape(Vfree(:,I),(/NCoord/)),Tangent)
168 1 pfleura2
         END DO
169 1 pfleura2
         Tangent=0.d0
170 1 pfleura2
         DO I=1,NCoord
171 1 pfleura2
            Tangent=Tangent+Tanf(I)*Vfree(:,I)
172 1 pfleura2
         END DO
173 1 pfleura2
         ! first we subtract Tangent from vfree
174 1 pfleura2
         DO I=1,NCoord
175 1 pfleura2
            Norm=dot_product(reshape(vfree(:,I),(/NCoord/)),Tangent)
176 1 pfleura2
            Vfree(:,I)=Vfree(:,I)-Norm*Tangent
177 1 pfleura2
     END DO
178 1 pfleura2
179 8 pfleura2
         Idx=0
180 1 pfleura2
         ! Schmidt orthogonalization of the Vfree vectors
181 1 pfleura2
         DO I=1,NCoord
182 1 pfleura2
            ! We subtract the first vectors, we do it twice as the Schmidt procedure is not numerically stable.
183 1 pfleura2
            DO Isch=1,2
184 1 pfleura2
               DO J=1,Idx
185 1 pfleura2
                  Norm=dot_product(reshape(Vfree(:,I),(/NCoord/)),reshape(Vfree(:,J),(/NCoord/)))
186 1 pfleura2
                  Vfree(:,I)=Vfree(:,I)-Norm*Vfree(:,J)
187 1 pfleura2
               END DO
188 1 pfleura2
            END DO
189 1 pfleura2
            Norm=dot_product(reshape(Vfree(:,I),(/NCoord/)),reshape(Vfree(:,I),(/NCoord/)))
190 1 pfleura2
            IF (Norm.GE.crit) THEN
191 1 pfleura2
               Idx=Idx+1
192 1 pfleura2
               Vfree(:,Idx)=Vfree(:,I)/sqrt(Norm)
193 1 pfleura2
            END IF
194 1 pfleura2
         END DO
195 1 pfleura2
196 1 pfleura2
         Print *, 'Idx=', Idx
197 1 pfleura2
         IF (Idx/= NCoord-1) THEN
198 1 pfleura2
            WRITE(*,*) "Pb in orthogonalizing Vfree to tangent for geom",IGeom
199 1 pfleura2
            WRITE(IoOut,*) "Pb in orthogonalizing Vfree to tangent for geom",IGeom
200 1 pfleura2
            STOP
201 1 pfleura2
         END IF
202 1 pfleura2
203 1 pfleura2
         DEALLOCATE(Tanf)
204 1 pfleura2
         NFree=Idx
205 1 pfleura2
      ELSE ! Tangent =0, matches IF (Norm.GT.eps) THEN
206 1 pfleura2
         if (debug) WRITE(*,*) "Tangent=0, using full displacement"
207 1 pfleura2
         NFree=NCoord
208 1 pfleura2
      END IF !IF (Norm.GT.eps) THEN
209 1 pfleura2
210 1 pfleura2
      if (debug) WRITE(*,*) 'DBG Step_DIIS_All, IGeom, NFree=', IGeom, NFree
211 1 pfleura2
212 1 pfleura2
      ! We now calculate the new step
213 1 pfleura2
      ! we project the hessian onto the free vectors
214 1 pfleura2
      ALLOCATE(HFree(NFree*NFree),Htmp(NCoord,NFree),Grad_free(NFree),Grad_new_free_inter(NFree))
215 1 pfleura2
    ALLOCATE(Geom_free(NFree),Step_free(NFree),Geom_new_free_inter(NFree),Geom_new_free(NFree))
216 1 pfleura2
      DO J=1,NFree
217 1 pfleura2
        DO I=1,NCoord
218 1 pfleura2
           Htmp(I,J)=0.d0
219 1 pfleura2
           DO K=1,NCoord
220 1 pfleura2
              Htmp(I,J)=Htmp(I,J)+Hess(((I-1)*NCoord)+K)*Vfree(K,J)
221 1 pfleura2
           END DO
222 1 pfleura2
        END DO
223 1 pfleura2
      END DO
224 1 pfleura2
      DO J=1,NFree
225 1 pfleura2
        DO I=1,NFree
226 1 pfleura2
       HFree(I+((J-1)*NFree))=0.d0
227 1 pfleura2
           DO K=1,NCoord
228 1 pfleura2
        HFree(I+((J-1)*NFree))=HFree(I+((J-1)*NFree))+Vfree(K,I)*Htmp(K,J)
229 1 pfleura2
           END DO
230 1 pfleura2
        END DO
231 1 pfleura2
      END DO
232 1 pfleura2
233 1 pfleura2
      DO I=1,NFree
234 1 pfleura2
         Grad_free(I)=dot_product(reshape(Vfree(:,I),(/NCoord/)),Grad)
235 1 pfleura2
     Geom_free(I)=dot_product(reshape(Vfree(:,I),(/NCoord/)),Geom)
236 1 pfleura2
      END DO
237 1 pfleura2
      !Added Ends here.***********************************************
238 1 pfleura2
239 1 pfleura2
!C  SPACE SIMPLY LOADS THE CURRENT VALUES OF Geom AND GRAD INTO
240 1 pfleura2
!C  THE ARRAYS GeomSet AND GradSet
241 1 pfleura2
!C  HEAT is never used, not even in Space_all(...)
242 1 pfleura2
243 1 pfleura2
      CALL Space_all(NGeomF,IGeom,MRESET,MSET,Geom,Grad,HEAT,NCoord,GeomSet,GradSet,ESET,FRST)
244 1 pfleura2
245 1 pfleura2
      IF (PRINT)  WRITE(*,'(/,''       GDIIS after Space  '')')
246 1 pfleura2
247 1 pfleura2
    DO J=1,MSet(IGeom)
248 1 pfleura2
         DO K=1,NFree
249 1 pfleura2
            GradSet_free(IGeom,((J-1)*NFree)+K)=dot_product(reshape(Vfree(:,K),(/NCoord/)),&
250 1 pfleura2
               GradSet(IGeom,((J-1)*NCoord)+1:((J-1)*NCoord)+NCoord))
251 1 pfleura2
        GeomSet_free(IGeom,((J-1)*NFree)+K)=dot_product(reshape(Vfree(:,K),(/NCoord/)),&
252 1 pfleura2
                GeomSet(IGeom,((J-1)*NCoord)+1:((J-1)*NCoord)+NCoord))
253 1 pfleura2
         END DO
254 1 pfleura2
    END DO
255 1 pfleura2
!C
256 1 pfleura2
!C     INITIALIZE SOME VARIABLES AND CONSTANTS
257 1 pfleura2
!C
258 1 pfleura2
      NDIIS = MSET(IGeom)
259 1 pfleura2
      MPLUS = MSET(IGeom) + 1
260 1 pfleura2
      MM = MPLUS * MPLUS
261 1 pfleura2
!C
262 1 pfleura2
!C     COMPUTE THE APPROXIMATE ERROR VECTORS
263 1 pfleura2
!C
264 1 pfleura2
      INV=-NFree
265 1 pfleura2
      DO 30 I=1,MSET(IGeom)
266 1 pfleura2
         INV = INV + NFree
267 1 pfleura2
         DO 30 J=1,NFree
268 1 pfleura2
            S = 0.D0
269 1 pfleura2
            KJ=(J*(J-1))/2
270 1 pfleura2
            DO 10 K=1,J
271 1 pfleura2
               KJ = KJ+1
272 1 pfleura2
   10       S = S - HFree(KJ) * GradSet_free(IGeom,INV+K)
273 1 pfleura2
            DO 20 K=J+1,NFree
274 1 pfleura2
               KJ = (K*(K-1))/2+J
275 1 pfleura2
   20       S = S - HFree(KJ) * GradSet_free(IGeom,INV+K)
276 1 pfleura2
   30 ERR(IGeom,INV+J) = S
277 1 pfleura2
278 1 pfleura2
!C
279 1 pfleura2
!C     CONSTRUCT THE GDIIS MATRIX
280 1 pfleura2
!C
281 1 pfleura2
      DO 40 I=1,MM
282 1 pfleura2
   40 B(I) = 1.D0
283 1 pfleura2
284 1 pfleura2
      JJ=0
285 1 pfleura2
      INV=-NFree
286 1 pfleura2
      DO 50 I=1,MSET(IGeom)
287 1 pfleura2
         INV=INV+NFree
288 1 pfleura2
         JNV=-NFree
289 1 pfleura2
         DO 50 J=1,MSET(IGeom)
290 1 pfleura2
            JNV=JNV+NFree
291 1 pfleura2
            JJ = JJ + 1
292 1 pfleura2
            B(JJ)=0.D0
293 1 pfleura2
            DO 50 K=1,NFree
294 1 pfleura2
      !Print *, 'B(',JJ,')=', B(JJ) + ERR(IGeom,INV+K) * ERR(IGeom,JNV+K)
295 1 pfleura2
   50 B(JJ) = B(JJ) + ERR(IGeom,INV+K) * ERR(IGeom,JNV+K)
296 1 pfleura2
297 1 pfleura2
     ! The following shifting is required to correct indices of B_ij elements in the GDIIS matrix.
298 1 pfleura2
   ! The correction is needed because the last coloumn of the matrix contains all 1 and one zero.
299 1 pfleura2
      DO 60 I=MSET(IGeom)-1,1,-1
300 1 pfleura2
         DO 60 J=MSET(IGeom),1,-1
301 1 pfleura2
   60 B(I*MSET(IGeom)+J+I) = B(I*MSET(IGeom)+J)
302 1 pfleura2
303 1 pfleura2
      ! For the last row and last column of GEDIIS matrix:
304 1 pfleura2
      DO 70 I=1,MPLUS
305 1 pfleura2
         B(MPLUS*I) = 1.D0
306 1 pfleura2
   70 B(MPLUS*MSET(IGeom)+I) = 1.D0
307 1 pfleura2
      B(MM) = 0.D0
308 1 pfleura2
!C
309 1 pfleura2
!C     ELIMINATE ERROR VECTORS WITH THE LARGEST NORM
310 1 pfleura2
!C
311 1 pfleura2
   80 CONTINUE
312 1 pfleura2
      DO 90 I=1,MM
313 1 pfleura2
   90 BS(I) = B(I)
314 1 pfleura2
315 1 pfleura2
      IF (NDIIS .EQ. MSET(IGeom)) GO TO 140
316 1 pfleura2
      DO 130 II=1,MSET(IGeom)-NDIIS
317 1 pfleura2
         XMAX = -1.D10
318 1 pfleura2
         ITERA = 0
319 1 pfleura2
         DO 110 I=1,MSET(IGeom)
320 1 pfleura2
            XNORM = 0.D0
321 1 pfleura2
            INV = (I-1) * MPLUS
322 1 pfleura2
            DO 100 J=1,MSET(IGeom)
323 1 pfleura2
  100       XNORM = XNORM + ABS(B(INV + J))
324 1 pfleura2
            IF (XMAX.LT.XNORM .AND. XNORM.NE.1.0D0) THEN
325 1 pfleura2
               XMAX = XNORM
326 1 pfleura2
               ITERA = I
327 1 pfleura2
               IONE = INV + I
328 1 pfleura2
            ENDIF
329 1 pfleura2
  110    CONTINUE
330 1 pfleura2
331 1 pfleura2
         DO 120 I=1,MPLUS
332 1 pfleura2
            INV = (I-1) * MPLUS
333 1 pfleura2
            DO 120 J=1,MPLUS
334 1 pfleura2
               JNV = (J-1) * MPLUS
335 1 pfleura2
               IF (J.EQ.ITERA) B(INV + J) = 0.D0
336 1 pfleura2
               B(JNV + I) = B(INV + J)
337 1 pfleura2
         !Print *,'B(JNV + I)=',B(JNV + I)
338 1 pfleura2
  120    CONTINUE
339 1 pfleura2
         B(IONE) = 1.0D0
340 1 pfleura2
  130 CONTINUE
341 1 pfleura2
  140 CONTINUE
342 1 pfleura2
!C
343 1 pfleura2
!C     OUTPUT THE GDIIS MATRIX
344 1 pfleura2
!C
345 1 pfleura2
      IF (DEBUG) THEN
346 1 pfleura2
         WRITE(*,'(/5X,'' GDIIS MATRIX'')')
347 1 pfleura2
         ITmp=min(12,MPLUS)
348 1 pfleura2
         DO IJ=1,MPLUS
349 1 pfleura2
            WRITE(*,'(12(F12.4,1X))') B((IJ-1)*MPLUS+1:(IJ-1)*MPLUS+ITmp)
350 1 pfleura2
         END DO
351 1 pfleura2
      ENDIF
352 1 pfleura2
!C
353 1 pfleura2
!C     SCALE DIIS MATRIX BEFORE INVERSION
354 1 pfleura2
!C
355 1 pfleura2
      DO 160 I=1,MPLUS
356 1 pfleura2
         II = MPLUS * (I-1) + I
357 1 pfleura2
     !Print *, 'B(',II,')=', B(II)
358 1 pfleura2
     !Print *, 'GSave(',IGeom,',',I,')=', 1.D0 / DSQRT(1.D-20+DABS(B(II)))
359 1 pfleura2
  160 GSAVE(IGeom,I) = 1.D0 / DSQRT(1.D-20+DABS(B(II)))
360 1 pfleura2
361 1 pfleura2
      GSAVE(IGeom,MPLUS) = 1.D0
362 1 pfleura2
      !Print *, 'GSave(',IGeom,',',MPlus,')=1.D0'
363 1 pfleura2
364 1 pfleura2
      DO 170 I=1,MPLUS
365 1 pfleura2
         DO 170 J=1,MPLUS
366 1 pfleura2
            IJ = MPLUS * (I-1) + J
367 1 pfleura2
  170 B(IJ) = B(IJ) * GSAVE(IGeom,I) * GSAVE(IGeom,J)
368 1 pfleura2
!C
369 1 pfleura2
!C     OUTPUT SCALED GDIIS MATRIX
370 1 pfleura2
!C
371 1 pfleura2
      IF (DEBUG) THEN
372 1 pfleura2
         WRITE(*,'(/5X,'' GDIIS MATRIX (SCALED)'')')
373 1 pfleura2
         ITmp=min(12,MPLUS)
374 1 pfleura2
         DO IJ=1,MPLUS
375 1 pfleura2
            WRITE(*,'(12(F12.4,1X))') B((IJ-1)*MPLUS+1:(IJ-1)*MPLUS+ITmp)
376 1 pfleura2
         END DO
377 1 pfleura2
      ENDIF
378 1 pfleura2
!C
379 1 pfleura2
!C     INVERT THE GDIIS MATRIX B
380 1 pfleura2
!C
381 1 pfleura2
      CALL MINV(B,MPLUS,DET) ! matrix inversion.
382 1 pfleura2
383 1 pfleura2
      DO 190 I=1,MPLUS
384 1 pfleura2
         DO 190 J=1,MPLUS
385 1 pfleura2
            IJ = MPLUS * (I-1) + J
386 1 pfleura2
      !Print *, 'B(',IJ,')=', B(IJ)
387 1 pfleura2
      !Print *, 'GSAVE(',IGeom,',',I,')=', GSAVE(IGeom,I)
388 1 pfleura2
      !Print *, 'GSAVE(',IGeom,',',J,')=', GSAVE(IGeom,J)
389 1 pfleura2
      !Print *, 'B(',IJ,')=', B(IJ) * GSAVE(I) * GSAVE(J)
390 1 pfleura2
  190 B(IJ) = B(IJ) * GSAVE(IGeom,I) * GSAVE(IGeom,J)
391 1 pfleura2
!C
392 1 pfleura2
!C     COMPUTE THE INTERMEDIATE INTERPOLATED PARAMETER AND GRADIENT VECTORS
393 1 pfleura2
!C
394 1 pfleura2
      !Print *, 'MSET(',IGeom,')=', MSET(IGeom), ' MPLUS=', MPLUS
395 1 pfleura2
      DO 200 K=1,NFree
396 1 pfleura2
         Geom_new_free_inter(K) = 0.D0
397 1 pfleura2
         Grad_new_free_inter(K) = 0.D0
398 1 pfleura2
         DO 200 I=1,MSET(IGeom)
399 1 pfleura2
            INK = (I-1) * NFree + K
400 1 pfleura2
            Geom_new_free_inter(K) = Geom_new_free_inter(K) + B(MPLUS*MSET(IGeom)+I) * GeomSet_free(IGeom,INK)
401 1 pfleura2
      !Print *, 'Geom_new_free_inter(',K,')=', Geom_new_free_inter(K)
402 1 pfleura2
      !Print *, 'B(MPLUS*MSET(',IGeom,')+',I,')=', B(MPLUS*MSET(IGeom)+I)
403 1 pfleura2
      !Print *, 'GeomSet_free(',IGeom,',',INK,')=', GeomSet_free(IGeom,INK)
404 1 pfleura2
  200 Grad_new_free_inter(K) = Grad_new_free_inter(K) + B(MPLUS*MSET(IGeom)+I) * GradSet_free(IGeom,INK)
405 1 pfleura2
      HP=0.D0
406 1 pfleura2
      DO 210 I=1,MSET(IGeom)
407 1 pfleura2
  210 HP=HP+B(MPLUS*MSET(IGeom)+I)*ESET(I)
408 1 pfleura2
      DO 220 K=1,NFree
409 1 pfleura2
  220 DXTMP(IGeom,K) = Geom_free(K) - Geom_new_free_inter(K)
410 1 pfleura2
      XNORM = SQRT(DOT_PRODUCT(DXTMP(IGeom,1:NFree),DXTMP(IGeom,1:NFree)))
411 1 pfleura2
      IF (PRINT) THEN
412 1 pfleura2
         WRITE (6,'(/10X,''DEVIATION IN X '',F10.6, 8X,''DETERMINANT '',G9.3)') XNORM,DET
413 1 pfleura2
         WRITE(*,'(10X,''GDIIS COEFFICIENTS'')')
414 1 pfleura2
         WRITE(*,'(10X,5F12.5)') (B(MPLUS*MSET(IGeom)+I),I=1,MSET(IGeom))
415 1 pfleura2
      ENDIF
416 1 pfleura2
417 1 pfleura2
!C     THE FOLLOWING TOLERENCES FOR XNORM AND DET ARE SOMEWHAT ARBITRARY!
418 1 pfleura2
      THRES = MAX(10.D0**(-NFree), 1.D-25)
419 1 pfleura2
      IF (XNORM.GT.2.D0 .OR. DABS(DET).LT. THRES) THEN
420 1 pfleura2
         IF (PRINT)THEN
421 1 pfleura2
            WRITE(*,*) "THE DIIS MATRIX IS ILL CONDITIONED"
422 1 pfleura2
            WRITE(*,*) " - PROBABLY, VECTORS ARE LINEARLY DEPENDENT - "
423 1 pfleura2
            WRITE(*,*) "THE DIIS STEP WILL BE REPEATED WITH A SMALLER SPACE"
424 1 pfleura2
         END IF
425 1 pfleura2
         DO 230 K=1,MM
426 1 pfleura2
  230    B(K) = BS(K)
427 1 pfleura2
         NDIIS = NDIIS - 1
428 1 pfleura2
         IF (NDIIS .GT. 0) GO TO 80
429 1 pfleura2
         IF (PRINT) WRITE(*,'(10X,''NEWTON-RAPHSON STEP TAKEN'')')
430 1 pfleura2
         DO 240 K=1,NFree
431 1 pfleura2
            Geom_new_free_inter(K) = Geom_free(K)
432 1 pfleura2
  240       Grad_new_free_inter(K) = Grad_free(K)
433 1 pfleura2
      ENDIF ! matches IF (XNORM.GT.2.D0 .OR. DABS(DET).LT. THRES) THEN, L378
434 1 pfleura2
435 1 pfleura2
    ! q_{m+1} = q'_{m+1} - H^{-1}g'_{m+1}
436 1 pfleura2
    Geom_new_free=0.d0
437 1 pfleura2
    DO I = 1, NFree
438 1 pfleura2
       DO J = 1, NFree
439 1 pfleura2
          ! If Hinv=.False., then we need to invert Hess
440 1 pfleura2
        !Geom_new_free(:) = Geom_new_free(:) + HFree(:,I)*Grad_new_free_inter(I)
441 1 pfleura2
       Geom_new_free(J) = Geom_new_free(J) + HFree(I+((J-1)*NFree))*Grad_new_free_inter(I)
442 1 pfleura2
     END DO
443 1 pfleura2
    END DO
444 1 pfleura2
    Geom_new_free(:) = Geom_new_free_inter(:) - Geom_new_free(:)
445 1 pfleura2
446 1 pfleura2
    Step_free = Geom_new_free - Geom_free
447 1 pfleura2
448 1 pfleura2
    Step = 0.d0
449 1 pfleura2
      DO I=1,NFree
450 1 pfleura2
     Step = Step + Step_free(I)*Vfree(:,I)
451 1 pfleura2
      END DO
452 1 pfleura2
453 1 pfleura2
      DEALLOCATE(Hfree,Htmp,Grad_free,Grad_new_free_inter,Step_free,Geom_free)
454 1 pfleura2
      DEALLOCATE(Geom_new_free_inter,Geom_new_free)
455 1 pfleura2
456 1 pfleura2
    IF (PRINT)  WRITE(*,'(/,''       END GDIIS  '',/)')
457 1 pfleura2
458 1 pfleura2
      END SUBROUTINE Step_diis_all