Statistiques
| Révision :

root / src / Step_RFO_all.f90 @ 1

Historique | Voir | Annoter | Télécharger (7,97 ko)

1 1 equemene
SUBROUTINE Step_RFO_all(NCoord,Step,IGeom,Geom,Grad,Hess,Tangent)
2 1 equemene
3 1 equemene
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
4 1 equemene
!
5 1 equemene
!This subroutine calculates new coordinates given a Hessian, the forces
6 1 equemene
! and the old coordinates
7 1 equemene
!
8 1 equemene
!!!!!!!!!!
9 1 equemene
! v1.0
10 1 equemene
! Uses only basic RFO step
11 1 equemene
!
12 1 equemene
!!!!!!!!!!
13 1 equemene
! v 2.0
14 1 equemene
! We add the test of ADF here, so that it should be more efficient.
15 1 equemene
! This version uses HInv to decide wether it should work with the Hessian
16 1 equemene
! or its inverse.
17 1 equemene
!
18 1 equemene
! v 3.0
19 1 equemene
! Uses DIIS. Done by P. Dayal.
20 1 equemene
!
21 1 equemene
! v3.1
22 1 equemene
! Back to origins ! We remove the ADF test here to see what we loose...
23 1 equemene
! untill of course its replacement by something more efficient... and free :)
24 1 equemene
!!!!!!!!!!!!!!!!!
25 1 equemene
!
26 1 equemene
! Input:
27 1 equemene
!   - NCoord: INTEGER(KINT), Number of degrees of freedom
28 1 equemene
!   - IGeom : INTEGER(KINT), Index of the geometry along the path
29 1 equemene
!   - Geom  : REAL(KREAL)(NCOORD), Geometry expressed in full coordinates
30 1 equemene
!   - Hess  : REAL(KREAL)(Ncoord,NCoord), Hessian at the current geometry
31 1 equemene
!
32 1 equemene
!
33 1 equemene
! Output:
34 1 equemene
!   - Step  : REAL(KREAL)(Ncoord), Calculated step
35 1 equemene
!
36 1 equemene
! In/Out:
37 1 equemene
!   - Tangent: REAL(KREAL)(Ncoord), Tangent to the path, at the current point
38 1 equemene
!             if Tangent=0, then we are optimizing a minimum,  tangent is not considered.
39 1 equemene
!               Input: Expressed in full coordinates.
40 1 equemene
!              Output: Replaced by the tangent expressed in Free vectors
41 1 equemene
! (Changes by PFL 3 Jan 2008)
42 1 equemene
!   -  Grad: READ(KREAL) (NCoord), Gradient at the current point
43 1 equemene
!               Input: Expressed in full coordinates.
44 1 equemene
! PFL 18 Jan 2008: Grad is no longer changed on output ->
45 1 equemene
!              Output: Replaced by the gradient expressed in Free vector, in the subspace orthogonal to the tangent.
46 1 equemene
! <- PFL 18 Jan 2008: Grad is no longer changed on output
47 1 equemene
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
48 1 equemene
49 1 equemene
  use Io_module, only : IoOut
50 1 equemene
51 1 equemene
  use Path_module, only : NGeomF, Hinv,Coord,Vfree, NGintMax
52 1 equemene
  ! VFree(Ncoord,Ncoord)
53 1 equemene
54 1 equemene
  IMPLICIT NONE
55 1 equemene
56 1 equemene
  INTEGER, PARAMETER :: KINT=KIND(1)
57 1 equemene
  INTEGER, PARAMETER :: KREAL=KIND(1.D0)
58 1 equemene
59 1 equemene
  INTEGER(KINT), INTENT(IN) :: NCoord,IGeom
60 1 equemene
  REAL(KREAL), INTENT(IN) :: Hess(NCoord,NCoord)
61 1 equemene
  REAL(KREAL), INTENT(IN) :: Grad(NCoord),Geom(NCoord)
62 1 equemene
  REAL(KREAL), INTENT(INOUT) :: Tangent(Ncoord) ! Destroyed on output
63 1 equemene
  REAL(KREAL), INTENT(OUT) :: Step(NCoord)
64 1 equemene
65 1 equemene
  INTEGER(KINT) :: NFree
66 1 equemene
  REAL(KREAL), ALLOCATABLE :: eigval(:), eigvec(:,:), eigvli(:)
67 1 equemene
  REAL(KREAL), ALLOCATABLE :: Tanf(:)
68 1 equemene
  REAL(KREAL), ALLOCATABLE :: Grad_f(:),Step_f(:) ! NFree
69 1 equemene
70 1 equemene
  REAL(KREAL), PARAMETER :: tiny=1e-20, zero=0., dele3=1e-6, eps=1e-12
71 1 equemene
  REAL(KREAL), PARAMETER :: crit=1e-8
72 1 equemene
  INTEGER(KINT) :: n, i, j, isignx, im, idx,k, isch
73 1 equemene
  REAL(KREAL) :: grd, evl, eval,e1,e2, norm
74 1 equemene
  REAL(KREAL) :: dg, dx
75 1 equemene
  CHARACTER(120) :: fmt, fmt2, Line
76 1 equemene
77 1 equemene
  LOGICAL :: Debug
78 1 equemene
79 1 equemene
  REAL(KREAL), ALLOCATABLE :: HFree(:,:) ! NFree,NFree
80 1 equemene
  REAL(KREAL), ALLOCATABLE :: Htmp(:,:) ! NCoord,NFree
81 1 equemene
82 1 equemene
  LOGICAL, SAVE :: LFirst=.TRUE.
83 1 equemene
84 1 equemene
  INTERFACE
85 1 equemene
     function valid(string) result (isValid)
86 1 equemene
       CHARACTER(*), intent(in) :: string
87 1 equemene
       logical                  :: isValid
88 1 equemene
     END function VALID
89 1 equemene
  END INTERFACE
90 1 equemene
91 1 equemene
  debug=valid("step_rfo_all")
92 1 equemene
  if (debug) WRITE(*,*) "=========================== Entering Step_RFO_All ===================="
93 1 equemene
  if (debug) WRITE(*,*) "=========================== IGeom=",IGeom," ===================="
94 1 equemene
95 1 equemene
! PFL 22.Nov.2007 ->
96 1 equemene
! Nfree is equal to Ncoord-1 only when optimizing in the plane
97 1 equemene
! orthogonal to the tangent.
98 1 equemene
! In the case of a regular opt, NFree=Ncoord.
99 1 equemene
! Next line has been moved later
100 1 equemene
!  NFree=Ncoord-1
101 1 equemene
! <- PFL 22.Nov.2007
102 1 equemene
103 1 equemene
  IF (debug) THEN
104 1 equemene
     WRITE(*,*) 'DBG Step_RFO_All Hess'
105 1 equemene
     WRITE(*,*) 'DBG Step_RFO_All NCoord=',NCoord
106 1 equemene
107 1 equemene
     Idx=min(12,NCoord)
108 1 equemene
     DO I=1,NCoord
109 1 equemene
        WRITE(*,'(12(1X,F10.4))') Hess(I,1:Idx)
110 1 equemene
     END DO
111 1 equemene
     WRITE(*,*) 'DBG Step_RFO_All Grad'
112 1 equemene
     WRITE(*,'(12(1X,F10.4))') Grad(1:Idx)
113 1 equemene
     WRITE(*,*) 'DBG Step_RFO_All Coord'
114 1 equemene
     WRITE(*,'(12(1X,F10.4))') Geom(1:Idx)
115 1 equemene
     WRITE(*,*) 'DBG Step_RFO_All Tangent'
116 1 equemene
     WRITE(*,'(12(1X,F10.4))') tangent(1:Idx)
117 1 equemene
118 1 equemene
  END IF
119 1 equemene
120 1 equemene
  Call FreeMv(NCoord,Vfree) ! VFree(Ncoord,Ncoord)
121 1 equemene
! we orthogonalize Vfree to the tangent vector of this geom
122 1 equemene
! 2007/05/29 Only if Tangent/=0.d0
123 1 equemene
  Norm=sqrt(dot_product(Tangent,Tangent))
124 1 equemene
  IF (Norm.GT.eps) THEN
125 1 equemene
     ALLOCATE(Tanf(NCoord))
126 1 equemene
127 1 equemene
     ! We normalize Tangent
128 1 equemene
     Tangent=Tangent/Norm
129 1 equemene
130 1 equemene
     ! We convert Tangent into vfree only displacements
131 1 equemene
     ! This is useless for now (2007.Apr.23) as vfree=Id matrix
132 1 equemene
     ! but it will be usefull as soon as we introduce Constraints
133 1 equemene
     DO I=1,NCoord
134 1 equemene
        Tanf(I)=dot_product(reshape(vfree(:,I),(/NCoord/)),Tangent)
135 1 equemene
     END DO
136 1 equemene
     Tangent=0.d0
137 1 equemene
     DO I=1,NCoord
138 1 equemene
        Tangent=Tangent+Tanf(i)*vfree(:,I)
139 1 equemene
     END DO
140 1 equemene
141 1 equemene
     ! first we substract Tangent from vfree
142 1 equemene
     DO I=1,NCoord
143 1 equemene
        Norm=dot_product(reshape(vfree(:,i),(/NCoord/)),Tangent)
144 1 equemene
        Vfree(:,I)=vfree(:,i)-Norm*Tangent
145 1 equemene
     END DO
146 1 equemene
147 1 equemene
     Idx=0.
148 1 equemene
     ! Schmidt orthogonalization of the vfree vectors
149 1 equemene
     DO I=1,NCoord
150 1 equemene
        ! We substract the first vectors
151 1 equemene
        ! we do it twice as the Schmidt procedure is not numerically stable
152 1 equemene
        DO isch=1,2
153 1 equemene
           DO J=1,Idx
154 1 equemene
              Norm=dot_product(reshape(vfree(:,I),(/NCoord/)),reshape(vfree(:,J),(/NCoord/)))
155 1 equemene
              vfree(:,I)=vfree(:,I)-Norm*vfree(:,J)
156 1 equemene
           END DO
157 1 equemene
        END DO
158 1 equemene
        Norm=dot_product(reshape(vfree(:,I),(/NCoord/)),reshape(vfree(:,I),(/NCoord/)))
159 1 equemene
        IF (Norm.GE.crit) THEN
160 1 equemene
           idx=idx+1
161 1 equemene
           vfree(:,idx)=vfree(:,i)/sqrt(Norm)
162 1 equemene
        END IF
163 1 equemene
     END DO
164 1 equemene
165 1 equemene
     If (Idx/= NCoord-1) THEN
166 1 equemene
        WRITE(*,*) "Pb in orthogonalizing vfree to tangent for geom",IGeom
167 1 equemene
        WRITE(Ioout,*) "Pb in orthogonalizing vfree to tangent for geom",IGeom
168 1 equemene
        STOP
169 1 equemene
     END IF
170 1 equemene
171 1 equemene
     DEALLOCATE(Tanf)
172 1 equemene
173 1 equemene
     NFree=Idx
174 1 equemene
175 1 equemene
  ELSE ! Tangent =0, matches IF (Norm.GT.eps) THEN
176 1 equemene
     if (debug) WRITE(*,*) "Tangent=0, using full displacement"
177 1 equemene
     NFree=NCoord
178 1 equemene
  END IF !IF (Norm.GT.eps) THEN
179 1 equemene
180 1 equemene
  if (debug) WRITE(*,*) 'DBG Step_RFO_All NFree=',NFree
181 1 equemene
182 1 equemene
183 1 equemene
! We now calculate the new step
184 1 equemene
! we project the hessian onto the free vectors
185 1 equemene
     ALLOCATE(hfree(NFree,NFree),htmp(NCoord,NFree),Grad_f(NFree),Step_f(NFree))
186 1 equemene
     DO J=1,NFree
187 1 equemene
        DO I=1,NCoord
188 1 equemene
           Htmp(I,J)=0.d0
189 1 equemene
           DO K=1,NCoord
190 1 equemene
              Htmp(I,J)=htmp(I,J)+Hess(I,K)*vfree(K,J)
191 1 equemene
           END DO
192 1 equemene
        END DO
193 1 equemene
     END DO
194 1 equemene
     DO J=1,NFree
195 1 equemene
        DO I=1,NFree
196 1 equemene
           HFree(i,j)=0.d0
197 1 equemene
           DO K=1,NCoord
198 1 equemene
              HFree(i,j)=hfree(i,j)+vfree(k,i)*htmp(k,j)
199 1 equemene
           END DO
200 1 equemene
        END DO
201 1 equemene
     END DO
202 1 equemene
203 1 equemene
! We diagonalize the hessian or its inverse
204 1 equemene
  ALLOCATE(eigval(NFree), eigvec(NFree,NFree), eigvli(NFree))
205 1 equemene
206 1 equemene
  call Jacobi(Hfree,NFree,eigvli,eigvec,NFree)
207 1 equemene
208 1 equemene
  if (debug) THEN
209 1 equemene
     WRITE(*,*) 'Eigensystem, Step_RFO_all.f90, L225'
210 1 equemene
     fmt2='(I5,":",F8.3," -",  (1X,F10.4))'
211 1 equemene
     WRITE(fmt2(19:20),'(I2)') min(NFree,99)
212 1 equemene
     DO I=1,NFree
213 1 equemene
        WRITE(*,fmt2) I,Eigvli(I),eigvec(:,I)
214 1 equemene
     END DO
215 1 equemene
  END IF
216 1 equemene
217 1 equemene
  ! We inverse the eigenvalues if Hess corresponds to Hessian inverse
218 1 equemene
  IF (Hinv) THEN
219 1 equemene
     do J=1,NFree
220 1 equemene
        if (abs(eigvli(j)) <= tiny) eigvli(j) = zero
221 1 equemene
        eigval(j) = sign (eigvli(j)**2 / (dele3 + abs(eigvli(j))**3), eigvli(j))
222 1 equemene
        if (abs(eigval(j)) <= tiny) eigval(j) = zero
223 1 equemene
     end do
224 1 equemene
  ELSE
225 1 equemene
     eigval=eigvli
226 1 equemene
  END IF
227 1 equemene
228 1 equemene
  call trie(NFree,eigval,eigvec,NFree)
229 1 equemene
230 1 equemene
  DO I=1,NFree
231 1 equemene
     Grad_f(I)=dot_product(reshape(vfree(:,I),(/NCoord/)),grad)
232 1 equemene
  END DO
233 1 equemene
234 1 equemene
  ! We now construct the step
235 1 equemene
236 1 equemene
  Step_f=0.d0
237 1 equemene
  DO I=1,NFree
238 1 equemene
     grd= dot_product(grad_f,reshape(eigvec(:,i),(/NFree/)))
239 1 equemene
     eval = 0.5 * (abs(eigval(i)) + sqrt (eigval(i)**2 + 4.*grd**2))
240 1 equemene
     dx   = (-grd) / eval
241 1 equemene
     step_f = step_f + dx * eigvec(:,i)
242 1 equemene
     if (debug) write (*,*) i,eigval(i),eval,grd,dx
243 1 equemene
  END DO
244 1 equemene
245 1 equemene
  Step=0.d0
246 1 equemene
! PFL 04 Apr 2008 ->
247 1 equemene
! Grad is once again modified
248 1 equemene
!  Grad=0.d0
249 1 equemene
  DO I=1,NFree
250 1 equemene
     Step=Step+ step_f(i)*vfree(:,i)
251 1 equemene
!     Grad=Grad+ Grad_f(i)*vfree(:,i)
252 1 equemene
  END DO
253 1 equemene
! <- PFL 04 Apr 2008
254 1 equemene
255 1 equemene
  DEALLOCATE(eigval,eigvec,eigvli,hfree,htmp,grad_f,step_f)
256 1 equemene
257 1 equemene
  if (debug) THEN
258 1 equemene
     WRITE(*,*) 'DBG Step_RFO_All Step'
259 1 equemene
     WRITE(*,'(12(1X,F8.4))') Step(1:Idx)
260 1 equemene
  END IF
261 1 equemene
262 1 equemene
  if (debug) WRITE(*,*) "=========================== Step_RFO_All Over ===================="
263 1 equemene
264 1 equemene
END SUBROUTINE STEP_RFO_ALL
265 1 equemene