Statistiques
| Révision :

root / src / PathCreate.f90 @ 1

Historique | Voir | Annoter | Télécharger (35,64 ko)

1 1 equemene
!================================================================
2 1 equemene
!
3 1 equemene
! This subroutine create a path using starting geometries
4 1 equemene
! it is 'original' in the sense that the path is generated
5 1 equemene
! by interpolating internal coordinates instead of cartesian.
6 1 equemene
! Comes from the Extrapol.f subroutine of Cart suite.
7 1 equemene
! Rewritten in F90 to be more flexible
8 1 equemene
!
9 1 equemene
!================================================================
10 1 equemene
11 1 equemene
SUBROUTINE PathCreate(IOpt)
12 1 equemene
13 1 equemene
  use Io_module
14 1 equemene
  use Path_module, only : Nat, NGeomI, NCoord, NGeomF, IGeomRef, NMaxL, IReparam, IReparamT, &
15 1 equemene
       Coord, Frozen, Cart, NCart, NFroz, XyzGeomI, atome, r_cov, fact, &
16 1 equemene
       IndZmat, Renum, Order, OrderInv, IntCoordI, IntCoordF,Pi, BMat_BakerT, Nom, &
17 1 equemene
       Hess,IntFroz, ISpline, IntTangent, XyzGeomF, NPrim,Xprimitive_t, OptGeom,  &
18 1 equemene
       UMatF, UMat_local, XyzTangent, Linear
19 1 equemene
  ! BMat_BakerT (3*Nat,NCoord), XyzGeomI(NGeomI,3,Nat), IGeomRef=-1 (default value)
20 1 equemene
  ! IntCoordI(NGeomI,NCoord)
21 1 equemene
22 1 equemene
  IMPLICIT NONE
23 1 equemene
24 1 equemene
  REAL(KREAL), PARAMETER :: Inf=1e32
25 1 equemene
  INTEGER(KINT), INTENT(IN) :: IOpt
26 1 equemene
27 1 equemene
  INTEGER(KINT) ::  at,long
28 1 equemene
  REAL(KREAL), ALLOCATABLE :: val_zmat(:,:), val_zmatTmp(:,:) ! (3,Nat)
29 1 equemene
  REAL(KREAL), ALLOCATABLE :: X0(:), Y0(:), Z0(:) ! Nat
30 1 equemene
  REAL(KREAL), ALLOCATABLE ::  XyzTmp(:,:), XyzTmp2(:,:) ! (Nat,3)
31 1 equemene
  !  REAL(KREAL), ALLOCATABLE ::  XyzTmp3(:,:) ! (3,Nat)
32 1 equemene
  REAL(KREAL), ALLOCATABLE ::  IntCoordTmp(:) ! (NCoord)
33 1 equemene
  INTEGER(KINT), ALLOCATABLE :: IndZmat0(:,:) !Nat,5
34 1 equemene
  REAL(KREAL), ALLOCATABLE :: Coef(:,:) ! (NGeomI,NCoord)
35 1 equemene
  ! NPrim=Number of primitive coordinates.
36 1 equemene
  REAL(KREAL), ALLOCATABLE :: XGeom(:) ! NGeomI
37 1 equemene
  REAL(KREAL), ALLOCATABLE :: XGeomF(:) ! NGeomF
38 1 equemene
  REAL(KREAL), ALLOCATABLE :: Hess_int(:,:) ! Hess_int (3*Nat,3*Nat), used for Baker case
39 1 equemene
  INTEGER(KINT) :: NGeomS
40 1 equemene
41 1 equemene
  REAL(KREAL) :: Rmsd,MRot(3,3), Delta, normDeltaX_int
42 1 equemene
  REAL(KREAL), PARAMETER ::  LimAngle=145.d0,TwoPi=360.d0
43 1 equemene
  REAL(KREAL)  ::s,ds,dist,a_val,d
44 1 equemene
  INTEGER(KINT) :: I,J,K,NbCycle,igeom,nb,ig,iat
45 1 equemene
  INTEGER(KINT) :: Itmp, Jat, L
46 1 equemene
  INTEGER(KINT) :: Idx,IBeg
47 1 equemene
  CHARACTER(LCHARS) :: Title
48 1 equemene
  REAL(KREAL), ALLOCATABLE :: x(:), y(:), z(:)
49 1 equemene
  LOGICAL ::  debug, print
50 1 equemene
  LOGICAL, SAVE :: First=.TRUE.
51 1 equemene
  ! Frozen contains the indices of frozen atoms
52 1 equemene
  LOGICAL, ALLOCATABLE :: FCart(:) ! Nat
53 1 equemene
  INTEGER, ALLOCATABLE :: AtCart(:) !Nat
54 1 equemene
  INTEGER(KINT), ALLOCATABLE ::  LIAISONS(:,:),LiaisonsIni(:,:) ! (Nat,0:NMaxL)
55 1 equemene
  INTEGER(KINT), ALLOCATABLE :: Fragment(:),NbAtFrag(:) !nat
56 1 equemene
  INTEGER(KINT), ALLOCATABLE :: FragAt(:,:) !nat,nat
57 1 equemene
  INTEGER(KINT) :: NbFrag,NFragRef
58 1 equemene
59 1 equemene
60 1 equemene
  INTERFACE
61 1 equemene
     function valid(string) result (isValid)
62 1 equemene
       CHARACTER(*), intent(in) :: string
63 1 equemene
       logical                  :: isValid
64 1 equemene
     END function VALID
65 1 equemene
66 1 equemene
     FUNCTION test_zmat(na,ind_zmat)
67 1 equemene
68 1 equemene
       USE Path_module
69 1 equemene
70 1 equemene
       logical :: test_zmat
71 1 equemene
       integer(KINT) :: na
72 1 equemene
       integer(KINT) :: ind_zmat(Na,5)
73 1 equemene
     END FUNCTION TEST_ZMAT
74 1 equemene
  END INTERFACE
75 1 equemene
76 1 equemene
77 1 equemene
78 1 equemene
  debug=valid("pathcreate")
79 1 equemene
  print=valid("printgeom")
80 1 equemene
  if (debug) Call header("Entering PathCreate")
81 1 equemene
  if (debug.AND.First) WRITE(*,*) "=		 First call					="
82 1 equemene
83 1 equemene
  if (debug) WRITE(*,*) "Iopt,IReparam=",Iopt,IReparam
84 1 equemene
85 1 equemene
  ALLOCATE(Coef(NGeomI,NCoord),val_zmat(Nat,3),val_zmatTMP(Nat,3))
86 1 equemene
  ALLOCATE(X0(Nat),Y0(Nat),Z0(Nat),Indzmat0(Nat,5))
87 1 equemene
  ALLOCATE(X(Nat),Y(Nat),Z(Nat),Xgeom(NGeomI),XgeomF(NGeomF))
88 1 equemene
  ! ALLOCATE(XyzTmp(Nat,3),XyzTmp2(Nat,3),XyzTmp3(3,Nat))
89 1 equemene
  ALLOCATE(XyzTmp(Nat,3),XyzTmp2(Nat,3))
90 1 equemene
  ALLOCATE(IntCoordTmp(NCoord))
91 1 equemene
92 1 equemene
  Do I=1,NGeomI
93 1 equemene
     XGeom(I)=FLoat(I)-1.d0
94 1 equemene
  END DO
95 1 equemene
96 1 equemene
  ! First iteration of the optimization:
97 1 equemene
  IF (First) THEN ! matches at L484
98 1 equemene
     if (debug) WRITE(*,*) "first iteration in PathCreate.90, L93"
99 1 equemene
100 1 equemene
     ! This is the first call, so we might have to generate a Zmat
101 1 equemene
     First=.FALSE.
102 1 equemene
103 1 equemene
     IF ( ((COORD.EQ."ZMAT").OR.(COORD.EQ."HYBRID").OR.(COORD.EQ."MIXED") &
104 1 equemene
          .OR.(COORD.EQ."BAKER")).AND.(IGeomRef.LE.0)) THEN
105 1 equemene
106 1 equemene
        ! User has not defined the Reference geometry, we have to choose it ourselves!
107 1 equemene
        ! This is done by counting the number of fragments of each geometry. The
108 1 equemene
        ! reference geometry is the one with the least fragments. When there are
109 1 equemene
        ! frozen or cart atoms, they are discarded to count the fragments.
110 1 equemene
111 1 equemene
        ALLOCATE(Liaisons(Nat,0:NMaxL))
112 1 equemene
        ALLOCATE(Fragment(nat),NbAtFrag(nat),FragAt(nat,nat),FCart(Nat))
113 1 equemene
        FCart=.FALSE.
114 1 equemene
        ! FCart(Nat) was under IF below earlier but is being accessed after this loop.
115 1 equemene
        IF ((Frozen(1).NE.0).OR.(Cart(1).NE.0)) THEN
116 1 equemene
           ALLOCATE(AtCart(Nat),LiaisonsIni(Nat,0:NMaxL))
117 1 equemene
           FCart=.FALSE.
118 1 equemene
           NCart=0
119 1 equemene
           Idx=1
120 1 equemene
           DO WHILE (Frozen(Idx).NE.0)
121 1 equemene
              IF (Frozen(Idx).LT.0) THEN
122 1 equemene
                 DO I=Frozen(Idx-1),abs(Frozen(Idx))
123 1 equemene
                    IF (.NOT.FCart(I)) THEN
124 1 equemene
                       NCart=NCart+1
125 1 equemene
                       AtCart(NCart)=I
126 1 equemene
                       FCart(I)=.TRUE.
127 1 equemene
                    END IF
128 1 equemene
                 END DO
129 1 equemene
              ELSE IF (.NOT.FCart(Frozen(Idx))) THEN
130 1 equemene
                 FCart(Frozen(Idx))=.TRUE.
131 1 equemene
                 NCart=NCart+1
132 1 equemene
                 AtCart(NCart)=Frozen(Idx)
133 1 equemene
              END IF
134 1 equemene
              Idx=Idx+1
135 1 equemene
           END DO ! matches DO WHILE (Frozen(Idx).NE.0)
136 1 equemene
           NFroz=NCart
137 1 equemene
           Idx=1
138 1 equemene
           DO WHILE (Cart(Idx).NE.0)
139 1 equemene
              IF (Cart(Idx).LT.0) THEN
140 1 equemene
                 DO I=Cart(Idx-1),abs(Cart(Idx))
141 1 equemene
                    IF (.NOT.FCart(I)) THEN
142 1 equemene
                       NCart=NCart+1
143 1 equemene
                       AtCart(NCart)=I
144 1 equemene
                       FCart(I)=.TRUE.
145 1 equemene
                    END IF
146 1 equemene
                 END DO
147 1 equemene
              ELSEIF (.NOT.FCart(Cart(Idx))) THEN
148 1 equemene
                 FCart(Cart(Idx))=.TRUE.
149 1 equemene
                 NCart=NCart+1
150 1 equemene
                 AtCart(NCart)=Cart(Idx)
151 1 equemene
              END IF
152 1 equemene
              Idx=Idx+1
153 1 equemene
           END DO !matches DO WHILE (Cart(Idx).NE.0)
154 1 equemene
           IF (debug) THEN
155 1 equemene
              WRITE(*,'(1X,A,I4,A,I4,A)') "DBG PathCreate - GeomRef :: Found ", &
156 1 equemene
                   NFroz," frozen atoms, and a total of ",NCart, &
157 1 equemene
                   " atoms described in cartesian coordinates"
158 1 equemene
              WRITE(*,*) "AtCart:",AtCart(1:NCart)
159 1 equemene
           END IF
160 1 equemene
        END IF ! IF ((Frozen(1).NE.0).OR.(Cart(1).NE.0)) THEN
161 1 equemene
162 1 equemene
        NFragRef=2*Nat
163 1 equemene
        DO IGeom=1,NGeomI
164 1 equemene
           x(1:Nat) = XyzGeomI(IGeom,1,1:Nat)
165 1 equemene
           y(1:Nat) = XyzGeomI(IGeom,2,1:Nat)
166 1 equemene
           z(1:Nat) = XyzGeomI(IGeom,3,1:Nat)
167 1 equemene
           ! we calculate the connectivities
168 1 equemene
           Call CalcCnct(nat,atome,x,y,z,LIAISONS,r_cov,fact)
169 1 equemene
           ! if needed, we get rid of links between cart or frozen atoms
170 1 equemene
           IF (NCart.GE.2) THEN
171 1 equemene
              LiaisonsIni=Liaisons
172 1 equemene
              DO I=1,NCart
173 1 equemene
                 Iat=AtCart(I)
174 1 equemene
                 if (debug) WRITE(*,'(20(1X,I3))') I,Iat,  &
175 1 equemene
                      (LiaisonsIni(Iat,Itmp),ITmp=0,LiaisonsIni(Iat,0))
176 1 equemene
                 DO J=1,LiaisonsIni(Iat,0)
177 1 equemene
                    Jat=LiaisonsIni(Iat,J)
178 1 equemene
                    IF (FCart(Jat)) THEN
179 1 equemene
                       Call Annul(Liaisons,Iat,Jat)
180 1 equemene
                       Call Annul(Liaisons,Jat,Iat)
181 1 equemene
                       Call Annul(LiaisonsIni,Jat,Iat)
182 1 equemene
                       Liaisons(Iat,0)=Liaisons(Iat,0)-1
183 1 equemene
                       Liaisons(Jat,0)=Liaisons(Jat,0)-1
184 1 equemene
                       LiaisonsIni(Jat,0)=LiaisonsIni(Jat,0)-1
185 1 equemene
                    END IF
186 1 equemene
                 END DO
187 1 equemene
              END DO
188 1 equemene
           END IF ! matches IF (NCart.GE.2) THEN
189 1 equemene
           ! we now calculate the number of fragments.
190 1 equemene
           Call Decomp_frag(nat,liaisons,.NOT.Fcart,nbfrag,Fragment,NbAtFrag,FragAt)
191 1 equemene
           IF (NbFrag.LT.NFragRef) THEN
192 1 equemene
              NFragRef=NbFrag
193 1 equemene
              ! The reference geometry, IGeomRef, is determined based on the least number
194 1 equemene
              ! of fragments (here if (((COORD.EQ."ZMAT").OR.(COORD.EQ."HYBRID").OR.(COORD
195 1 equemene
              !.EQ."MIXED")).AND.(IGeomRef.LE.0))), otherwise it still has the value of
196 1 equemene
              ! IGeomRef=-1.
197 1 equemene
              IGeomRef=IGeom
198 1 equemene
           END IF
199 1 equemene
        END DO ! matches DO IGeom=1,NGeomI
200 1 equemene
        DEALLOCATE(FCart)
201 1 equemene
     END IF ! matches IF (((COORD.EQ."ZMAT").OR.(COORD.EQ."HYBRID").OR.(COORD.EQ."MIXED")
202 1 equemene
     ! .OR.(COORD.EQ."BAKER")).AND.(IGeomRef.LE.0)).
203 1 equemene
204 1 equemene
     if (debug) WRITE(*,*) "DBG PathCreate : IGeomRef= ",IGeomRef
205 1 equemene
206 1 equemene
     ! we now compute the internal coordinates for this geometry !
207 1 equemene
     ! The reference geometry, IGeomRef, is determined based on the least number
208 1 equemene
     ! of fragments if (((COORD.EQ."ZMAT").OR.(COORD.EQ."HYBRID").OR.(COORD
209 1 equemene
     !.EQ."MIXED")).AND.(IGeomRef.LE.0)), otherwise it has the value of
210 1 equemene
     ! IGeomRef=-1.
211 1 equemene
     x(1:Nat) = XyzGeomI(IGeomRef,1,1:Nat) ! XyzGeomI(NGeomI,3,Nat)
212 1 equemene
     y(1:Nat) = XyzGeomI(IGeomRef,2,1:Nat)
213 1 equemene
     z(1:Nat) = XyzGeomI(IGeomRef,3,1:Nat)
214 1 equemene
215 1 equemene
     IndZmat=0
216 1 equemene
     IndZmat0=0
217 1 equemene
218 1 equemene
     SELECT CASE(COORD)
219 1 equemene
     CASE ('BAKER')
220 1 equemene
        ! atome(Nat), r_cov(0:Max_Z)
221 1 equemene
        ! Frozen(Nat) contains the indices of frozen atoms
222 1 equemene
        Call Calc_baker(atome,r_cov,fact,frozen,IGeomRef)
223 1 equemene
        if (debug) THEN
224 1 equemene
           WRITE(*,*) "UMat_local after Calc_baker"
225 1 equemene
           DO I=1,3*Nat-6
226 1 equemene
              WRITE(*,'(50(1X,F12.8))') UMat_local(:,I)
227 1 equemene
           END DO
228 1 equemene
        END IF
229 1 equemene
        DO IGeom=1,NGeomF
230 1 equemene
           UMatF(IGeom,:,:)=UMat_Local(:,:)
231 1 equemene
        END DO
232 1 equemene
233 1 equemene
        ALLOCATE(Xprimitive_t(NPrim))
234 1 equemene
        ! x, y, z corresponds the reference geometry.
235 1 equemene
        DO I=1,Nat
236 1 equemene
           Order(I)=I
237 1 equemene
           OrderInv(I)=I
238 1 equemene
        END DO
239 1 equemene
        x0=x
240 1 equemene
        y0=y
241 1 equemene
        z0=z
242 1 equemene
     CASE ('ZMAT','HYBRID')
243 1 equemene
        ! IN case we are using Hybrid or zmat coordinate system, we have to
244 1 equemene
        ! generate the internal coordinates with a Z-Matrix
245 1 equemene
        ! IN case we have frozen atoms, we generate a constrained Zmat
246 1 equemene
        IF (Frozen(1).NE.0) THEN
247 1 equemene
           Renum=.True.
248 1 equemene
           call Calc_zmat_const_frag(Nat,atome,IndZmat0,val_zmat,x,y,z,r_cov,fact,frozen)
249 1 equemene
        ELSE
250 1 equemene
           !no zmat... we create our own
251 1 equemene
           call Calc_zmat_frag(Nat,atome,IndZmat0,val_zmat,x,y,z,r_cov,fact)
252 1 equemene
           if (valid('old_zmat')) THEN
253 1 equemene
              call Calc_zmat(Nat,atome,IndZmat0,val_zmat,x,y,z,r_cov,fact)
254 1 equemene
              WRITE(*,*) "DBG PathCreate Calc_Zmat.... STOP"
255 1 equemene
              STOP
256 1 equemene
           END IF
257 1 equemene
        END IF
258 1 equemene
259 1 equemene
        if (debug) WRITE(*,*) 'Back from Calc_zmat'
260 1 equemene
        IF (.NOT.test_zmat(nat,IndZmat0)) THEN
261 1 equemene
           WRITE(IOOUT,*) "I cannot generate a valid Zmat... help"
262 1 equemene
           STOP
263 1 equemene
        END IF
264 1 equemene
265 1 equemene
        ! The IndZmat0 generated by Calc_zmat refers to the order of the input x,y,z
266 1 equemene
        ! However, we need it with the new order so that we can use the zmat
267 1 equemene
        ! coordinates to generate cartesian coordinates.
268 1 equemene
        ! So, we have to reorder it...
269 1 equemene
        DO I=1,Nat
270 1 equemene
           Order(IndZmat0(I,1))=I
271 1 equemene
           OrderInv(I)=IndZmat0(I,1)
272 1 equemene
           ! I let X0 being the Cartesian coordinates of the reference geometry. Before it was
273 1 equemene
           ! those of the First geometry (which was also the reference one). This might change!
274 1 equemene
           X0(i)=X(IndZmat0(i,1))
275 1 equemene
           Y0(i)=Y(IndZmat0(i,1))
276 1 equemene
           Z0(i)=Z(IndZmat0(i,1))
277 1 equemene
        END DO
278 1 equemene
        IndZmat(1,1)=Order(IndZmat0(1,1))
279 1 equemene
        IndZmat(2,1)=Order(IndZmat0(2,1))
280 1 equemene
        IndZmat(2,2)=Order(IndZmat0(2,2))
281 1 equemene
        IndZmat(3,1)=Order(IndZmat0(3,1))
282 1 equemene
        IndZmat(3,2)=Order(IndZmat0(3,2))
283 1 equemene
        IndZmat(3,3)=Order(IndZmat0(3,3))
284 1 equemene
        DO I=4,Nat
285 1 equemene
           DO J=1,4
286 1 equemene
              IndZmat(I,J)=Order(IndZmat0(I,J))
287 1 equemene
           END DO
288 1 equemene
        end do
289 1 equemene
        IF (DEBUG) THEN
290 1 equemene
           WRITE(IOOUT,*) "DBG PathCreate : IndZmat"
291 1 equemene
           DO I=1,Nat
292 1 equemene
              WRITE(IOOUT,*) (IndZmat(I,J),J=1,5)
293 1 equemene
           END DO
294 1 equemene
           WRITE(IOOUT,*) "DBG PathCreate : IndZmat0"
295 1 equemene
           DO I=1,Nat
296 1 equemene
              WRITE(IOOUT,*) (IndZmat0(I,J),J=1,5)
297 1 equemene
           END DO
298 1 equemene
299 1 equemene
        END IF
300 1 equemene
301 1 equemene
        ! It is the first call, we have to create all internal coordinates
302 1 equemene
        if (debug) WrITE(*,*) "DBG PathCreate L302: First Call, we generate internal coords"
303 1 equemene
        DO igeom=1,NgeomI
304 1 equemene
           x(1:Nat) = XyzGeomI(IGeom,1,1:Nat)
305 1 equemene
           y(1:Nat) = XyzGeomI(IGeom,2,1:Nat)
306 1 equemene
           z(1:Nat) = XyzGeomI(IGeom,3,1:Nat)
307 1 equemene
308 1 equemene
           if (debug) WRITE(*,*) "DBG PathCreate L308: we generate internal coords for geom",IGeom
309 1 equemene
310 1 equemene
           Call ConvXyzZmat(Nat,x,y,z,IndZmat0,val_zmatTmp)
311 1 equemene
           IntCoordI(IGeom,1)=val_zmatTmp(2,1)
312 1 equemene
           IntCoordI(IGeom,2)=val_zmatTmp(3,1)
313 1 equemene
           IntCoordI(IGeom,3)=val_zmatTmp(3,2)*Pi/180.
314 1 equemene
           Idx=4
315 1 equemene
           DO i=4,nat
316 1 equemene
              IntCoordI(IGeom,Idx)=val_zmatTmp(i,1)
317 1 equemene
              Idx=Idx+1
318 1 equemene
              IntCoordI(IGeom,Idx)=val_zmatTmp(i,2)*Pi/180.
319 1 equemene
              Idx=Idx+1
320 1 equemene
321 1 equemene
              ! Some tests to check that the dihedral angles are similar... this is
322 1 equemene
              ! important if they are close to Pi.
323 1 equemene
              Delta=0.
324 1 equemene
325 1 equemene
              if (abs(val_zmatTMP(i,3)-val_zmat(i,3))>=180.) THEN
326 1 equemene
                 if ((val_zmatTMP(i,3)-val_zmat(i,3))<=-180.) THEN
327 1 equemene
                    Delta=-1.0d0*TwoPi
328 1 equemene
                 ELSE
329 1 equemene
                    Delta=TwoPi
330 1 equemene
                 END IF
331 1 equemene
                 if (debug) THEN
332 1 equemene
                    WRITE(*,*) Nom(atome(i)),				&
333 1 equemene
                         abs(val_zmatTMP(i,3)-val_zmat(i,3)), &
334 1 equemene
                         val_zmatTMP(i,3),val_zmat(i,3),Delta, &
335 1 equemene
                         val_zmatTMP(i,3)-Delta
336 1 equemene
                 END IF
337 1 equemene
              END IF
338 1 equemene
              IntCoordI(IGeom,Idx)=(val_zmatTmp(i,3)-Delta)/180.*Pi
339 1 equemene
              Idx=Idx+1
340 1 equemene
           END DO
341 1 equemene
        END DO  ! End Loop on Igeom
342 1 equemene
343 1 equemene
     CASE ('MIXED')
344 1 equemene
        ! IN case we are using mixed coordinate system, we have to
345 1 equemene
        ! we generate the internal coordinates with a Z-Matrix
346 1 equemene
        Renum=.TRUE.
347 1 equemene
        !
348 1 equemene
        call Calc_mixed_frag(Nat,atome,IndZmat0,val_zmat,x,y,z, &
349 1 equemene
             r_cov,fact,frozen,cart,ncart)
350 1 equemene
351 1 equemene
        if (debug) WRITE(*,*) 'Back from Calc_Mixed'
352 1 equemene
353 1 equemene
        ! How to test this partial zmat ? it must be good as it was automatically generated...
354 1 equemene
        !        IF (.NOT.test_zmat(nat,IndZmat0)) THEN
355 1 equemene
        !           WRITE(IOOUT,*) "I cannot generate a valid Zmat... help"
356 1 equemene
        !           STOP
357 1 equemene
        !        END IF
358 1 equemene
359 1 equemene
        ! The IndZmat0 generated by Calc_zmat refers to the order of the input x,y,z
360 1 equemene
        ! However, we need it with the new order so that we can use the zmat
361 1 equemene
        ! coordinates to generate cartesian coordinates.
362 1 equemene
        ! So, we have to reorder it...
363 1 equemene
        DO I=1,Nat
364 1 equemene
           Order(IndZmat0(I,1))=I
365 1 equemene
           OrderInv(I)=IndZmat0(I,1)
366 1 equemene
           ! I let X0 being the Cartesian coordinates of the reference geometry. Before it was
367 1 equemene
           ! those of the First geometry (which was also the reference one). This might change!
368 1 equemene
           X0(i)=X(IndZmat0(i,1))
369 1 equemene
           Y0(i)=Y(IndZmat0(i,1))
370 1 equemene
           Z0(i)=Z(IndZmat0(i,1))
371 1 equemene
        END DO
372 1 equemene
        IndZmat=0
373 1 equemene
        IndZmat(1:NCart,:)=-1
374 1 equemene
375 1 equemene
        DO I=1,Nat
376 1 equemene
           IndZmat(I,1)=Order(IndZmat0(I,1))
377 1 equemene
        END DO
378 1 equemene
379 1 equemene
        SELECT CASE (NCart)
380 1 equemene
        CASE (1)
381 1 equemene
           IndZmat(2,2)=Order(IndZmat0(2,2))
382 1 equemene
           IndZmat(3,2)=Order(IndZmat0(3,2))
383 1 equemene
           IndZmat(3,3)=Order(IndZmat0(3,3))
384 1 equemene
           IdX=4
385 1 equemene
        CASE (2)
386 1 equemene
           IndZmat(3,2)=Order(IndZmat0(3,2))
387 1 equemene
           IndZmat(3,3)=Order(IndZmat0(3,3))
388 1 equemene
           Idx=4
389 1 equemene
        CASE DEFAULT
390 1 equemene
           Idx=NCart+1
391 1 equemene
        END SELECT
392 1 equemene
393 1 equemene
        DO I=Idx,Nat
394 1 equemene
           DO J=1,4
395 1 equemene
              IndZmat(I,J)=Order(IndZmat0(I,J))
396 1 equemene
           END DO
397 1 equemene
        end do
398 1 equemene
        IF (DEBUG) THEN
399 1 equemene
           WRITE(IOOUT,*) "DBG PathCreate : IndZmat - Mixed"
400 1 equemene
           DO I=1,Nat
401 1 equemene
              WRITE(IOOUT,*) (IndZmat(I,J),J=1,5)
402 1 equemene
           END DO
403 1 equemene
        END IF
404 1 equemene
405 1 equemene
        ! It is the first call, we have to create all internal coordinates
406 1 equemene
        !            Idx=1
407 1 equemene
        !            DO I=1,NCart
408 1 equemene
        !               IntCoordI(1,Idx)=val_zmat(I,1)
409 1 equemene
        !               IntCoordI(1,Idx+1)=val_zmat(I,2)
410 1 equemene
        !               IntCoordI(1,Idx+2)=val_zmat(I,3)
411 1 equemene
        !               Idx=Idx+3
412 1 equemene
        !            END DO
413 1 equemene
        !            SELECT CASE (NCART)
414 1 equemene
        !            CASE (1)
415 1 equemene
        !               IntCoordI(1,Idx)=val_zmat(2,1)
416 1 equemene
        !               IntCoordI(1,Idx+1)=val_zmat(3,1)
417 1 equemene
        !               IntCoordI(1,Idx+2)=val_zmat(3,2)*Pi/180.
418 1 equemene
        !               Idx=Idx+3
419 1 equemene
        !               IBeg=4
420 1 equemene
        !            CASE (2)
421 1 equemene
        !               IntCoordI(1,Idx)=val_zmat(3,1)
422 1 equemene
        !               IntCoordI(1,Idx+1)=val_zmat(3,2)*Pi/180.
423 1 equemene
        !               Idx=Idx+2
424 1 equemene
        !               IBeg=4
425 1 equemene
        !            CASE DEFAULT
426 1 equemene
        !               IBeg=NCart+1
427 1 equemene
        !            END SELECT
428 1 equemene
        !            DO i=iBeg,Nat
429 1 equemene
        !               IntCoordI(1,Idx)=val_zmat(i,1)
430 1 equemene
        !               Idx=Idx+1
431 1 equemene
        !               DO j=2,3
432 1 equemene
        !                  IntCoordI(1,Idx)=val_zmat(i,j)*Pi/180.
433 1 equemene
        !                  Idx=Idx+1
434 1 equemene
        !               END DO
435 1 equemene
        !            END DO
436 1 equemene
437 1 equemene
        !            If (debug) WRITE(*,*) "Idx, NCoord",Idx-1,NCoord
438 1 equemene
439 1 equemene
        DO Igeom=1,NgeomI
440 1 equemene
           x(1:Nat) = XyzGeomI(IGeom,1,1:Nat)
441 1 equemene
           y(1:Nat) = XyzGeomI(IGeom,2,1:Nat)
442 1 equemene
           z(1:Nat) = XyzGeomI(IGeom,3,1:Nat)
443 1 equemene
444 1 equemene
           Call ConvXyzMixed(Nat,Ncart,x,y,z,IndZmat0,val_zmatTmp(1,1))
445 1 equemene
           Idx=1
446 1 equemene
           DO I=1,NCart
447 1 equemene
              IntCoordI(IGeom,Idx)=val_zmatTmp(I,1)
448 1 equemene
              IntCoordI(IGeom,Idx+1)=val_zmatTmp(I,2)
449 1 equemene
              IntCoordI(IGeom,Idx+2)=val_zmatTmp(I,3)
450 1 equemene
              Idx=Idx+3
451 1 equemene
           END DO
452 1 equemene
453 1 equemene
           SELECT CASE (NCART)
454 1 equemene
           CASE (1)
455 1 equemene
              IntCoordI(IGeom,Idx)=val_zmatTmp(2,1)
456 1 equemene
              Idx=Idx+1
457 1 equemene
              IntCoordI(IGeom,Idx)=val_zmatTmp(3,1)
458 1 equemene
              IntCoordI(IGeom,Idx+1)=val_zmatTmp(3,2)*Pi/180.
459 1 equemene
              Idx=Idx+2
460 1 equemene
              IBeg=4
461 1 equemene
           CASE (2)
462 1 equemene
              IntCoordI(IGeom,Idx)=val_zmatTmp(3,1)
463 1 equemene
              IntCoordI(IGeom,Idx+1)=val_zmatTmp(3,2)*Pi/180.
464 1 equemene
              Idx=Idx+2
465 1 equemene
              IBeg=4
466 1 equemene
           CASE DEFAULT
467 1 equemene
              Ibeg=Ncart+1
468 1 equemene
           END SELECT
469 1 equemene
           DO i=IBeg,Nat
470 1 equemene
              IntCoordI(IGeom,Idx)=val_zmatTmp(i,1)
471 1 equemene
              Idx=Idx+1
472 1 equemene
              IntCoordI(IGeom,Idx)=val_zmatTmp(i,2)*Pi/180.
473 1 equemene
              Idx=Idx+1
474 1 equemene
475 1 equemene
              ! Some tests to check that the dihedral angles are similar... this is
476 1 equemene
              ! important if they are close to Pi.
477 1 equemene
              Delta=0.
478 1 equemene
479 1 equemene
              if (abs(val_zmatTMP(i,3)-val_zmat(i,3))>=180.) THEN
480 1 equemene
                 if ((val_zmatTMP(i,3)-val_zmat(i,3))<=-180.) THEN
481 1 equemene
                    Delta=-1.0d0*TwoPi
482 1 equemene
                 ELSE
483 1 equemene
                    Delta=TwoPi
484 1 equemene
                 END IF
485 1 equemene
                 if (debug) THEN
486 1 equemene
                    WRITE(*,*) Nom(atome(i)), &
487 1 equemene
                         abs(val_zmatTMP(i,3)-val_zmat(i,3)), &
488 1 equemene
                         val_zmatTMP(i,3),val_zmat(i,3),Delta, &
489 1 equemene
                         val_zmatTMP(i,3)-Delta
490 1 equemene
                 END IF
491 1 equemene
              END IF
492 1 equemene
              IntCoordI(IGeom,Idx)=(val_zmatTmp(i,3)-Delta)/180.*Pi
493 1 equemene
              Idx=Idx+1
494 1 equemene
           END DO
495 1 equemene
496 1 equemene
        END DO
497 1 equemene
     CASE ('CART')
498 1 equemene
        DO I=1,Nat
499 1 equemene
           Order(I)=I
500 1 equemene
           OrderInv(I)=I
501 1 equemene
        END DO
502 1 equemene
        X0=X
503 1 equemene
        Y0=y
504 1 equemene
        Z0=z
505 1 equemene
     END SELECT
506 1 equemene
507 1 equemene
  ELSE ! First iteration of the optimization. Match at L616
508 1 equemene
509 1 equemene
     IGeom=1
510 1 equemene
     x(1:Nat) = XyzGeomI(IGeom,1,1:Nat)
511 1 equemene
     y(1:Nat) = XyzGeomI(IGeom,2,1:Nat)
512 1 equemene
     z(1:Nat) = XyzGeomI(IGeom,3,1:Nat)
513 1 equemene
514 1 equemene
     SELECT CASE (COORD)
515 1 equemene
     CASE ('HYBRID')
516 1 equemene
        IndZmat0=IndZmat
517 1 equemene
        Call ConvXyzZmat(Nat,x,y,z,IndZmat,val_zmat(1,1))
518 1 equemene
     CASE ('ZMAT')
519 1 equemene
        IndZmat0=IndZmat
520 1 equemene
        val_zmat=0.d0
521 1 equemene
        val_zmat(2,1)=IntCoordI(1,1)
522 1 equemene
        val_zmat(3,1)=IntCoordI(1,2)
523 1 equemene
        val_zmat(3,2)=IntCoordI(1,3)*180./Pi
524 1 equemene
525 1 equemene
        Idx=4
526 1 equemene
        DO iat=4,Nat
527 1 equemene
           val_zmat(iat,1)=IntCoordI(1,idx)
528 1 equemene
           Idx=Idx+1
529 1 equemene
           do j=2,3
530 1 equemene
              val_zmat(iat,J)=IntCoordI(1,idx)*180./Pi
531 1 equemene
              Idx=Idx+1
532 1 equemene
           END DO
533 1 equemene
        END DO
534 1 equemene
535 1 equemene
     CASE ('MIXED')
536 1 equemene
        IndZmat0=IndZmat
537 1 equemene
        val_zmat=0.d0
538 1 equemene
        Idx=1
539 1 equemene
        DO I=1,NCart
540 1 equemene
           DO J=1,3
541 1 equemene
              val_zmat(i,j)= IntCoordI(1,Idx)
542 1 equemene
              Idx=Idx+1
543 1 equemene
           END DO
544 1 equemene
        END DO
545 1 equemene
        SELECT CASE (NCart)
546 1 equemene
        CASE(1)
547 1 equemene
           val_zmat(2,1)=IntCoordI(1,Idx)
548 1 equemene
           val_zmat(3,1)=IntCoordI(1,Idx+1)
549 1 equemene
           val_zmat(3,2)=IntCoordI(1,Idx+2)*180./Pi
550 1 equemene
           Idx=Idx+3
551 1 equemene
           IBeg=4
552 1 equemene
        CASE(2)
553 1 equemene
           val_zmat(3,1)=IntCoordI(1,Idx)
554 1 equemene
           val_zmat(3,2)=IntCoordI(1,Idx)*180./Pi
555 1 equemene
           Idx=Idx+2
556 1 equemene
           IBeg=4
557 1 equemene
        CASE DEFAULT
558 1 equemene
           IBeg=NCart+1
559 1 equemene
        END SELECT
560 1 equemene
561 1 equemene
        DO Iat=IBeg,Nat
562 1 equemene
           val_zmat(iat,1)=IntCoordI(1,idx)
563 1 equemene
           Idx=Idx+1
564 1 equemene
           do j=2,3
565 1 equemene
              val_zmat(iat,J)=IntCoordI(1,idx)*180./Pi
566 1 equemene
              Idx=Idx+1
567 1 equemene
           END DO
568 1 equemene
        END DO
569 1 equemene
     CASE ('BAKER')
570 1 equemene
        ! Nothing to be done here.
571 1 equemene
     CASE ('CART')
572 1 equemene
        ! Nothing to be done here.
573 1 equemene
     CASE DEFAULT
574 1 equemene
        WRITE(*,*) "Coord=",TRIM(COORD)," not recognized in PathCreate.L554.STOP"
575 1 equemene
        STOP
576 1 equemene
     END SELECT
577 1 equemene
     X0=x
578 1 equemene
     y0=y
579 1 equemene
     z0=z
580 1 equemene
  END IF  ! First
581 1 equemene
582 1 equemene
  ! Now that we have a zmat, we will generate all the IntCoodI corresponding...
583 1 equemene
  ! First one
584 1 equemene
  IF (COORD.EQ.'HYBRID') THEN     ! Matches at L680
585 1 equemene
     DO IGeom=1,NGeomI
586 1 equemene
        x(1:Nat) = XyzGeomI(IGeom,1,1:Nat)
587 1 equemene
        y(1:Nat) = XyzGeomI(IGeom,2,1:Nat)
588 1 equemene
        z(1:Nat) = XyzGeomI(IGeom,3,1:Nat)
589 1 equemene
590 1 equemene
        Call ConvXyzZmat(Nat,x,y,z,IndZmat0,val_zmatTmp(1,1))
591 1 equemene
        IntCoordI(IGeom,1)=val_zmatTmp(2,1)
592 1 equemene
        IntCoordI(IGeom,2)=val_zmatTmp(3,1)
593 1 equemene
        IntCoordI(IGeom,3)=val_zmatTmp(3,2)*Pi/180.
594 1 equemene
        Idx=4
595 1 equemene
        DO i=4,nat
596 1 equemene
           IntCoordI(IGeom,Idx)=val_zmatTmp(i,1)
597 1 equemene
           Idx=Idx+1
598 1 equemene
           IntCoordI(IGeom,Idx)=val_zmatTmp(i,2)*Pi/180.
599 1 equemene
           Idx=Idx+1
600 1 equemene
601 1 equemene
           ! Some tests to check that the dihedral angles are similar... this is
602 1 equemene
           ! important if they are close to Pi.
603 1 equemene
           Delta=0.
604 1 equemene
605 1 equemene
           if (abs(val_zmatTMP(i,3)-val_zmat(i,3))>=180.) THEN
606 1 equemene
              if ((val_zmatTMP(i,3)-val_zmat(i,3))<=-180.) THEN
607 1 equemene
                 Delta=-1.0d0*TwoPi
608 1 equemene
              ELSE
609 1 equemene
                 Delta=TwoPi
610 1 equemene
              END IF
611 1 equemene
              if (debug) THEN
612 1 equemene
                 WRITE(*,*) Nom(atome(i)), &
613 1 equemene
                      abs(val_zmatTMP(i,3)-val_zmat(i,3)), &
614 1 equemene
                      val_zmatTMP(i,3),val_zmat(i,3),Delta, &
615 1 equemene
                      val_zmatTMP(i,3)-Delta
616 1 equemene
              END IF
617 1 equemene
           END IF
618 1 equemene
           IntCoordI(IGeom,Idx)=(val_zmatTmp(i,3)-Delta)/180.*Pi
619 1 equemene
           Idx=Idx+1
620 1 equemene
        END DO
621 1 equemene
     END DO
622 1 equemene
  END IF ! Matches Coord=Hybrid
623 1 equemene
624 1 equemene
  ! PFL 24 Nov 2008 ->
625 1 equemene
  ! This should not be necessary...
626 1 equemene
  !   ! if we have frozen atoms, we make sure that they do not move between geometries
627 1 equemene
  !   IF (IntFroz.NE.0) THEN
628 1 equemene
  !      if (debug) WRITE(*,*) 'DBG PathCreate L641: Number of frozen coordinates=', IntFroz
629 1 equemene
  !      DO IGeom=2,NGeomI ! For IOpt .GT. 0, NGeomI is equal to NGeomF
630 1 equemene
  !         IntCoordI(IGeom,1:IntFroz)=IntCoordI(1,1:IntFroz)
631 1 equemene
  !      END DO
632 1 equemene
  !   END IF
633 1 equemene
  ! -> PFL 24 Nov 2008
634 1 equemene
635 1 equemene
  Idx=min(9,NCoord)
636 1 equemene
637 1 equemene
  IF (DEBUG.AND.(COORD.NE.'CART')) THEN
638 1 equemene
     WRITE(*,*) "DBG PathCreate. L685 IntCoordI(IGeom,:)"
639 1 equemene
     DO I=1,NGeomI
640 1 equemene
        WRITE(*,'("Geom:",I5,9(1X,F10.4))') I,IntCoordI(I,1:Idx)
641 1 equemene
     END DO
642 1 equemene
     ! We write it also in terms of Zmat
643 1 equemene
     IF ((COORD.EQ.'ZMAT').OR.(COORD.EQ.'HYBRID')) THEN
644 1 equemene
        DO I=1,NGeomI
645 1 equemene
           WRITE(*,*) 'Zmat for geom ',I,'/',NGeomI,'Xgeom=',Xgeom(I)
646 1 equemene
           WRITE(*,'(1X,A5,3(1X,I5,1X,F11.6))') Nom(Atome(IndZmat0(1,1)))
647 1 equemene
           WRITE(*,'(1X,A5,3(1X,I5,1X,F11.6))') Nom(Atome(IndZmat0(2,1))), &
648 1 equemene
                IndZmat(2,2),IntCoordI(I,1)
649 1 equemene
           WRITE(*,'(1X,A5,3(1X,I5,1X,F11.6))') Nom(Atome(IndZmat0(3,1))), &
650 1 equemene
                IndZmat(3,2),IntCoordI(I,2),IndZmat(3,3),IntCoordI(I,3)*180./Pi
651 1 equemene
           Idx=4
652 1 equemene
           DO J=4,Nat
653 1 equemene
              WRITE(*,'(1X,A5,3(1X,I5,1X,F11.6))') Nom(Atome(IndZmat0(J,1))), &
654 1 equemene
                   IndZmat(J,2),IntCoordI(I,Idx),IndZmat(J,3),          &
655 1 equemene
                   IntCoordI(I,Idx+1)*180./Pi, &
656 1 equemene
                   IndZmat(J,4),IntCoordI(I,Idx+2)*180./Pi
657 1 equemene
              Idx=Idx+3
658 1 equemene
           END DO
659 1 equemene
660 1 equemene
           XyzTmp2=0.
661 1 equemene
           ! We convert it into Cartesian coordinates
662 1 equemene
           XyzTmp2(2,1)=IntCoordI(I,1)
663 1 equemene
           d=IntCoordI(I,2)
664 1 equemene
           a_val=IntCoordI(I,3)
665 1 equemene
           if (Nat.GE.3) THEN
666 1 equemene
              if (IndZmat(3,2).EQ.1)  THEN
667 1 equemene
                 XyzTmp2(3,1)=XYzTmp2(1,1)+d*cos(a_val)
668 1 equemene
              ELSE
669 1 equemene
                 XyzTmp2(3,1)=XyzTmp2(2,1)-d*cos(a_val)
670 1 equemene
              ENDIF
671 1 equemene
              XyzTmp2(3,2)=d*sin(a_val)
672 1 equemene
           ENDIF
673 1 equemene
674 1 equemene
           Idx=4
675 1 equemene
           DO iat=4,Nat
676 1 equemene
              val_zmatTMP(iat,1)=IntCoordI(I,idx)
677 1 equemene
              Idx=Idx+1
678 1 equemene
              DO j=2,3
679 1 equemene
                 val_zmatTMP(iat,J)=IntCoordI(I,idx)*180./Pi
680 1 equemene
                 Idx=Idx+1
681 1 equemene
              END DO
682 1 equemene
           END DO
683 1 equemene
           DO iat=4,Nat
684 1 equemene
              call ConvertZmat_cart(iat,IndZmat,val_zmatTMP, &
685 1 equemene
                   XYzTMP2(1,1), XYzTMP2(1,2),XYzTMP2(1,3))
686 1 equemene
           END DO
687 1 equemene
           DO Iat=1,nat
688 1 equemene
              WRITE(*,'(1X,A5,3(1X,F11.6))') Nom(Atome(IndZmat0(Iat,1))),&
689 1 equemene
                   XyzTmp2(iat,1:3)
690 1 equemene
           END DO
691 1 equemene
692 1 equemene
        END DO
693 1 equemene
     END IF
694 1 equemene
     IF (COORD.EQ.'MIXED') THEN
695 1 equemene
        DO I=1,NGeomI
696 1 equemene
           WRITE(*,*) 'Cart+Zmat for geom ',I,'/',NGeomI,'Xgeom=',Xgeom(I)
697 1 equemene
           Idx=1
698 1 equemene
           XyzTmp2=0.
699 1 equemene
           DO J=1,NCART
700 1 equemene
              WRITE(*,'(1X,A5,3(1X,F11.6))') Nom(Atome(IndZmat0(1,1))), &
701 1 equemene
                   IntCoordI(I,Idx:Idx+2)
702 1 equemene
              XyzTmp2(J,1:3)=IntCoordI(I,Idx:Idx+2)
703 1 equemene
              Idx=Idx+3
704 1 equemene
           END DO
705 1 equemene
           SELECT CASE (NCart)
706 1 equemene
           CASE (1)
707 1 equemene
              J=2
708 1 equemene
              WRITE(*,'(1X,A5,3(I5,F11.6))') Nom(Atome(IndZmat0(J,1))), &
709 1 equemene
                   IndZmat(J,2),IntCoordI(I,Idx)
710 1 equemene
              Idx=Idx+1
711 1 equemene
              J=3
712 1 equemene
              WRITE(*,'(1X,A5,3(I5,F11.6))') Nom(Atome(IndZmat0(J,1))), &
713 1 equemene
                   IndZmat(J,2),IntCoordI(I,Idx),IndZmat(J,3), &
714 1 equemene
                   IntCoordI(I,Idx+1)*180./Pi
715 1 equemene
              Idx=Idx+2
716 1 equemene
              Ibeg=4
717 1 equemene
           CASE (2)
718 1 equemene
              J=3
719 1 equemene
              WRITE(*,'(1X,A5,3(I5,F11.6))') Nom(Atome(IndZmat0(J,1))), &
720 1 equemene
                   IndZmat(J,2),IntCoordI(I,Idx),IndZmat(J,3), &
721 1 equemene
                   IntCoordI(I,Idx+1)*180./Pi
722 1 equemene
              Idx=Idx+2
723 1 equemene
              Ibeg=4
724 1 equemene
           CASE DEFAULT
725 1 equemene
              IBeg=NCart+1
726 1 equemene
           END SELECT
727 1 equemene
           DO J=IBeg,Nat
728 1 equemene
              IF (J.EQ.2) &
729 1 equemene
                   WRITE(*,'(1X,A5,3(I5,F11.6))') Nom(Atome(IndZmat0(J,1))), &
730 1 equemene
                   IndZmat(J,2),IntCoordI(I,Idx),IndZmat(J,3), &
731 1 equemene
                   IntCoordI(I,Idx+1)*180./Pi, &
732 1 equemene
                   IndZmat(J,4),IntCoordI(I,Idx+2)*180./Pi
733 1 equemene
              Idx=Idx+3
734 1 equemene
           END DO
735 1 equemene
736 1 equemene
           ! We convert it into Cartesian coordinates
737 1 equemene
           IntCoordTmp=IntCoordI(I,1:NCoord)
738 1 equemene
           Call Mixed2cart(Nat,IndZmat,IntCoordTmp,XyzTmp2)
739 1 equemene
740 1 equemene
           DO Iat=1,nat
741 1 equemene
              WRITE(*,'(1X,A5,3(1X,F11.6))') Nom(Atome(IndZmat0(Iat,1))),&
742 1 equemene
                   XyzTmp2(iat,1:3)
743 1 equemene
           END DO
744 1 equemene
745 1 equemene
        END DO
746 1 equemene
     END IF
747 1 equemene
  END IF ! matches IF (DEBUG.AND.(COORD.NE.'CART')) THEN
748 1 equemene
749 1 equemene
  if (debug) WRITE(*,*) "Before interpolation, PathCreate.f90, L740, IOpt=",IOpt, &
750 1 equemene
       "ISpline=", ISpline
751 1 equemene
  ! Now comes the Interpolation:
752 1 equemene
  IF ((NGeomI>2).AND.(IOpt.GE.ISpline)) THEN
753 1 equemene
     Linear=.FALSE.
754 1 equemene
     ! We have at least three geometries so we can apply cubic spline
755 1 equemene
     SELECT CASE (COORD)
756 1 equemene
     CASE ('ZMAT','HYBRID','MIXED')
757 1 equemene
        DO I=1,NCoord
758 1 equemene
           ! We compute the spline coefficients
759 1 equemene
           call spline(xGeom,IntCoordI(1,I),NGeomI,Inf,Inf, Coef(1,I))
760 1 equemene
           if (debug) THEN
761 1 equemene
              WRITE(*,*) 'Coef Spline for coord',I
762 1 equemene
              WRITE(*,*) Coef(1:NGeomI,I)
763 1 equemene
           END IF
764 1 equemene
        END DO
765 1 equemene
     CASE ('BAKER')
766 1 equemene
        ! We compute the spline coefficients
767 1 equemene
        ! xGeom(NGeomI), IntCoordI(NGeomI,3*Nat-6) declared in Path_module.f90
768 1 equemene
        ! can also be used for the Baker's internal coordinates.
769 1 equemene
        ! we need to get Baker's internal coordinates from cartesian coordinates.
770 1 equemene
        ! as we have subroutine ConvXyzmat(...) in Z matrix case.
771 1 equemene
        ! Coef(NGeomI,NCoord) or (NGeomI,N3at) has INTENT(OUT)
772 1 equemene
        DO I=1,NCoord ! NCoord=3*Nat-6-symmetry_eliminated.
773 1 equemene
           call spline(xGeom,IntCoordI(1,I),NGeomI,Inf,Inf,Coef(1,I))
774 1 equemene
           ! IF (debug) THEN
775 1 equemene
           !   WRITE(*,*) 'Coef Spline for coord',I
776 1 equemene
           !  WRITE(*,*) Coef(1:NGeomI,I)
777 1 equemene
           !    END IF
778 1 equemene
        END DO
779 1 equemene
     CASE ('CART')
780 1 equemene
        DO I=1,Nat
781 1 equemene
           ! We compute the spline coefficients
782 1 equemene
           call spline(xGeom,XyzGeomI(1,1,I),NGeomI,Inf,Inf, Coef(1,3*I-2))
783 1 equemene
           call spline(xGeom,XyzGeomI(1,2,I),NGeomI,Inf,Inf, Coef(1,3*I-1))
784 1 equemene
           call spline(xGeom,XyzGeomI(1,3,I),NGeomI,Inf,Inf, Coef(1,3*I))
785 1 equemene
           if (debug) THEN
786 1 equemene
              WRITE(*,*) 'Coef Spline for coord',i
787 1 equemene
              WRITE(*,*) Coef(1:NGeomI,I)
788 1 equemene
           END IF
789 1 equemene
        END DO
790 1 equemene
     CASE DEFAULT
791 1 equemene
        WRITE(*,*) "Coord=",TRIM(COORD)," not recognized in PathCreate.L783.STOP"
792 1 equemene
        STOP
793 1 equemene
     END SELECT
794 1 equemene
  ELSE ! matches IF ((NGeomI>2).AND.(Iopt.Ge.ISpline)) THEN
795 1 equemene
     ! On n'a que deux images. On fera une interpolation lineaire,
796 1 equemene
     ! qui est un cas particulier avec Coef=0
797 1 equemene
     if (debug.AND.(NGeomI.EQ.2)) WRITE(*,*) "DBG : Only 2 starting geometries"
798 1 equemene
     if (debug.AND.(Iopt.LE.ISpline)) WRITE(*,*) "DBG : Not enough path -> linear int"
799 1 equemene
     Coef=0.d0
800 1 equemene
     Linear=.TRUE.
801 1 equemene
  END IF ! matches IF ((NGeomI>2).AND.(Iopt.Ge.ISpline)) THEN
802 1 equemene
  ! Shall we redistribute the points along the path ?
803 1 equemene
  if (debug) WRITE(*,*) "PathCreate.f90, L795, IOpt=", IOpt, "IReparam=", IReparam
804 1 equemene
  IF (MOD(IOpt,IReparam).EQ.0) THEN
805 1 equemene
806 1 equemene
     ! We generate the Path, in two steps:
807 1 equemene
     ! i) we calculate the length of the mass weighted (MW) path
808 1 equemene
     ! ii) we sample the path to get the geometries
809 1 equemene
810 1 equemene
     NGeomS=NGeomI
811 1 equemene
     SELECT CASE (COORD)
812 1 equemene
     CASE ('ZMAT','HYBRID')
813 1 equemene
        ! We call the extrapolation once to get the path length
814 1 equemene
        dist=Inf
815 1 equemene
        Call ExtraPol_int(IOpt,s,dist,x0,y0,z0,xgeom,Coef,XgeomF)
816 1 equemene
        ! we have the length, we calculate the distance between two points
817 1 equemene
818 1 equemene
        if (s.LE.1e-6) THEN
819 1 equemene
           IF (OptGeom.LE.0) THEN
820 1 equemene
              WRITE(*,*) "Length of the path is 0 and you are not doing Geometry Optimization."
821 1 equemene
              WRITE(*,*) "ERROR !!! Stop !"
822 1 equemene
              STOP
823 1 equemene
           END IF
824 1 equemene
        ELSE
825 1 equemene
           ! we have the length, we calculate the distance between two points
826 1 equemene
           dist=s/Real(NGeomf-1)
827 1 equemene
           if (debug) WRITE(*,*) 'Dbg PathCreate ZMAT s, dist:',s,dist
828 1 equemene
           ! we call it again to obtain the geometries !
829 1 equemene
           Call ExtraPol_int(iopt,s,dist,x0,y0,z0,xgeom,Coef,XgeomF)
830 1 equemene
        END IF
831 1 equemene
     CASE ('BAKER')
832 1 equemene
        ! We generate the Path, in two steps:
833 1 equemene
        ! i) we calculate the length of the mass weighted (MW) path
834 1 equemene
        ! ii) we sample the path to get the geometries
835 1 equemene
836 1 equemene
        ! We call the extrapolation first time to get the path length
837 1 equemene
        ! iopt: Number of the cycles for the optimization.
838 1 equemene
        ! s: a real number and has INTENT(OUT), probably returns the
839 1 equemene
        ! length of the path.
840 1 equemene
        ! dist=Inf=> ExtraPol_baker has to calculate the length of the path.
841 1 equemene
        ! X0(Nat),Y0(Nat),Z0(Nat): reference geometry.
842 1 equemene
        ! Xgeom: Xgeom(NGeomI) has INTENT(IN)
843 1 equemene
        ! Coef(NGeomI,NCoord) is obtained from spline interpolation subroutine.
844 1 equemene
        ! XgeomF: XGeomF(NGeomF) has INTENT(OUT)
845 1 equemene
        ! Which reference coordinate geometry X0, Y0, Z0 to use???
846 1 equemene
        dist=Inf
847 1 equemene
        !if (debug) WRITE(*,*) "Before the call of ExtraPol_baker in redistribution &
848 1 equemene
        !of the points, in PathCreate.f90, L836"
849 1 equemene
        !Print *, 'Before ExtraPol_baker, PathCreate.90, L848, IntCoordI='
850 1 equemene
        !Print *, IntCoordI
851 1 equemene
        Call ExtraPol_baker(s,dist,x0,y0,z0,xgeom,Coef,XgeomF)
852 1 equemene
        !Print *, 'After ExtraPol_baker, PathCreate.90, L848, IntCoordI='
853 1 equemene
        !Print *, IntCoordI
854 1 equemene
        !if (debug) WRITE(*,*) "After the call of ExtraPol_baker in the redistribution &
855 1 equemene
        ! of the points, in PathCreate.f90, L843"
856 1 equemene
857 1 equemene
        ! we have the lenght, we calculate the distance between two points
858 1 equemene
        !Print *, 'After first call of ExtraPol_baker in PathCreate.f90, s=', s
859 1 equemene
860 1 equemene
        if (s.LE.1e-6) THEN
861 1 equemene
           IF (OptGeom.LE.0) THEN
862 1 equemene
              WRITE(*,*) "Length of the path is 0 and you are not doing Geometry Optimization."
863 1 equemene
              WRITE(*,*) "ERROR !!! Stop !"
864 1 equemene
              STOP
865 1 equemene
           END IF
866 1 equemene
        ELSE
867 1 equemene
868 1 equemene
           dist=s/Real(NGeomf-1)
869 1 equemene
           !if (debug) WRITE(*,*) 'Dbg PathCreate ZMAT s, dist:',s,dist
870 1 equemene
871 1 equemene
           ! we call it again to obtain the geometries !
872 1 equemene
           Call ExtraPol_baker(s,dist,x0,y0,z0,xgeom,Coef,XgeomF)
873 1 equemene
           WRITE(*,*) "At the end of Baker case in the redistribution of the points, in PathCreate.f90, L966"
874 1 equemene
        END IF
875 1 equemene
876 1 equemene
        DO IGeom=1,NGeomF
877 1 equemene
           WRITE(*,*) "UMatF for IGeom=",IGeom
878 1 equemene
           DO I=1,3*Nat-6
879 1 equemene
              WRITE(*,'(50(1X,F12.8))') UMatF(IGeom,:,I)
880 1 equemene
           END DO
881 1 equemene
        END DO
882 1 equemene
883 1 equemene
     CASE ('MIXED')
884 1 equemene
        !           WRITE(*,*) "IOIOIOIOIOIOIOI"
885 1 equemene
        ! We call the extrapolation once to get the path length
886 1 equemene
        Dist=Inf
887 1 equemene
        Call ExtraPol_Mixed(s,dist,x0,y0,z0,xgeom,Coef)
888 1 equemene
889 1 equemene
        if (s.LE.1e-6) THEN
890 1 equemene
           IF (OptGeom.LE.0) THEN
891 1 equemene
              WRITE(*,*) "Length of the path is 0 and you are not doing Geometry Optimization."
892 1 equemene
              WRITE(*,*) "ERROR !!! Stop !"
893 1 equemene
              STOP
894 1 equemene
           END IF
895 1 equemene
        ELSE
896 1 equemene
897 1 equemene
           ! we have the length, we calculate the distance between two points
898 1 equemene
           dist=s/Real(NGeomf-1)
899 1 equemene
           if (debug) WRITE(*,*) 'Dbg PathCreate Mixed s, dist:',s,dist
900 1 equemene
901 1 equemene
           ! we call it again to obtain the geometries !
902 1 equemene
           Call ExtraPol_Mixed(s,dist,x0,y0,z0,xgeom,Coef)
903 1 equemene
904 1 equemene
           IF (debug) THEN
905 1 equemene
              DO I=1,NGeomF
906 1 equemene
                 WRITE(*,'(1X,A,12(1X,F10.5))') "IntTangent:",IntTangent(I,1:NCoord)
907 1 equemene
              END DO
908 1 equemene
           END IF
909 1 equemene
        END IF
910 1 equemene
     CASE ('CART')
911 1 equemene
        ! We call the extrapolation once to get the path length
912 1 equemene
        Dist=Inf
913 1 equemene
        Call ExtraPol_cart(iopt,s,dist,x0,y0,z0,xgeom,Coef)
914 1 equemene
915 1 equemene
        if (s.LE.1e-6) THEN
916 1 equemene
           IF (OptGeom.LE.0) THEN
917 1 equemene
              WRITE(*,*) "Length of the path is 0 and you are not doing Geometry Optimization."
918 1 equemene
              WRITE(*,*) "ERROR !!! Stop !"
919 1 equemene
              STOP
920 1 equemene
           END IF
921 1 equemene
        ELSE
922 1 equemene
           ! we have the lenght, we calculate the distance between two points
923 1 equemene
           dist=s/Real(NGeomf-1)
924 1 equemene
           if (debug) WRITE(*,*) 'Debug s, dist:',s,dist
925 1 equemene
926 1 equemene
           ! we call it again to obtain the geometries !
927 1 equemene
           Call ExtraPol_cart(iopt,s,dist,x0,y0,z0,xgeom,Coef)
928 1 equemene
        END IF
929 1 equemene
     END SELECT
930 1 equemene
  ELSE
931 1 equemene
     ! PFL 3 Jan 2008 ->
932 1 equemene
     ! Tangents are not recalculated if the points are not reparameterized
933 1 equemene
     ! PFL 6 Apr 2008 ->
934 1 equemene
     ! Unless user has asked to reparameterized them !
935 1 equemene
     IF (mod(Iopt,iReparamT).EQ.0) THEN
936 1 equemene
        XGeomF=XGeom
937 1 equemene
        NGeomS=NGeomI
938 1 equemene
        Call CalcTangent(XgeomF,NGeomS,xgeom,Coef)
939 1 equemene
        !
940 1 equemene
     END IF
941 1 equemene
     ! <- PFL 3 Jan 2008 / 6 Apr 2008
942 1 equemene
  END IF ! if (mod(Iop,iReparam).EQ.0)
943 1 equemene
  if (debug) WRITE(*,*) "PathCreate.f90, L885"
944 1 equemene
945 1 equemene
  ! PFL 22.Nov.2007 ->
946 1 equemene
  ! We do not write tangents for baker coordinates because they are hard to
947 1 equemene
  ! interpret for a chemist.
948 1 equemene
949 1 equemene
  IF (debug.AND.(COORD.NE."BAKER")) THEN
950 1 equemene
     ! we write the tangents :-)
951 1 equemene
     DO I=1,NGeomF
952 1 equemene
        SELECT CASE(Coord)
953 1 equemene
        CASE ('ZMAT','MIXED')
954 1 equemene
           IntCoordTmp=IntTangent(I,:)
955 1 equemene
           WRITE(*,'(1X,A,12(1X,F10.5))') "IntCoordTmp:",IntCoordTmp(1:NCoord)
956 1 equemene
           WRITE(*,'(1X,A,12(1X,F10.5))') "IntTangent:",IntTangent(I,1:NCoord)
957 1 equemene
        CASE ('CART','HYBRID')
958 1 equemene
           IntCoordTmp=XyzTangent(I,:)
959 1 equemene
        CASE DEFAULT
960 1 equemene
           WRITE(*,*) "Coord=",TRIM(COORD)," not recognized in PathCreate. STOP"
961 1 equemene
           STOP
962 1 equemene
        END SELECT
963 1 equemene
        WRITE(Title,"('Tangents for geometry ',I3,'/',I3,' for iteration ',I3)") I,NgeomF
964 1 equemene
        Call PrintGeom(Title,Nat,Ncoord,IntCoordTmp,Coord,6,Atome,Order,OrderInv,IndZmat)
965 1 equemene
     END DO
966 1 equemene
  END IF
967 1 equemene
968 1 equemene
969 1 equemene
  IF (DEBUG.AND.(COORD.NE.'CART')) THEN
970 1 equemene
     Idx=min(12,NCoord)
971 1 equemene
     WRITE(*,*) "DBG PathCreate. IntCoordF(IGeom,:)"
972 1 equemene
     DO I=1,NGeomF
973 1 equemene
        WRITE(*,'("Geom:",I5,12(1X,F10.4))') I,IntCoordF(I,1:Idx)
974 1 equemene
     END DO
975 1 equemene
  END IF
976 1 equemene
977 1 equemene
  DEALLOCATE(Coef,val_zmat,val_zmatTMP)
978 1 equemene
  DEALLOCATE(X0,Y0,Z0,Indzmat0)
979 1 equemene
  DEALLOCATE(X,Y,Z,Xgeom,XgeomF)
980 1 equemene
  DEALLOCATE(XyzTmp,XyzTmp2)
981 1 equemene
982 1 equemene
  if (debug) Call header("PathCreate over")
983 1 equemene
984 1 equemene
END SUBROUTINE PathCreate