Statistiques
| Révision :

root / src / Extrapol_int.f90 @ 1

Historique | Voir | Annoter | Télécharger (16,56 ko)

1 1 equemene
SUBROUTINE Extrapol_int(iopt,s,dist,x0,y0,z0,xgeom,Coef,XgeomF)
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
  ! Default value of FRot=.TRUE.
12 1 equemene
  ! Default value of NMaxPtPath = 1000
13 1 equemene
  ! IntCoordI(:,:) ! (NGeomI,3*Nat-6)
14 1 equemene
  ! XyzGeomF(:,:,:) ! (NGeomF,3,Nat)
15 1 equemene
  ! Default value of FAlign=.TRUE.
16 1 equemene
  use Path_module, only : NMaxPtPath, IntCoordI, Pi, IndZmat, XyzGeomF, &
17 1 equemene
       IntCoordF, IntTangent, Renum, Nom, Order, MassAt, SGeom, XyzGeomI, &
18 1 equemene
       Atome, Nat, NGeomI, NCoord, NGeomF, OrderInv,NFroz,FrozAtoms
19 1 equemene
  ! IndZmat(Nat,5)
20 1 equemene
21 1 equemene
  use Io_module
22 1 equemene
23 1 equemene
24 1 equemene
  IMPLICIT NONE
25 1 equemene
26 1 equemene
27 1 equemene
  REAL(KREAL), INTENT(OUT) :: s
28 1 equemene
  ! X0(Nat),Y0(Nat),Z0(Nat): reference geometry.
29 1 equemene
  REAL(KREAL), INTENT(IN) :: dist,X0(Nat),Y0(Nat),Z0(Nat)
30 1 equemene
  REAL(KREAL), INTENT(IN) :: Xgeom(NGeomI),Coef(NGeomI,NCoord)
31 1 equemene
  ! Iopt: Number of the cycles for the optimization
32 1 equemene
  INTEGER(KINT), INTENT(IN) :: Iopt
33 1 equemene
  REAL(KREAL), INTENT(OUT) :: XGeomF(NGeomF)
34 1 equemene
35 1 equemene
  INTEGER(KINT) :: IdxGeom, I, J, K, Idx
36 1 equemene
  REAL(KREAL) :: Rmsd,MRot(3,3), ds, u, v
37 1 equemene
  REAL(KREAL) :: a_val, d
38 1 equemene
39 1 equemene
  REAL(KREAL), ALLOCATABLE :: XyzTmp(:,:), XyzTmp2(:,:) ! (Nat,3)
40 1 equemene
  REAL(KREAL), ALLOCATABLE :: ValZmat(:,:),DerInt(:) ! (Nat,3)
41 1 equemene
42 1 equemene
43 1 equemene
  LOGICAL ::  debug, print,printspline
44 1 equemene
  LOGICAL, EXTERNAL :: valid
45 1 equemene
46 1 equemene
  INTEGER(KINT) :: NSpline
47 1 equemene
  CHARACTER(LCHARS) :: FileSpline,TmpChar
48 1 equemene
49 1 equemene
50 1 equemene
  !	LOGICAL :: FAlign=.FALSE., FRot=.FALSE.
51 1 equemene
52 1 equemene
  ! We will calculate the length of the path, in MW coordinates...
53 1 equemene
  ! this is done is a stupid way: we interpolate the zmatrix values,
54 1 equemene
  ! convert them into cartesian, weight the cartesian
55 1 equemene
  ! and calculate the evolution of the distance !
56 1 equemene
  ! We have to follow the same procedure for every geometry
57 1 equemene
  ! so even for the first one, we have to convert it from zmat
58 1 equemene
  ! to cartesian !
59 1 equemene
60 1 equemene
  debug=valid("pathcreate")
61 1 equemene
  print=valid("printgeom")
62 1 equemene
  printspline=(valid("printspline").AND.(dist<=1e30))
63 1 equemene
64 1 equemene
  if (debug) Call Header("Entering Extrapol_int")
65 1 equemene
66 1 equemene
! We want 100 points along the interpolating path
67 1 equemene
  NSpline=int(NMaxPtPath/100)
68 1 equemene
  if (printspline) THEN
69 1 equemene
     WRITE(TmpChar,'(I5)') Iopt
70 1 equemene
     FileSpline=Trim(adjustL(PathName)) // '_spline.' // AdjustL(TRIM(TmpChar))
71 1 equemene
     OPEN(IOTMP,FILE=FileSpline)
72 1 equemene
73 1 equemene
  END IF
74 1 equemene
75 1 equemene
  ALLOCATE(XyzTmp(Nat,3),XyzTmp2(Nat,3),valzmat(Nat,3),DerInt(NCoord))
76 1 equemene
  IdxGeom=1
77 1 equemene
78 1 equemene
  XYZTmp2(1,1)=0.
79 1 equemene
  XYZTmp2(1,2)=0.
80 1 equemene
  XYZTmp2(1,3)=0.
81 1 equemene
  XYZTmp2(2,2)=0.
82 1 equemene
  XYZTmp2(2,3)=0.
83 1 equemene
  XYZTmp2(3,3)=0.
84 1 equemene
85 1 equemene
  valzmat=0.
86 1 equemene
  valzmat(2,1)=IntCoordI(1,1)
87 1 equemene
  valzmat(3,1)=IntCoordI(1,2)
88 1 equemene
  valzmat(3,2)=IntCoordI(1,3)*180./Pi
89 1 equemene
  Idx=4
90 1 equemene
  DO I=4,Nat
91 1 equemene
     ValZmat(I,1)=IntCoordI(1,Idx)
92 1 equemene
     Idx=Idx+1
93 1 equemene
     DO J=2,3
94 1 equemene
        ValZmat(I,J)=IntCoordI(1,Idx)*180./Pi
95 1 equemene
        Idx=Idx+1
96 1 equemene
     END DO
97 1 equemene
  END DO
98 1 equemene
99 1 equemene
  XyzTmp2(2,1)=valzmat(2,1)
100 1 equemene
  d=valzmat(3,1)
101 1 equemene
  a_val=valzmat(3,2)/180.*Pi
102 1 equemene
  !              write(*,*) "aval,pi",a_val,valzmat(3,2),pi
103 1 equemene
  if (Nat.GE.3) THEN
104 1 equemene
     if (IndZmat(3,2).EQ.1)  THEN
105 1 equemene
        XyzTmp2(3,1)=XYzTmp2(1,1)+d*cos(a_val)
106 1 equemene
     ELSE
107 1 equemene
        XyzTmp2(3,1)=XyzTmp2(2,1)-d*cos(a_val)
108 1 equemene
     ENDIF
109 1 equemene
     XyzTmp2(3,2)=d*sin(a_val)
110 1 equemene
  ENDIF
111 1 equemene
  !              i=1
112 1 equemene
  !                WRITE(*,*) 'TOTOCart:',i, (XYzTMP2(I,J),J=1,3)
113 1 equemene
  !                WRITE(*,*) 'TOTOZma:',i, (valzmat(I,J),J=1,3)
114 1 equemene
  !              i=2
115 1 equemene
  !                WRITE(*,*) 'TOTOCart:',i, (XYzTMP2(I,J),J=1,3)
116 1 equemene
  !                WRITE(*,*) 'TOTOZma:',i, (valzmat(I,J),J=1,3)
117 1 equemene
  !              i=3
118 1 equemene
  !                WRITE(*,*) 'TOTOCart:',i, (XYzTMP2(I,J),J=1,3)
119 1 equemene
  !                WRITE(*,*) 'TOTOZma:',i, (valzmat(I,J),J=1,3)
120 1 equemene
121 1 equemene
  DO i=4,Nat
122 1 equemene
     call ConvertZmat_cart(i,IndZmat,valzmat,                &
123 1 equemene
          XYzTMP2(1,1), XYzTMP2(1,2),XYzTMP2(1,3))
124 1 equemene
     !                  WRITE(*,*) 'TOTOZma:',i,IndZmat(I,1),            &
125 1 equemene
     !                        (IndZmat(I,J+1),valzmat(I,J),J=1,3)
126 1 equemene
     !                   WRITE(*,*) 'TOTOCart:',i, (XYzTMP2(I,J),J=1,3)
127 1 equemene
  END DO
128 1 equemene
129 1 equemene
  ! We align this geometry with the original one
130 1 equemene
  ! PFL 17/July/2006: only if we have more than 4 atoms.
131 1 equemene
  IF (Nat.GE.4) THEN
132 1 equemene
     ! The rotation matrix MRot has INTENT(OUT) in subroutine rotation_matrix(...),
133 1 equemene
     ! which is called in the CalcRmsd(...).
134 1 equemene
     ! PFL 24 Nov 2008 ->
135 1 equemene
     ! If we have frozen atoms we align only those ones.
136 1 equemene
     if (NFroz.GT.0) THEN
137 1 equemene
        Call AlignPartial(Nat,x0,y0,z0,                     &
138 1 equemene
             xyzTmp2(1,1),xyzTmp2(1,2),xyzTMP2(1,3),       &
139 1 equemene
             FrozAtoms,MRot)
140 1 equemene
     ELSE
141 1 equemene
        Call  CalcRmsd(Nat, x0,y0,z0,                              &
142 1 equemene
             xyzTmp2(1,1),xyzTmp2(1,2),xyzTMP2(1,3),       &
143 1 equemene
             MRot,rmsd,.TRUE.,.TRUE.)
144 1 equemene
     END IF
145 1 equemene
     ! <- PFL 24 Nov 2008
146 1 equemene
  END IF
147 1 equemene
148 1 equemene
  XyzGeomF(IdxGeom,:,:)=Reshape(XyzTmp2(:,:),(/3,Nat/),ORDER=(/2,1/))
149 1 equemene
  IntCoordF(IdxGeom,:)=IntCoordI(1,:)
150 1 equemene
151 1 equemene
  ! We calculate the first derivatives
152 1 equemene
  u=0.d0
153 1 equemene
  DO Idx=1,NCoord
154 1 equemene
     call splintder(u,v,DerInt(iDX),NGeomI,xgeom(1),IntCoordI(1,Idx),Coef(1,Idx))
155 1 equemene
  END DO
156 1 equemene
  IntTangent(IdxGeom,:)=DerInt
157 1 equemene
158 1 equemene
  if (print.AND.(Dist.LE.1e20)) THEN
159 1 equemene
     WRITE(IOOUT,'(1X,I5)') Nat
160 1 equemene
     WRITE(IOOUT,*) "# Cartesian Coordinates for geom",IdxGeom
161 1 equemene
     DO i=1,Nat
162 1 equemene
        If (Renum) THEN
163 1 equemene
           WRITE(IOOUT,'(1X,A2,3(1X,F15.6))') Nom(Atome(I)),      &
164 1 equemene
                (XyzTmp2(Order(I),J),J=1,3)
165 1 equemene
        ELSE
166 1 equemene
           WRITE(IOOUT,'(1X,A2,3(1X,F15.6))') Nom(Atome(OrderInv(I))),      &
167 1 equemene
                (XyzTmp2(I,J),J=1,3)
168 1 equemene
        END IF
169 1 equemene
     END DO
170 1 equemene
  END IF
171 1 equemene
172 1 equemene
  ! We initialize the first geometry
173 1 equemene
  ! PFL 26 Nov 2008 ->
174 1 equemene
  ! Now, I copy XyzTmp2 into XyzTmp because XyzTmp2 has been aligned
175 1 equemene
  ! with the reference geometry
176 1 equemene
177 1 equemene
  XyzTmp=XyzTmp2
178 1 equemene
179 1 equemene
  !   XyzTmp(1,1)=0.
180 1 equemene
  !   XyzTmp(1,2)=0.
181 1 equemene
  !   XyzTmp(1,3)=0.
182 1 equemene
  !   XyzTmp(2,2)=0.
183 1 equemene
  !   XyzTmp(2,3)=0.
184 1 equemene
  !   XyzTmp(3,3)=0.
185 1 equemene
186 1 equemene
  !   XyzTmp(2,1)=valzmat(2,1)
187 1 equemene
  !   d=valzmat(3,1)
188 1 equemene
  !   a_val=valzmat(3,2)/180.*Pi
189 1 equemene
190 1 equemene
  !   if (Nat.GE.3) THEN
191 1 equemene
  !      if (IndZmat(3,2).EQ.1)  THEN
192 1 equemene
  !         XyzTmp(3,1)=XYzTmp(1,1)+d*cos(a_val)
193 1 equemene
  !      ELSE
194 1 equemene
  !         XyzTmp(3,1)=XyzTmp(2,1)-d*cos(a_val)
195 1 equemene
  !      ENDIF
196 1 equemene
  !      XyzTmp(3,2)=d*sin(a_val)
197 1 equemene
  !   ENDIF
198 1 equemene
199 1 equemene
  !   DO i=4,Nat
200 1 equemene
  !      call ConvertZmat_cart(i,IndZmat,valzmat,        &
201 1 equemene
  !           XYzTMP(1,1), XYzTMP(1,2),XYzTMP(1,3))
202 1 equemene
  !   END DO
203 1 equemene
204 1 equemene
  ! <- PFL 26 Nov 2008
205 1 equemene
206 1 equemene
  s=0.
207 1 equemene
  if (printspline) THEN
208 1 equemene
     SELECT CASE (Nat)
209 1 equemene
     CASE(2)
210 1 equemene
        WRITE(IOTMP,'(15(1X,F10.5))') s,valzmat(2,1)
211 1 equemene
     CASE (3)
212 1 equemene
        WRITE(IOTMP,'(15(1X,F10.5))') s,valzmat(2,1),valzmat(3,1:2)
213 1 equemene
     CASE(4:)
214 1 equemene
        WRITE(IOTMP,'(15(1X,F10.5))') s,valzmat(2,1),valzmat(3,1:2),valzmat(4:Nat,1:3)
215 1 equemene
     END SELECT
216 1 equemene
  END IF
217 1 equemene
  valzmat=0.d0
218 1 equemene
219 1 equemene
  DO K=1,NMaxPtPath
220 1 equemene
     u=real(K)/NMaxPtPath*(NGeomI-1.)
221 1 equemene
222 1 equemene
     XYZTmp2(1,1)=0.
223 1 equemene
     XYZTmp2(1,2)=0.
224 1 equemene
     XYZTmp2(1,3)=0.
225 1 equemene
     XYZTmp2(2,2)=0.
226 1 equemene
     XYZTmp2(2,3)=0.
227 1 equemene
     XYZTmp2(3,3)=0.
228 1 equemene
229 1 equemene
     ! We generate the interpolated Zmatrix
230 1 equemene
     call splintder(u,v,DerInt(1),NGeomI,xgeom(1),IntCoordI(1,1),Coef(1,1))
231 1 equemene
     valzmat(2,1)=v
232 1 equemene
     call splintder(u,v,DerInt(2),NGeomI,xgeom(1),IntCoordI(1,2),Coef(1,2))
233 1 equemene
     valzmat(3,1)=v
234 1 equemene
     call splintder(u,v,DerInt(3),NGeomI,xgeom(1),IntCoordI(1,3),Coef(1,3))
235 1 equemene
     valzmat(3,2)=v*180./Pi
236 1 equemene
     Idx=4
237 1 equemene
     DO I=4,Nat
238 1 equemene
        call splintder(u,v,DerInt(Idx),NGeomI,xgeom(1),IntCoordI(1,Idx),Coef(1,Idx))
239 1 equemene
        valzmat(I,1)=v
240 1 equemene
        Idx=Idx+1
241 1 equemene
        DO J=2,3
242 1 equemene
           call splintder(u,v,DerInt(Idx),NGeomI,xgeom(1),IntCoordI(1,Idx),Coef(1,Idx))
243 1 equemene
           valzmat(I,J)=v*180./pi
244 1 equemene
           Idx=Idx+1
245 1 equemene
        END DO
246 1 equemene
     END DO ! matches DO I=4,Nat
247 1 equemene
248 1 equemene
     ! We convert it into Cartesian coordinates
249 1 equemene
     XyzTmp2(2,1)=valzmat(2,1)
250 1 equemene
     d=valzmat(3,1)
251 1 equemene
     a_val=valzmat(3,2)/180.*Pi
252 1 equemene
     if (Nat.GE.3) THEN
253 1 equemene
        if (IndZmat(3,2).EQ.1)  THEN
254 1 equemene
           XyzTmp2(3,1)=XYzTmp2(1,1)+d*cos(a_val)
255 1 equemene
        ELSE
256 1 equemene
           XyzTmp2(3,1)=XyzTmp2(2,1)-d*cos(a_val)
257 1 equemene
        ENDIF
258 1 equemene
        XyzTmp2(3,2)=d*sin(a_val)
259 1 equemene
     ENDIF
260 1 equemene
261 1 equemene
     DO I=4,Nat
262 1 equemene
        call ConvertZmat_cart(I,IndZmat,valzmat,       &
263 1 equemene
             XYzTMP2(1,1), XYzTMP2(1,2),XYzTMP2(1,3))
264 1 equemene
     END DO
265 1 equemene
266 1 equemene
     IF (Nat.GE.4) THEN
267 1 equemene
        ! PFL 24 Nov 2008 ->
268 1 equemene
        ! If we have frozen atoms we align only those ones.
269 1 equemene
        if (NFroz.GT.0) THEN
270 1 equemene
           Call AlignPartial(Nat,x0,y0,z0,                     &
271 1 equemene
                xyzTmp2(1,1),xyzTmp2(1,2),xyzTMP2(1,3),       &
272 1 equemene
                FrozAtoms,MRot)
273 1 equemene
        ELSE
274 1 equemene
           ! PFL 26 Nov 2008!
275 1 equemene
           ! Note to myself: in Extrapol_cart we always align on x0,y0,z0 but here
276 1 equemene
           ! we align on the previous geom... what is the best ? Is there a difference ?
277 1 equemene
           Call  CalcRmsd(Nat, XyzTmp(1:Nat,1),XyzTmp(1:Nat,2),XyzTmp(1:Nat,3), &
278 1 equemene
                xyzTmp2(1,1),xyzTmp2(1,2),xyzTMP2(1,3),       &
279 1 equemene
                MRot,rmsd,.TRUE.,.TRUE.)
280 1 equemene
        END IF
281 1 equemene
        ! <- PFL 24 Nov 2008
282 1 equemene
     END IF
283 1 equemene
284 1 equemene
     ds=0.
285 1 equemene
     DO I=1,Nat
286 1 equemene
        DO J=1,3
287 1 equemene
           ds=ds+MassAt(I)*(XYZTMp2(I,J)-XYZTmp(I,J))**2
288 1 equemene
           XYZTmp(I,J)=XyzTMP2(I,J)
289 1 equemene
        END DO
290 1 equemene
     END DO
291 1 equemene
292 1 equemene
293 1 equemene
     s=s+sqrt(ds)
294 1 equemene
295 1 equemene
     if ((printspline).AND.(MOD(K,NSpline).EQ.0)) THEN
296 1 equemene
        SELECT CASE (Nat)
297 1 equemene
        CASE(2)
298 1 equemene
           WRITE(IOTMP,'(15(1X,F10.5))') s,valzmat(2,1)
299 1 equemene
        CASE (3)
300 1 equemene
           WRITE(IOTMP,'(15(1X,F10.5))') s,valzmat(2,1),valzmat(3,1:2)
301 1 equemene
        CASE(4:)
302 1 equemene
           WRITE(IOTMP,'(15(1X,F10.5))') s,valzmat(2,1),valzmat(3,1:2),valzmat(4:Nat,1:3)
303 1 equemene
        END SELECT
304 1 equemene
     END IF
305 1 equemene
306 1 equemene
     !         if (debug) WRITE(*,*) "Debug u,s,dist",u,s,dist
307 1 equemene
     if (s>=dist) THEN
308 1 equemene
        if (debug) THEN
309 1 equemene
           WRITE(*,*) "DBG Zmat",s
310 1 equemene
           WRITE(*,'(1X,I5)') IndZmat(1,1)
311 1 equemene
           WRITE(*,'(1X,I5,I5,1X,F10.4)') IndZmat(2,1),IndZmat(2,2),valzmat(2,1)
312 1 equemene
           WRITE(*,'(1X,I5,2(I5,1X,F10.4))') IndZmat(3,1),IndZmat(3,2),valzmat(3,1)  &
313 1 equemene
                ,IndZmat(3,3),valzmat(3,2)
314 1 equemene
           DO I=4,Nat
315 1 equemene
              WRITE(*,'(1X,I5,3(I5,1X,F10.4))') IndZmat(I,1),IndZmat(I,2),valzmat(I,1)  &
316 1 equemene
                   ,IndZmat(I,3),valzmat(I,2),IndZmat(I,4),valzmat(I,3)
317 1 equemene
           END DO
318 1 equemene
        END IF ! matches if (debug) THEN
319 1 equemene
320 1 equemene
        s=s-dist
321 1 equemene
        IdxGeom=IdxGeom+1
322 1 equemene
        SGeom(IdxGeom)=s+IdxGeom*dist
323 1 equemene
        XgeomF(IdxGeom)=u
324 1 equemene
        XyzGeomF(IdxGeom,:,:)=Reshape(XyzTmp2(:,:),(/3,Nat/),ORDER=(/2,1/))
325 1 equemene
        IntCoordF(IdxGeom,1)=valzmat(2,1)
326 1 equemene
        IntCoordF(IdxGeom,2)=valzmat(3,1)
327 1 equemene
        IntCoordF(IdxGeom,3)=valzmat(3,2)/180.*Pi
328 1 equemene
        Idx=4
329 1 equemene
        DO I=4,Nat
330 1 equemene
           IntCoordF(IdxGeom,Idx)=valzmat(I,1)
331 1 equemene
           IntCoordF(IdxGeom,Idx+1)=valzmat(I,2)/180.*Pi
332 1 equemene
           IntCoordF(IdxGeom,Idx+2)=valzmat(I,3)/180.*Pi
333 1 equemene
           Idx=Idx+3
334 1 equemene
        END DO
335 1 equemene
        IntTangent(IdxGeom,:)=DerInt
336 1 equemene
337 1 equemene
        if (print) THEN
338 1 equemene
           WRITE(IOOUT,'(1X,I5)') Nat
339 1 equemene
           WRITE(IOOUT,*) "# Cartesian coord for Geometry ",IdxGeom,K
340 1 equemene
           ! PFL 17/July/2006: only if we have more than 4 atoms.
341 1 equemene
           IF (Nat.GE.4) THEN
342 1 equemene
              ! PFL 24 Nov 2008 ->
343 1 equemene
              ! If we have frozen atoms we align only those ones.
344 1 equemene
              if (NFroz.GT.0) THEN
345 1 equemene
                 Call AlignPartial(Nat,x0,y0,z0,                     &
346 1 equemene
                      xyzTmp2(1,1),xyzTmp2(1,2),xyzTMP2(1,3),       &
347 1 equemene
                      FrozAtoms,MRot)
348 1 equemene
              ELSE
349 1 equemene
                 Call  CalcRmsd(Nat, x0,y0,z0,                               &
350 1 equemene
                      xyzTmp2(1,1),xyzTmp2(1,2),xyzTMP2(1,3),   &
351 1 equemene
                      MRot,rmsd,.TRUE.,.TRUE.)
352 1 equemene
              END IF
353 1 equemene
              ! <- PFL 24 Nov 2008
354 1 equemene
355 1 equemene
           END IF
356 1 equemene
357 1 equemene
           DO I=1,Nat
358 1 equemene
              If (Renum) THEN
359 1 equemene
                 WRITE(IOOUT,'(1X,A2,3(1X,F15.6))') Nom(Atome(I)),   &
360 1 equemene
                      (XyzTmp2(Order(I),J),J=1,3)
361 1 equemene
              ELSE
362 1 equemene
                 WRITE(IOOUT,'(1X,A2,3(1X,F15.6))') Nom(Atome(OrderInv(I))),    &
363 1 equemene
                      (XyzTmp2(I,J),J=1,3)
364 1 equemene
              END IF
365 1 equemene
           END DO
366 1 equemene
367 1 equemene
        END IF ! matches if (print) THEN
368 1 equemene
     END IF ! matches if (s>=dist) THEN
369 1 equemene
  END DO ! matches DO K=1,NMaxPtPath, Is it correct??
370 1 equemene
371 1 equemene
372 1 equemene
  if (printspline) THEN
373 1 equemene
     SELECT CASE (Nat)
374 1 equemene
     CASE(2)
375 1 equemene
        WRITE(IOTMP,'(15(1X,F10.5))') s,valzmat(2,1)
376 1 equemene
     CASE (3)
377 1 equemene
        WRITE(IOTMP,'(15(1X,F10.5))') s,valzmat(2,1),valzmat(3,1:2)
378 1 equemene
     CASE(4:)
379 1 equemene
        WRITE(IOTMP,'(15(1X,F10.5))') s,valzmat(2,1),valzmat(3,1:2),valzmat(4:Nat,1:3)
380 1 equemene
     END SELECT
381 1 equemene
  END IF
382 1 equemene
383 1 equemene
  if (s>=0.9*dist) THEN
384 1 equemene
     if (debug) WRITE(*,*) "DBG Extrapol_int L383: Adding last geom"
385 1 equemene
     write(*,*) "Extrapol_int u,xgeom(NGeomI),s,dist,s-dist",u,xgeom(NGeomI),s,dist,s-dist
386 1 equemene
!     u=xgeom(NGeomI)
387 1 equemene
     s=s-dist
388 1 equemene
389 1 equemene
390 1 equemene
!      ! We generate the interpolated Zmatrix
391 1 equemene
!      call splintder(u,v,DerInt(1),NGeomI,xgeom(1),IntCoordI(1,1),Coef(1,1))
392 1 equemene
!      valzmat(2,1)=v
393 1 equemene
!      call splintder(u,v,DerInt(2),NGeomI,xgeom(1),IntCoordI(1,2),Coef(1,2))
394 1 equemene
!      valzmat(3,1)=v
395 1 equemene
!      call splintder(u,v,DerInt(3),NGeomI,xgeom(1),IntCoordI(1,3),Coef(1,3))
396 1 equemene
!      valzmat(3,2)=v*180./Pi
397 1 equemene
!      Idx=4
398 1 equemene
!      DO I=4,Nat
399 1 equemene
!         call splintder(u,v,DerInt(Idx),NGeomI,xgeom(1),IntCoordI(1,Idx),Coef(1,Idx))
400 1 equemene
!         valzmat(I,1)=v
401 1 equemene
!         Idx=Idx+1
402 1 equemene
!         DO J=2,3
403 1 equemene
!            call splintder(u,v,DerInt(Idx),NGeomI,xgeom(1),IntCoordI(1,Idx),Coef(1,Idx))
404 1 equemene
!            valzmat(I,J)=v*180./pi
405 1 equemene
!            Idx=Idx+1
406 1 equemene
!         END DO
407 1 equemene
!      END DO ! matches DO I=4,Nat
408 1 equemene
409 1 equemene
!      ! We convert it into Cartesian coordinates
410 1 equemene
!      XyzTmp2(2,1)=valzmat(2,1)
411 1 equemene
!      d=valzmat(3,1)
412 1 equemene
!      a_val=valzmat(3,2)/180.*Pi
413 1 equemene
!      if (Nat.GE.3) THEN
414 1 equemene
!         if (IndZmat(3,2).EQ.1)  THEN
415 1 equemene
!            XyzTmp2(3,1)=XYzTmp2(1,1)+d*cos(a_val)
416 1 equemene
!         ELSE
417 1 equemene
!            XyzTmp2(3,1)=XyzTmp2(2,1)-d*cos(a_val)
418 1 equemene
!         ENDIF
419 1 equemene
!         XyzTmp2(3,2)=d*sin(a_val)
420 1 equemene
!      ENDIF
421 1 equemene
422 1 equemene
!      DO I=4,Nat
423 1 equemene
!         call ConvertZmat_cart(I,IndZmat,valzmat,       &
424 1 equemene
!              XYzTMP2(1,1), XYzTMP2(1,2),XYzTMP2(1,3))
425 1 equemene
!      END DO
426 1 equemene
427 1 equemene
!      IF (Nat.GE.4) THEN
428 1 equemene
!         ! PFL 24 Nov 2008 ->
429 1 equemene
!         ! If we have frozen atoms we align only those ones.
430 1 equemene
!         if (NFroz.GT.0) THEN
431 1 equemene
!            Call AlignPartial(Nat,x0,y0,z0,                     &
432 1 equemene
!                 xyzTmp2(1,1),xyzTmp2(1,2),xyzTMP2(1,3),       &
433 1 equemene
!                 FrozAtoms,MRot)
434 1 equemene
!         ELSE
435 1 equemene
!            ! PFL 26 Nov 2008!
436 1 equemene
!            ! Note to myself: in Extrapol_cart we always align on x0,y0,z0 but here
437 1 equemene
!            ! we align on the previous geom... what is the best ? Is there a difference ?
438 1 equemene
!            Call  CalcRmsd(Nat, XyzTmp(1:Nat,1),XyzTmp(1:Nat,2),XyzTmp(1:Nat,3), &
439 1 equemene
!                 xyzTmp2(1,1),xyzTmp2(1,2),xyzTMP2(1,3),       &
440 1 equemene
!                 MRot,rmsd,.TRUE.,.TRUE.)
441 1 equemene
!         END IF
442 1 equemene
!         ! <- PFL 24 Nov 2008
443 1 equemene
!      END IF
444 1 equemene
445 1 equemene
     IdxGeom=IdxGeom+1
446 1 equemene
447 1 equemene
448 1 equemene
449 1 equemene
     IF (IdxGeom.GT.NGeomF) THEN
450 1 equemene
        WRITE(IOOUT,*) "!!! ERROR in Extrapol_int !!!!"
451 1 equemene
        WRITE(IOOUT,*) "Too many structures. Increase NMaxPath"
452 1 equemene
        WRITE(*,*) "** PathCreate ***"
453 1 equemene
        WRITE(*,*) "Distribution of points along the path is wrong."
454 1 equemene
        WRITE(*,*) "Increase value of NMaxPtPath in the input file"
455 1 equemene
        WRITE(*,*) "Present value is:", NMaxPtPath
456 1 equemene
        STOP
457 1 equemene
     END IF
458 1 equemene
459 1 equemene
     SGeom(IdxGeom)=s+IdxGeom*dist
460 1 equemene
     XgeomF(IdxGeom)=min(u,NGeomI-1.d0)
461 1 equemene
     XyzGeomF(IdxGeom,:,:)=Reshape(XyzTmp2(:,:),(/3,Nat/),ORDER=(/2,1/))
462 1 equemene
     !  XyzGeomF(IdxGeom,:,:)=XyzTmp2(:,:)
463 1 equemene
     IntCoordF(IdxGeom,1)=valzmat(2,1)
464 1 equemene
     IntCoordF(IdxGeom,2)=valzmat(3,1)
465 1 equemene
     IntCoordF(IdxGeom,3)=valzmat(3,2)/180.*Pi
466 1 equemene
     Idx=4
467 1 equemene
     DO I=4,Nat
468 1 equemene
        IntCoordF(IdxGeom,Idx)=valzmat(I,1)
469 1 equemene
        IntCoordF(IdxGeom,Idx+1)=valzmat(I,2)/180.*Pi
470 1 equemene
        IntCoordF(IdxGeom,Idx+2)=valzmat(I,3)/180.*Pi
471 1 equemene
        Idx=Idx+3
472 1 equemene
     END DO
473 1 equemene
     IntTangent(IdxGeom,:)=DerInt
474 1 equemene
475 1 equemene
     if (print) THEN
476 1 equemene
        WRITE(IOOUT,'(1X,I5)') Nat
477 1 equemene
        WRITE(IOOUT,*) "# Cartesian coord for Geometry ",IdxGeom,K
478 1 equemene
        ! PFL 17/July/2006: only if we have more than 4 atoms.
479 1 equemene
        IF (Nat.GE.4) THEN
480 1 equemene
           ! PFL 24 Nov 2008 ->
481 1 equemene
           ! If we have frozen atoms we align only those ones.
482 1 equemene
           if (NFroz.GT.0) THEN
483 1 equemene
              Call AlignPartial(Nat,x0,y0,z0,                     &
484 1 equemene
                   xyzTmp2(1,1),xyzTmp2(1,2),xyzTMP2(1,3),       &
485 1 equemene
                   FrozAtoms,MRot)
486 1 equemene
           ELSE
487 1 equemene
              Call  CalcRmsd(Nat, x0,y0,z0,                               &
488 1 equemene
                   xyzTmp2(1,1),xyzTmp2(1,2),xyzTMP2(1,3),   &
489 1 equemene
                   MRot,rmsd,.TRUE.,.TRUE.)
490 1 equemene
           END IF
491 1 equemene
           ! <- PFL 24 Nov 2008
492 1 equemene
        END IF
493 1 equemene
494 1 equemene
        DO I=1,Nat
495 1 equemene
           If (Renum) THEN
496 1 equemene
              WRITE(IOOUT,'(1X,A2,3(1X,F15.6))') Nom(Atome(I)),    &
497 1 equemene
                   (XyzTmp2(Order(I),J),J=1,3)
498 1 equemene
           ELSE
499 1 equemene
              WRITE(IOOUT,'(1X,A2,3(1X,F15.6))') Nom(Atome(OrderInv(I))),     &
500 1 equemene
                   (XyzTmp2(I,J),J=1,3)
501 1 equemene
           END IF
502 1 equemene
        END DO ! matches DO I=1,Nat
503 1 equemene
     END IF ! matches if (print) THEN
504 1 equemene
  END IF ! matches if (s>=0.9*dist) THEN
505 1 equemene
506 1 equemene
  if (debug) WRITE(*,*) 's final =',s
507 1 equemene
508 1 equemene
  DEALLOCATE(XyzTmp,XyzTmp2,valzmat)
509 1 equemene
510 1 equemene
  if (printspline) CLOSE(IOTMP)
511 1 equemene
512 1 equemene
  if (debug) Call Header("Extrapol_int Over")
513 1 equemene
514 1 equemene
515 1 equemene
END SUBROUTINE EXTRAPOL_INT