Statistiques
| Révision :

root / src / Path.f90

Historique | Voir | Annoter | Télécharger (93,01 ko)

1
! This programs generates and optimizes a reaction path
2
! between at least two endpoints.
3

    
4
!----------------------------------------------------------------------
5
!  Copyright 2003-2014 Ecole Normale Supérieure de Lyon, 
6
!  Centre National de la Recherche Scientifique,
7
!  Université Claude Bernard Lyon 1. All rights reserved.
8
!
9
!  This work is registered with the Agency for the Protection of Programs 
10
!  as IDDN.FR.001.100009.000.S.P.2014.000.30625
11
!
12
!  Authors: P. Fleurat-Lessard, P. Dayal
13
!  Contact: optnpath@gmail.com
14
!
15
! This file is part of "Opt'n Path".
16
!
17
!  "Opt'n Path" is free software: you can redistribute it and/or modify
18
!  it under the terms of the GNU Affero General Public License as
19
!  published by the Free Software Foundation, either version 3 of the License,
20
!  or (at your option) any later version.
21
!
22
!  "Opt'n Path" is distributed in the hope that it will be useful,
23
!  but WITHOUT ANY WARRANTY; without even the implied warranty of
24
!
25
!  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
26
!  GNU Affero General Public License for more details.
27
!
28
!  You should have received a copy of the GNU Affero General Public License
29
!  along with "Opt'n Path". If not, see <http://www.gnu.org/licenses/>.
30
!
31
! Contact The Office of Technology Licensing, valorisation@ens-lyon.fr,
32
! for commercial licensing opportunities.
33
!----------------------------------------------------------------------
34

    
35

    
36
!
37
! It uses NAMELIST for input, see below !
38
!
39
! v3.0
40
! First version entirely in Fortran.
41
! It uses routines from Cart (path creation and parameterisation) 
42
! and from IRC06, especially routines for point optimization.
43
!
44
! TO DO:
45
! 1) Possibility to read and/or calculate some hessian structures
46
! 2) Use of internal coordinate to estimate the hessian for stable
47
! species in a much better way...
48
!
49
!!!!!!!!!!!!!!!
50
! v3.1
51
! The Hessian update includes neighbour points.
52
!
53
! v3.2
54
! We add the option Hinv that uses the BFGS update of the Hessian inverse
55
!
56
! v3.3
57
! We add the full option for ZMAT coordinates, where all is done using
58
! internal coordinates.
59
! v3.31
60
! The step size is controlled using the step norm and not the maximum step
61
! component.
62
! v3.5
63
! Big modifications of Calc_zmat_const_frag in order to be able
64
! to treat VASP geometries. 
65
! For now, only XYZ geometries are read and written. VASP interface
66
! has to be written.
67
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
68
! v3.6
69
! Some minor modif in Calc_zmat_const_frag to have nicer programming
70
! and a new mode added: Coord=MIXED where part of the system
71
! is extrapolated in cartesian coordinates and the rest of it in zmat.
72
! it might be Useful for VASP, or when lots of atoms are frozen
73
! by default, when Coord=MIXED, all frozen atoms are described in cartesian
74
! coordinates.
75
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
76
! v3.61
77
! We move further and further to VASP program. New variables added to the 'path' namelist:
78
! input: what is the program used for the geometries ?
79
!     Possible values: xyz (or cart) for Xmol format; VASP. Xyz should be used for Gaussian
80
! prog: what is the program used for the calculations ?
81
!     Possible values for now: gaussian, vasp.
82
! For now (02/2007), when prog='vasp' is used, only the initial path is created.
83
! That means that we have only added input/output subroutines :-)
84
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
85
! v3.7
86
! We try to improve the optimization steps. For that, we first modify many routines
87
! so that the new step is calculated in the 'free' degrees of freedom, as it is done
88
! in IRC07/ADF for example. That will allow us to impose constraints in an easier way.
89
!
90
! v3.701
91
! Add a new option for the initial extrapolation of the Hessian
92
!
93
!v3.71
94
! The optimization step has been improved... but the vfree part has not yet been included.
95
! This has still to be done :-)
96
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
97
! v3.8
98
! I have included part of the vfree procedure: for now freemv returns the Id
99
! matrix, that is used to project out the tangent vector.
100
! This improves the optimization a lot, but I will have to implement
101
! a real freemw subroutine to have constraints there !
102
! v3.81 Technical version
103
! I have added a new program 'Ext'. When this one is used, Path creates a Ext.in file,
104
! calls Ext.exe file to get a Ext.out file that contains the Energy and the gradient.
105
! Format:
106
! Ext.in : Xmol format. The second line (comment in Xmol) contains the COORD name.
107
! Ext.out: Energy on firt line (1X,D25.15), then gradient in CARTESIAN coordinates
108
!  (3(1X,D25.15)) format. Natoms lines. 
109
! TO DO:  Gradient could be given in COORD format, ie cartesian for COORD=CART, XYZ or HYBRID
110
! ZMAT for CORD=ZMAT (in that case, 6 zeros are there at the begining !)
111
! For MIXED, it is equivalent to CART :-)
112
! v3.811
113
! I have added a prog="TEST" option, where egradient calls egrad_test subroutine.
114
! It then calculates the energy and gradient as it wants and it returns the cartesian 
115
! gradient. The purpose is to have an analytical approximation of the PES of the system
116
! under study to gain some time in testing the program. This is not documented :-)
117
!
118
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
119
!  v3.9
120
! In order to be fully interfaced with VASP, I have to change the architecture
121
! of the program. In particular, with VASP, one can use a Para8+NEB routine
122
! of VASP to calculate energy+forces for all points of the path.
123
! v3.91
124
! One small modification: in the cart list, one can freeze a whole sequence by
125
! entering a negative number for the last atom of the sequence
126
! for example : cart=1 -160 165 -170 will define atoms from 1 to 160 and from
127
! 165 to 170 (included) as cartesian atoms.  
128
! Of course, Same applies to Frozen
129
! v3.92 / v3.93
130
! Slight modifications. One noticeable: when using Vasp, the program analyses the
131
! displacements to suggest which atoms could be described in CART.
132
! v3.94 
133
! VaspMode=Para now implemented. One needs to be careful in defining 'ProgExe'.
134
! In particular, one must put the mpirun command in ProgExe !!! There is NO test.
135
! v3.95
136
! When using internal coordinates (zmat, hybrid or mixes), Path calculates the number
137
! of fragments for each geometry. The reference one (ie the one used to compute the internal
138
! coordinates) is now the one with the least fragments.
139
! user can also choose one geometry by specifying IGeomRef in the Path namelist.
140
! v3.96
141
! I have added a test for the geometry step: it does not allow valence angle to 
142
! be negative or bigger than 180. I hope that this might help geometry optimization
143
! when dealing with nearly linear molecules.
144
! v3.961
145
! The options cart and frozen are now LOGICAL:
146
! Fcart=T indicates that a &cartlist namelist should be read !
147
! Ffrozen=T indicates that a &frozenlist namelist should be read !
148
! TO DO: Autocart=T indicates that the atoms described in cartesian coordiantes should
149
! be found automatically
150
! v3.97
151
! Baker has been implemented by P. Dayal: we are interpolating Xint for now.
152
! TO do: interpolate Umat ?
153
! -----
154
! v3.971
155
! AutoCart=T is being implemented. Goal: having a 'black box' version for Vasp users.
156
! Vmd: True if user wants to watch the path using VMD. Only used for VASP for now.
157
!------------
158
! v3.98
159
! Calc_zmat has been replaced by Calc_zmat_frag which is more robust.
160
! Still missing: linear molecules and some tests.
161
!
162
! v3.981
163
! * Added a non document flag in .valid file that switch on the numerical
164
! calculation of the hessian instead of the update.
165
! * Added HesUpd variable in the namelist. Default value is MS for path
166
!   optimization because it does not imposes a positive hessian, and BFGS
167
!  for geometry optimization
168
! v 4.0
169
! * This version has been made public within the CARTE project.
170
! * Added:
171
! - Step_method to choose the optimization method: RFO or Diis
172
! - DynMaxStep: if TRUE, the maximum size of a step is updated at each step. 
173
!             If energy goes up, Smax=Smax*0.8, if not Smax=Smax*1.2. 
174
!             It is ensured that the dynamical Smax is within [0.5*SMax_0,2*Smax_0]
175
!
176
!!!!!!!!!!!!!!!!!!!!!!
177
! v4.1
178
! * Para mode has been partly implemented for Gaussian.
179
!  VaspMode is thus now 'RunMode' and can be Serial or Para
180
! Only Gaussian and VASP are supported for Para mode now.
181
! v4.12 
182
! Some bugs in unconstrained zmat construction are corrected.
183
! v4.13
184
! Prakash has implemented the GEDIIS optimization procedure.
185
! v4.14
186
! There is a small problem for some inputs in VASP, where the
187
! last geometry is not the one given by the user. 
188
! It seems to come from the fact that some people try to freeze
189
! some unfrozen atoms
190
! So some tests have been added to check that frozen atoms do not move.
191
!!!
192
! v4.15
193
! There were some bugs when reading and expanding cartlist and frozenlist
194
! I have changed the way frozen atoms are compared by adding partial alignment.
195
! v4.16
196
! Some bugs were corrected.
197
! v4.17
198
! Added MOPAC as a program.
199
! v4.175
200
! Added Three more parameters for defining the input and output names for
201
! the calculations.
202
! CalcName: Prefix for the files used for the energy and gradient calculations
203
! ISuffix: Suffix for the input file
204
! OSuffix: suffix for the output file.
205
! This maters for Gaussian for example.
206
!
207
! v4.177 (P) 2010 Nov 22
208
! - We add TurboMole as a new external code.
209
! - Subtle change for Input: the default is XYZ whatever the code, except
210
! for VASP. 
211
!
212
! v4.178 (P) 2010 Nov 28
213
! - We add the possibility to call CHAMFRE reactive force field using 
214
! prog=TEST2 or CHAMFRE
215
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
216
! OpenPath v1.4  2011 May-June
217
! - Also added two flags: CalcEReac and CalcEProd. If .TRUE. Path will
218
! compute the energy of the reactant
219
! (and/or Product) at the begining of the calculations.
220
! This is useful if you start from non optimized points.
221
!
222
! - Also added more methods for Hessian updates. The following methods are
223
! now availables:
224
!   For inverse Hessian: BFGS, DFP, MS. 
225
!   For Hessian: BFGS, DFP, MS, Bofill
226
! 
227
! -Small change: HesUpd is replaced by Hupdate
228
!
229
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
230
! TO DO
231
! - Trying to improve the output of Path. In particular, we now create
232
! a .datl file containing the image index, curvilinear coordinate and energy
233
! in the spirit of the AnaPath tool.
234
! AnaPath is still usefull as it can extract geometrical parameters on top
235
! of the energy
236
! - When using Hessian update, it is more efficient to use Cholesky 
237
! decomposition, and to update this decomposition rather than the Hessian.
238
! See Nocedal&Wright p141.
239
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
240
!
241
! Project Name has changed to Opt'n Path
242
! OpenPaht 2011 May-June -> Opt'n Path v1.4 
243
!
244
! 2013 Jan 18 Opt'n Path v1.47 (going to 1.5 slowly)
245
! We add Siesta (and start thinking of add CP2K)
246
!  as a new "energy engine" code
247
! TO DO to go to 1.5: finish cleaning...
248
!
249
! 2013 Feb Opt'n Path v1.48
250
! We add some keyword for more output for Geometry Optimizations
251
! GeomFile: name of the file to print out the geometries and their energy
252
! as Xyz file. (only format for now)
253
!
254
! 2013 Feb opt'n Path v1.49
255
! We add the possibility to analyze the geometries in terms
256
! of Bonds, Angles, dihedrals
257
! with the option to add CenterOfMass atoms for the analysis (a la Xyz2Path)
258
! This is basicaly the merging of AnaPath into Opt'n Path... at last !
259
! This is done by adding a Flag into the Path namelist:
260
! AnaGeom: logical, if true Path looks for the AnaList namelist
261
! AnaList: list of variables, if present and if AnaGeom=T then Opt'n Path
262
! will read it and print the values of the variable in a Path.dat file
263
! If AnaGeom is T but Analist is not given, then Path.dat just contains the energy. 
264
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
265
! 2014 March Opt'n Path v1.50 Released under AGPL
266
! We used this release to clean the source files (and delete some unused files!)
267
! The Chamfre reactive Force field is not public and has been removed:
268
! if you want it, contact optnpath@gmail.com to see how to get it.
269
! it was anyway an old version of CH4+Ni(111) with old parameters.
270
!
271
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
272

    
273
PROGRAM PathOpt
274

    
275
  use VarTypes
276
  use Path_module
277
  use Io_module
278

    
279
  IMPLICIT NONE
280

    
281
  CHARACTER(132) :: FileIn, FileOut, Line
282

    
283
  INTEGER(KINT) :: I,J,K,IGeom,iat, IGeom0, IGeomF
284
  INTEGER(KINT) :: IOpt
285
  INTEGER(KINT) :: Idx
286
  INTEGER(KINT) :: N3at, NFree, Nfr
287

    
288
  INTEGER(KINT) :: List(2*MaxFroz)
289

    
290
  REAL(KREAL) :: E,FactStep !E=Energy
291
  REAL(KREAL) :: Alpha,sa,ca,norm,s,NormStep,NormGrad
292
  REAL(KREAL) :: EReac,EProd,HP,HEAT ! HEAT=E
293
  REAL(KREAL), ALLOCATABLE :: GeomTmp(:),GradTmp(:),ZeroVec(:) !NCoord
294
  REAL(KREAL), ALLOCATABLE :: GradOld(:,:) ! (NGeomF,NCoord)
295
  REAL(KREAL), ALLOCATABLE :: GeomTmp2(:),GradTmp2(:) ! NCoord
296
  REAL(KREAL), ALLOCATABLE :: HessTmp(:,:)
297
  REAL(KREAL), ALLOCATABLE :: Hprim(:,:) !(NPrim,NPrim)
298
  REAL(KREAL), ALLOCATABLE :: HprimU(:,:) !(NPrim,3*Nat-6))
299
  LOGICAL, SAVE :: allocation_flag
300

    
301
  ! Flag to see if frozen atoms are frozen (see below)
302
  LOGICAL :: FChkFrozen
303

    
304
  ! Energies for all points along the path at the previous iteration
305
  REAL(KREAL), ALLOCATABLE ::  EPathold(:) ! NGeomF
306
  ! Maximum step allowed for this geometry
307
  REAL(KREAL), ALLOCATABLE ::  MaxStep(:) ! NGeomF
308

    
309
! these are used to read temporary coordinates
310
  LOGICAL :: FFrozen,FCart
311

    
312
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
313
  !
314
  ! To analyse the frozen atoms
315
  !
316
  REAL(KREAL), ALLOCATABLE :: x1(:),y1(:),z1(:) ! nat
317
  REAL(KREAL), ALLOCATABLE :: x2(:),y2(:),z2(:) ! nat
318
  REAL(KREAL) :: MRot(3,3),Norm1,Norm2,Dist
319
  LOGICAL, ALLOCATABLE :: ListAtFroz(:)
320
  INTEGER(KINT) :: Iat1, Iat2, Iat3
321

    
322
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
323

    
324
  LOGICAL :: Debug, Fini,Flag_Opt_Geom
325

    
326
!  INTEGER(KINT), EXTERNAL :: Iargc
327
  INTEGER(KINT), EXTERNAL ::  ConvertNumAt
328
  INTEGER(KINT) :: IoS
329

    
330
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
331
  !
332
  ! For Debugging purposes
333
  !
334
  LOGICAL :: FCalcHess
335
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
336

    
337

    
338
  INTERFACE
339
     function valid(string) result (isValid)
340
       CHARACTER(*), intent(in) :: string
341
       logical                  :: isValid
342
     END function VALID
343

    
344
     SUBROUTINE Read_Geom(Input)
345
       CHARACTER(32), INTENT(IN) :: input
346
     END SUBROUTINE READ_GEOM
347

    
348

    
349
     subroutine hupdate_all (n, dx, dgrad, HessOld)
350

    
351
       IMPLICIT NONE
352

    
353
       INTEGER, PARAMETER :: KINT=KIND(1)
354
       INTEGER, PARAMETER :: KREAL=KIND(1.0D0)
355

    
356
       INTEGER(KINT), INTENT(IN) :: n
357
       real(KREAL) :: dx(n), dgrad(n), HessOld(n*n)
358
     END subroutine hupdate_all
359

    
360
     SUBROUTINE Hinvup_BFGS_new(Nfree,ds,dgrad,Hess)
361

    
362
       IMPLICIT NONE
363
       
364
       INTEGER, PARAMETER :: KINT=KIND(1)
365
       INTEGER, PARAMETER :: KREAL=KIND(1.D0)
366
       
367
       INTEGER(KINT), INTENT(IN) :: NFREE
368
       REAL(KREAL), INTENT(INOUT) :: Hess(Nfree,Nfree)
369
       REAL(KREAL), INTENT(IN) :: ds(Nfree)
370
       REAL(KREAL), INTENT(IN) :: dGrad(Nfree)
371
       
372
     END subroutine Hinvup_BFGS_new
373

    
374

    
375
    FUNCTION InString(Line,String,Case,Clean,Back)  Result(Pos)
376

    
377
      Use VarTypes
378

    
379
      implicit none
380
! Input
381
      CHARACTER(*), INTENT(IN) :: Line
382
      CHARACTER(*), INTENT(IN) :: String
383
      LOGICAL, OPTIONAL, INTENT(IN) :: Case
384
      LOGICAL, OPTIONAL, INTENT(IN) :: Back
385
      CHARACTER(*), OPTIONAL, INTENT(IN) :: Clean
386

    
387
! Output
388
! the position of String in Line (the first one) unless Back is present
389
      INTEGER(KINT) :: Pos
390
    END FUNCTION InString
391

    
392
    SUBROUTINE die(routine, msg, file, line, unit)
393

    
394
      Use VarTypes
395
      Use io_module
396

    
397
      implicit none
398
      character(len=*), intent(in)           :: routine, msg
399
      character(len=*), intent(in), optional :: file
400
      integer(KINT), intent(in), optional      :: line, unit
401

    
402
    END SUBROUTINE die
403

    
404
    SUBROUTINE Warning(routine, msg, file, line, unit)
405

    
406
      Use VarTypes
407
      Use io_module
408

    
409
      implicit none
410

    
411
      character(len=*), intent(in)           :: routine, msg
412
      character(len=*), intent(in), optional :: file
413
      integer(KINT), intent(in), optional      :: line, unit
414

    
415
    END SUBROUTINE Warning
416

    
417

    
418
  END INTERFACE
419

    
420
  Namelist/path/fact,r_cov,nat,ngeomi,ngeomf,debugFile, &
421
       MW,mass,Ffrozen, renum, OptReac,OptProd,Coord,Step_method,MaxCyc, &
422
       SMax, SThresh, GThresh,IReparam, IReparamT,Hinv, ISpline, PathOnly,Fcart, &
423
       input,prog, ProgExe,RunMode, AtTypes,poscar,PathName,  &
424
       OptGeom,IniHup, HupNeighbour, hesUpd, HUpdate, &
425
       FTan, EReac, EProd, IGeomRef, Vmd, AutoCart, DynMaxStep, &
426
       NMaxPtPath, FrozTol, BoxTol,CalcName,ISuffix,OSuffix, WriteVasp, &
427
       NGintMax, Align, CalcEReac,CalcEProd, GeomFile,AnAGeom,AnaFile,GplotFile
428

    
429
  Namelist/cartlist/list
430
  Namelist/frozenlist/list
431
  Namelist/analist/nb
432

    
433

    
434
  Flag_Opt_Geom = .FALSE. ! Initialized.
435

    
436
!!!!!!!!!!!!!!!!!!!!!!!!!
437
  ! 
438
  ! We print the Version info in file
439
  !
440
  WRITE(*,'(1X,A)') "Opt'n Path v1.50 (c) PFL/PD 2003-2014"
441
  WRITE(*,'(1X,A)') "Contact: optnpath@gmail.com"
442

    
443
  ! We read the files  names
444
!  SELECT CASE (iargc())
445

    
446

    
447

    
448

    
449
  SELECT CASE (command_argument_count())
450
  CASE (2)
451
     call getarg(1,FileIn)
452
     OPEN(IOIN,FILE=FileIn,STATUS='UNKNOWN')
453
     call getarg(2,FileOut)
454
     OPEN(IOOUT,FILE=FileOut,STATUS='UNKNOWN')
455
  CASE (1)
456
     call getarg(1,FileIn)
457
     IF ((FileIn=="-help").OR.(FileIn=="--help")) THEN
458
        WRITE(*,*) "Opt'n Path mini-help"
459
        WRITE(*,*) "--------------"
460
        WRITE(*,*) ""
461
        WRITE(*,*) "Use: Path Input_file Output_file"
462
        WRITE(*,*) "Input_file starts with a Namelist called path"
463
        WRITE(*,*) ""
464
! The following has been generated (March 19, 2013) using the Mini_help.tex file
465
! 1) Edit Mini_help.tex
466
! 2) latex Mini_help.tex
467
! 3) catdvi -e 1 -U  Mini_help.dvi | sed -re "s/\[U\+2022\]/-/g" | sed -re "s/([^^[:space:]])\s+/\1 /g" > file.txt
468
! 4) edit file.txt to keep only the following lines, and to reformat a bit
469
! 5) awk '{print "WRITE(*,*) \"" $0 "\""}' file.txt > help
470
! 5) cut&paste help in Path.f90 ...
471
        WRITE(*,*) " &path"
472
        WRITE(*,*) " nat=3, ! Number of atoms"
473
        WRITE(*,*) " ngeomi=3, ! Number of initial geometries"
474
        WRITE(*,*) " ngeomf=12, !Number of geometries along the path"
475
        WRITE(*,*) " OptReac=.T., ! Do you want to optimize the reactants ?"
476
        WRITE(*,*) " OptProd=.T., ! Optimize the products"
477
        WRITE(*,*) " coord='zmat', ! We use Z-matrix coordinates"
478
        WRITE(*,*) " maxcyc=31, ! Max number of iterations"
479
        WRITE(*,*) " IReparam=2,! re-distribution of points along the path every 2 iterations"
480
        WRITE(*,*) " ISpline=50, ! Start using spline interpolation at iteration 50"
481
        WRITE(*,*) " Hinv=.T. , ! Use inverse of the Hessian internally (default: T)"
482
        WRITE(*,*) " MW=T, ! Works in Mass Weighted coordiante (default T)"
483
        WRITE(*,*) " PathName='Path_HCN_zmat_test', ! Name of the file used for path outputs"
484
        WRITE(*,*) " prog='gaussian',! we use G03 to get energy and gradients"
485
        WRITE(*,*) " SMax=0.1 ! Displacement cannot exceed 0.1 atomic units (or mass weighted at. unit)"
486
        WRITE(*,*) " /"
487
        WRITE(*,*) "  3"
488
        WRITE(*,*) " Energy : 0.04937364"
489
        WRITE(*,*) " H 0.0000 0.0000 0.0340"
490
        WRITE(*,*) " C 0.0000 0.0000 1.1030"
491
        WRITE(*,*) " N 0.0000 0.0000 2.2631"
492
        WRITE(*,*) "  3"
493
        WRITE(*,*) " Energy : 0.04937364"
494
        WRITE(*,*) " H 0.0000 1.1000 1.1030"
495
        WRITE(*,*) " C 0.0000 0.0000 1.1030"
496
        WRITE(*,*) " N 0.0000 0.0000 2.2631"
497
        WRITE(*,*) "3"
498
        WRITE(*,*) " CNH"
499
        WRITE(*,*) "H 0.000000 0.000000 3.3"
500
        WRITE(*,*) "C 0.000000 0.000000 1.1"
501
        WRITE(*,*) "N 0.000000 0.000000 2.26"
502
        WRITE(*,*) "%chk=Test"
503
        WRITE(*,*) "#P AM1 FORCE"
504
        WRITE(*,*) " HCN est bien"
505
        WRITE(*,*) ""
506
        WRITE(*,*) "0,1"
507
        WRITE(*,*) "H 0.000000 0.000000 0.000000"
508
        WRITE(*,*) "C 0.000000 0.000000 1.000"
509
        WRITE(*,*) "N 0.000000 0.000000 3.00"
510
        WRITE(*,*) ""
511
        WRITE(*,*) "*******"
512
        WRITE(*,*) "* Compulsory variables are:"
513
        WRITE(*,*) "*******"
514
        WRITE(*,*) "NGeomi: Number of geometries defining the Initial path"
515
        WRITE(*,*) "NGeomf: Number of geometries defining the Final path"
516
        WRITE(*,*) "Nat: Number of atoms"
517
        WRITE(*,*) ""
518
        WRITE(*,*) "*******"
519
        WRITE(*,*) "* Other options:"
520
        WRITE(*,*) "*******"
521
        WRITE(*,*) "Input: String that indicates the type of the input geometries. Accepted values are: Cart (or"
522
        WRITE(*,*) "    Xmol or Xyz), Vasp, Turbomole or Siesta."
523
        WRITE(*,*) "Prog: string that indicates the program that will be used for energy and gradient calculations."
524
        WRITE(*,*) "    Accepted values are: Gaussian, Mopac, Vasp, Turbomole, Siesta or Ext."
525
        WRITE(*,*) ""
526
        WRITE(*,*) ""
527
        WRITE(*,*) "        - In case of a Gaussian calculations, input must be set to Cart. One example of a gaus-"
528
        WRITE(*,*) "          sian input should be added at the end of the input file.See example file Test_HCN_zmat_g03.path."
529
        WRITE(*,*) "        - In the case of a VASP calculation, if input is set to Cart, then the preamble of a"
530
        WRITE(*,*) "          VASP calculation s"
531
        WRITE(*,*) "        - Mopac: Examples using sequential call to MOPAC2009 to calculate the energies and"
532
        WRITE(*,*) "          forces along the path. hould be added at the end of the input file. See example file"
533
        WRITE(*,*) "          Test_VASP_cart.path. In the case of a VASP calculation, one should also give value"
534
        WRITE(*,*) "          of the RunMode variable ."
535
        WRITE(*,*) "        - In the case of a SIESTA calculation, an example of a Siesta input file should be added"
536
        WRITE(*,*) "          at the end of the input file. See Test_Siesta.path."
537
        WRITE(*,*) ""
538
        WRITE(*,*) "RunMode: When running on a multi-processor machine, this indicates wether Opt'n Path"
539
        WRITE(*,*) "    should calculate the energy and gradient of the whole path in parallel or not. User has"
540
        WRITE(*,*) "    two options. One is to calculate the energy and gradient of each point sequentially. This"
541
        WRITE(*,*) "    is usefull when running on one (or two) processors. In this case, RunMode should be put"
542
        WRITE(*,*) "    to SERIAL.When running in parallel with 8 or more processors, one can use VASP to"
543
        WRITE(*,*) "    calculate simultaneously the energies and gradients for all points, as in a normal NEB cal-"
544
        WRITE(*,*) "    culation. In this case, RunMode must be set to PARA. For now, this is usefull only for VASP."
545
        WRITE(*,*) ""
546
        WRITE(*,*) "ProgExe: Name (with full path) of the executable to be used to get energies and gradients."
547
        WRITE(*,*) "    For example, if VASP is used in parallel, one might have something like:"
548
        WRITE(*,*) "    ProgExe='/usr/local/mpich/bin/mpirun -machinefile machine -np 8 ~/bin/VASP_46'."
549
        WRITE(*,*) "    Another option that I use, is to put ProgExe='./run_vasp' and I put every option needed"
550
        WRITE(*,*) "    to run VASP into the run_vasp file."
551
        WRITE(*,*) "EReac: (REAL) By default, Opt'n Path does not compute the energy of the reactants and"
552
        WRITE(*,*) "    products. This thus indicates the reactants energy to Opt'n Path to have better plots at"
553
        WRITE(*,*) "    the end."
554
        WRITE(*,*) "EProd: (REAL) By default, Opt'n Path does not compute the energy of the reactants and"
555
        WRITE(*,*) "    products. This thus indicates the products energy to Opt'n Path to have better plots."
556
        WRITE(*,*) ""
557
        WRITE(*,*) "PathName: Prefix used to save the path. Default is Path."
558
        WRITE(*,*) "Poscar: string that will be used as the prefix for the different POSCAR files in a VASP calcu-"
559
        WRITE(*,*) "    lations. Usefull only if PathOnly=.TRUE., not used for internal calculations."
560
        WRITE(*,*) "CalcName: Prefix for the files used for the energy and gradient calculations"
561
        WRITE(*,*) ""
562
        WRITE(*,*) "ISuffix: Suffix for the input file used for energy and gradient calculations. The full inputfile"
563
        WRITE(*,*) "    name will thus be CalcName.ISuffix."
564
        WRITE(*,*) "OSuffix: Suffix for the output file used for energy and gradient calculations. The full outputfile"
565
        WRITE(*,*) "    name will thus be CalcName.OSuffix."
566
        WRITE(*,*) ""
567
        WRITE(*,*) "IGeomRef: Index of the geometry used to construct the internal coordinates. Valid only for"
568
        WRITE(*,*) "     Coord=Zmat, Hybrid or Mixed."
569
        WRITE(*,*) "Fact: REAL used to define if two atoms are linked. If d(A,B) =< fact* (rcov(A) + rcov(B)),"
570
        WRITE(*,*) "     then A and B are considered Linked."
571
        WRITE(*,*) ""
572
        WRITE(*,*) "debugFile: Name of the file that indicates which subroutine should print debug info."
573
        WRITE(*,*) "Coord: System of coordinates to use. Possible choices are:"
574
        WRITE(*,*) "        - CART (or Xyz): works in cartesian"
575
        WRITE(*,*) "        - Zmat: works in internal coordinates (Zmat)"
576
        WRITE(*,*) "        - Mixed: frozen atoms, as well as atoms defined by the 'cart' array(see below) are"
577
        WRITE(*,*) "          describe in CARTESIAN, whereas the others are described in Zmat"
578
        WRITE(*,*) "        - Baker: use of Baker coordinates, also called delocalized internal coordinates"
579
        WRITE(*,*) "        - Hybrid: geometries are described in zmat, but the gradient are used in cartesian"
580
        WRITE(*,*) "Step_method: method to compute the step for optimizing a geometry; choices are:"
581
        WRITE(*,*) ""
582
        WRITE(*,*) "        - RFO: Rational function optimization"
583
        WRITE(*,*) "        - GDIIS: Geometry optimization using direct inversion in the iterative supspace"
584
        WRITE(*,*) "HUpdate: method to update the hessian. By default, it is Murtagh-Sargent Except for geom-"
585
        WRITE(*,*) "     etry optimization where it is BFGS."
586
        WRITE(*,*) "MaxCyc: maximum number of iterations for the path optimization"
587
        WRITE(*,*) ""
588
        WRITE(*,*) "Smax: Maximum length of a step during path optimization"
589
        WRITE(*,*) "SThresh: Step Threshold to consider that the path is stationary"
590
        WRITE(*,*) "GThresh: Gradient Threshold to consider that the path is stationary, only orthogonal part is"
591
        WRITE(*,*) "     taken"
592
        WRITE(*,*) ""
593
        WRITE(*,*) "FTan: We moving the path, this gives the proportion of the displacement tangent to the path"
594
        WRITE(*,*) "     that is kept. FTan=1. corresponds to the full displacement, whereas FTan=0. gives a"
595
        WRITE(*,*) "     displacement orthogonal to the path."
596
        WRITE(*,*) "IReparam: The path is not reparameterised at each iteration. This gives the frequency of"
597
        WRITE(*,*) "     reparameterization."
598
        WRITE(*,*) "IReparamT: When the path is not reparameterised at each iteration, this gives the frequency"
599
        WRITE(*,*) "     of reparameterization of the tangents."
600
        WRITE(*,*) ""
601
        WRITE(*,*) "ISpline: By default, a linear interpolation is used to generate the path. This option indicates"
602
        WRITE(*,*) "     the first step where spline interpolation is used."
603
        WRITE(*,*) "BoxTol: Real between 0. and 1. When doing periodic calculations, it might happen that an"
604
        WRITE(*,*) "     atom moves out of the unit cell. Path detects this by comparing the displacement to"
605
        WRITE(*,*) "     boxtol: if an atom moves by more than Boxtol, then it is moved back into the unit cell."
606
        WRITE(*,*) "     Default value: 0.5."
607
        WRITE(*,*) "FrozTol: (Real) This indicates the threshold to determine wether an atom moves between two"
608
        WRITE(*,*) "     images. Default is 1e-4."
609
        WRITE(*,*) ""
610
        WRITE(*,*) "OptGeom: This INTEGER indicates the index of the geometry you want to optimize. If"
611
        WRITE(*,*) "    OptGeom is set, then Opt'n Path performs a geometry optimization instead of a path"
612
        WRITE(*,*) "    interpolation."
613
        WRITE(*,*) "GeomFile: Name of the file to print the geometries and their energy during a geometry opti-"
614
        WRITE(*,*) "    mization. If this variable is not given then nothing is printed."
615
        WRITE(*,*) "AnaFile: Name of the file to print the values of the geometrical parameters that are monitored"
616
        WRITE(*,*) "    if AnaGeom=.TRUE.. Default is PathName.dat"
617
        WRITE(*,*) ""
618
        WRITE(*,*) "GplotFile: Name of the gnuplot file to plot the evolution of the geometrical parameters that"
619
        WRITE(*,*) "    are monitored if AnaGeom=.TRUE.. Default is PathName.gplot"
620
        WRITE(*,*) ""
621
        WRITE(*,*) "*******"
622
        WRITE(*,*) "* Arrays:"
623
        WRITE(*,*) "*******"
624
        WRITE(*,*) ""
625
        WRITE(*,*) "Rcov: Array containing the covalent radii of the first 86 elements. You can modify it using,"
626
        WRITE(*,*) "    rcov(6)=0.8."
627
        WRITE(*,*) "Mass: Array containing the atomic mass of the first 86 elements."
628
        WRITE(*,*) "AtTypes: Name of the different atoms used in a VASP calculations. If not given, Opt'n Path will"
629
        WRITE(*,*) "    read the POTCAR file."
630
        WRITE(*,*) ""
631
        WRITE(*,*) "*******"
632
        WRITE(*,*) "* Flags:"
633
        WRITE(*,*) "*******"
634
        WRITE(*,*) ""
635
        WRITE(*,*) "MW: Flag. True if one wants to work in Mass Weighted coordinates. Default=.TRUE."
636
        WRITE(*,*) "Renum: Flag. True if one wants to reoder the atoms in the initial order. default is .TRUE."
637
        WRITE(*,*) "    unless for Coord equals CART."
638
        WRITE(*,*) ""
639
        WRITE(*,*) "OptProd: True if one wants to optimize the geometry of the products."
640
        WRITE(*,*) "OptReac: True if one wants to optimize the geometry of the reactants."
641
        WRITE(*,*) "CalcEProd: if TRUE the product energy will be computed. Default is FALSE. Not Compatible"
642
        WRITE(*,*) "    with RunMode=Para."
643
        WRITE(*,*) "CalcEReac: if TRUE the reactants energy will be computed. Default is FALSE. Not Compat-"
644
        WRITE(*,*) "    ible with RunMode=Para."
645
        WRITE(*,*) ""
646
        WRITE(*,*) "PathOnly: TRUE if one wants to generate the initial path, and stops."
647
        WRITE(*,*) "Align: If .FALSE., successive geometries along the path are not aligned on each other before"
648
        WRITE(*,*) "    path interpolation. Default is .TRUE. if there are 4 atoms or more."
649
        WRITE(*,*) "Hinv: if True, then Hessian inversed is used."
650
        WRITE(*,*) "IniHup: if True, then Hessian inverse is extrapolated using the initial path calculations."
651
        WRITE(*,*) ""
652
        WRITE(*,*) "HupNeighbour: if True, then Hessian inverse is extrapolated using the neighbouring points of"
653
        WRITE(*,*) "    the path."
654
        WRITE(*,*) "FFrozen: True if one wants to freeze the positions of some atoms. If True, a &frozenlist"
655
        WRITE(*,*) "    namelist containing the list of frozen atoms must be given. If VASP is used, and frozen is"
656
        WRITE(*,*) "    not given here, the program will use the F flags of the input geometry"
657
        WRITE(*,*) "FCart: True if one wants to describe some atoms using cartesian coordinates. *** Only used in"
658
        WRITE(*,*) "    'mixed' calculations. *** If True, a &cartlist namelist containing the list of cart atoms"
659
        WRITE(*,*) "    must be given. By default, only frozen atoms are described in cartesian coordinates."
660
        WRITE(*,*) ""
661
        WRITE(*,*) "Autocart: True if you want to let the program choosing the cartesian atoms."
662
        WRITE(*,*) "VMD: TRUE if you want to use VMD to look at the Path. Used only for VASP for now."
663
        WRITE(*,*) ""
664
        WRITE(*,*) "WriteVASP: TRUE if you want to print the images coordinates in POSCAR files. See also"
665
        WRITE(*,*) "      the POSCAR option. This can be used only if prog or input=VASP."
666
        WRITE(*,*) "AnaGeom: If TRUE, Opt'n Path will create a file .dat for geometries analysis. If True, "
667
        WRITE(*,*) "Opt'n Path will look for the AnaList namelist after the Path Namelist."
668
        WRITE(*,*) "DynMaxStep: if TRUE, the maximum allowed step is updated at each step, for each geometry."
669
        WRITE(*,*) "      If energy goes up, Smax = Smax*0.8, if not Smax = Smax*1.2. It is ensured that the"
670
        WRITE(*,*) "      dynamical Smax is within [0.5*SMax_0 ,2*Smax_0 ]."
671
        WRITE(*,*) ""
672
        WRITE(*,*) "*******"
673
        WRITE(*,*) "* Additional namelists:"
674
        WRITE(*,*) "*******"
675
        WRITE(*,*) ""
676
        WRITE(*,*) "&cartlist list= ... &end This gives the list of atoms that are described using cartesian coor-"
677
        WRITE(*,*) "      dinates. Read only if FCart=.TRUE.. To indicate an atom range, from 1 to 5 for example,"
678
        WRITE(*,*) "      one can put 1 -5 in the list. For example:"
679
        WRITE(*,*) "      &cartlist list = 1 2 6 12 -20 &end"
680
        WRITE(*,*) "      will described atoms 1, 2, 6, 12, 13, 14, 15, 16, 17, 18, 19 and 20 in cartesian."
681
        WRITE(*,*) "&Frozenlist list= ... &end This gives the list of atoms that are frozen during optimization."
682
        WRITE(*,*) "      Read only if FFrozen=.TRUE.. To indicate an atom range, from 1 to 5 for example, one"
683
        WRITE(*,*) "      can put 1 -5 in the list."
684
        WRITE(*,*) ""
685
        WRITE(*,*) "&Analist nb= ... &end list of variables for geometry analysis. If present and if Ana-"
686
        WRITE(*,*) "      Geom=T then Opt'n Path will read it and print the values of the variable in a .dat file If"
687
        WRITE(*,*) "      AnaGeom is T but Analist is not given, then Path.dat just contains the energy. Analist"
688
        WRITE(*,*) "      contains the number of variables to monitor: Nb, and is followed by the description of the"
689
        WRITE(*,*) "      variables among: b(ond) At1 At2 a(ngle) At1 At2 At3 d(ihedral) At1 At2 At3 At4 c NbAt"
690
        WRITE(*,*) "      At1 At2 At3 At4 At5... to create a center of mass. The centers of mass are added at the"
691
        WRITE(*,*) "      end of the real atoms of the system."
692
!!!!!!!!!! end of included file
693
        WRITE(*,*) ""
694
        STOP
695
     END IF
696

    
697
     OPEN(IOIN,FILE=FileIn,STATUS='UNKNOWN')
698
     IOOUT=6
699
  CASE (0)
700
     IOIN=5
701
     IOOUT=6
702
  END SELECT
703
  
704
! We set the file delimiter (system dependent)
705
  Call Set_FileDelim
706

    
707
  ! We initiliaze variables
708
  Pi=dacos(-1.0d0)
709
  Nat=1
710
  Fact=1.1
711
  IGeomRef=-1
712
  NGeomI=1
713
  NGeomF=8
714
  IReparam=5
715
  IReparamT=-1
716
  ISpline=5
717
  debug=.False.
718
  MW=.TRUE.
719
  bohr=.False.
720
  Coord='ZMAT'
721
  Step_method='RFO'
722
  DebugFile='Path.valid'
723
  PathName="Path"
724
  MaxCyc=50
725
  SMax=0.1D0
726
  SThresh=-1.
727
  GThresh=-1.
728
  FTan=0.
729
  Hinv=.TRUE.
730
  IniHUp=.FALSE.
731
  HupNeighbour=.FALSE.
732
  HesUpd="EMPTY"
733
  HUpdate="EMPTY"
734
  FFrozen=.FALSE.
735
  FCart=.FALSE.
736
  List=0
737
  renum=.TRUE.
738
  OptReac=.FALSE.
739
  OptProd=.FALSE.
740
  CalcEReac=.FALSE.
741
  CalcEProd=.FALSE.
742
  EReac=0.d0
743
  EProd=0.d0 
744
  OptGeom=-1
745
  GeomFile="EMPTY"
746
  AnaGeom=.FALSE.
747
  AnaFile="EMPTY"
748
  GplotFile="EMPTY"
749
  Nb=0
750
  NbCom=0
751
  PathOnly=.FALSE.
752
  Prog='EMPTY'
753
  ProgExe='EMPTY'
754
  Runmode='SERIAL'
755
  Input='EMPTY'
756
  Poscar="POSCAR"
757
  AutoCart=.FALSE.
758
  VMD=.TRUE.
759
  WriteVASP=.FALSE.
760
  DynMaxStep=.FALSE.
761
  CalcName="EMPTY"
762
  ISuffix="EMPTY"
763
  OSuffix="EMPTY"
764
  NGintMax=10
765
  Align=.TRUE.
766

    
767
  ! Number of point used to compute the length of the path,
768
  ! and to reparameterize the path
769
  NMaxPtPath=-1 
770
  FrozTol=1e-4
771

    
772
  ! Read the namelist
773
  read (IOIN,path)
774

    
775
  debug=valid("Main").or.valid("Path")
776

    
777
  FCalcHess=valid("CalcHess")
778
  PathName=AdjustL(PathName)
779
  Coord=AdjustL(Coord)
780
  CALL UpCase(coord)
781

    
782
  Step_method=AdjustL(Step_method)
783
  CALL UpCase(Step_method)
784

    
785
  Prog=AdjustL(Prog)
786
  CALL UpCase(prog)
787

    
788
  Input=AdjustL(Input)
789
  CALL UpCase(input)
790

    
791
  Runmode=AdjustL(Runmode)
792
  Call UpCase(Runmode)
793
  IF (Runmode(1:4).EQ.'PARA')    Runmode="PARA"
794

    
795
  if ((RunMode.EQ."PARA").AND.(CalcEReac.OR.CalcEProd)) THEN
796
     WRITE(*,*) "CalcEReac and CalcEProd are not compatible (for now) with RunMode='PARA'"
797
     WRITE(*,*) "Setting CalcERead and CalcEProd to FALSE"
798
     CalcEReac=.FALSE.
799
     CalcEProd=.FALSE.
800
  END IF
801

    
802
  If (IReparamT<=0) IReparamT=IReparam
803

    
804
! We take care of HesUpd flag
805
! this is needed because some users might still use it
806
  if (HesUpd.NE."EMPTY") THEN
807
! We are pityless:
808
     WRITE(IOOUT,*) "HesUpd is deprecated. Use Hupdate instead"
809
     WRITE(*,*) "HesUpd is deprecated. Use Hupdate instead"
810
     STOP
811
  END IF
812

    
813
  IF (HUpdate=='EMPTY') THEN
814
     IF (OptGeom>=1) THEN
815
        HupDate="BFGS"
816
     ELSE
817
        HUpdate="MS"
818
     END IF
819
  END IF
820

    
821
  If ((COORD.EQ.'XYZ').OR.(COORD(1:4).EQ.'CART')) THEN 
822
     COORD='CART'
823
  END IF
824

    
825
  IF (COORD.EQ.'CART') THEN
826
     Renum=.FALSE.
827
     IF (OptGeom>0) THEN
828
        IGeomRef=OptGeom
829
     ELSE
830
        IGeomRef=1
831
     END IF
832
  END IF
833

    
834
  
835
  if (Prog.EQ.'TEST2'.OR.Prog.EQ.'CHAMFRE') Then
836
     WRITE(IOOUT,*) 'The CHAMFRE Reactive Force Field is not public.'
837
     WRITE(IOOUT,*) 'Contact optnpath@gmail.com to get it.'
838
     STOP
839
  END IF
840
  if (Prog.EQ.'2D') Prog="TEST2D"
841
  if (Prog.EQ.'TEST3') Prog="LEPS"
842

    
843

    
844
  Select Case (Prog)
845
    CASE ("EMPTY","G09","GAUSSIAN")
846
     Prog='GAUSSIAN'
847
     If (ProgExe=="EMPTY") ProgExe="g09"
848
     if (CalcName=="EMPTY") CalcName="Path"
849
     if (ISuffix=="EMPTY")  ISuffix="com"
850
     if (OSuffix=="EMPTY")  OSuffix="log"
851
     UnitProg="au"
852
     ConvE=au2kcal
853
    CASE ("G03")
854
     Prog='GAUSSIAN'
855
     If (ProgExe=="EMPTY") ProgExe="g03"
856
     if (CalcName=="EMPTY") CalcName="Path"
857
     if (ISuffix=="EMPTY")  ISuffix="com"
858
     if (OSuffix=="EMPTY")  OSuffix="log"
859
     UnitProg="au"
860
     ConvE=au2kcal
861
    CASE ("EXT")
862
     If (ProgExe=="EMPTY") ProgExe="./Ext.exe"
863
     if (CalcName=="EMPTY") CalcName="Ext"
864
     if (ISuffix=="EMPTY")  ISuffix="in"
865
     if (OSuffix=="EMPTY")  OSuffix="out"
866
     UnitProg="au"
867
     ConvE=au2kcal
868
    CASE ('MOPAC')
869
     If (ProgExe=="EMPTY") ProgExe="mopac"
870
     if (CalcName=="EMPTY") CalcName="Path"
871
     if (ISuffix=="EMPTY")  ISuffix="mop"
872
     if (OSuffix=="EMPTY")  OSuffix="out"
873
     UnitProg="au"
874
     ConvE=au2kcal
875
    CASE ("SIESTA")
876
     If (ProgExe=="EMPTY") ProgExe="siesta"
877
     if (CalcName=="EMPTY") CalcName="Path"
878
     if (ISuffix=="EMPTY")  ISuffix="fdf"
879
     if (OSuffix=="EMPTY")  OSuffix="out"
880
     UnitProg="eV"
881
     ConvE=eV2kcal
882
    CASE ("VASP")
883
     If (ProgExe=="EMPTY") ProgExe="VASP"
884
     UnitProg="eV"
885
     ConvE=eV2kcal
886
     FPBC=.TRUE.
887
     IPer=3
888
     Kabeg=-1
889
     kaEnd=1
890
     kbBeg=-1
891
     kbEnd=1
892
     kcBeg=-1
893
     kcEnd=1
894
    CASE ("TM","TURBOMOLE")
895
     Prog="TURBOMOLE"
896
     If (ProgExe=="EMPTY") ProgExe="jobex -c 1 -keep"
897
     UnitProg="au"
898
     ConvE=au2kcal
899
     FPBC=.FALSE.
900
    CASE ("TEST","CHAMFRE","TEST2D","LEPS")
901
     ProgExe=""
902
     UnitProg="au"
903
     ConvE=au2kcal
904
    CASE DEFAULT
905
     WRITE(*,*) "Prog=",Adjustl(trim(Prog))," not recognized. STOP"
906
     STOP
907
  END SELECT 
908

    
909
  if (Input.EQ.'EMPTY') THEN
910
     Select Case (Prog)
911
       CASE ("VASP")
912
          Input=Prog
913
       CASE ("CHAMFRE")
914
          Input="VASP"
915
       CASE DEFAULT
916
          Input='XYZ'
917
     END SELECT
918
    WRITE(*,*) "Input has been set to the default: ",INPUT
919
 END IF
920

    
921
  WriteVASP=WriteVASP.AND.((Prog=="VASP").OR.(Input=="VASP"))
922

    
923
  IF ((RunMode=="PARA").AND.((Prog/="GAUSSIAN").AND.(Prog/="VASP"))) THEN
924
     WRITE(*,*) "Program=",TRIM(Prog)," not yet supported for Para mode."
925
     STOP
926
  END IF
927

    
928
  if (OptGeom.GE.1) THEN
929
     FPrintGeom=.FALSE.
930
     If (GeomFile/='EMPTY') THEN
931
        FPrintGeom=.TRUE.
932
     END IF
933
     IF (IGeomRef.LE.0) THEN
934
        IGeomRef=OptGeom
935
     ELSE
936
        IF (IGeomRef.NE.OptGeom) THEN
937
           WRITE(IOOUT,*) "STOP: IGeomRef and OptGeom both set... but to different values !"
938
           WRITE(IOOUT,*) "Check it : IGeomRef=",IGeomRef," OptGeom=",OptGeom
939

    
940
           WRITE(*,*) "STOP: IGeomRef and OptGeom both set... but to different values !"
941
           WRITE(*,*) "Check it : IGeomRef=",IGeomRef," OptGeom=",OptGeom
942
           STOP
943
        END IF
944
     END IF
945
  END IF
946

    
947
  ALLOCATE(Cart(Nat))
948
  Cart=0
949

    
950
  ALLOCATE(Frozen(Nat))
951
  Frozen=0
952

    
953
  IF (FCart) THEN
954
! We rewind the file to be sure to browse all of it to read the Cart namelist
955
     REWIND(IOIN)
956
     List=0
957
     READ(IOIN,cartlist)
958
     IF (COORD.NE.'CART') THEN
959
        Cart=List(1:Nat)
960
        if (debug) WRITE(*,*) "DBG Path L512 Cart",Cart
961
     ELSE
962
        WRITE(*,*) "FCart=T is not allowed when Coord='CART'"
963
        WRITE(*,*) "I will discard the cartlist"
964
        Cart=0
965
     END IF
966
  END IF
967

    
968
  if (FFrozen) THEN
969

    
970
     REWIND(IOIN)
971
     List=0
972
     READ(IOIN,Frozenlist)
973
     Frozen=List(1:Nat)
974
     if (debug) WRITE(*,*) "DBG Path L517 Frozen",Frozen
975
  END IF
976

    
977
  If (FCart) Call Expand(Cart,NCart,Nat)
978
  IF (FFrozen) Call Expand(Frozen,NFroz,Nat)
979

    
980
  if (debug) WRITE(*,*) "DBG Main L609, Ncart,Cart",NCart,Cart
981
  if (debug) WRITE(*,*) "DBG Main L610, NFroz,Frozen", NFroz,Frozen
982

    
983
  if (AnaGeom) THEN
984
     REWIND(IOIN)
985
     READ(IOIN,AnaList,IOSTAT=IoS)
986
     IF (IOS==0) THEN ! we have a AnaList namelist 
987
        Call ReadAnaList
988
     ELSE
989
! No AnaList namelist, we will print only the energy
990
        FormAna='(1X,F8.3,1X,1X,F7.2,1X,F15.6)'
991
     END IF
992
     IF (AnaFile=="EMPTY") THEN
993
        AnaFile=TRIM(PathName) // '.dat'
994
     END IF
995
     OPEN(IODat,File=AnaFile)
996
     IF (GplotFile=="EMPTY") THEN
997
        GplotFile=TRIM(PathName) // '.gplot'
998
     END IF
999
     
1000
     OPEN(IODat,File=AnaFile)
1001
     If (OptGeom<=0) THEN
1002
        OPEN(IOGplot,File=GPlotFile)
1003
        WRITE(IoGplot,'(A)') "#!/usr/bin/gnuplot -persist"
1004
        WRITE(IoGplot,'(A)') " set pointsize 2"
1005
        WRITE(IoGplot,'(A)') " xcol=1"
1006
        WRITE(IoGplot,'(A,I5)') " Ecol=",NbVar+3
1007
     END IF
1008
  END IF
1009

    
1010
        
1011

    
1012
  if (NMaxPtPath.EQ.-1) then
1013
     NMaxPtPath=min(50*NGeomF,2000)
1014
     NMaxPtPath=max(20*NGeomF,NMaxPtPath)
1015
  end if
1016

    
1017
  !  NMaxPtPath=10000
1018

    
1019
  ! We ensure that FTan is in [0.:1.]
1020
  FTan=min(abs(FTan),1.d0)
1021

    
1022
! PFL 2011 Mar 14 ->
1023
! Added some printing for analyses with Anapath
1024
  if (debug) THEN
1025
     WRITE(IOOUT,path)
1026
  ELSE
1027
! Even when debug is off we print NAT, NGEOMI, NGEOMF, MAXCYC
1028
! and PATHNAME 
1029
     WRITE(IOOUT,'(1X,A,I5)') "NAT = ", nat
1030
     WRITE(IOOUT,'(1X,A,I5)') "NGEOMI = ", NGeomI
1031
     WRITE(IOOUT,'(1X,A,I5)') "NGEOMF = ", NGeomF
1032
     WRITE(IOOUT,'(1X,A,I5)') "MAXCYC = ", MaxCYC
1033
     WRITE(IOOUT,'(1X,A,1X,A)') "PATHNAME = ", Trim(PATHNAME)
1034
  END IF
1035

    
1036
  FTan=1.-FTan
1037

    
1038
  !Thresholds...
1039
  if (SThresh.LE.0) SThresh=0.01d0
1040
  If (GThresh.LE.0) GThresh=SThresh/4.
1041
  SThreshRms=Sthresh*2./3.
1042
  GThreshRms=Gthresh*2./3.
1043

    
1044
  ! First batch of allocations. Arrays that depend only on NGeomI, Nat
1045
  ALLOCATE(XyzGeomI(NGeomI,3,Nat), AtName(NAt))
1046
  ALLOCATE(IndZmat(Nat,5),Order(Nat),Atome(Nat))
1047
  ALLOCATE(MassAt(NAt),OrderInv(Nat))
1048

    
1049
  AtName=""
1050
  MassAt=1.
1051

    
1052
! As we have used rewind many times, the position in the input file
1053
! is blurry (at least !) we thus have to go back to the Geometries description
1054
! (TO DO: use a better Input parser !)
1055

    
1056
  REWIND(IOIN)
1057
! We search the '&path' namelist
1058
  READ(IOIN,'(A)',Iostat=Ios) Line
1059
  Fini=.FALSE.
1060
  DO WHILE ((Ios==0).AND.InString(Line,"&PATH")==0)
1061
     if (debug) WRITE(*,*) "Lookgin for Path:",TRIM(Line)
1062
     READ(IOIN,'(A)',Iostat=Ios) Line
1063
  END DO
1064
  if (debug) WRITE(*,*) "Path found:",TRIM(LINE)
1065
  ! We are on the &path line, we move to the end
1066
  Call NoComment(Line)
1067
  DO WHILE ((Ios==0).AND.InString(Line,"/")==0)
1068
     if (debug) WRITE(*,*) "Lookgin for /:",TRIM(Line)
1069
     READ(IOIN,'(A)',Iostat=Ios) Line
1070
     Call NoComment(Line)
1071
     Call noString(Line)
1072
  END DO
1073
! We are at then end of &Path / namelist
1074
! We scan for other Namelists
1075
  READ(IOIN,'(A)',Iostat=Ios) Line
1076
  if (debug) WRITe(*,*) "Another Namelist ?",TRIM(Line)
1077
  DO WHILE  ((IoS==0).AND.(Index(Line,'&')/=0))
1078
     Call NoComment(Line)
1079
     if (debug) WRITe(*,*) "Another Namelist ?",TRIM(Line)
1080
     Idx=InString(Line,'Analist')
1081
     DO WHILE ((Ios==0).AND.InString(Line,"/")==0)
1082
        if (debug) WRITE(*,*) "Lookgin for /:",TRIM(Line)
1083
        READ(IOIN,'(A)',Iostat=Ios) Line
1084
        Call NoComment(Line)
1085
     END DO
1086
     If (Idx/=0) THEN
1087
! we have just read &Analist namelist, we have to skip the variables description
1088
        DO I=1,Nb
1089
           READ(IOIN,'(A)',Iostat=Ios) Line
1090
           if (debug) WRITe(*,*) "We skip Analist",TRIM(LINE)
1091
        END DO
1092
     END IF
1093
     READ(IOIN,'(A)',Iostat=Ios) Line
1094
     if (debug) WRITe(*,*) "We skip the line:",TRIM(LINE)
1095
  END DO
1096
  BACKSPACE(IOIN)
1097

    
1098
  ! We read the initial geometries
1099
  Call Read_Geom(input)
1100

    
1101
  ! We convert atome names into atom mass number
1102
  DO I=1,NAt
1103
     !     WRITE(*,*) 'I,AtName',I,AtName(I)
1104
     Atome(I)=ConvertNumAt(AtName(I))
1105
  END DO
1106

    
1107
 If (AnaGeom) THEN
1108
    If (NbVar>0) THEN
1109
! We print the description of the varialbes in AnaFile
1110
       Call PrintAnaList(IoDat)
1111
       If (OptGeom<=0) THEN
1112
          WRITE(IoDat,'(A)') "# s Var1 ... VarN Erel(kcal/mol) E (" // TRIM(UnitProg) //")"
1113
       ELSE
1114
          WRITE(IoDat,'(A)') "# Iter Var1 ... VarN Erel(kcal/mol) E (" // TRIM(UnitProg) //")"
1115
       END IF
1116
    ELSE
1117
       If (OptGeom<=0) THEN
1118
          WRITE(IoDat,'(A)') "#  s    Erel(kcal/mol)   E (" // TRIM(UnitProg) //")"
1119
       ELSE
1120
          WRITE(IoDat,'(A)') "#  Iter    Erel(kcal/mol)   E (" // TRIM(UnitProg) //")"       
1121
       END IF
1122
    END IF
1123
 END IF
1124

    
1125
  ! PFL 23 Sep 2008 ->
1126
  ! We check that frozen atoms are really frozen, ie that their coordinates do not change
1127
  ! between the first geometry and the others.
1128
  IF (NFroz.GT.0) THEN
1129
     ALLOCATE(ListAtFroz(Nat),x1(Nat),y1(nat),z1(nat))
1130
     ALLOCATE(x2(nat),y2(nat),z2(nat)) 
1131
     ListAtFroz=.FALSE.
1132

    
1133
     x1(1:Nat)=XyzgeomI(1,1,1:Nat)
1134
     y1(1:Nat)=XyzgeomI(1,2,1:Nat)
1135
     z1(1:Nat)=XyzgeomI(1,3,1:Nat)
1136

    
1137
     SELECT CASE (NFroz)
1138
        ! We have Frozen atoms
1139
        ! PFL 28 Oct 2008 ->
1140
        ! It might happen that the geometries are translated/rotated.
1141
        ! So if we have 3 (or more) frozen atoms, we re-orient the geometries, based on the first
1142
        ! three frozen atoms.
1143

    
1144
     CASE (3:)
1145
        DO I=1,NFroz
1146
           ListAtFroz(Frozen(I))=.TRUE.
1147
        END DO
1148
     CASE (2)
1149
        IAt1=Frozen(1)
1150
        IAt2=Frozen(2)
1151
        ListAtFroz(Iat1)=.TRUE.
1152
        ListAtFroz(Iat2)=.TRUE.
1153
        x2(1)=x1(Iat2)-x1(Iat1)
1154
        y2(1)=y1(Iat2)-y1(Iat1)
1155
        z2(1)=z1(Iat2)-z1(Iat1)
1156
        Norm1=sqrt(x2(1)**2+y2(1)**2+z2(1)**2)
1157
        Dist=-1.
1158
        ! We scan all atoms to find one that is not aligned with Iat1-Iat2
1159
        DO I=1,Nat
1160
           if ((I.EQ.Iat1).OR.(I.EQ.Iat2)) Cycle
1161
           x2(2)=x1(Iat2)-x1(I)
1162
           y2(2)=y1(Iat2)-y1(I)
1163
           z2(2)=z1(Iat2)-z1(I)
1164
           Norm2=sqrt(x2(2)**2+y2(2)**2+z2(2)**2)
1165
           ca=(x2(1)*x2(2)+y2(1)*y2(2)+z2(1)*Z2(2))/(Norm1*Norm2)
1166
           if (abs(ca)<0.9) THEN
1167
              IF (Norm2>Dist) THEN
1168
                 Iat3=I
1169
                 Dist=Norm2
1170
              END IF
1171
           END IF
1172
        END DO
1173
        ListAtFroz(Iat3)=.TRUE.
1174
        if (debug) WRITE(*,*) "DBG Path, NFroz=2, third frozen=",Iat3
1175
     CASE (1)
1176
        IAt1=Frozen(1)
1177
        ListAtFroz(Iat1)=.TRUE.
1178
        Dist=-1.
1179
        ! We scan all atoms to find one that is further from At1
1180
        DO I=1,Nat
1181
           if (I.EQ.Iat1) Cycle
1182
           x2(1)=x1(Iat1)-x1(I)
1183
           y2(1)=y1(Iat1)-y1(I)
1184
           z2(1)=z1(Iat1)-z1(I)
1185
           Norm1=sqrt(x2(1)**2+y2(1)**2+z2(1)**2)
1186
           IF (Norm1>Dist) THEN
1187
              Iat2=I
1188
              Dist=Norm1
1189
           END IF
1190
        END DO
1191
        ListAtFroz(Iat2)=.TRUE.
1192
        if (debug) WRITE(*,*) "DBG Path, NFroz=1, second frozen=",Iat2
1193
        x2(1)=x1(Iat2)-x1(Iat1)
1194
        y2(1)=y1(Iat2)-y1(Iat1)
1195
        z2(1)=z1(Iat2)-z1(Iat1)
1196
        Norm1=sqrt(x2(1)**2+y2(1)**2+z2(1)**2)
1197
        Dist=-1.
1198
        ! We scan all atoms to find one that is not aligned with Iat1-Iat2
1199
        Iat3=1
1200
        DO WHILE (ListAtFroz(Iat3).AND.(Iat3<=Nat))
1201
           Iat3=Iat3+1
1202
        END DO
1203
        DO I=1,Nat
1204
           if ((I.EQ.Iat1).OR.(I.EQ.Iat2)) Cycle
1205
           x2(2)=x1(Iat2)-x1(I)
1206
           y2(2)=y1(Iat2)-y1(I)
1207
           z2(2)=z1(Iat2)-z1(I)
1208
           Norm2=sqrt(x2(2)**2+y2(2)**2+z2(2)**2)
1209
           ca=(x2(1)*x2(2)+y2(1)*y2(2)+z2(1)*Z2(2))/(Norm1*Norm2)
1210
           if (abs(ca)<0.9) THEN
1211
              IF (Norm2>Dist) THEN
1212
                 Iat3=I
1213
                 Dist=Norm2
1214
              END IF
1215
           END IF
1216
        END DO
1217
        ListAtFroz(Iat3)=.TRUE.
1218
        if (debug) WRITE(*,*) "DBG Path, NFroz=1, third frozen=",Iat3
1219
     END SELECT
1220

    
1221
     DO I=2,NGeomI
1222
        ! First, we align the Ith geometry on the first one, using only
1223
        ! the positions of the "frozen" atoms. (see above: it might be that
1224
        ! ListAtFroz contains non frozen atoms used to align the geometries
1225
        x2(1:Nat)=XyzgeomI(I,1,1:Nat)
1226
        y2(1:Nat)=XyzgeomI(I,2,1:Nat)
1227
        z2(1:Nat)=XyzgeomI(I,3,1:Nat)
1228
        Call Alignpartial(Nat,x1,y1,z1,x2,y2,z2,ListAtFroz,MRot)
1229

    
1230
        FChkFrozen=.FALSE.
1231
        DO J=1,NFroz
1232
           IAt=Frozen(J)
1233
           IF ((abs(X1(Iat)-X2(Iat)).GT.FrozTol).OR. &
1234
                (abs(y1(Iat)-y2(Iat)).GT.FrozTol).OR.  &
1235
                (abs(z1(Iat)-z2(Iat)).GT.FrozTol))                     THEN
1236
              IF (.NOT.FChkFrozen) WRITE(*,*) "*** WARNING ****"
1237
              FChkFrozen=.TRUE.
1238
              WRITE(*,*) "Atom ",Iat," is set to Frozen but its coordinates change"
1239
              WRITE(*,*) "from geometry 1 to geometry ",I
1240
           END IF
1241
        END DO
1242
     END DO
1243
     IF (FChkFrozen) THEN
1244
        WRITE(*,*) "Some frozen atoms are not frozen... check this and play again"
1245
        STOP
1246
     END IF
1247
  END IF
1248

    
1249

    
1250
  N3at=3*Nat
1251
  NFree=N3at-6   ! ATTENTION: THIS IS NOT VALID FOR ALL TYPES OF COORDINATES.
1252

    
1253

    
1254
  Call ReadInput
1255

    
1256
  if (FPBC)  THEN
1257
     Allocate(XGeomRefPBC(Nat),YGeomRefPBC(Nat),ZGeomRefPBC(Nat))
1258
     XGeomRefPBC(1:Nat)=XyzGeomI(1,1,1:Nat)
1259
     YGeomRefPBC(1:Nat)=XyzGeomI(1,2,1:Nat)
1260
     ZGeomRefPBC(1:Nat)=XyzGeomI(1,3,1:Nat)
1261

    
1262
     Call CheckPeriodicBound
1263
  END IF
1264

    
1265
  IF (COORD=="MIXED") Call TestCart(AutoCart)
1266

    
1267
  SELECT CASE(NFroz)
1268
  CASE (2)
1269
     IntFroz=1
1270
  CASE (3)
1271
     IntFroz=3
1272
  CASE (4:)
1273
     IntFroz=(NFroz-2)*3  !(NFroz-3)*3+3
1274
  END SELECT
1275

    
1276
  if (debug) WRITE(*,'(1X,A,A,5I5)') "DBG Path, L825, Coord, NCart, NCoord, N3at, NFroz: "&
1277
       ,TRIM(COORD),Ncart,NCoord,N3at,NFroz
1278
  if (debug) WRITE(*,*) "DBG Path, L827, Cart",Cart
1279

    
1280
  if (((NCart+NFroz).EQ.0).AND.(Coord=="MIXED")) THEN
1281
     WRITE(IOOUT,*) "Coord=MIXED but Cart list empty: taking Coord=ZMAT."
1282
     COORD="ZMAT"
1283
  END IF
1284

    
1285
  IF ((Coord=="MIXED").AND.(NFroz.NE.0)) IntFroz=3*NFroz
1286

    
1287
  SELECT CASE(COORD)
1288
  CASE ('ZMAT')
1289
     NCoord=Nfree
1290
     ALLOCATE(dzdc(3,nat,3,nat))
1291
  CASE ('MIXED')
1292
     SELECT CASE (NCart+NFroz)
1293
     CASE (1) 
1294
        NCoord=N3At-3
1295
     CASE (2)
1296
        NCoord=N3At-1
1297
     CASE (3:)
1298
        NCoord=N3At
1299
     END SELECT
1300
     ALLOCATE(dzdc(3,nat,3,nat))
1301
  CASE ('BAKER')
1302
     Symmetry_elimination=0
1303
     NCoord=3*Nat-6-Symmetry_elimination !NFree = 3*Nat-6
1304
     ALLOCATE(BMat_BakerT(3*Nat,NCoord))
1305
     ALLOCATE(BTransInv(NCoord,3*Nat))
1306
     ALLOCATE(BTransInv_local(NCoord,3*Nat))
1307
  CASE ('HYBRID')
1308
     NCoord=N3at
1309
  CASE ('CART')
1310
     NCoord=N3at
1311
  END SELECT
1312

    
1313
  if (debug) WRITE(*,*) "DBG Path, L826, Coord, NCart,NCoord, N3At",TRIM(COORD),Ncart, NCoord,N3at
1314

    
1315
  ALLOCATE(IntCoordI(NGeomI,NCoord),IntCoordF(NGeomF,NCoord))
1316
  ALLOCATE(XyzGeomF(NGeomF,3,Nat),XyzTangent(NGeomF,3*Nat))
1317
  ALLOCATE(Vfree(NCoord,NCoord),IntTangent(NGeomF,NCoord))
1318
  ALLOCATE(Energies(NgeomF),ZeroVec(NCoord)) ! Energies is declared in  Path_module.f90
1319
  ALLOCATE(Grad(NGeomF,NCoord),GeomTmp(NCoord),GradTmp(NCoord))
1320
  ALLOCATE(GeomOld_all(NGeomF,NCoord),GradOld(NGeomF,NCoord))
1321
  ALLOCATE(Hess(NGeomF,NCoord,NCoord),SGeom(NGeomF)) ! SGeom is declared in  Path_module.f90
1322
  ALLOCATE(EPathOld(NGeomF),MaxStep(NGeomF))
1323

    
1324
  ZeroVec=0.d0
1325
  DO I =1, NGeomF
1326
     IntTangent(I,:)=0.d0
1327
  END DO
1328

    
1329
  if (debug) THEN
1330
     Print *, 'L886, IntTangent(1,:)='
1331
     Print *, IntTangent(1,:)
1332
  END IF
1333

    
1334
  if (.NOT.OptReac) Energies(1)=Ereac
1335
  if (.NOT.OptProd) Energies(NGeomF)=EProd
1336
  MaxStep=SMax
1337

    
1338
  ! We initialize the mass array
1339
  if (MW) THEN
1340
     WRITE(*,*) 'Working in MW coordinates'
1341
     DO I=1,Nat
1342
        massAt(I)=Mass(Atome(I))
1343
     END DO
1344
  ELSE
1345
     DO I=1,Nat
1346
        MassAt(I)=1.d0
1347
     END DO
1348
  END IF
1349

    
1350
  WRITE(*,*) "Prog=",TRIM(PROG)
1351

    
1352
  ALLOCATE(FrozAtoms(Nat))
1353

    
1354
  !  IF (debug) WRITe(*,*) "DBG Main L940 NFroz",NFroz
1355
  !  IF (debug) WRITe(*,*) "DBG Main L940 Frozen",Frozen
1356
  !  IF (debug) WRITe(*,*) "DBG Main L940 FrozAtoms",FrozAtoms
1357
  IF (NFroz.EQ.0) THEN
1358
     FrozAtoms=.TRUE.
1359
  ELSE
1360
     I=1
1361
     NFr=0
1362
     FrozAtoms=.False.
1363
     DO WHILE (Frozen(I).NE.0)
1364
        IF (Frozen(I).LT.0) THEN
1365
           DO J=Frozen(I-1),abs(Frozen(I))
1366
              IF (.NOT.FrozAtoms(J)) THEN
1367
                 NFr=NFr+1
1368
                 FrozAtoms(J)=.TRUE.
1369
              END IF
1370
           END DO
1371
        ELSEIF (.NOT.FrozAtoms(Frozen(I))) THEN
1372
           FrozAtoms(Frozen(I))=.TRUE.
1373
           NFr=NFr+1
1374
        END IF
1375
        I=I+1
1376
     END DO
1377
     IF (NFr.NE.NFroz) THEN
1378
        WRITE(*,*) "Pb in PATH: Number of Frozen atoms not good :-( ",NFroz,NFr
1379
        STOP
1380
     END IF
1381
  END IF
1382

    
1383
!  if (debug) THEN
1384
     !Print *, 'L968, IntTangent(1,:)='
1385
     !Print *, IntTangent(1,:)
1386
!  END IF
1387

    
1388
  ! We have read everything we needed... time to work :-)
1389
  IOpt=0
1390
  FirstTimePathCreate = .TRUE. ! Initialized.
1391
  Call PathCreate(IOpt)    ! IntTangent is also computed in PathCreate.
1392
  FirstTimePathCreate = .FALSE.
1393

    
1394
  if (debug) THEN
1395
     Print *, 'L980, IntTangent(1,:)='
1396
     Print *, IntTangent(1,:)
1397
  END IF
1398

    
1399
  ! PFL 30 Mar 2008 ->
1400
  ! The following is now allocated in Calc_Baker. This is more logical to me
1401
  !   IF (COORD .EQ. "BAKER") Then
1402
  !      ALLOCATE(XprimitiveF(NgeomF,NbCoords))
1403
  !      ALLOCATE(UMatF(NGeomF,NbCoords,NCoord))
1404
  !      ALLOCATE(BTransInvF(NGeomF,NCoord,3*Nat))
1405
  !   END IF
1406
  ! <- PFL 30 mar 2008
1407

    
1408
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1409
  !
1410
  !
1411
  ! OptGeom is the index of the geometry which is to be optimized.
1412
  IF (Optgeom.GT.0) THEN
1413
     Flag_Opt_Geom=.TRUE.
1414
     SELECT CASE(Coord)
1415
     CASE ('CART','HYBRID')
1416
!!! CAUTION : PFL 29.AUG.2008 ->
1417
        ! XyzGeomI/F stored in (NGeomI/F,3,Nat) and NOT (NGeomI/F,Nat,3)
1418
        ! This should be made  consistent !!!!!!!!!!!!!!!
1419
        GeomTmp=Reshape(reshape(XyzGeomI(OptGeom,:,:),(/Nat,3/),ORDER=(/2,1/)),(/3*Nat/))
1420
        !           GeomTmp=Reshape(XyzGeomF(IGeom,:,:),(/3*Nat/))
1421
!!! <- CAUTION : PFL 29.AUG.2008
1422
     CASE ('ZMAT','MIXED')
1423
        !GeomTmp=IntCoordF(OptGeom,:)
1424
        GeomTmp=IntCoordI(OptGeom,:)
1425
     CASE ('BAKER')
1426
        !GeomTmp=IntCoordF(OptGeom,:)
1427
        GeomTmp=IntCoordI(OptGeom,:)
1428
     CASE DEFAULT
1429
        WRITE(*,*) "Coord=",TRIM(COORD)," not recognized in Path L935.STOP"
1430
        STOP
1431
     END SELECT
1432

    
1433
     ! NCoord = NFree, Coord = Type of coordinate; e.g.: Baker
1434
     Flag_Opt_Geom = .TRUE.
1435
     Call Opt_geom(OptGeom,Nat,Ncoord,Coord,GeomTmp,E,Flag_Opt_Geom,Step_method)
1436

    
1437
     WRITE(Line,"('Geometry ',I3,' optimized')") Optgeom
1438
     if (debug) WRITE(*,*) "Before PrintGeom, L1059, Path.f90"
1439
     Call PrintGeom(Line,Nat,NCoord,GeomTmp,Coord,IoOut,Atome,Order,OrderInv,IndZmat)
1440
     STOP
1441
  END IF ! IF (Optgeom.GT.0) THEN
1442

    
1443
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1444
  ! End of GeomOpt
1445
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1446

    
1447
  IF (PathOnly) THEN
1448
     Call Header("PathOnly=.T. , Stop here")
1449
     Call Write_path(-1)
1450
     if ((prog.EQ.'VASP').OR.WriteVasp) Call Write_vasp(poscar)
1451
     STOP
1452
  END IF
1453

    
1454
  if ((debug.AND.(prog.EQ.'VASP')).OR.WriteVasp)  Call Write_vasp(poscar)
1455

    
1456
  DEALLOCATE(XyzGeomI,IntCoordI)
1457
  NGeomI=NGeomF
1458
  ALLOCATE(XyzGeomI(NGeomF,3,Nat),IntCoordI(NGeomF,NCoord))
1459

    
1460
  IF (DEBUG) WRITE(*,*) ' Back from PathCreate, L965, Path.f90'
1461
  ! we print this path, which is the first one :-) called Iteration0
1462
  ! we now have to calculate the gradient for each point (and the energy
1463
  ! if we work at 0K)
1464

    
1465
  if (DEBUG.AND.(COORD.EQ."BAKER")) THEN
1466
     DO IGeom=1,NGeomF
1467
        WRITE(*,*) "Before Calc_baker_allgeomf UMatF for IGeom=",IGeom
1468
        DO I=1,3*Nat-6
1469
           WRITE(*,'(50(1X,F12.8))') UMatF(IGeom,:,I)
1470
        END DO
1471
     END DO
1472
  END IF
1473

    
1474
  ! To calculate B^T^-1 for all extrapolated final geometries:
1475
  ! PFL 18 Jan 2008 ->
1476
  ! Added a test for COORD=BAKER before the call to calc_baker_allgeomF
1477
  IF (COORD.EQ."BAKER")   Call Calc_baker_allGeomF()
1478
  ! <-- PFL 18 Jan 2008
1479

    
1480
  if (DEBUG.AND.(COORD.EQ."BAKER")) THEN
1481
     DO IGeom=1,NGeomF
1482
        WRITE(*,*) "After Calc_baker_allgeomf UMatF for IGeom=",IGeom
1483
        DO I=1,3*Nat-6
1484
           WRITE(*,'(50(1X,F12.8))') UMatF(IGeom,:,I)
1485
        END DO
1486
     END DO
1487
  END IF
1488

    
1489
  IOpt=0
1490
  Call EgradPath(IOpt)
1491

    
1492
  if (debug)  WRITE(*,*) "Calling Write_path, L1002, Path.f90, IOpt=",IOpt
1493
  Call Write_path(IOpt)
1494
! Shall we analyze the geometries ?
1495
     IF (AnaGeom) Call AnaPath(Iopt,IoDat)
1496

    
1497
  if ((debug.AND.(prog.EQ.'VASP')).OR.WriteVasp)  Call Write_vasp(poscar)
1498

    
1499
  ! We have the geometries, the first gradients... we will generate the first hessian matrices :-)
1500
  ! ... v3.71 Only if IniHUp=.TRUE. which is not the default. In this version, we take the hessian
1501
  ! of end points as Unity matrices, and we update them along the path.
1502

    
1503
  ! By default, Hess=Id
1504
  Hess=0.
1505
  IF(Coord .EQ. "ZMAT") Then
1506
     ! We use the fact that we know that approximate good hessian values
1507
     ! are 0.5 for bonds, 0.1 for valence angle and 0.02 for dihedral angles
1508
     DO IGeom=1,NGeomF
1509
        Hess(IGeom,1,1)=0.5d0
1510
        Hess(IGeom,2,2)=0.5d0
1511
        Hess(IGeom,3,3)=0.1d0
1512
        DO J=1,Nat-3
1513
           Hess(IGeom,3*J+1,3*J+1)=0.5d0
1514
           Hess(IGeom,3*J+2,3*J+2)=0.1d0
1515
           Hess(IGeom,3*J+3,3*J+3)=0.02d0
1516
        END DO
1517
        IF (HInv) THEN
1518
           DO I=1,NCoord
1519
              Hess(IGeom,I,I)=1.d0/Hess(IGeom,I,I)
1520
           END DO
1521
        END IF
1522
     END DO
1523
  ELSE
1524
     DO I=1,NCoord
1525
        DO J=1,NGeomF
1526
           Hess(J,I,I)=1.d0
1527
        END DO
1528
     END DO
1529
  END IF
1530

    
1531
  IF (COORD .EQ. "BAKER") THEN
1532
     ! UMat(NPrim,NCoord)
1533
     ALLOCATE(Hprim(NPrim,NPrim),HprimU(NPrim,3*Nat-6))
1534
     Hprim=0.d0
1535
     ScanCoord=>Coordinate
1536
     I=0
1537
     DO WHILE (Associated(ScanCoord%next))
1538
        I=I+1
1539
        SELECT CASE (ScanCoord%Type)
1540
        CASE ('BOND')
1541
           !DO J=1,NGeomF ! why all geometries?? Should be only 1st and NGeomF??
1542
           Hprim(I,I) = 0.5d0
1543
           !END DO
1544
        CASE ('ANGLE')
1545
           Hprim(I,I) = 0.2d0
1546
        CASE ('DIHEDRAL')
1547
           Hprim(I,I) = 0.1d0
1548
        END SELECT
1549
        ScanCoord => ScanCoord%next
1550
     END DO
1551

    
1552
     ! HprimU = H^prim U:
1553
     HprimU=0.d0
1554
     DO I=1, 3*Nat-6
1555
        DO J=1,NPrim
1556
           HprimU(:,I) = HprimU(:,I) + Hprim(:,J)*UMat(J,I)
1557
        END DO
1558
     END DO
1559

    
1560
     ! Hess = U^T HprimU = U^T H^prim U:
1561
     Hess=0.d0
1562
     DO I=1, 3*Nat-6
1563
        DO J=1,NPrim
1564
           ! UMat^T is needed below.
1565
           Hess(1,:,I) = Hess(1,:,I) + UMat(J,:)*HprimU(J,I)
1566
        END DO
1567
     END DO
1568
     DO K=2,NGeomF
1569
        Hess(K,:,:)=Hess(1,:,:)
1570
     END DO
1571
     DEALLOCATE(Hprim,HprimU)
1572
  end if !  ends IF COORD=BAKER
1573
  ALLOCATE(GradTmp2(NCoord),GeomTmp2(NCoord))
1574
  ALLOCATE(HessTmp(NCoord,NCoord))
1575

    
1576
  IF (IniHUp) THEN
1577
     IF (FCalcHess) THEN
1578
        ! The numerical calculation of the Hessian has been switched on
1579
        DO IGeom=1,NGeomF
1580
           IF ((COORD.EQ.'ZMAT') .OR. (COORD.EQ.'BAKER')) THEN
1581
              GeomTmp=IntCoordF(IGeom,:)
1582
           ELSE
1583
              GeomTmp=Reshape(XyzGeomF(IGeom,:,:),(/3*Nat/))
1584
           END IF
1585
           Call CalcHess(NCoord,GeomTmp,Hess(IGeom,:,:),IGeom,Iopt)
1586
        END DO
1587
     ELSE
1588
        ! We generate a forward hessian and a backward one and we mix them.
1589
        ! First, the forward way:
1590
        DO IGeom=2,NGeomF-1
1591
           IF ((COORD.EQ.'ZMAT') .OR. (COORD.EQ.'BAKER')) THEN
1592
              GeomTmp=IntCoordF(IGeom,:)-IntCoordF(IGeom-1,:)
1593
           ELSE
1594
              GeomTmp=Reshape(XyzGeomF(IGeom,:,:),(/3*Nat/))-Reshape(XyzGeomF(IGeom-1,:,:),(/3*Nat/))
1595
           END IF
1596
           GradTmp=Grad(IGeom-1,:)-Grad(IGeom,:)
1597
           HessTmp=Hess(IGeom-1,:,:)
1598
           Call Hupdate_all(NCoord,GeomTmp,GradTmp,HessTmp)
1599
           Hess(IGeom,:,:)=HessTmp
1600
        END DO
1601

    
1602
        ! Now, the backward way:
1603
        HessTmp=Hess(NGeomF,:,:)
1604
        DO IGeom=NGeomF-1,2,-1
1605
           IF ((COORD.EQ.'ZMAT') .OR. (COORD.EQ.'BAKER')) THEN
1606
              GeomTmp=IntCoordF(IGeom,:)-IntCoordF(IGeom+1,:)
1607
           ELSE
1608
              GeomTmp=Reshape(XyzGeomF(IGeom,:,:),(/3*Nat/))-Reshape(XyzGeomF(IGeom+1,:,:),(/3*Nat/))
1609
           END IF
1610
           GradTmp=Grad(IGeom,:)-Grad(IGeom+1,:)
1611
           Call Hupdate_all(NCoord,GeomTmp,GradTmp,HessTmp)
1612
           alpha=0.5d0*Pi*(IGeom-1.)/(NGeomF-1.)
1613
           ca=cos(alpha)
1614
           sa=sin(alpha)
1615
           Hess(IGeom,:,:)=ca*Hess(IGeom,:,:)+sa*HessTmp(:,:)
1616
        END DO
1617
     END IF ! matches IF (FCalcHess)
1618
  END IF ! matches IF (IniHUp) THEN
1619

    
1620
  ! For debug purposes, we diagonalize the Hessian matrices
1621
  IF (debug) THEN
1622
     !WRITE(*,*) "DBG Main, L1104, - EigenSystem for Hessian matrices"
1623
     DO I=1,NGeomF
1624
        WRITE(*,*) "DBG Main - Point ",I
1625
        Call Jacobi(Hess(I,:,:),NCoord,GradTmp2,HessTmp,NCoord)
1626
        DO J=1,NCoord
1627
           WRITE(*,'(1X,I3,1X,F10.6," : ",20(1X,F8.4))') J,GradTmp2(J),HessTmp(J,1:min(20,NCoord))
1628
        END DO
1629
     END DO
1630
  END IF ! matches IF (debug) THEN
1631

    
1632
  ! we have the hessian matrices and the gradients, we can start the optimizations !
1633
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1634
  !
1635
  ! Main LOOP : Optimization of the Path
1636
  !
1637
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1638
  if (debug)   Print *, 'NGeomF=', NGeomF
1639
  allocation_flag = .TRUE.
1640

    
1641
  Fini=.FALSE.
1642

    
1643
  DO WHILE ((IOpt.LT.MaxCyc).AND.(.NOT. Fini))
1644
     if (debug) Print *, 'IOpt at the begining of the loop, L1128=', IOpt
1645
     IOpt=IOpt+1
1646

    
1647
     SELECT CASE (COORD)
1648
     CASE ('ZMAT','MIXED','BAKER')
1649
        GeomOld_all=IntCoordF
1650
     CASE ('CART','HYBRID')
1651
        GeomOld_all=Reshape(XyzGeomF,(/NGeomF,NCoord/))
1652
     CASE DEFAULT
1653
        WRITE(*,*) 'Coord=',TRIM(COORD),' not recognized. Path L1149.STOP'
1654
        STOP
1655
     END SELECT
1656

    
1657
     IF (((COORD.EQ.'ZMAT').OR.(COORD.EQ.'BAKER').OR.(COORD.EQ.'MIXED')).AND. &
1658
          valid("printtangent")) THEN
1659
        WRITE(*,*) "Visualization of tangents"
1660
        Idx=min(12,NCoord)
1661
        DO I=1,NGeomF
1662
           WRITE(*,'(12(1X,F12.5))') IntCoordF(I,1:Idx)-0.5d0*IntTangent(I,1:Idx)
1663
           WRITE(*,'(12(1X,F12.5))') IntCoordF(I,1:Idx)+0.5d0*IntTangent(I,1:Idx)
1664
           WRITE(*,*) 
1665
        END DO
1666
        WRITE(*,*) "END of tangents"
1667
     END IF
1668

    
1669
     IF (((COORD.EQ.'ZMAT').OR.(COORD.EQ.'BAKER').OR.(COORD.EQ.'MIXED')).AND. &
1670
          valid("printgrad")) THEN
1671
        WRITE(*,*) "Visualization of gradients"
1672
        Idx=min(12,NCoord)
1673
        DO I=1,NGeomF
1674
           WRITE(*,'(12(1X,F12.5))') IntCoordF(I,1:Idx)-1.d0*Grad(I,1:Idx)
1675
           WRITE(*,'(12(1X,F12.5))') IntCoordF(I,1:Idx)+1.d0*Grad(I,1:Idx)
1676
           WRITe(*,*) 
1677
        END DO
1678
        WRITE(*,*) "END of gradients"
1679
     END IF
1680

    
1681
     Fini=.TRUE.
1682
     IF (OptReac) THEN !OptReac: True if one wants to optimize the geometry of the reactants. Default is FALSE.
1683
        IGeom=1
1684
        if (debug) WRITE(*,*) '**************************************'
1685
        if (debug) WRITE(*,*) 'Optimizing reactant'
1686
        if (debug) WRITE(*,*) '**************************************'
1687
        SELECT CASE (COORD)
1688
        CASE ('ZMAT','MIXED','BAKER')
1689
           SELECT CASE (Step_method)
1690
           CASE ('RFO')
1691
              !GradTmp(NCoord) becomes Step in Step_RFO_all and has INTENT(OUT).
1692
              Call Step_RFO_all(NCoord,GradTmp,1,IntCoordF(1,:),Grad(1,:),Hess(1,:,:),ZeroVec)
1693
              Print *, GradTmp
1694
           CASE ('GDIIS')
1695
              ! GradTmp(NCoord) becomes "step" below and has INTENT(OUT).:
1696
              Call Step_DIIS_all(NGeomF,1,GradTmp,IntCoordF(1,:),Grad(1,:),HP,HEAT,&
1697
                   Hess(1,:,:),NCoord,allocation_flag,ZeroVec)
1698
              Print *, 'OptReac, Steps from GDIIS, GeomNew - IntCoordF(1,:)='
1699
              Print *, GradTmp
1700
           CASE ('GEDIIS')
1701
              ! GradTmp(NCoord) becomes "step" below and has INTENT(OUT).:
1702
              ! Energies are updated in EgradPath.f90
1703
              Call Step_GEDIIS_All(NGeomF,1,GradTmp,IntCoordF(1,:),Grad(1,:),Energies(1),Hess(1,:,:),&
1704
                   NCoord,allocation_flag,ZeroVec)
1705
              !Call Step_GEDIIS(GeomTmp,IntCoordF(1,:),Grad(1,:),Energies(1),Hess(1,:,:),NCoord,allocation_flag)
1706
              !GradTmp = GeomTmp - IntCoordF(1,:)
1707
              !Print *, 'Old Geometry:'
1708
              !Print *, IntCoordF(1,:)
1709
              Print *, 'OptReac, Steps from GEDIIS, GradTmp = GeomTmp - IntCoordF(1,:)='
1710
              Print *, GradTmp
1711
              !Print *, 'GeomTmp:'
1712
              !Print *, GeomTmp
1713
              GeomTmp(:) = GradTmp(:) + IntCoordF(1,:)
1714
           CASE DEFAULT
1715
              WRITE (*,*) "Step_method=",TRIM(Step_method)," not recognized, Path.f90, L1194. Stop"
1716
              STOP
1717
           END SELECT
1718
        CASE ('HYBRID','CART')
1719
           Call Step_RFO_all(NCoord,GradTmp,1,XyzGeomF(1,:,:),Grad(1,:),Hess(1,:,:),ZeroVec)
1720
        CASE DEFAULT
1721
           WRITE(*,*) 'Coord=',TRIM(COORD),' not recognized. Path L1200. STOP'
1722
           STOP
1723
        END SELECT
1724

    
1725
        IF (debug) THEN
1726
           WRITE(Line,*) 'DBG Path, L1227,', TRIM(Step_method), 'Step for IOpt=',IOpt, ', IGeom=1'
1727
           Call PrintGeom(Line,Nat,NCoord,GeomTmp,Coord,6,Atome,Order,OrderInv,IndZmat)
1728
        END IF
1729

    
1730
        ! we have the Newton+RFO step, we will check that the maximum displacement is not greater than Smax
1731
        NormStep=sqrt(DOT_Product(GradTmp,GradTmp))      
1732
        FactStep=min(1.d0,MaxStep(Igeom)/NormStep)
1733
        Fini=(Fini.AND.(NormStep.LE.SThresh))
1734
        OptReac=(NormStep.GT.SThresh)
1735
        IF (debug) WRITE(*,*) "NormStep, SThresh, OptReac=",NormStep, SThresh, OptReac
1736
        NormGrad=sqrt(DOT_Product(reshape(Grad(1,:),(/Nfree/)),reshape(Grad(1,:),(/NFree/))))
1737
        Fini=(Fini.AND.(NormGrad.LE.GThresh))
1738
        OptReac=(OptReac.OR.(NormGrad.GT.GThresh))
1739
        !Print *, 'Grad(1,:):'
1740
        !Print *, Grad(1,:)
1741
        IF (debug) WRITE(*,*) "NormGrad, GThresh, OptReac=",NormGrad, GThresh, OptReac
1742

    
1743
        GradTmp=GradTmp*FactStep
1744

    
1745
        ! we take care that frozen atoms do not move.
1746
        IF (NFroz.NE.0) THEN
1747
           SELECT CASE (COORD)
1748
           CASE ('ZMAT','MIXED')
1749
              GradTmp(1:IntFroz)=0.d0
1750
           CASE ('CART','HYBRID')
1751
              DO I=1,Nat
1752
                 IF (FrozAtoms(I)) THEN
1753
                    Iat=Order(I)
1754
                    GradTmp(3*Iat-2:3*Iat)=0.d0
1755
                 END IF
1756
              END DO
1757
           CASE('BAKER')
1758
              GradTmp(1:IntFroz)=0.d0 !GradTmp is "step" in Step_RFO_all(..)
1759
           CASE DEFAULT
1760
              WRITE(*,*) 'Coord=',TRIM(COORD),' not recognized. Path L1323.STOP'
1761
              STOP
1762
           END SELECT
1763
        END IF ! matches IF (NFroz.NE.0) THEN
1764

    
1765
        IF (debug) THEN
1766
           !WRITE(Line,*) 'DBG Path, L1244, Step for IOpt=',IOpt, ', IGeom=1'
1767
           !Call PrintGeom(Line,Nat,NCoord,GradTmp,Coord,6,Atome,Order,OrderInv,IndZmat)
1768
        END IF
1769

    
1770
        IF (debug) THEN
1771
           !WRITE(*,*) "DBG Main, L1249, IOpt=",IOpt, ', IGeom=1'
1772
           IF ((COORD.EQ.'ZMAT') .OR. (COORD.EQ.'BAKER')) THEN
1773
              WRITE(*,'(12(1X,F8.3))') IntCoordF(1,1:min(12,NFree))
1774
           ELSE
1775
              DO Iat=1,Nat
1776
                 WRITE(*,'(1X,A5,3(1X,F11.6))') Nom(Atome(Iat)), &
1777
                      XyzGeomF(IGeom,1:3,Iat)
1778
              END DO
1779
           END IF
1780
        END IF ! matches IF (debug) THEN
1781

    
1782
        SELECT CASE (COORD)
1783
        CASE ('ZMAT','MIXED','BAKER')
1784
           IntcoordF(1,:)=IntcoordF(1,:)+GradTmp(:) !IGeom=1
1785
        CASE ('HYBRID','CART')
1786
           XyzGeomF(1,:,:)=XyzGeomF(1,:,:)+reshape(GradTmp(:),(/3,Nat/))
1787
        CASE DEFAULT
1788
           WRITE(*,*) 'Coord=',TRIM(COORD),' not recognized. Path L1201.STOP'
1789
           STOP
1790
        END SELECT
1791

    
1792
        IF (debug) THEN
1793
           WRITE(*,*) "DBG Main, L1271, IOpt=",IOpt, ', IGeom=1'
1794
           IF ((COORD.EQ.'ZMAT') .OR. (COORD.EQ.'BAKER')) THEN
1795
              WRITE(*,'(12(1X,F8.3))') IntCoordF(1,1:min(12,NFree))
1796
           ELSE
1797
              DO Iat=1,Nat
1798

    
1799
!!!!!!!!!! There was an OrderInv here... should I put it back ?
1800
                 ! It was with indzmat. IndZmat cannot appear here...
1801
                 WRITE(*,'(1X,A5,3(1X,F11.6))') Nom(Atome(Iat)), &
1802
                      XyzGeomF(IGeom,1:3,Iat)
1803
              END DO
1804
           END IF
1805
        END IF ! matches IF (debug) THEN
1806

    
1807
        IF (.NOT.OptReac) WRITE(*,*) "Reactants optimized"
1808
     ELSE ! Optreac
1809
        IF (debug) WRITE(*,*) "Reactants already optimized, Fini=",Fini
1810
     END IF ! matches IF (OptReac) THEN
1811

    
1812
     IF (OptProd) THEN !OptProd: True if one wants to optimize the geometry of the products. Default is FALSE.
1813
        IGeom=NGeomF
1814
        if (debug) WRITE(*,*) '******************'
1815
        if (debug) WRITE(*,*) 'Optimizing product'
1816
        if (debug) WRITE(*,*) '******************'
1817
        SELECT CASE (COORD)
1818
        CASE ('ZMAT','MIXED','BAKER')
1819
           Print *, 'Optimizing product'
1820
           SELECT CASE (Step_method)
1821
           CASE ('RFO')
1822
              !GradTmp(NCoord)) becomes "Step" in Step_RFO_all and has INTENT(OUT).
1823
              Call Step_RFO_all(NCoord,GradTmp,NGeomF,IntCoordF(NGeomF,:),Grad(NGeomF,:),Hess(NGeomF,:,:),ZeroVec)
1824
              Print *, GradTmp
1825
           CASE ('GDIIS')
1826
              ! GradTmp becomes "step" below and has INTENT(OUT):
1827
              Call Step_DIIS_all(NGeomF,NGeomF,GradTmp,IntCoordF(NGeomF,:),Grad(NGeomF,:),&
1828
                   HP,HEAT,Hess(NGeomF,:,:),NCoord,allocation_flag,ZeroVec)
1829
              Print *, 'OptProd, Steps from GDIIS, GeomNew - IntCoordF(NGeomF,:)='
1830
              Print *, GradTmp
1831
           CASE ('GEDIIS')
1832
              ! GradTmp(NCoord) becomes "step" below and has INTENT(OUT):
1833
              Call Step_GEDIIS_All(NGeomF,NGeomF,GradTmp,IntCoordF(NGeomF,:),Grad(NGeomF,:),Energies(NGeomF),&
1834
                   Hess(NGeomF,:,:),NCoord,allocation_flag,ZeroVec)
1835
              Print *, 'OptProd, Steps from GEDIIS, GeomNew - IntCoordF(NGeomF,:)='
1836
              Print *, GradTmp
1837
           CASE DEFAULT
1838
              WRITE (*,*) "Step_method=",TRIM(Step_method)," not recognized, Path.f90, L1309. Stop"
1839
              STOP
1840
           END SELECT
1841
        CASE ('HYBRID','CART')
1842
           Call Step_RFO_all(NCoord,GradTmp,IGeom,XyzGeomF(NGeomF,:,:),Grad(NGeomF,:),Hess(NGeomF,:,:),ZeroVec)
1843
        CASE DEFAULT
1844
           WRITE(*,*) 'Coord=',TRIM(COORD),' not recognized. Path L1460.STOP'
1845
           STOP
1846
        END SELECT
1847

    
1848
        ! we have the Newton+RFO step, we will check that the displacement is not greater than Smax
1849
        NormStep=sqrt(DOT_Product(GradTmp,GradTmp))      
1850
        FactStep=min(1.d0,MaxStep(IGeom)/NormStep)
1851
        Fini=(Fini.AND.(NormStep.LE.SThresh))
1852
        OptProd=.NOT.(NormStep.LE.SThresh)
1853
        NormGrad=sqrt(DOT_Product(reshape(Grad(NGeomF,:),(/Nfree/)),reshape(Grad(NGeomF,:),(/NFree/))))
1854
        Fini=(Fini.AND.(NormGrad.LE.GThresh))
1855
        OptProd=(OptProd.OR.(NormGrad.GT.GThresh))
1856
        IF (debug) WRITE(*,*) "NormGrad, GThresh, OptProd=",NormGrad, GThresh, OptProd
1857

    
1858
        GradTmp=GradTmp*FactStep
1859

    
1860
        ! we take care that frozen atoms do not move
1861
        IF (NFroz.NE.0) THEN
1862
           SELECT CASE (COORD)
1863
           CASE ('ZMAT','MIXED','BAKER')
1864
              GradTmp(1:IntFroz)=0.d0
1865
           CASE ('CART','HYBRID')
1866
              DO I=1,Nat
1867
                 IF (FrozAtoms(I)) THEN
1868
                    Iat=Order(I)
1869
                    GradTmp(3*Iat-2:3*Iat)=0.d0
1870
                 END IF
1871
              END DO
1872
           CASE DEFAULT
1873
              WRITE(*,*) 'Coord=',TRIM(COORD),' not recognized. Path L1045.STOP'
1874
              STOP
1875
           END SELECT
1876
        END IF ! matches IF (NFroz.NE.0) THEN
1877

    
1878
        IF (debug) THEN
1879
           WRITE(*,*) "DBG Main, L1354, IGeom=, IOpt=",IGeom,IOpt
1880
           IF ((COORD.EQ.'ZMAT') .OR. (COORD.EQ.'BAKER')) THEN
1881
              WRITE(*,'(12(1X,F8.3))') IntCoordF(IGeom,1:min(12,NFree))
1882
           ELSE
1883
              DO Iat=1,Nat
1884
                 WRITE(*,'(1X,A5,3(1X,F11.6))') Nom(Atome(Iat)), &
1885
                      XyzGeomF(IGeom,1:3,Iat)
1886
              END DO
1887
           END IF
1888
        END IF
1889

    
1890
        SELECT CASE (COORD)
1891
        CASE ('ZMAT','MIXED','BAKER')
1892
           IntcoordF(NGeomF,:)=IntcoordF(NGeomF,:)+GradTmp(:) ! IGeom is NGeomF.
1893
        CASE ('HYBRID','CART')
1894
           XyzGeomF(IGeom,:,:)=XyzGeomF(IGeom,:,:)+reshape(GradTmp(:),(/3,Nat/))
1895
        CASE DEFAULT
1896
           WRITE(*,*) 'Coord=',TRIM(COORD),' not recognized. Path L1050.STOP'
1897
           STOP
1898
        END SELECT
1899

    
1900
        IF (debug) THEN
1901
           WRITE(*,*) "DBG Main, L1376, IGeom=, IOpt=",IGeom,IOpt
1902
           IF ((COORD.EQ.'ZMAT') .OR. (COORD.EQ.'BAKER')) THEN
1903
              WRITE(*,'(12(1X,F8.3))') IntCoordF(IGeom,1:min(12,NFree))
1904
           ELSE
1905
              DO Iat=1,Nat
1906
                 WRITE(*,'(1X,A5,3(1X,F11.6))') Nom(Atome(Iat)), &
1907
                      XyzGeomF(IGeom,1:3,Iat)
1908
              END DO
1909
           END IF
1910
        END IF
1911
     ELSE ! Optprod
1912
        IF (debug) WRITE(*,*) "Product already optimized, Fini=",Fini
1913
     END IF !matches IF (OptProd) THEN 
1914

    
1915
     IF (debug) WRITE(*,*) "Fini before L1491 path:",Fini
1916

    
1917
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1918
     !
1919
     !  Optimizing other geometries
1920
     !
1921
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1922

    
1923

    
1924

    
1925
     DO IGeom=2,NGeomF-1 ! matches at L1556
1926
        if (debug) WRITE(*,*) '****************************'
1927
        if (debug) WRITE(*,*) 'All other geometries, IGeom=',IGeom
1928
        if (debug) WRITE(*,*) '****************************'
1929

    
1930
        SELECT CASE (COORD)
1931
        CASE ('ZMAT','BAKER','MIXED')
1932
           GradTmp2=reshape(IntTangent(IGeom,:),(/NCoord/))
1933
           ! PFL 6 Apr 2008 ->
1934
           ! Special case, if FTan=0. we do not consider Tangent at all.
1935
           ! To DO: add the full treatment of FTan
1936
           if (FTan==0.) GradTmp2=ZeroVec
1937
           ! <- PFL 6 Apr 2008
1938
           if (debug) THEN
1939
              Print *, 'L1500, IntTangent(',IGeom,',:)='
1940
              Print *, IntTangent(IGeom,:)
1941
           END IF
1942
           !GradTmp(NCoord)) is actually "Step" in Step_RFO_all and has INTENT(OUT).
1943
           SELECT CASE (Step_method)
1944
           CASE ('RFO')
1945
              Call Step_RFO_all(NCoord,GradTmp,IGeom,IntCoordF(IGeom,:),Grad(IGeom,:),Hess(IGeom,:,:),GradTmp2)
1946
           CASE ('GDIIS')
1947
              !The following has no effect at IOpt==1
1948
              !Print *, 'Before call of Step_diis_all, All other geometries, IGeom=', IGeom
1949
              Call Step_DIIS_all(NGeomF,IGeom,GradTmp,IntCoordF(IGeom,:),Grad(IGeom,:),HP,HEAT,&        
1950
                   Hess(IGeom,:,:),NCoord,allocation_flag,GradTmp2)
1951
              Print *, 'All others, Steps from GDIIS, GeomNew - IntCoordF(IGeom,:)='
1952
              Print *, GradTmp
1953
           CASE ('GEDIIS')
1954
              ! GradTmp(NCoord) becomes "step" below and has INTENT(OUT):
1955
              Call Step_GEDIIS_All(NGeomF,IGeom,GradTmp,IntCoordF(IGeom,:),Grad(IGeom,:),Energies(IGeom),&
1956
                   Hess(IGeom,:,:),NCoord,allocation_flag,GradTmp2)
1957
              Print *, 'All others, Steps from GEDIIS, GeomNew - IntCoordF(IGeom,:)='
1958
              Print *, GradTmp
1959
           CASE DEFAULT
1960
              WRITE (*,*) "Step_method=",TRIM(Step_method)," not recognized, Path.f90, L1430. Stop"
1961
              STOP
1962
           END SELECT
1963
        CASE ('HYBRID','CART')
1964
           ! XyzTangent is implicitely in Nat,3... but all the rest is 3,Nat
1965
           ! so we change it
1966
           DO I=1,Nat
1967
              DO J=1,3
1968
                 GradTmp2(J+(I-1)*3)=XyzTangent(IGeom,(J-1)*Nat+I)
1969
              END DO
1970
           END DO
1971
           !           GradTmp2=XyzTangent(IGeom,:)
1972
           ! PFL 6 Apr 2008 ->
1973
           ! Special case, if FTan=0. we do not consider Tangent at all.
1974
           ! To DO: add the full treatment of FTan
1975
           if (FTan==0.) GradTmp2=ZeroVec
1976
           ! <- PFL 6 Apr 2008
1977

    
1978
           Call Step_RFO_all(NCoord,GradTmp,IGeom,XyzGeomF(IGeom,:,:),Grad(IGeom,:),Hess(IGeom,:,:),GradTmp2)
1979
        CASE DEFAULT
1980
           WRITE(*,*) 'Coord=',TRIM(COORD),' not recognized. Path L1083.STOP'
1981
           STOP
1982
        END SELECT
1983

    
1984
        ! we take care that frozen atoms do not move
1985
        IF (NFroz.NE.0) THEN
1986
           SELECT CASE (COORD)
1987
           CASE ('ZMAT','MIXED','BAKER')
1988
              IF (debug) THEN 
1989
                 WRITE(*,*) 'Step computed. Coord=',Coord
1990
                 WRITE(*,*) 'Zeroing components for frozen atoms. Intfroz=', IntFroz
1991
              END IF
1992
              GradTmp(1:IntFroz)=0.d0
1993
           CASE ('CART','HYBRID')
1994
              if (debug) THEN
1995
                 WRITE(*,*) "DBG Path Zeroing components L1771. Step before zeroing"
1996
                 DO I=1,Nat
1997
                    WRITe(*,*) I,GradTmp(3*I-2:3*I)
1998
                 END DO
1999
              END IF
2000
              DO I=1,Nat
2001
                 IF (FrozAtoms(I)) THEN
2002
                    if (debug) THEN
2003
                       write(*,*) 'Step Computed. Coord=',Coord
2004
                       WRITE(*,*) 'Atom',I,' is frozen. Zeroing',Order(I)
2005
                    END IF
2006
                    Iat=Order(I)
2007
                    GradTmp(3*Iat-2:3*Iat)=0.d0
2008
                 END IF
2009
              END DO
2010

    
2011
                 if (debug) THEN
2012
                    WRITE(*,*) "DBG Path Zeroing components L1785. Step After zeroing"
2013
                    DO I=1,Nat
2014
                       WRITe(*,*) I,GradTmp(3*I-2:3*I)
2015
                    END DO
2016
                 END IF
2017

    
2018
           CASE DEFAULT
2019
              WRITE(*,*) 'Coord=',TRIM(COORD),' not recognized. Path L1338.STOP'
2020
              STOP
2021
           END SELECT
2022
        END IF !matches IF (NFroz.NE.0) THEN
2023

    
2024
        IF (debug) THEN
2025
           SELECT CASE (COORD)
2026
           CASE ('ZMAT','MIXED','BAKER')
2027
              WRITE(*,'(A,12(1X,F8.3))') 'Step tan:',IntTangent(IGeom,1:min(12,NFree))
2028
              WRITE(*,'(A,12(1X,F8.3))') 'Ortho Step:',GradTmp(1:min(12,NFree))
2029
           CASE ('CART','HYBRID')
2030
              WRITE(*,'(A,12(1X,F8.3))') 'Step tan:',XyzTangent(IGeom,1:min(12,NFree))
2031
               WRITE(*,'(A,12(1X,F8.3))') 'Ortho Step:',GradTmp(1:min(12,NFree))
2032
           CASE DEFAULT
2033
              WRITE(*,*) 'Coord=',TRIM(COORD),' not recognized. Path L1588.STOP'
2034
              STOP
2035
           END SELECT
2036
        END IF ! matches if (debug) THEN
2037

    
2038
        ! we check that the maximum displacement is not greater than Smax
2039
        If (debug) WRITE(*,*) "Fini before test:",Fini
2040
        NormStep=sqrt(DOT_Product(GradTmp,GradTmp))      
2041
        FactStep=min(1.d0,maxStep(Igeom)/NormStep)
2042
        Fini=(Fini.AND.(NormStep.LE.SThresh))
2043
        IF (debug) WRITE(*,*) "IGeom,NormStep, SThresh,Fini",IGeom,NormStep, SThresh, Fini
2044

    
2045
        GradTmp=GraDTmp*FactStep
2046

    
2047
        if (debug) WRITE(*,*) "DBG Main, L1475, FactStep=",FactStep
2048
        if (debug.AND.(COORD.EQ.'ZMAT')) WRITE(*,'(A,12(1X,F10.6))') 'Scaled Step:',GradTmp(1:min(12,NFree))
2049

    
2050
        IF (debug) THEN
2051
           WRITE(*,*) "DBG Main, L1479, IGeom=, IOpt=",IGeom,IOpt
2052
           IF ((COORD.EQ.'ZMAT') .OR. (COORD.EQ.'BAKER')) THEN
2053
              WRITE(*,'(12(1X,F8.3))') IntCoordF(IGeom,1:min(12,NFree))
2054
           ELSE
2055
              DO Iat=1,Nat
2056
                 WRITE(*,'(1X,A5,3(1X,F11.6))') Nom(Atome(Iat)), &
2057
                      XyzGeomF(IGeom,1:3,Iat)
2058
              END DO
2059
           END IF
2060
        END IF ! matches if (debug) THEN
2061

    
2062
        SELECT CASE (COORD)
2063
        CASE ('ZMAT')
2064
           IntcoordF(IGeom,:)=IntcoordF(IGeom,:)+GradTmp(:)
2065
           if (debug) Print *, 'New Geom=IntcoordF(',IGeom,',:)=', IntcoordF(IGeom,:)
2066
           WRITE(IOOUT,"('Geometry ',I3,'/',I3,' for iteration ',I3)") IGeom,NgeomF,IOpt
2067
           WRITE(IOOUT,'(1X,A5,3(1X,I4,1X,F11.6))') Nom(Atome(OrderInv(indzmat(1,1))))
2068
           WRITE(IOOUT,'(1X,A5,3(1X,I4,1X,F11.6))') Nom(Atome(OrderInv(indzmat(2,1)))), &
2069
                OrderInv(indzmat(2,2)),IntcoordF(IGeom,1)
2070
           WRITE(IOOUT,'(1X,A5,3(1X,I4,1X,F11.6))') Nom(Atome(OrderInv(indzmat(3,1)))), &
2071
                OrderInv(indzmat(3,2)),IntcoordF(IGeom,2), OrderInv(indzmat(3,3)),IntcoordF(IGeom,3)*180./Pi
2072
           Idx=4
2073
           DO Iat=4,Nat
2074
              WRITE(IOOUT,'(1X,A5,3(1X,I4,1X,F11.6))') Nom(Atome(OrderInv(indzmat(iat,1)))), &
2075
                   OrderInv(indzmat(iat,2)),IntcoordF(IGeom,Idx), &
2076
                   OrderInv(indzmat(iat,3)),IntcoordF(IGeom,Idx+1)*180./pi, &
2077
                   OrderInv(indzmat(iat,4)),IntcoordF(IGeom,Idx+2)*180/Pi
2078
              Idx=Idx+3
2079
           END DO
2080

    
2081
        CASE ('BAKER')
2082
           IntcoordF(IGeom,:)=IntcoordF(IGeom,:)+GradTmp(:)
2083
           if (debug) Print *, 'New Geom=IntcoordF(',IGeom,',:)=', IntcoordF(IGeom,:)
2084
           WRITE(IOOUT,"('Geometry ',I3,'/',I3,' for iteration ',I3)") IGeom,NgeomF,IOpt
2085
           WRITE(IOOUT,*) "COORD=BAKER, printing IntCoordF is not meaningfull."
2086

    
2087
        CASE ('MIXED')
2088
           IntcoordF(IGeom,:)=IntcoordF(IGeom,:)+GradTmp(:)
2089
           if (debug) Print *, 'New Geom=IntcoordF(',IGeom,',:)=', IntcoordF(IGeom,:)
2090
           WRITE(IOOUT,"('Geometry ',I3,'/',I3,' for iteration ',I3)") IGeom,NgeomF,IOpt
2091
           DO Iat=1,NCart
2092
              WRITE(IOOUT,'(1X,A5,3(1X,F13.8))') Nom(Atome(OrderInv(indzmat(1,1)))),IntcoordF(IGeom,3*Iat-2:3*Iat)
2093
           END DO
2094
           Idx=3*NCart+1
2095
           IF (NCart.EQ.1) THEN
2096
              WRITE(IOOUT,'(1X,A5,3(1X,I4,1X,F11.6))') Nom(Atome(OrderInv(indzmat(2,1)))), &
2097
                   OrderInv(indzmat(2,2)),IntcoordF(IGeom,4)
2098
              WRITE(IOOUT,'(1X,A5,3(1X,I4,1X,F11.6))') Nom(Atome(OrderInv(indzmat(3,1)))), &
2099
                   OrderInv(indzmat(3,2)),IntcoordF(IGeom,5), OrderInv(indzmat(3,3)),IntcoordF(IGeom,6)*180./Pi
2100

    
2101
              Idx=7
2102
           END IF
2103
           IF (NCart.EQ.2) THEN
2104
              WRITE(IOOUT,'(1X,A5,3(1X,I4,1X,F11.6))') Nom(Atome(OrderInv(indzmat(3,1)))), &
2105
                   OrderInv(indzmat(3,2)),IntcoordF(IGeom,7), OrderInv(indzmat(3,3)),IntcoordF(IGeom,8)*180./Pi
2106
              Idx=9
2107
           END IF
2108

    
2109
           
2110
           DO Iat=max(NCart+1,4),Nat
2111
              WRITE(IOOUT,'(1X,A5,3(1X,I4,1X,F11.6))') Nom(Atome(OrderInv(indzmat(iat,1)))), &
2112
                   OrderInv(indzmat(iat,2)),IntcoordF(IGeom,Idx), &
2113
                   OrderInv(indzmat(iat,3)),IntcoordF(IGeom,Idx+1)*180./pi, &
2114
                   OrderInv(indzmat(iat,4)),IntcoordF(IGeom,Idx+2)*180/Pi
2115
              Idx=Idx+3
2116
           END DO
2117
           if (debug) Print *, 'New Geom=IntcoordF(',IGeom,',:)=', IntcoordF(IGeom,:)
2118

    
2119
        CASE ('HYBRID','CART')
2120
           XyzGeomF(IGeom,:,:)=XyzGeomF(IGeom,:,:)+reshape(GradTmp(:),(/3,Nat/))
2121
        CASE DEFAULT
2122
           WRITE(*,*) 'Coord=',TRIM(COORD),' not recognized. Path L1537.STOP'
2123
           STOP
2124
        END SELECT
2125

    
2126
        IF (debug) THEN
2127
           WRITE(*,*) "DBG Main, L1516, IGeom=, IOpt=",IGeom,IOpt
2128
           IF ((COORD.EQ.'ZMAT') .OR. (COORD.EQ.'BAKER')) THEN
2129
              WRITE(*,'(12(1X,F8.3))') IntCoordF(IGeom,1:min(12,NFree))
2130
           ELSE
2131
              DO Iat=1,Nat
2132
                 WRITE(*,'(1X,A5,3(1X,F11.6))') Nom(Atome(Iat)), &
2133
                      XyzGeomF(IGeom,1:3,Iat)
2134
              END DO
2135
           END IF
2136
        END IF ! matches if (debug) THEN
2137

    
2138
        ! We project out the tangential part of the gradient to know if we are done
2139
        GradTmp=Grad(IGeom,:)
2140
        NormGrad=sqrt(dot_product(GradTmp,GradTmp))
2141
        if (debug) WRITE(*,*) "Norm Grad tot=",NormGrad
2142
        SELECT CASE (COORD)
2143
        CASE ('ZMAT','MIXED','BAKER')
2144
           S=DOT_PRODUCT(GradTmp,IntTangent(IGeom,:))
2145
           Norm=DOT_PRODUCT(IntTangent(IGeom,:),IntTangent(IGeom,:))
2146
           GradTmp=GradTmp-S/Norm*IntTangent(IGeom,:)
2147
           Ca=S/(sqrt(Norm)*NormGrad)
2148
           S=DOT_PRODUCT(GradTmp,IntTangent(IGeom,:))
2149
           GradTmp=GradTmp-S/Norm*IntTangent(IGeom,:)
2150
        CASE ('CART','HYBRID')
2151
           S=DOT_PRODUCT(GradTmp,XyzTangent(IGeom,:))
2152
           Norm=DOT_PRODUCT(XyzTangent(IGeom,:),XyzTangent(IGeom,:))
2153
           Ca=S/(sqrt(Norm)*NormGrad)
2154
           GradTmp=GradTmp-S/Norm*XyzTangent(IGeom,:)
2155
           S=DOT_PRODUCT(GradTmp,XyzTangent(IGeom,:))
2156
           GradTmp=GradTmp-S/Norm*XyzTangent(IGeom,:)
2157
        CASE DEFAULT
2158
           WRITE(*,*) 'Coord=',TRIM(COORD),' not recognized. Path L1190.STOP'
2159
           STOP
2160
        END SELECT
2161
        IF (debug) WRITE(*,'(1X,A,3(1X,F10.6))') "cos and angle between grad and tangent",ca, acos(ca), acos(ca)*180./pi
2162
        NormGrad=sqrt(DOT_Product(GradTmp,GradTmp))
2163
        Fini=(Fini.AND.(NormGrad.LE.GThresh))
2164
        IF (debug) WRITE(*,*) "NormGrad_perp, GThresh, Fini=",NormGrad, GThresh, Fini
2165

    
2166
     END DO ! matches DO IGeom=2,NGeomF-1
2167
     ! we save the old gradients
2168
     GradOld=Grad
2169
     EPathOld=Energies
2170

    
2171

    
2172

    
2173
     ! Shall we re-parameterize the path ?
2174
     ! PFL 2007/Apr/10 ->
2175
     ! We call PathCreate in all cases, it will take care of the 
2176
     ! reparameterization, as well as calculating the tangents.
2177
     !     IF (MOD(IOpt,IReparam).EQ.0) THEN
2178
     XyzGeomI=XyzGeomF
2179
     IntCoordI=IntCoordF
2180

    
2181
     Call PathCreate(IOpt)
2182
     !     END IF
2183
     ! <- PFL 2007/Apr/10
2184

    
2185
     if (debug) WRITE(*,'(1X,A,I5,A,I5,A,L2)')  'Path.f90, L1415, IOpt=', IOpt, 'MaxCyc=', MaxCyc,' Fini=', Fini
2186
     IF ((.NOT.Fini).AND.(IOpt.LT.MaxCyc)) THEN
2187

    
2188
        ! We have the new path, we calculate its energy and gradient
2189

    
2190
        Call EgradPath(IOpt)
2191
        !IF(IOPT .EQ. 10) Then
2192
        !         Print *, 'Stopping at my checkpoint.'
2193
        !           STOP !This is my temporary checkpoint.
2194
        !ENDIF
2195

    
2196
        ! PFL 31 Mar 2008 ->
2197
        ! Taken from v3.99 but we added a flag...
2198
        ! Added in v3.99 : MaxStep is modified according to the evolution of energies
2199
        ! if Energies(IGeom)<=EPathOld then MaxStep is increased by 1.1 
2200
        ! else it is decreased by 0.8
2201

    
2202
        if (DynMaxStep) THEN
2203
           if (debug) WRITE(*,*) "Dynamically updating the Maximum step"
2204
           if (OptReac) THEN
2205
              If (Energies(1)<EPathOld(1)) Then
2206
                 MaxStep(1)=min(1.1*MaxStep(1),2.*SMax)
2207
              ELSE
2208
                 MaxStep(1)=max(0.8*MaxStep(1),SMax/2.)
2209
              END IF
2210
           END IF
2211

    
2212
           if (OptProd) THEN
2213
              If (Energies(NGeomF)<EPathOld(NGeomF)) Then
2214
                 MaxStep(NGeomF)=min(1.1*MaxStep(NGeomF),2.*SMax)
2215
              ELSE
2216
                 MaxStep(NGeomF)=max(0.8*MaxStep(NGeomF),SMax/2.)
2217
              END IF
2218
           END IF
2219

    
2220
           DO IGeom=2,NGeomF-1
2221
              If (Energies(IGeom)<EPathOld(IGeom)) Then
2222
                 MaxStep(IGeom)=min(1.1*MaxStep(IGeom),2.*SMax)
2223
              ELSE
2224
                 MaxStep(IGeom)=max(0.8*MaxStep(IGeom),SMax/2.)
2225
              END IF
2226
           END DO
2227
           if (debug) WRITE(*,*) "Maximum step",MaxStep(1:NgeomF)
2228
        END IF ! test on DynMaxStep
2229
        if (debug) WRITE(*,*) "Maximum step",MaxStep(1:NgeomF)
2230
        ! <- PFL 31 MAr 2008
2231
        ! Also XyzGeomF is updated in EgradPath for Baker Case.
2232
        !  It should get updated for other cases too.
2233

    
2234
        DO IGeom=1,NGeomF
2235
           SELECT CASE (COORD)
2236
           CASE('ZMAT')
2237
              WRITE(IOOUT,"('Geometry ',I3,'/',I3,' for iteration ',I3)") IGeom,NgeomF,IOpt
2238
              GeomTmp=IntCoordF(IGeom,:)
2239
              WRITE(IOOUT,'(1X,A5,3(1X,I4,1X,F11.6))') Nom(Atome(OrderInv(indzmat(1,1))))
2240
              WRITE(IOOUT,'(1X,A5,3(1X,I4,1X,F11.6))') Nom(Atome(OrderInv(indzmat(2,1)))), &
2241
                   OrderInv(indzmat(2,2)),Geomtmp(1)
2242
              WRITE(IOOUT,'(1X,A5,3(1X,I4,1X,F11.6))') Nom(Atome(OrderInv(indzmat(3,1)))), &
2243
                   OrderInv(indzmat(3,2)),Geomtmp(2), &
2244
                   OrderInv(indzmat(3,3)),Geomtmp(3)*180./Pi
2245
              Idx=4
2246
              DO Iat=4,Nat
2247
                 WRITE(IOOUT,'(1X,A5,3(1X,I4,1X,F11.6))') Nom(Atome(OrderInv(indzmat(iat,1)))), &
2248
                      OrderInv(indzmat(iat,2)),Geomtmp(Idx), &
2249
                      OrderInv(indzmat(iat,3)),Geomtmp(Idx+1)*180./pi, &
2250
                      OrderInv(indzmat(iat,4)),Geomtmp(Idx+2)*180/Pi
2251
                 Idx=Idx+3
2252
              END DO
2253
           CASE('BAKER')
2254
              !WRITE(IOOUT,"('Geometry ',I3,'/',I3,' for iteration ',I3)") IGeom,NgeomF,IOpt
2255
              !GeomTmp=IntCoordF(IGeom,:)
2256
           CASE('CART','HYBRID','MIXED')
2257
              WRITE(IOOUT,'(1X,I5)') Nat
2258
              WRITE(IOOUT,"('Geometry ',I3,'/',I3,' for iteration ',I3)") IGeom,NgeomF,IOpt
2259
              GeomTmp=Reshape(XyzGeomF(IGeom,:,:),(/3*Nat/))
2260
              DO I=1,Nat
2261
                 Iat=I
2262
                 If (renum) Iat=OrderInv(I)
2263
                 WRITE(IOOUT,'(1X,A5,3(1X,F11.6))') Nom(Atome(iat)), Geomtmp(3*Iat-2:3*Iat)
2264
              END DO
2265
           CASE DEFAULT
2266
              WRITE(*,*) 'Coord=',TRIM(COORD),' not recognized. Path L1356.STOP'
2267
              STOP
2268
           END SELECT
2269
        END DO ! matches DO IGeom=1,NGeomF
2270

    
2271
        Call Write_path(IOpt)
2272
! Shall we analyze the geometries ?
2273
     IF (AnaGeom) Call AnaPath(Iopt,IoDat)
2274

    
2275
        ! We update the Hessian matrices
2276
        IF (debug) WRITE(*,*) "Updating Hessian matrices",NCoord
2277
        ! First using the displacement from the old path
2278
        IGeom0=2
2279
        IGeomF=NGeomF-1
2280
        IF (OptReac) IGeom0=1
2281
        IF (OptProd) IGeomF=NGeomF
2282

    
2283
        IF (FCalcHess) THEN
2284
           DO IGeom=IGeom0,IGeomF
2285
              SELECT CASE (COORD)
2286
              CASE ('ZMAT','MIXED','BAKER')
2287
                 GeomTmp2=IntCoordF(IGeom,:)
2288
              CASE ('CART','HYBRID')
2289
                 GeomTmp2=Reshape(XyzGeomF(IGeom,:,:),(/3*Nat/))
2290
              CASE DEFAULT
2291
                 WRITE(*,*) "Coord=",TRIM(COORD)," not recognized. PATH L1267.STOP"
2292
                 STOP
2293
              END SELECT
2294
              Call CalcHess(NCoord,GeomTmp2,Hess(IGeom,:,:),IGeom,Iopt)
2295
           END DO
2296
        ELSE
2297
           DO IGeom=IGeom0,IGeomF
2298
              GeomTmp=GeomOld_all(IGeom,:)
2299
              SELECT CASE (COORD)
2300
              CASE ('ZMAT','MIXED','BAKER')
2301
                 GeomTmp2=IntCoordF(IGeom,:)
2302
              CASE ('CART','HYBRID')
2303
                 GeomTmp2=Reshape(XyzGeomF(IGeom,:,:),(/3*Nat/))
2304
              CASE DEFAULT
2305
                 WRITE(*,*) "Coord=",TRIM(COORD)," not recognized. PATH L1267.STOP"
2306
                 STOP
2307
              END SELECT
2308
              GeomTmp=GeomTmp2-GeomTmp
2309
              GradTmp=Grad(IGeom,:)-GradOld(IGeom,:)
2310
              HessTmp=Hess(IGeom,:,:)
2311
              Call Hupdate_all(NCoord,GeomTmp,GradTmp,HessTmp)
2312
              Hess(IGeom,:,:)=HessTmp
2313
           END DO ! matches DO IGeom=IGeom0,IGeomF
2314

    
2315
           ! Second using the neighbour points
2316
           IF (HupNeighbour) THEN
2317
              ! Only one point for end points.
2318
              IF (OptReac) THEN
2319
                 IF ((COORD.EQ.'ZMAT') .OR. (COORD.EQ.'BAKER')) THEN
2320
                    GeomTmp=IntCoordF(1,:)-IntCoordF(2,:)
2321
                 ELSE
2322
                    GeomTmp=Reshape(XyzGeomF(1,:,:),(/3*Nat/))-Reshape(XyzGeomF(2,:,:),(/3*Nat/))
2323
                 END IF
2324
                 GradTmp=Grad(1,:)-Grad(2,:)
2325
                 HessTmp=Hess(1,:,:)
2326
                 Call Hupdate_all(NCoord,GeomTmp,GradTmp,HessTmp)
2327
                 Hess(1,:,:)=HessTmp
2328
              END IF
2329

    
2330
              IF (OptProd) THEN
2331
                 IF ((COORD.EQ.'ZMAT') .OR. (COORD.EQ.'BAKER')) THEN
2332
                    GeomTmp=IntCoordF(NGeomF,:)-IntCoordF(NGeomF-1,:)
2333
                 ELSE
2334
                    GeomTmp=Reshape(XyzGeomF(NGeomF,:,:),(/3*Nat/))-Reshape(XyzGeomF(NGeomF-1,:,:),(/3*Nat/))
2335
                 END IF
2336
                 GradTmp=Grad(NGeomF,:)-Grad(NGeomF-1,:)
2337
                 HessTmp=Hess(NGeomF,:,:)
2338
                 Call Hupdate_all(NCoord,GeomTmp,GradTmp,HessTmp)        
2339
                 Hess(NGeomF,:,:)=HessTmp
2340
              END IF
2341

    
2342
              ! Two points for the rest of the path
2343
              DO IGeom=2,NGeomF-1
2344
                 IF ((COORD.EQ.'ZMAT').OR.(COORD.EQ.'BAKER')) THEN
2345
                    GeomTmp=IntCoordF(IGeom,:)-IntCoordF(IGeom+1,:)
2346
                 ELSE
2347
                    GeomTmp=Reshape(XyzGeomF(IGeom,:,:),(/3*Nat/))-Reshape(XyzGeomF(IGeom+1,:,:),(/3*Nat/))
2348
                 END IF
2349
                 GradTmp=Grad(IGeom,:)-Grad(IGeom+1,:)
2350
                 HessTmp=Hess(IGeom,:,:)
2351
                 Call Hupdate_all(NCoord,GeomTmp,GradTmp,HessTmp)        
2352

    
2353
                 IF ((COORD.EQ.'ZMAT') .OR. (COORD.EQ.'BAKER')) THEN
2354
                    GeomTmp=IntCoordF(IGeom,:)-IntCoordF(IGeom-1,:)
2355
                 ELSE
2356
                    GeomTmp=Reshape(XyzGeomF(IGeom,:,:),(/3*Nat/))-Reshape(XyzGeomF(IGeom-1,:,:),(/3*Nat/))
2357
                 END IF
2358
                 GradTmp=Grad(IGeom,:)-Grad(IGeom-1,:)
2359

    
2360
                 Call Hupdate_all(NCoord,GeomTmp,GradTmp,HessTmp)        
2361
                 Hess(IGeom,:,:)=HessTmp
2362
              END DO ! matches DO IGeom=2,NGeomF-1
2363
           END IF !matches IF (HupNeighbour) THEN
2364
        END IF ! matches IF (FCalcHess)
2365
     END IF ! If (not.fini.).AND.(IOpt.LE.MaxCyc)
2366
  END DO ! matches DO WHILE ((IOpt.LT.MaxCyc).AND.(.NOT.Fini))
2367

    
2368
!   IF (PROG=="GAUSSIAN") THEN
2369
!      DEALLOCATE(Gauss_paste)
2370
!      DEALLOCATE(Gauss_root)
2371
!      DEALLOCATE(Gauss_comment)
2372
!      DEALLOCATE(Gauss_end)
2373
!   END IF
2374

    
2375
  DEALLOCATE(XyzGeomF, IntCoordF)
2376
  DEALLOCATE(XyzGeomI, IntCoordI)
2377
  DEALLOCATE(XyzTangent,IntTangent)
2378
  DEALLOCATE(AtName,IndZmat,Order,Atome,MassAt)
2379
  DEALLOCATE(GeomOld_all)
2380

    
2381
  if (PROG=="GAUSSIAN") THEN
2382
     ! We de-allocate the Gauss_XX lists
2383
     ! transverse the list and deallocate each node
2384
     previous => Gauss_root ! make current point to head of list
2385
     DO
2386
        IF (.NOT. ASSOCIATED(previous)) EXIT ! exit if null pointer
2387
        current => previous%next ! make list point to next node of head
2388
        DEALLOCATE(previous) ! deallocate current head node
2389
        previous => current  ! make current point to new head
2390
     END DO
2391

    
2392
     previous => Gauss_comment ! make current point to head of list
2393
     DO
2394
        IF (.NOT. ASSOCIATED(previous)) EXIT ! exit if null pointer
2395
        current => previous%next ! make list point to next node of head
2396
        DEALLOCATE(previous) ! deallocate current head node
2397
        previous => current  ! make current point to new head
2398
     END DO
2399

    
2400
     previous => Gauss_end ! make current point to head of list
2401
     DO
2402
        IF (.NOT. ASSOCIATED(previous)) EXIT ! exit if null pointer
2403
        current => previous%next ! make list point to next node of head
2404
        DEALLOCATE(previous) ! deallocate current head node
2405
        previous => current  ! make current point to new head
2406
     END DO
2407

    
2408

    
2409
  END IF
2410

    
2411
  DEALLOCATE(GeomTmp, Hess, GradTmp)
2412
  IF (COORD.EQ.'ZMAT')  DEALLOCATE(dzdc)
2413
  IF (COORD.EQ.'BAKER') THEN
2414
     DEALLOCATE(BMat_BakerT,BTransInv,BTransInv_local,Xprimitive_t)
2415
     DEALLOCATE(XprimitiveF,UMatF,BTransInvF,UMat,UMat_local)
2416
  END IF
2417

    
2418
  If (FPBC)   DeAllocate(XGeomRefPBC,YGeomRefPBC,ZGeomRefPBC)
2419
  WRITE(IOOUT,*) "Exiting Path, IOpt=",IOpt
2420

    
2421
  Close(IOIN)
2422
  Close(IOOUT)
2423
  IF (AnaGeom) Close(IODAT)
2424
  IF (AnaGeom.AND.(OptGeom<=0)) Close(IOGPlot)
2425

    
2426
END PROGRAM PathOpt