Statistiques
| Révision :

root / src / Extrapol_cart.f90 @ 4

Historique | Voir | Annoter | Télécharger (10,27 ko)

1 1 equemene
SUBROUTINE Extrapol_cart(iopt,s,dist,x0,y0,z0,xgeom,Coef)
2 1 equemene
3 1 equemene
  ! This subroutine constructs the path, and if dist<>Infinity, it samples
4 1 equemene
  ! the path to obtain geometries.
5 1 equemene
  ! Basically, you call it twice: i) dist=infinity, it will calculate the length of the path
6 1 equemene
  ! ii) dist finite, it will give you the images you want along the path.
7 1 equemene
  !
8 1 equemene
  ! For now, it gives equidistant geometries
9 1 equemene
  !
10 1 equemene
11 1 equemene
  use Path_module
12 1 equemene
  use Io_module
13 1 equemene
14 1 equemene
15 1 equemene
  IMPLICIT NONE
16 1 equemene
17 1 equemene
18 1 equemene
  REAL(KREAL), INTENT(OUT) :: s
19 1 equemene
  ! X0(Nat),Y0(Nat),Z0(Nat): reference geometry.
20 1 equemene
  REAL(KREAL), INTENT(IN) :: dist,X0(Nat),Y0(Nat),Z0(Nat)
21 1 equemene
  REAL(KREAL), INTENT(IN) :: Xgeom(NGeomI),Coef(NGeomI,NCoord)
22 1 equemene
! Iopt: Number of the cycles for the optimization
23 1 equemene
  INTEGER(KINT), INTENT(IN) :: Iopt
24 1 equemene
  INTEGER(KINT) :: IdxGeom, I, J, K, Idx,Iat, IGeom
25 1 equemene
! NSpline is the number of points along the interpolating path
26 1 equemene
  INTEGER(KINT) :: NSpline
27 1 equemene
! FileSpline: Filename to save the interpolating path coordinates
28 1 equemene
  CHARACTER(LCHARS) :: FileSpline,TmpChar
29 1 equemene
  REAL(KREAL) :: Rmsd,MRot(3,3), ds, u, v
30 1 equemene
  REAL(KREAL) :: a_val, d
31 1 equemene
32 1 equemene
  REAL(KREAL), ALLOCATABLE :: XyzTmp(:,:), XyzTmp2(:,:) ! (Nat,3)
33 1 equemene
  REAL(KREAL), ALLOCATABLE :: DerXyz(:,:) ! Nat,3
34 1 equemene
35 1 equemene
36 1 equemene
  LOGICAL ::  debug, print, printspline
37 1 equemene
  LOGICAL, EXTERNAL :: valid
38 1 equemene
39 1 equemene
  !We will calculate the length of the path, in MW coordinates...
40 1 equemene
  ! this is done is a stupid way: we interpolate the zmatrix values,
41 1 equemene
  ! convert them into cartesian, weight the cartesian
42 1 equemene
  ! and calculate the evolution of the distance !
43 1 equemene
  ! We have to follow the same procedure for every geometry
44 1 equemene
  ! so even for the first one, we have to convert it from zmat
45 1 equemene
  ! to cartesian !
46 1 equemene
47 1 equemene
  debug=valid("pathcreate")
48 1 equemene
  print=valid("printgeom")
49 1 equemene
50 1 equemene
  printspline=(valid("printspline").AND.(dist<=1e30))
51 1 equemene
52 1 equemene
  if (debug) Call Header("Entering Extrapol_cart")
53 1 equemene
54 1 equemene
! We want 100 points along the interpolating path
55 1 equemene
  NSpline=int(NMaxPtPath/100)
56 1 equemene
57 1 equemene
  if (printspline) THEN
58 1 equemene
     WRITE(TmpChar,'(I5)') Iopt
59 1 equemene
     FileSpline=Trim(adjustL(PathName)) // '_spline.' // AdjustL(TRIM(TmpChar))
60 1 equemene
     OPEN(IOTMP,FILE=FileSpline)
61 1 equemene
62 1 equemene
  END IF
63 1 equemene
64 1 equemene
65 1 equemene
  ALLOCATE(XyzTmp(Nat,3),XyzTmp2(Nat,3),DerXyz(Nat,3))
66 1 equemene
67 4 pfleura2
! PFL 2011 June 22
68 4 pfleura2
! There was an alignment procedure there.
69 4 pfleura2
! It has been moved to PathCreate before the
70 4 pfleura2
! computation of the Spline coefficient.
71 1 equemene
72 1 equemene
  XyzGeomF(1,:,:)=XyzGeomI(1,:,:)
73 1 equemene
74 1 equemene
75 1 equemene
  ! We initialize the first geometry
76 1 equemene
77 1 equemene
  XyzTmp=Reshape(XyzGeomI(1,:,:),(/Nat,3/),ORDER=(/2,1/))
78 1 equemene
79 1 equemene
80 1 equemene
81 1 equemene
  s=0.d0
82 4 pfleura2
  SGeom(1)=0.d0
83 4 pfleura2
84 1 equemene
  if (printspline) THEN
85 1 equemene
     u=0.d0
86 1 equemene
     DO Iat=1,Nat
87 1 equemene
        ! We generate the interpolated coordinates
88 1 equemene
        if (Linear) THEN
89 1 equemene
           call LinearInt(u,XyzTmp2(Iat,1),DerXyz(Iat,1),NGeomI,xgeom(1),XyzGeomI(1,1,Iat))
90 1 equemene
           call LinearInt(u,XyzTmp2(Iat,2),DerXyz(Iat,2),NGeomI,xgeom(1),XyzGeomI(1,2,Iat))
91 1 equemene
           call LinearInt(u,XyzTmp2(Iat,3),DerXyz(Iat,3),NGeomI,xgeom(1),XyzGeomI(1,3,Iat))
92 1 equemene
93 1 equemene
        ELSE
94 1 equemene
           call splintder(u,XyzTmp2(Iat,1),DerXyz(Iat,1),NGeomI,xgeom(1),XyzGeomI(1,1,Iat),Coef(1,3*Iat-2))
95 1 equemene
           call splintder(u,XyzTmp2(Iat,2),DerXyz(Iat,2),NGeomI,xgeom(1),XyzGeomI(1,2,Iat),Coef(1,3*Iat-1))
96 1 equemene
           call splintder(u,XyzTmp2(Iat,3),DerXyz(Iat,3),NGeomI,xgeom(1),XyzGeomI(1,3,Iat),Coef(1,3*Iat))
97 1 equemene
        END IF
98 1 equemene
     END DO
99 1 equemene
100 1 equemene
     WRITE(IOTMP,*) Nat
101 1 equemene
     WRITE(IOTMP,'(1X,A,1X,F15.6)') "Debug Spline - Coord=Cart,s=",s
102 1 equemene
     DO Iat=1,Nat
103 1 equemene
        WRITE(IOTMP,'(1X,A2,3(1X,F15.6))') Nom(Atome(Iat)),    &
104 1 equemene
                   (XyzTmp2(Iat,1:3))
105 1 equemene
     END DO
106 1 equemene
  END IF
107 1 equemene
108 1 equemene
 IdxGeom=1
109 1 equemene
110 1 equemene
  DO K=1,NMaxPtPath
111 1 equemene
     u=real(K)/NMaxPtPath*(NGeomI-1.)
112 1 equemene
113 1 equemene
     DO Iat=1,Nat
114 1 equemene
        ! We generate the interpolated coordinates
115 1 equemene
        if (Linear) THEN
116 1 equemene
           call LinearInt(u,XyzTmp2(Iat,1),DerXyz(Iat,1),NGeomI,xgeom(1),XyzGeomI(1,1,Iat))
117 1 equemene
           call LinearInt(u,XyzTmp2(Iat,2),DerXyz(Iat,2),NGeomI,xgeom(1),XyzGeomI(1,2,Iat))
118 1 equemene
           call LinearInt(u,XyzTmp2(Iat,3),DerXyz(Iat,3),NGeomI,xgeom(1),XyzGeomI(1,3,Iat))
119 1 equemene
120 1 equemene
        ELSE
121 1 equemene
           call splintder(u,XyzTmp2(Iat,1),DerXyz(Iat,1),NGeomI,xgeom(1),XyzGeomI(1,1,Iat),Coef(1,3*Iat-2))
122 1 equemene
           call splintder(u,XyzTmp2(Iat,2),DerXyz(Iat,2),NGeomI,xgeom(1),XyzGeomI(1,2,Iat),Coef(1,3*Iat-1))
123 1 equemene
           call splintder(u,XyzTmp2(Iat,3),DerXyz(Iat,3),NGeomI,xgeom(1),XyzGeomI(1,3,Iat),Coef(1,3*Iat))
124 1 equemene
        END IF
125 1 equemene
     END DO
126 1 equemene
127 1 equemene
128 4 pfleura2
! PFL 2011 June 22: We now align on the previous one
129 4 pfleura2
! as we do for internal coord interpolation
130 4 pfleura2
131 4 pfleura2
! We align this geometry with the previous one
132 4 pfleura2
133 1 equemene
  ! PFL 17/July/2006: only if we have more than 4 atoms.
134 1 equemene
!  IF (Nat.GT.4) THEN
135 1 equemene
! PFL 24 Nov 2008 ->
136 1 equemene
! If we have frozen atoms we align only those ones.
137 1 equemene
! PFL 8 Feb 2011 ->
138 1 equemene
! I add a flag to see if we should align or not.
139 1 equemene
! For small systems, it might be better to let the user align himself
140 1 equemene
      IF (Align) THEN
141 1 equemene
         if (NFroz.GT.0) THEN
142 4 pfleura2
            Call AlignPartial(Nat,                     &
143 4 pfleura2
                 xyzTmp(1,1),xyzTmp(1,2),xyzTMP(1,3),       &
144 1 equemene
                 xyzTmp2(1,1),xyzTmp2(1,2),xyzTMP2(1,3),       &
145 1 equemene
                 FrozAtoms,MRot)
146 1 equemene
         ELSE
147 4 pfleura2
            Call  CalcRmsd(Nat,                              &
148 4 pfleura2
                 xyzTmp(1,1),xyzTmp(1,2),xyzTMP(1,3),       &
149 1 equemene
                 xyzTmp2(1,1),xyzTmp2(1,2),xyzTMP2(1,3),       &
150 1 equemene
                 MRot,rmsd,.TRUE.,.TRUE.)
151 1 equemene
         END IF
152 1 equemene
! <- PFL 24 Nov 2008
153 1 equemene
      END IF
154 1 equemene
! -> PFL 8 Feb 2011
155 1 equemene
!  END IF
156 1 equemene
157 1 equemene
158 1 equemene
159 1 equemene
     ds=0.
160 1 equemene
     DO I=1,Nat
161 1 equemene
        DO J=1,3
162 1 equemene
           ds=ds+MassAt(I)*(XYZTMp2(I,J)-XYZTmp(I,J))**2
163 1 equemene
           XYZTmp(I,J)=XyzTMP2(I,J)
164 1 equemene
        ENDDO
165 1 equemene
     ENDDO
166 1 equemene
     s=s+sqrt(ds)
167 1 equemene
168 1 equemene
     !         if (debug) WRITE(*,*) "Debug u,s,dist",u,s,dist
169 1 equemene
170 1 equemene
  if ((printspline).AND.(MOD(K,NSpline).EQ.0)) THEN
171 1 equemene
     WRITE(IOTMP,*) Nat
172 1 equemene
     WRITE(IOTMP,'(1X,A,1X,F15.6)') "Debug Spline - Coord=Cart,s=",s
173 1 equemene
     DO Iat=1,Nat
174 1 equemene
        WRITE(IOTMP,'(1X,A2,3(1X,F15.6))') Nom(Atome(Iat)),    &
175 1 equemene
                   (XyzTmp2(Iat,1:3))
176 1 equemene
     END DO
177 1 equemene
  END IF
178 1 equemene
179 1 equemene
180 1 equemene
     if (s>=dist) THEN
181 1 equemene
182 1 equemene
        if (debug) THEN
183 1 equemene
           WRITE(*,*) "DBG Interpol_cart",s
184 1 equemene
           DO i=1,Nat
185 1 equemene
              WRITE(IOOUT,'(1X,A2,3(1X,F15.6))') Nom(Atome(I)),    &
186 1 equemene
                   (XyzTmp2(I,J),J=1,3)
187 1 equemene
           END DO
188 1 equemene
        END IF
189 1 equemene
190 1 equemene
        s=s-dist
191 1 equemene
        IdxGeom=IdxGeom+1
192 4 pfleura2
        SGeom(IdxGeom)=s+dist*(IdxGeom-1)
193 1 equemene
194 1 equemene
  ! We align this geometry with the original one
195 1 equemene
  ! PFL 17/July/2006: only if we have more than 4 atoms.
196 1 equemene
!  IF (Nat.GT.4) THEN
197 1 equemene
! PFL 24 Nov 2008 ->
198 1 equemene
! If we have frozen atoms we align only those ones.
199 1 equemene
! PFL 8 Feb 2011 ->
200 1 equemene
! I add a flag to see if we should align or not.
201 1 equemene
! For small systems, it might be better to let the user align himself
202 1 equemene
      IF (Align) THEN
203 1 equemene
         if (NFroz.GT.0) THEN
204 1 equemene
            Call AlignPartial(Nat,x0,y0,z0,                     &
205 1 equemene
                 xyzTmp2(1,1),xyzTmp2(1,2),xyzTMP2(1,3),       &
206 1 equemene
                 FrozAtoms,MRot)
207 1 equemene
         ELSE
208 1 equemene
            Call  CalcRmsd(Nat, x0,y0,z0,                              &
209 1 equemene
                 xyzTmp2(1,1),xyzTmp2(1,2),xyzTMP2(1,3),       &
210 1 equemene
                 MRot,rmsd,.TRUE.,.TRUE.)
211 1 equemene
         END IF
212 1 equemene
! <- PFL 24 Nov 2008
213 1 equemene
      END IF
214 1 equemene
! -> PFL 8 Feb 2011
215 1 equemene
!  END IF
216 1 equemene
217 1 equemene
        XyzGeomF(IdxGeom,:,:)=Reshape(XyzTmp2(:,:),(/3,Nat/),ORDER=(/2,1/))
218 1 equemene
        XyzTangent(IdxGeom,:)=Reshape(DerXyz(:,:),(/3*Nat/))
219 1 equemene
220 1 equemene
        if (print) THEN
221 1 equemene
           WRITE(IOOUT,'(1X,I5)') Nat
222 1 equemene
           WRITE(IOOUT,*) "# Cartesian coord for Geometry ",IdxGeom,K
223 1 equemene
224 1 equemene
           DO i=1,Nat
225 1 equemene
              WRITE(IOOUT,'(1X,A2,3(1X,F15.6))') Nom(Atome(I)),    &
226 1 equemene
                   (XyzTmp2(I,J),J=1,3)
227 1 equemene
           END DO
228 1 equemene
229 1 equemene
        END IF
230 1 equemene
     END IF  ! s>= dist
231 1 equemene
  ENDDO  ! K
232 1 equemene
233 1 equemene
234 1 equemene
  if (s>=0.9*dist) THEN
235 1 equemene
     s=s-dist
236 1 equemene
     XyzTmp2=Reshape(XyzGeomI(NGeomI,:,:),(/Nat,3/),ORDER=(/2,1/))
237 1 equemene
238 1 equemene
  if (printspline) THEN
239 1 equemene
     WRITE(IOTMP,*) Nat
240 1 equemene
     WRITE(IOTMP,*) "Debug Spline - Coord=Cart,s=",s
241 1 equemene
     DO Iat=1,Nat
242 1 equemene
        WRITE(IOTMP,'(1X,A2,3(1X,F15.6))') Nom(Atome(Iat)),    &
243 1 equemene
                   (XyzTmp2(Iat,1:3))
244 1 equemene
     END DO
245 1 equemene
  END IF
246 1 equemene
247 1 equemene
248 1 equemene
  ! We align this geometry with the original one
249 1 equemene
  ! PFL 17/July/2006: only if we have more than 4 atoms.
250 1 equemene
!  IF (Nat.GT.4) THEN
251 1 equemene
! PFL 24 Nov 2008 ->
252 1 equemene
! If we have frozen atoms we align only those ones.
253 1 equemene
! PFL 8 Feb 2011 ->
254 1 equemene
! I add a flag to see if we should align or not.
255 1 equemene
! For small systems, it might be better to let the user align himself
256 1 equemene
      IF (Align) THEN
257 1 equemene
         if (NFroz.GT.0) THEN
258 1 equemene
            Call AlignPartial(Nat,x0,y0,z0,                     &
259 1 equemene
                 xyzTmp2(1,1),xyzTmp2(1,2),xyzTMP2(1,3),       &
260 1 equemene
                 FrozAtoms,MRot)
261 1 equemene
         ELSE
262 1 equemene
            Call  CalcRmsd(Nat, x0,y0,z0,                              &
263 1 equemene
                 xyzTmp2(1,1),xyzTmp2(1,2),xyzTMP2(1,3),       &
264 1 equemene
                 MRot,rmsd,.TRUE.,.TRUE.)
265 1 equemene
         END IF
266 1 equemene
! <- PFL 24 Nov 2008
267 1 equemene
      END IF
268 1 equemene
! -> PFL 8 Feb 2011
269 1 equemene
!  END IF
270 1 equemene
271 1 equemene
     IdxGeom=IdxGeom+1
272 4 pfleura2
     SGeom(IdxGeom)=s+dist*(IdxGeom-1)
273 1 equemene
274 1 equemene
    IF (IdxGeom.GT.NGeomF) THEN
275 1 equemene
        WRITE(IOOUT,*) "!!! ERROR in Extrapol_cart !!!!"
276 1 equemene
        WRITE(IOOUT,*) "Too many structures. Increase NMaxPath"
277 1 equemene
        WRITE(*,*) "** PathCreate ***"
278 1 equemene
        WRITE(*,*) "Distribution of points along the path is wrong."
279 1 equemene
        WRITE(*,*) "Increase value of NMaxPtPath in the input file"
280 1 equemene
        WRITE(*,*) "Present value is:", NMaxPtPath
281 1 equemene
        STOP
282 1 equemene
     END IF
283 1 equemene
284 1 equemene
285 1 equemene
  ! We align this geometry with the original one
286 1 equemene
  ! PFL 17/July/2006: only if we have more than 4 atoms.
287 1 equemene
!  IF (Nat.GT.4) THEN
288 1 equemene
! PFL 24 Nov 2008 ->
289 1 equemene
! If we have frozen atoms we align only those ones.
290 1 equemene
! PFL 8 Feb 2011 ->
291 1 equemene
! I add a flag to see if we should align or not.
292 1 equemene
! For small systems, it might be better to let the user align himself
293 1 equemene
      IF (Align) THEN
294 1 equemene
         if (NFroz.GT.0) THEN
295 1 equemene
            Call AlignPartial(Nat,x0,y0,z0,                     &
296 1 equemene
                 xyzTmp2(1,1),xyzTmp2(1,2),xyzTMP2(1,3),       &
297 1 equemene
                 FrozAtoms,MRot)
298 1 equemene
         ELSE
299 1 equemene
            Call  CalcRmsd(Nat, x0,y0,z0,                              &
300 1 equemene
                 xyzTmp2(1,1),xyzTmp2(1,2),xyzTMP2(1,3),       &
301 1 equemene
                 MRot,rmsd,.TRUE.,.TRUE.)
302 1 equemene
         END IF
303 1 equemene
! <- PFL 24 Nov 2008
304 1 equemene
      END IF
305 1 equemene
! -> PFL 8 Feb 2011
306 1 equemene
!  END IF
307 1 equemene
308 1 equemene
     XyzGeomF(IdxGeom,:,:)=Reshape(XyzTmp2(:,:),(/3,Nat/),ORDER=(/2,1/))
309 1 equemene
     XyzTangent(IdxGeom,:)=Reshape(DerXyz(:,:),(/3*Nat/))
310 1 equemene
311 1 equemene
     if (print) THEN
312 1 equemene
        WRITE(IOOUT,'(1X,I5)') Nat
313 1 equemene
        WRITE(IOOUT,*) "# Cartesian coord for Geometry ",IdxGeom,K
314 1 equemene
315 1 equemene
        DO i=1,Nat
316 1 equemene
           WRITE(IOOUT,'(1X,A2,3(1X,F15.6))') Nom(Atome(I)),     &
317 1 equemene
                (XyzTmp2(I,J),J=1,3)
318 1 equemene
        END DO
319 1 equemene
     END IF
320 1 equemene
  END IF
321 1 equemene
322 1 equemene
  DEALLOCATE(XyzTmp,XyzTmp2)
323 1 equemene
324 1 equemene
  if (debug) WRITE(*,*) 's final =',s
325 1 equemene
326 1 equemene
  if (printspline) CLOSE(IOTMP)
327 1 equemene
328 1 equemene
  if (debug) Call Header("Extrapol_cart over")
329 1 equemene
330 1 equemene
END SUBROUTINE EXTRAPOL_CART