Statistiques
| Révision :

root / src / Path.f90 @ 2

Historique | Voir | Annoter | Télécharger (86,91 ko)

1 1 equemene
! This programs generates and optimizes a reaction path
2 1 equemene
! between at least two endpoints.
3 1 equemene
!
4 1 equemene
! It uses NAMELIST for input, see below !
5 1 equemene
!
6 1 equemene
! v3.0
7 1 equemene
! First version entirely in Fortran.
8 1 equemene
! It uses routines from Cart (path creation and parameterisation)
9 1 equemene
! and from IRC06, especially routines for point optimization.
10 1 equemene
!
11 1 equemene
! TO DO:
12 1 equemene
! 1) Possibility to read and/or calculate some hessian structures
13 1 equemene
! 2) Use of internal coordinate to estimate the hessian for stable
14 1 equemene
! species in a much better way...
15 1 equemene
!
16 1 equemene
!!!!!!!!!!!!!!!
17 1 equemene
! v3.1
18 1 equemene
! The Hessian update includes neighbour points.
19 1 equemene
!
20 1 equemene
! v3.2
21 1 equemene
! We add the option Hinv that uses the BFGS update of the Hessian inverse
22 1 equemene
!
23 1 equemene
! v3.3
24 1 equemene
! We add the full option for ZMAT coordinates, where all is done using
25 1 equemene
! internal coordinates.
26 1 equemene
! v3.31
27 1 equemene
! The step size is controlled using the step norm and not the maximum step
28 1 equemene
! component.
29 1 equemene
! v3.5
30 1 equemene
! Big modifications of Calc_zmat_const_frag in order to be able
31 1 equemene
! to treat VASP geometries.
32 1 equemene
! For now, only XYZ geometries are read and written. VASP interface
33 1 equemene
! has to be written.
34 1 equemene
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
35 1 equemene
! v3.6
36 1 equemene
! Some minor modif in Calc_zmat_const_frag to have nicer programming
37 1 equemene
! and a new mode added: Coord=MIXED where part of the system
38 1 equemene
! is extrapolated in cartesian coordinates and the rest of it in zmat.
39 1 equemene
! it might be Useful for VASP, or when lots of atoms are frozen
40 1 equemene
! by default, when Coord=MIXED, all frozen atoms are described in cartesian
41 1 equemene
! coordinates.
42 1 equemene
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
43 1 equemene
! v3.61
44 1 equemene
! We move further and further to VASP program. New variables added to the 'path' namelist:
45 1 equemene
! input: what is the program used for the geometries ?
46 1 equemene
!     Possible values: xyz (or cart) for Xmol format; VASP. Xyz should be used for Gaussian
47 1 equemene
! prog: what is the program used for the calculations ?
48 1 equemene
!     Possible values for now: gaussian, vasp.
49 1 equemene
! For now (02/2007), when prog='vasp' is used, only the initial path is created.
50 1 equemene
! That means that we have only added input/output subroutines :-)
51 1 equemene
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
52 1 equemene
! v3.7
53 1 equemene
! We try to improve the optimization steps. For that, we first modify many routines
54 1 equemene
! so that the new step is calculated in the 'free' degrees of freedom, as it is done
55 1 equemene
! in IRC07/ADF for example. That will allow us to impose constraints in an easier way.
56 1 equemene
!
57 1 equemene
! v3.701
58 1 equemene
! Add a new option for the initial extrapolation of the Hessian
59 1 equemene
!
60 1 equemene
!v3.71
61 1 equemene
! The optimization step has been improved... but the vfree part has not yet been included.
62 1 equemene
! This has still to be done :-)
63 1 equemene
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
64 1 equemene
! v3.8
65 1 equemene
! I have included part of the vfree procedure: for now freemv returns the Id
66 1 equemene
! matrix, that is used to project out the tangent vector.
67 1 equemene
! This improves the optimization a lot, but I will have to implement
68 1 equemene
! a real freemw subroutine to have constraints there !
69 1 equemene
! v3.81 Technical version
70 1 equemene
! I have added a new program 'Ext'. When this one is used, Path creates a Ext.in file,
71 1 equemene
! calls Ext.exe file to get a Ext.out file that contains the Energy and the gradient.
72 1 equemene
! Format:
73 1 equemene
! Ext.in : Xmol format. The second line (comment in Xmol) contains the COORD name.
74 1 equemene
! Ext.out: Energy on firt line (1X,D25.15), then gradient in CARTESIAN coordinates
75 1 equemene
!  (3(1X,D25.15)) format. Natoms lines.
76 1 equemene
! TO DO:  Gradient could be given in COORD format, ie cartesian for COORD=CART, XYZ or HYBRID
77 1 equemene
! ZMAT for CORD=ZMAT (in that case, 6 zeros are there at the begining !)
78 1 equemene
! For MIXED, it is equivalent to CART :-)
79 1 equemene
! v3.811
80 1 equemene
! I have added a prog="TEST" option, where egradient calls egrad_test subroutine.
81 1 equemene
! It then calculates the energy and gradient as it wants and it returns the cartesian
82 1 equemene
! gradient. The purpose is to have an analytical approximation of the PES of the system
83 1 equemene
! under study to gain some time in testing the program. This is not documented :-)
84 1 equemene
!
85 1 equemene
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
86 1 equemene
!  v3.9
87 1 equemene
! In order to be fully interfaced with VASP, I have to change the architecture
88 1 equemene
! of the program. In particular, with VASP, one can use a Para8+NEB routine
89 1 equemene
! of VASP to calculate energy+forces for all points of the path.
90 1 equemene
! v3.91
91 1 equemene
! One small modification: in the cart list, one can freeze a whole sequence by
92 1 equemene
! entering a negative number for the last atom of the sequence
93 1 equemene
! for example : cart=1 -160 165 -170 will define atoms from 1 to 160 and from
94 1 equemene
! 165 to 170 (included) as cartesian atoms.
95 1 equemene
! Of course, Same applies to Frozen
96 1 equemene
! v3.92 / v3.93
97 1 equemene
! Slight modifications. One noticeable: when using Vasp, the program analyses the
98 1 equemene
! displacements to suggest which atoms could be described in CART.
99 1 equemene
! v3.94
100 1 equemene
! VaspMode=Para now implemented. One needs to be careful in defining 'ProgExe'.
101 1 equemene
! In particular, one must put the mpirun command in ProgExe !!! There is NO test.
102 1 equemene
! v3.95
103 1 equemene
! When using internal coordinates (zmat, hybrid or mixes), Path calculates the number
104 1 equemene
! of fragments for each geometry. The reference one (ie the one used to compute the internal
105 1 equemene
! coordinates) is now the one with the least fragments.
106 1 equemene
! user can also choose one geometry by specifying IGeomRef in the Path namelis.
107 1 equemene
! v3.96
108 1 equemene
! I have added a test for the geometry step: it does not allow valence angle to
109 1 equemene
! be negative or bigger than 180. I hope that this might help geometry optimization
110 1 equemene
! when dealing with nearly linear molecules.
111 1 equemene
! v3.961
112 1 equemene
! The options cart and frozen are now LOGICAL:
113 1 equemene
! Fcart=T indicates that a &cartlist namelist should be read !
114 1 equemene
! Ffrozen=T indicates that a &frozenlist namelist should be read !
115 1 equemene
! TO DO: Autocart=T indicates that the atoms described in cartesian coordiantes should
116 1 equemene
! be found automatically
117 1 equemene
! v3.97
118 1 equemene
! Baker has been implemented by P. Dayal: we are interpolating Xint for now.
119 1 equemene
! TO do: interpolate Umat ?
120 1 equemene
! -----
121 1 equemene
! v3.971
122 1 equemene
! AutoCart=T is being implemented. Goal: having a 'black box' version for Vasp users.
123 1 equemene
! Vmd: True if user wants to watch the path using VMD. Only used for VASP for now.
124 1 equemene
!------------
125 1 equemene
! v3.98
126 1 equemene
! Calc_zmat has been replaced by Calc_zmat_frag which is more robust.
127 1 equemene
! Still missing: linear molecules and some tests.
128 1 equemene
!
129 1 equemene
! v3.981
130 1 equemene
! * Added a non document flag in .valid file that switch on the numerical
131 1 equemene
! calculation of the hessian instead of the update.
132 1 equemene
! * Added HesUpd variable in the namelist. Default value is MS for path
133 1 equemene
!   optimization because it does not imposes a positive hessian, and BFGS
134 1 equemene
!  for geometry optimization
135 1 equemene
! v 4.0
136 1 equemene
! * This version has been made public within the CARTE project.
137 1 equemene
! * Added:
138 1 equemene
! - Step_method to choose the optimization method: RFO or Diis
139 1 equemene
! - DynMaxStep: if TRUE, the maximum size of a step is updated at each step.
140 1 equemene
!             If energy goes up, Smax=Smax*0.8, if not Smax=Smax*1.2.
141 1 equemene
!             It is ensured that the dynamical Smax is within [0.5*SMax_0,2*Smax_0]
142 1 equemene
!
143 1 equemene
!!!!!!!!!!!!!!!!!!!!!!
144 1 equemene
! v4.1
145 1 equemene
! * Para mode has been partly implemented for Gaussian.
146 1 equemene
!  VaspMode is thus now 'RunMode' and can be Serial or Para
147 1 equemene
! Only Gaussian and VASP are supported for Para mode now.
148 1 equemene
! v4.12
149 1 equemene
! Some bugs in unconstrained zmat construction are corrected.
150 1 equemene
! v4.13
151 1 equemene
! Prakash has implemented the GEDIIS optimization procedure.
152 1 equemene
! v4.14
153 1 equemene
! There is a small problem for some inputs in VASP, where the
154 1 equemene
! last geometry is not the one given by the user.
155 1 equemene
! It seems to come from the fact that some people try to freeze
156 1 equemene
! some unfrozen atoms
157 1 equemene
! So some tests have been added to check that frozen atoms do not move.
158 1 equemene
!!!
159 1 equemene
! v4.15
160 1 equemene
! There were some bugs when reading and expanding cartlist and frozenlist
161 1 equemene
! I have changed the way frozen atoms are compared by adding partial alignment.
162 1 equemene
! v4.16
163 1 equemene
! Some bugs were corrected.
164 1 equemene
! v4.17
165 1 equemene
! Added MOPAC as a program.
166 1 equemene
! v4.175
167 1 equemene
! Added Three more parameters for defining the input and output names for
168 1 equemene
! the calculations.
169 1 equemene
! CalcName: Prefix for the files used for the energy and gradient calculations
170 1 equemene
! ISuffix: Suffix for the input file
171 1 equemene
! OSuffix: suffix for the output file.
172 1 equemene
! This maters for Gaussian for example.
173 1 equemene
!
174 1 equemene
! v4.177 (P) 2010 Nov 22
175 1 equemene
! - We add TurboMole as a new external code.
176 1 equemene
! - Subtle change for Input: the default is XYZ whatever the code, except
177 1 equemene
! for VASP.
178 1 equemene
!
179 1 equemene
! v4.178 (P) 2010 Nov 28
180 1 equemene
! - We add the possibility to call CHAMFRE reactive force field using
181 1 equemene
! prog=TEST2 or CHAMFRE
182 1 equemene
!
183 1 equemene
184 1 equemene
185 1 equemene
PROGRAM PathOpt
186 1 equemene
187 1 equemene
  use VarTypes
188 1 equemene
  use Path_module
189 1 equemene
  use Io_module
190 1 equemene
191 1 equemene
  IMPLICIT NONE
192 1 equemene
193 1 equemene
  CHARACTER(132) :: FileIn, FileOut, Line,Line2
194 1 equemene
  CHARACTER(32) :: Input,poscar
195 1 equemene
196 1 equemene
  INTEGER(KINT) :: I,J,K,IGeom,iat, IGeom0, IGeomF
197 1 equemene
  INTEGER(KINT) :: IOpt
198 1 equemene
  INTEGER(KINT) :: Idx, LineL,LenLine
199 1 equemene
  INTEGER(KINT) :: N3at, NFree, Nfr
200 1 equemene
  ! Temporary integer counter
201 1 equemene
  INTEGER(KINT) :: NTmp
202 1 equemene
203 1 equemene
  INTEGER(KINT) :: List(2*MaxFroz)
204 1 equemene
205 1 equemene
  REAL(KREAL) :: E,FactStep,B(3) !E=Energy
206 1 equemene
  REAL(KREAL) :: Alpha,sa,ca,norm,s,NormStep,NormGrad
207 1 equemene
  REAL(KREAL) :: EReac,EProd,HP,HEAT ! HEAT=E
208 1 equemene
  REAL(KREAL), ALLOCATABLE :: GeomTmp(:),GradTmp(:),ZeroVec(:) !NCoord
209 1 equemene
  REAL(KREAL), ALLOCATABLE :: GradOld(:,:) ! (NGeomF,NCoord)
210 1 equemene
  REAL(KREAL), ALLOCATABLE :: GeomTmp2(:),GradTmp2(:) ! NCoord
211 1 equemene
  REAL(KREAL), ALLOCATABLE :: HessTmp(:,:)
212 1 equemene
  REAL(KREAL), ALLOCATABLE :: Hprim(:,:) !(NPrim,NPrim)
213 1 equemene
  REAL(KREAL), ALLOCATABLE :: HprimU(:,:) !(NPrim,3*Nat-6))
214 1 equemene
  LOGICAL, SAVE :: allocation_flag
215 1 equemene
216 1 equemene
  ! Flag to see if frozen atoms are frozen (see below)
217 1 equemene
  LOGICAL :: FChkFrozen
218 1 equemene
219 1 equemene
  ! Energies for all points along the path at the previous iteration
220 1 equemene
  REAL(KREAL), ALLOCATABLE ::  EPathold(:) ! NGeomF, where it is deallocated: Prakash
221 1 equemene
  ! Maximum step allowed for this geometry
222 1 equemene
  REAL(KREAL), ALLOCATABLE ::  MaxStep(:) ! NGeomF, where it is deallocated: Prakash
223 1 equemene
224 2 pfleura2
! these are used to read temporary coordinates
225 2 pfleura2
  REAL(KREAL) :: xtmp,ytmp,ztmp
226 2 pfleura2
227 1 equemene
  LOGICAL, ALLOCATABLE :: FTmp(:) ! Nat
228 1 equemene
  LOGICAL :: FFrozen,FCart
229 1 equemene
230 1 equemene
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
231 1 equemene
  !
232 1 equemene
  ! To analyse the frozen atoms
233 1 equemene
  !
234 1 equemene
  REAL(KREAL), ALLOCATABLE :: x1(:),y1(:),z1(:) ! nat
235 1 equemene
  REAL(KREAL), ALLOCATABLE :: x2(:),y2(:),z2(:) ! nat
236 1 equemene
  REAL(KREAL) :: MRot(3,3),Norm1,Norm2,Dist
237 1 equemene
  LOGICAL, ALLOCATABLE :: ListAtFroz(:)
238 1 equemene
  INTEGER(KINT) :: Iat1, Iat2, Iat3
239 1 equemene
240 1 equemene
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
241 1 equemene
  !
242 1 equemene
  ! For VASP
243 1 equemene
  !
244 1 equemene
  INTEGER(KINT), ALLOCATABLE :: NbAtType(:) !na
245 1 equemene
  INTEGER(KINT) :: NbType, NbTypeUser
246 1 equemene
247 1 equemene
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
248 1 equemene
249 1 equemene
  LOGICAL :: TChk
250 1 equemene
  LOGICAL :: Debug, Fini,Flag_Opt_Geom
251 1 equemene
252 1 equemene
!  INTEGER(KINT), EXTERNAL :: Iargc
253 1 equemene
  INTEGER(KINT), EXTERNAL ::  ConvertNumAt
254 1 equemene
255 1 equemene
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
256 1 equemene
  !
257 1 equemene
  ! For Debugging purposes
258 1 equemene
  !
259 1 equemene
  LOGICAL :: FCalcHess
260 1 equemene
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
261 1 equemene
262 1 equemene
263 1 equemene
  INTERFACE
264 1 equemene
     function valid(string) result (isValid)
265 1 equemene
       CHARACTER(*), intent(in) :: string
266 1 equemene
       logical                  :: isValid
267 1 equemene
     END function VALID
268 1 equemene
269 1 equemene
     SUBROUTINE Read_Geom(Input)
270 1 equemene
       CHARACTER(32), INTENT(IN) :: input
271 1 equemene
     END SUBROUTINE READ_GEOM
272 1 equemene
273 1 equemene
     subroutine hupdate_all (n, dx, dgrad, HessOld)
274 1 equemene
275 1 equemene
       IMPLICIT NONE
276 1 equemene
277 1 equemene
       INTEGER, PARAMETER :: KINT=KIND(1)
278 1 equemene
       INTEGER, PARAMETER :: KREAL=KIND(1.0D0)
279 1 equemene
280 1 equemene
       INTEGER(KINT), INTENT(IN) :: n
281 1 equemene
       real(KREAL) :: dx(n), dgrad(n), HessOld(n*n)
282 1 equemene
     END subroutine hupdate_all
283 1 equemene
284 1 equemene
     SUBROUTINE Hinvup_BFGS_new(Nfree,ds,dgrad,Hess)
285 1 equemene
286 1 equemene
       IMPLICIT NONE
287 1 equemene
288 1 equemene
       INTEGER, PARAMETER :: KINT=KIND(1)
289 1 equemene
       INTEGER, PARAMETER :: KREAL=KIND(1.D0)
290 1 equemene
291 1 equemene
       INTEGER(KINT), INTENT(IN) :: NFREE
292 1 equemene
       REAL(KREAL), INTENT(INOUT) :: Hess(Nfree,Nfree)
293 1 equemene
       REAL(KREAL), INTENT(IN) :: ds(Nfree)
294 1 equemene
       REAL(KREAL), INTENT(IN) :: dGrad(Nfree)
295 1 equemene
296 1 equemene
     END subroutine Hinvup_BFGS_new
297 1 equemene
298 1 equemene
299 1 equemene
  END INTERFACE
300 1 equemene
301 1 equemene
  Namelist/path/fact,r_cov,nat,ngeomi,ngeomf,debugFile, &
302 1 equemene
       MW,mass,Ffrozen, renum, OptReac,OptProd,Coord,Step_method,MaxCyc, &
303 1 equemene
       SMax, SThresh, GThresh,IReparam, IReparamT,Hinv, ISpline, PathOnly,Fcart, &
304 1 equemene
       input,prog, ProgExe,RunMode, AtTypes,poscar,PathName,  &
305 1 equemene
       OptGeom,IniHup, HupNeighbour, hesUpd, &
306 1 equemene
       FTan, EReac, EProd, IGeomRef, Vmd, AutoCart, DynMaxStep, &
307 1 equemene
       NMaxPtPath, FrozTol, BoxTol,CalcName,ISuffix,OSuffix, WriteVasp, &
308 1 equemene
       NGintMax, Align
309 1 equemene
310 1 equemene
  Namelist/cartlist/list
311 1 equemene
  Namelist/frozenlist/list
312 1 equemene
313 1 equemene
314 1 equemene
  Flag_Opt_Geom = .FALSE. ! Initialized.
315 1 equemene
316 1 equemene
  ! We read the files names
317 1 equemene
!  SELECT CASE (iargc())
318 1 equemene
  SELECT CASE (command_argument_count())
319 1 equemene
  CASE (2)
320 1 equemene
     call getarg(1,FileIn)
321 1 equemene
     OPEN(IOIN,FILE=FileIn,STATUS='UNKNOWN')
322 1 equemene
     call getarg(2,FileOut)
323 1 equemene
     OPEN(IOOUT,FILE=FileOut,STATUS='UNKNOWN')
324 1 equemene
  CASE (1)
325 1 equemene
     call getarg(1,FileIn)
326 1 equemene
     IF ((FileIn=="-help").OR.(FileIn=="--help")) THEN
327 1 equemene
        WRITE(*,*) "Path mini-help"
328 1 equemene
        WRITE(*,*) "--------------"
329 1 equemene
        WRITE(*,*) ""
330 1 equemene
        WRITE(*,*) "Use: Path Input_file Output_file"
331 1 equemene
        WRITE(*,*) "Input_file starts with a Namelist called path"
332 1 equemene
        WRITE(*,*) ""
333 1 equemene
        WRITE(*,*) "Compulsory variables are:"
334 1 equemene
        WRITE(*,*) "NGeomi: Number of geometries defining the Initial path"
335 1 equemene
        WRITE(*,*) "NGeomf: Number of geometries defining the Final path"
336 1 equemene
        WRITE(*,*) "Nat   : Number of atoms"
337 1 equemene
        WRITE(*,*) ""
338 1 equemene
        WRITE(*,*) "Other options"
339 1 equemene
        WRITE(*,*) "Input: string that indicates the type of the input geometries."
340 1 equemene
        WRITE(*,*) "Accepted values are: Cart (or Xmol or Xyz) or Vasp"
341 1 equemene
        WRITE(*,*) "Prog: string that indicates the program that will be used for energy and gradient calculations."
342 1 equemene
        WRITE(*,*) "      Accepted values are: Gaussian, Vasp, Mopac or Ext"
343 1 equemene
        WRITE(*,*) "      In case of a Gaussian or Mopac calculations, input must be set to Cart."
344 1 equemene
        WRITE(*,*) "      One example of a gaussian/mopac input should be added at the end of the"
345 1 equemene
        WRITE(*,*) "      input file.See example file Test_G03.path or Test_Mopac.path"
346 1 equemene
        WRITE(*,*) "      In the case of a VASP calculation, if input is set to Cart, then"
347 1 equemene
        WRITE(*,*) "    the preamble of a VASP calculation should be added at the end of"
348 1 equemene
        WRITE(*,*) "    the input file. See example file Test_VASP_cart.path"
349 1 equemene
        WRITE(*,*) "    In the case of a VASP calculation, one should also give value of the "
350 1 equemene
        WRITE(*,*) "    Runmode variable"
351 1 equemene
        WRITE(*,*) "Runmode: This indicates wether one should use VASP routine to calculate the energy"
352 1 equemene
        WRITE(*,*) "       and gradient of the whole path or not. If one wants to use VASP,"
353 1 equemene
        WRITE(*,*) "       Runmode must be set to PARA."
354 1 equemene
        WRITE(*,*) "PathName: Prefix used to save the path. Default is Path"
355 1 equemene
        WRITE(*,*) "Poscar: string that will be used as the prefix for the different "
356 1 equemene
        WRITE(*,*) "        POSCAR files in a VASP calculations. Usefull only if PathOnly=.TRUE.,"
357 1 equemene
        WRITE(*,*) "        not used for internal calculations."
358 1 equemene
        WRITE(*,*) " CalcName: Prefix for the files used for the energy and gradient calculations"
359 1 equemene
        WRITE(*,*) " ISuffix: Suffix for the input file."
360 1 equemene
        WRITE(*,*) " OSuffix: suffix for the output file."
361 1 equemene
        WRITE(*,*) "IGeomRef: Index of the geometry used to construct the internal coordinates."
362 1 equemene
        WRITE(*,*) "      Valid only for Coord=Zmat, Hybrid or Mixed"
363 1 equemene
        WRITE(*,*) "Fact: REAL used to define if two atoms are linked."
364 1 equemene
        WRITE(*,*) "      If d(A,B)<=fact*(rcov(A)+rcov(B)), then A and B are considered Linked."
365 1 equemene
        WRITE(*,*) "debugFile: Name of the file that indicates which subroutine should print debug info."
366 1 equemene
        WRITE(*,*) "Coord: System of coordinates to use. Possible choices are:"
367 1 equemene
        WRITE(*,*) "       - CART (or Xyz): works in cartesian"
368 1 equemene
        WRITE(*,*) "       - Zmat: works in internal coordinates (Zmat)"
369 1 equemene
        WRITE(*,*) "       - Mixed: frozen atoms, as well as atoms defined by the "
370 1 equemene
        WRITE(*,*) "       'cart' array(see below) are describe in CARTESIAN, whereas the"
371 1 equemene
        WRITE(*,*) "       others are described in Zmat"
372 1 equemene
        WRITE(*,*) "       - Baker: use of Baker coordinates, also called delocalized internal coordinates"
373 1 equemene
        WRITE(*,*) "       - Hybrid: geometries are described in zmat, but the gradient are used in cartesian"
374 1 equemene
        WRITE(*,*) "Step_method: method to compute the step for optimizing a geometry; choices are:"
375 1 equemene
        WRITE(*,*) "       - RFO: Rational function optimization"
376 1 equemene
        WRITE(*,*) "       - GDIIS: Geometry optimization using direct inversion in the iterative supspace"
377 1 equemene
        WRITE(*,*) " HesUpd: method to update the hessian. By default, it is Murtagh-Sargent"
378 1 equemene
        WRITE(*,*) "      Except for geometry optimization where it is BFGS."
379 1 equemene
        WRITE(*,*) "MaxCyc: maximum number of iterations for the path optimization"
380 1 equemene
        WRITE(*,*) "Smax: Maximum length of a step during path optimization"
381 1 equemene
        WRITE(*,*) "SThresh: Step Threshold to consider that the path is stationary"
382 1 equemene
        WRITE(*,*) "GThresh: Gradient Threshold to consider that the path is stationary, only orthogonal part is taken"
383 1 equemene
        WRITE(*,*) "FTan: We moving the path, this gives the proportion of the displacement tangent to the path"
384 1 equemene
        WRITE(*,*) "      that is kept. FTan=1. corresponds to the full displacement, "
385 1 equemene
        WRITE(*,*) "      whereas FTan=0. gives a displacement orthogonal to the path."
386 1 equemene
        WRITE(*,*) "IReparam: The path is not reparameterised at each iteration. This gives the frequency of reparameterization."
387 1 equemene
        WRITE(*,*) "ISpline: By default, a linear interpolation is used to generate the path."
388 1 equemene
        WRITE(*,*) "         This option indicates the first step where spline interpolation is used."
389 1 equemene
        WRITE(*,*) ""
390 1 equemene
        WRITE(*,*) "Arrays:"
391 1 equemene
        WRITE(*,*) "Rcov: Array containing the covalent radii of the first 80 elements."
392 1 equemene
        WRITE(*,*) "      You can modify it using, rcov(6)=0.8."
393 1 equemene
        WRITE(*,*) "Mass: Array containing the atomic mass of the first 80 elements."
394 1 equemene
        WRITE(*,*) "AtTypes: Name of the different atoms used in a VASP calculations."
395 1 equemene
        WRITe(*,*) "If not given, Path will read the POTCAR file."
396 1 equemene
        WRITE(*,*) ""
397 1 equemene
        WRITE(*,*) "Flags:"
398 1 equemene
        WRITE(*,*) "MW:  Flag. True if one wants to work in Mass Weighted coordinates. Default=.TRUE."
399 1 equemene
        WRITE(*,*) "Renum: Flag. True if one wants to reoder the atoms in the initial order. default is .TRUE. most of the time."
400 1 equemene
        WRITE(*,*) "OptProd: True if one wants to optimize the geometry of the products."
401 1 equemene
        WRITE(*,*) "OptReac: True if one wants to optimize the geometry of the reactants."
402 1 equemene
        WRITE(*,*) "PathOnly:TRUE if one wants to generate the initial path, and stops."
403 1 equemene
        WRITE(*,*) "Hinv: if True, then Hessian inversed is used."
404 1 equemene
        WRITE(*,*) "IniHup: if True, then Hessian inverse is extrapolated using the initial path calculations."
405 1 equemene
        WRITE(*,*) "HupNeighbour: if True, then Hessian inverse is extrapolated using the neighbouring points of the path."
406 1 equemene
        WRITE(*,*) "FFrozen: True if one wants to freeze the positions of some atoms."
407 1 equemene
        WRITE(*,*) "         If True, a &frozenlist namelist containing the list of frozen atoms must be given."
408 1 equemene
        WRITE(*,*) "          If VASP is used, and frozen is not given"
409 1 equemene
        WRITE(*,*) " here, the program will use the F flags of the input geometry"
410 1 equemene
        WRITE(*,*) "FCart:  True if one wants to describe some atoms using cartesian coordinates. "
411 1 equemene
        WRITE(*,*) "        *** Only used in 'mixed' calculations. ***"
412 1 equemene
        WRITE(*,*) "      If True, a &cartlist namelist containing the list of cart atoms must be given."
413 1 equemene
        WRITE(*,*) "      By default, only frozen atoms are described in cartesian coordinates."
414 1 equemene
        WRITE(*,*) ""
415 1 equemene
        WRITE(*,*) "DynMaxStep: if TRUE, the maximum allowed step is updated at each step, for each geometry."
416 1 equemene
        WRITE(*,*) "        If energy goes up, Smax=Smax*0.8, if not Smax=Smax*1.2. "
417 1 equemene
        WRITE(*,*) "       It is ensured that the dynamical Smax is within [0.5*SMax_0,2*Smax_0]"
418 1 equemene
        WRITE(*,*) "Autocart: True if you want to let the program choosing the cartesian atoms."
419 1 equemene
        WRITE(*,*) "VMD: TRUE if you want to use VMD to look at the Path. Used only for VASP for now"
420 1 equemene
        WRITE(*,*) "WriteVASP: TRUE if you want to print the images coordinates in POSCAR files."
421 1 equemene
        WRITE(*,*) "See also the POSCAR option. This can be used only if prog or input=VASP."
422 1 equemene
        WRITE(*,*) ""
423 1 equemene
        STOP
424 1 equemene
     END IF
425 1 equemene
     OPEN(IOIN,FILE=FileIn,STATUS='UNKNOWN')
426 1 equemene
     IOOUT=6
427 1 equemene
  CASE (0)
428 1 equemene
     IOIN=5
429 1 equemene
     IOOUT=6
430 1 equemene
  END SELECT
431 1 equemene
432 1 equemene
!!!!!!!!!!!!!!!!!!!!!!!!!
433 1 equemene
  !
434 1 equemene
  ! We print the Version info in file
435 1 equemene
  !
436 2 pfleura2
  WRITE(*,'(1X,A)') "OpenPath v1.0 (c) PFL/PD 2007-2011"
437 1 equemene
438 1 equemene
439 1 equemene
  ! We initiliaze variables
440 1 equemene
  Pi=dacos(-1.0d0)
441 1 equemene
  Nat=1
442 1 equemene
  Fact=1.1
443 1 equemene
  IGeomRef=-1
444 1 equemene
  NGeomI=1
445 1 equemene
  NGeomF=8
446 1 equemene
  IReparam=5
447 1 equemene
  IReparamT=-1
448 1 equemene
  ISpline=5
449 1 equemene
  debug=.False.
450 1 equemene
  MW=.TRUE.
451 1 equemene
  bohr=.False.
452 1 equemene
  Coord='ZMAT'
453 1 equemene
  Step_method='RFO'
454 1 equemene
  DebugFile='Path.valid'
455 1 equemene
  PathName="Path"
456 1 equemene
  MaxCyc=50
457 1 equemene
  SMax=0.1D0
458 1 equemene
  SThresh=-1.
459 1 equemene
  GThresh=-1.
460 1 equemene
  FTan=0.
461 1 equemene
  Hinv=.TRUE.
462 1 equemene
  IniHUp=.FALSE.
463 1 equemene
  HupNeighbour=.FALSE.
464 1 equemene
  HesUpd="MS"
465 1 equemene
  FFrozen=.FALSE.
466 1 equemene
  FCart=.FALSE.
467 1 equemene
  List=0
468 1 equemene
  renum=.TRUE.
469 1 equemene
  OptReac=.FALSE.
470 1 equemene
  OptProd=.FALSE.
471 1 equemene
  EReac=0.d0
472 1 equemene
  EProd=0.d0
473 1 equemene
  OptGeom=-1
474 1 equemene
  PathOnly=.FALSE.
475 1 equemene
  Prog='EMPTY'
476 1 equemene
  ProgExe='EMPTY'
477 1 equemene
  Runmode='SERIAL'
478 1 equemene
  Input='EMPTY'
479 1 equemene
  Poscar="POSCAR"
480 1 equemene
  AutoCart=.FALSE.
481 1 equemene
  VMD=.TRUE.
482 1 equemene
  WriteVASP=.FALSE.
483 1 equemene
  DynMaxStep=.FALSE.
484 1 equemene
  CalcName="EMPTY"
485 1 equemene
  ISuffix="EMPTY"
486 1 equemene
  OSuffix="EMPTY"
487 1 equemene
  NGintMax=10
488 1 equemene
  Align=.TRUE.
489 1 equemene
490 1 equemene
  ! Number of point used to compute the length of the path,
491 1 equemene
  ! and to reparameterize the path
492 1 equemene
  NMaxPtPath=-1
493 1 equemene
  FrozTol=1e-4
494 1 equemene
495 1 equemene
  ! Read the namelist
496 1 equemene
  read (IOIN,path)
497 1 equemene
498 1 equemene
  debug=valid("Main")
499 1 equemene
  FCalcHess=valid("CalcHess")
500 1 equemene
  PathName=AdjustL(PathName)
501 1 equemene
  Coord=AdjustL(Coord)
502 1 equemene
  CALL UpCase(coord)
503 1 equemene
504 1 equemene
  Step_method=AdjustL(Step_method)
505 1 equemene
  CALL UpCase(Step_method)
506 1 equemene
507 1 equemene
  Prog=AdjustL(Prog)
508 1 equemene
  CALL UpCase(prog)
509 1 equemene
510 1 equemene
  Input=AdjustL(Input)
511 1 equemene
  CALL UpCase(input)
512 1 equemene
513 1 equemene
  Runmode=AdjustL(Runmode)
514 1 equemene
  Call UpCase(Runmode)
515 1 equemene
  IF (Runmode(1:4).EQ.'PARA')    Runmode="PARA"
516 1 equemene
517 1 equemene
  If (IReparamT<=0) IReparamT=IReparam
518 1 equemene
519 1 equemene
  IF (COORD.EQ.'CART') THEN
520 1 equemene
     Renum=.FALSE.
521 1 equemene
     IGeomRef=1
522 1 equemene
  END IF
523 1 equemene
524 1 equemene
  if (Prog.EQ.'EMPTY') THEN
525 1 equemene
     Prog='GAUSSIAN'
526 1 equemene
     If (ProgExe=="EMPTY") ProgExe="g09"
527 1 equemene
  END IF
528 1 equemene
  if (Prog.EQ.'G03') THEN
529 1 equemene
     Prog='GAUSSIAN'
530 1 equemene
     If (ProgExe=="EMPTY") ProgExe="g03"
531 1 equemene
  END IF
532 1 equemene
  if (Prog.EQ.'G09') THEN
533 1 equemene
     Prog='GAUSSIAN'
534 1 equemene
     If (ProgExe=="EMPTY") ProgExe="g09"
535 1 equemene
  END IF
536 1 equemene
537 1 equemene
  if (Prog.EQ.'TM') Prog="TURBOMOLE"
538 1 equemene
  if (Prog.EQ.'TEST2') Prog="CHAMFRE"
539 1 equemene
540 1 equemene
541 1 equemene
  Select Case (Prog)
542 1 equemene
    CASE ("EXT")
543 1 equemene
     if (CalcName=="EMPTY") CalcName="Ext"
544 1 equemene
     if (ISuffix=="EMPTY")  ISuffix="in"
545 1 equemene
     if (OSuffix=="EMPTY")  OSuffix="out"
546 1 equemene
    CASE ('MOPAC')
547 1 equemene
     if (CalcName=="EMPTY") CalcName="Path"
548 1 equemene
     if (ISuffix=="EMPTY")  ISuffix="mop"
549 1 equemene
     if (OSuffix=="EMPTY")  OSuffix="out"
550 1 equemene
    CASE ("GAUSSIAN")
551 1 equemene
     if (CalcName=="EMPTY") CalcName="Path"
552 1 equemene
     if (ISuffix=="EMPTY")  ISuffix="com"
553 1 equemene
     if (OSuffix=="EMPTY")  OSuffix="log"
554 1 equemene
    CASE DEFAULT
555 1 equemene
     if (CalcName=="EMPTY") CalcName="Path"
556 1 equemene
     if (ISuffix=="EMPTY")  ISuffix="in"
557 1 equemene
     if (OSuffix=="EMPTY")  OSuffix="out"
558 1 equemene
  END SELECT
559 1 equemene
560 1 equemene
561 1 equemene
  if (Input.EQ.'EMPTY') THEN
562 1 equemene
     Select Case (Prog)
563 1 equemene
       CASE ("VASP")
564 1 equemene
          Input=Prog
565 1 equemene
       CASE ("CHAMFRE")
566 1 equemene
          Input="VASP"
567 1 equemene
       CASE DEFAULT
568 1 equemene
          Input='XYZ'
569 1 equemene
     END SELECT
570 1 equemene
    WRITE(*,*) "Input has been set to the default: ",INPUT
571 1 equemene
 END IF
572 1 equemene
573 1 equemene
  WriteVASP=WriteVASP.AND.((Prog=="VASP").OR.(Input=="VASP"))
574 1 equemene
575 1 equemene
  IF ((RunMode=="PARA").AND.((Prog/="GAUSSIAN").AND.(Prog/="VASP"))) THEN
576 1 equemene
     WRITE(*,*) "Program=",TRIM(Prog)," not yet supported for Para mode."
577 1 equemene
     STOP
578 1 equemene
  END IF
579 1 equemene
580 1 equemene
  if (OptGeom.GE.1) THEN
581 1 equemene
     HesUpd="BFGS"
582 1 equemene
     IF (IGeomRef.LE.0) THEN
583 1 equemene
        IGeomRef=OptGeom
584 1 equemene
     ELSE
585 1 equemene
        IF (IGeomRef.NE.OptGeom) THEN
586 1 equemene
           WRITE(IOOUT,*) "STOP: IGeomRef and OptGeom both set... but to different values !"
587 1 equemene
           WRITE(IOOUT,*) "Check it : IGeomRef=",IGeomRef," OptGeom=",OptGeom
588 1 equemene
589 1 equemene
           WRITE(*,*) "STOP: IGeomRef and OptGeom both set... but to different values !"
590 1 equemene
           WRITE(*,*) "Check it : IGeomRef=",IGeomRef," OptGeom=",OptGeom
591 1 equemene
           STOP
592 1 equemene
        END IF
593 1 equemene
     END IF
594 1 equemene
  END IF
595 1 equemene
596 1 equemene
  IF (ProgExe.EQ.'EMPTY') THEN
597 1 equemene
     SELECT CASE (PROG)
598 1 equemene
     CASE ("GAUSSIAN")
599 1 equemene
        ProgExe="g03"
600 1 equemene
     CASE ("MOPAC")
601 1 equemene
        ProgExe="mopac"
602 1 equemene
     CASE ("EXT")
603 1 equemene
        ProgExe="./Ext.exe"
604 1 equemene
     CASE ("VASP")
605 1 equemene
        ProgExe='VASP'
606 1 equemene
     CASE ("TURBOMOLE")
607 1 equemene
        ProgExe='jobex -c 1 -keep'
608 1 equemene
     CASE ("TEST")
609 1 equemene
        ProgExe=""
610 1 equemene
     CASE ("CHAMFRE")
611 1 equemene
        ProgExe=""
612 1 equemene
     CASE DEFAULT
613 1 equemene
        WRITE(*,*) "Prog=",Adjustl(trim(Prog))," not recognized. STOP"
614 1 equemene
        STOP
615 1 equemene
     END SELECT
616 1 equemene
  END IF
617 1 equemene
618 1 equemene
  if (FCart.AND.FFrozen) THEN
619 1 equemene
     ! We have to be carreful because user might use any order
620 1 equemene
     ! to give the two lists CartList and FrozenList
621 1 equemene
     READ(IOIN,'(A)') Line
622 1 equemene
     Call Upcase(Line)
623 1 equemene
     if (Index(Line,"CART").NE.0) THEN
624 1 equemene
        ALLOCATE(Cart(Nat))
625 1 equemene
        BackSpace(IOIN)
626 1 equemene
        List=0
627 1 equemene
        READ(IOIN,cartlist)
628 1 equemene
        IF (COORD.NE.'CART') THEN
629 1 equemene
           Cart=List(1:Nat)
630 1 equemene
           if (debug) WRITE(*,*) "DBG Path L512 Cart",Cart
631 1 equemene
        ELSE
632 1 equemene
           WRITE(*,*) "FCart=T is not allowed when Coord='CART'"
633 1 equemene
           WRITE(*,*) "I will discard the cartlist"
634 1 equemene
           Cart=0
635 1 equemene
        END IF
636 1 equemene
637 1 equemene
        ALLOCATE(Frozen(Nat))
638 1 equemene
        BACKSPACE(IOIN)
639 1 equemene
        List=0
640 1 equemene
        READ(IOIN,Frozenlist)
641 1 equemene
        Frozen=List(1:Nat)
642 1 equemene
        if (debug) WRITE(*,*) "DBG Path L517 Frozen",Frozen
643 1 equemene
     ELSE
644 1 equemene
        ALLOCATE(Frozen(Nat))
645 1 equemene
        BACKSPACE(IOIN)
646 1 equemene
        List=0
647 1 equemene
        READ(IOIN,Frozenlist)
648 1 equemene
        Frozen=List(1:Nat)
649 1 equemene
        if (debug) WRITE(*,*) "DBG Path L523 Frozen",Frozen
650 1 equemene
        ALLOCATE(Cart(Nat))
651 1 equemene
        BackSpace(IOIN)
652 1 equemene
        List=0
653 1 equemene
        READ(IOIN,cartlist)
654 1 equemene
        IF (COORD.NE.'CART') THEN
655 1 equemene
           Cart=List(1:Nat)
656 1 equemene
           if (debug) WRITE(*,*) "DBG Path L548 Cart",Cart
657 1 equemene
        ELSE
658 1 equemene
           WRITE(*,*) "FCart=T is not allowed when Coord='CART'"
659 1 equemene
           WRITE(*,*) "I will discard the cartlist"
660 1 equemene
           Cart=0
661 1 equemene
        END IF
662 1 equemene
     END IF
663 1 equemene
  ELSE
664 1 equemene
     if (FCart) THEN
665 1 equemene
        ALLOCATE(Cart(Nat))
666 1 equemene
        List=0
667 1 equemene
        READ(IOIN,cartlist)
668 1 equemene
        IF (COORD.NE.'CART') THEN
669 1 equemene
           Cart=List(1:Nat)
670 1 equemene
           if (debug) WRITE(*,*) "DBG Path L561 Cart",Cart
671 1 equemene
        ELSE
672 1 equemene
           WRITE(*,*) "FCart=T is not allowed when Coord='CART'"
673 1 equemene
           WRITE(*,*) "I will discard the cartlist"
674 1 equemene
           Cart=0
675 1 equemene
        END IF
676 1 equemene
     ELSE
677 1 equemene
        IF ((PROG=="VASP").OR.(AutoCart)) THEN
678 1 equemene
           ALLOCATE(Cart(Nat))
679 1 equemene
        ELSE
680 1 equemene
           ALLOCATE(Cart(1))
681 1 equemene
        END IF
682 1 equemene
        Cart=0
683 1 equemene
     END IF
684 1 equemene
685 1 equemene
     if (FFrozen) THEN
686 1 equemene
        ALLOCATE(Frozen(Nat))
687 1 equemene
        List=0
688 1 equemene
        READ(IOIN,Frozenlist)
689 1 equemene
        Frozen=List(1:Nat)
690 1 equemene
        WRITE(*,*) Frozen
691 1 equemene
        if (debug) WRITE(*,*) "DBG Path L549 Frozen",Frozen
692 1 equemene
     ELSE
693 1 equemene
        IF (PROG=="VASP") THEN
694 1 equemene
           ALLOCATE(Frozen(Nat))
695 1 equemene
        ELSE
696 1 equemene
           ALLOCATE(Frozen(1))
697 1 equemene
        END IF
698 1 equemene
        Frozen=0
699 1 equemene
     END IF
700 1 equemene
  END IF
701 1 equemene
702 1 equemene
703 1 equemene
  If (FCart) Call Expand(Cart,NCart,Nat)
704 1 equemene
  IF (FFrozen) Call Expand(Frozen,NFroz,Nat)
705 1 equemene
706 1 equemene
  if (debug) WRITE(*,*) "DBG Main L609, Ncart,Cart",NCart,Cart
707 1 equemene
  if (debug) WRITE(*,*) "DBG Main L610, NFroz,Frozen", NFroz,Frozen
708 1 equemene
709 1 equemene
  if (NMaxPtPath.EQ.-1) then
710 1 equemene
     NMaxPtPath=min(50*NGeomF,1000)
711 1 equemene
     NMaxPtPath=max(20*NGeomF,NMaxPtPath)
712 1 equemene
  end if
713 1 equemene
714 1 equemene
  !  NMaxPtPath=10000
715 1 equemene
716 1 equemene
  ! We ensure that FTan is in [0.:1.]
717 1 equemene
  FTan=min(abs(FTan),1.d0)
718 1 equemene
719 2 pfleura2
! PFL 2011 Mar 14 ->
720 2 pfleura2
! Added some printing for analyses with Anapath
721 2 pfleura2
  if (debug) THEN
722 2 pfleura2
     WRITE(IOOUT,path)
723 2 pfleura2
  ELSE
724 2 pfleura2
! Even when debug is off we print NAT, NGEOMI, NGEOMF, MAXCYC
725 2 pfleura2
! and PATHNAME
726 2 pfleura2
     WRITE(IOOUT,'(1X,A,I5)') "NAT = ", nat
727 2 pfleura2
     WRITE(IOOUT,'(1X,A,I5)') "NGEOMI = ", NGeomI
728 2 pfleura2
     WRITE(IOOUT,'(1X,A,I5)') "NGEOMF = ", NGeomF
729 2 pfleura2
     WRITE(IOOUT,'(1X,A,I5)') "MAXCYC = ", MaxCYC
730 2 pfleura2
     WRITE(IOOUT,'(1X,A,1X,A)') "PATHNAME = ", Trim(PATHNAME)
731 2 pfleura2
  END IF
732 1 equemene
733 1 equemene
  FTan=1.-FTan
734 1 equemene
735 1 equemene
  !Thresholds...
736 1 equemene
  if (SThresh.LE.0) SThresh=0.01d0
737 1 equemene
  If (GThresh.LE.0) GThresh=SThresh/4.
738 1 equemene
  SThreshRms=Sthresh*2./3.
739 1 equemene
  GThreshRms=Gthresh*2./3.
740 1 equemene
741 1 equemene
  ! First batch of allocations. Arrays that depend only on NGeomI, Nat
742 1 equemene
  ALLOCATE(XyzGeomI(NGeomI,3,Nat), AtName(NAt))
743 1 equemene
  ALLOCATE(IndZmat(Nat,5),Order(Nat),Atome(Nat))
744 1 equemene
  ALLOCATE(MassAt(NAt),OrderInv(Nat))
745 1 equemene
746 1 equemene
  ! We read the initial geometries
747 1 equemene
  Call Read_Geom(input)
748 1 equemene
749 1 equemene
  ! We convert atome names into atom mass number
750 1 equemene
  DO I=1,NAt
751 1 equemene
     !     WRITE(*,*) 'I,AtName',I,AtName(I)
752 1 equemene
     Atome(I)=ConvertNumAt(AtName(I))
753 1 equemene
  END DO
754 1 equemene
755 1 equemene
756 1 equemene
  ! PFL 23 Sep 2008 ->
757 1 equemene
  ! We check that frozen atoms are really frozen, ie that their coordinates do not change
758 1 equemene
  ! between the first geometry and the others.
759 1 equemene
  IF (NFroz.GT.0) THEN
760 1 equemene
     ALLOCATE(ListAtFroz(Nat),x1(Nat),y1(nat),z1(nat))
761 1 equemene
     ALLOCATE(x2(nat),y2(nat),z2(nat))
762 1 equemene
     ListAtFroz=.FALSE.
763 1 equemene
764 1 equemene
     x1(1:Nat)=XyzgeomI(1,1,1:Nat)
765 1 equemene
     y1(1:Nat)=XyzgeomI(1,2,1:Nat)
766 1 equemene
     z1(1:Nat)=XyzgeomI(1,3,1:Nat)
767 1 equemene
768 1 equemene
     SELECT CASE (NFroz)
769 1 equemene
        ! We have Frozen atoms
770 1 equemene
        ! PFL 28 Oct 2008 ->
771 1 equemene
        ! It might happen that the geometries are translated/rotated.
772 1 equemene
        ! So if we have 3 (or more) frozen atoms, we re-orient the geometries, based on the first
773 1 equemene
        ! three frozen atoms.
774 1 equemene
775 1 equemene
     CASE (3:)
776 1 equemene
        DO I=1,NFroz
777 1 equemene
           ListAtFroz(Frozen(I))=.TRUE.
778 1 equemene
        END DO
779 1 equemene
     CASE (2)
780 1 equemene
        IAt1=Frozen(1)
781 1 equemene
        IAt2=Frozen(2)
782 1 equemene
        ListAtFroz(Iat1)=.TRUE.
783 1 equemene
        ListAtFroz(Iat2)=.TRUE.
784 1 equemene
        x2(1)=x1(Iat2)-x1(Iat1)
785 1 equemene
        y2(1)=y1(Iat2)-y1(Iat1)
786 1 equemene
        z2(1)=z1(Iat2)-z1(Iat1)
787 1 equemene
        Norm1=sqrt(x2(1)**2+y2(1)**2+z2(1)**2)
788 1 equemene
        Dist=-1.
789 1 equemene
        ! We scan all atoms to find one that is not aligned with Iat1-Iat2
790 1 equemene
        DO I=1,Nat
791 1 equemene
           if ((I.EQ.Iat1).OR.(I.EQ.Iat2)) Cycle
792 1 equemene
           x2(2)=x1(Iat2)-x1(I)
793 1 equemene
           y2(2)=y1(Iat2)-y1(I)
794 1 equemene
           z2(2)=z1(Iat2)-z1(I)
795 1 equemene
           Norm2=sqrt(x2(2)**2+y2(2)**2+z2(2)**2)
796 1 equemene
           ca=(x2(1)*x2(2)+y2(1)*y2(2)+z2(1)*Z2(2))/(Norm1*Norm2)
797 1 equemene
           if (abs(ca)<0.9) THEN
798 1 equemene
              IF (Norm2>Dist) THEN
799 1 equemene
                 Iat3=I
800 1 equemene
                 Dist=Norm2
801 1 equemene
              END IF
802 1 equemene
           END IF
803 1 equemene
        END DO
804 1 equemene
        ListAtFroz(Iat3)=.TRUE.
805 1 equemene
        if (debug) WRITE(*,*) "DBG Path, NFroz=2, third frozen=",Iat3
806 1 equemene
     CASE (1)
807 1 equemene
        IAt1=Frozen(1)
808 1 equemene
        ListAtFroz(Iat1)=.TRUE.
809 1 equemene
        Dist=-1.
810 1 equemene
        ! We scan all atoms to find one that is further from At1
811 1 equemene
        DO I=1,Nat
812 1 equemene
           if (I.EQ.Iat1) Cycle
813 1 equemene
           x2(1)=x1(Iat1)-x1(I)
814 1 equemene
           y2(1)=y1(Iat1)-y1(I)
815 1 equemene
           z2(1)=z1(Iat1)-z1(I)
816 1 equemene
           Norm1=sqrt(x2(1)**2+y2(1)**2+z2(1)**2)
817 1 equemene
           IF (Norm1>Dist) THEN
818 1 equemene
              Iat2=I
819 1 equemene
              Dist=Norm1
820 1 equemene
           END IF
821 1 equemene
        END DO
822 1 equemene
        IAt2=Frozen(2)
823 1 equemene
        ListAtFroz(Iat2)=.TRUE.
824 1 equemene
        if (debug) WRITE(*,*) "DBG Path, NFroz=1, second frozen=",Iat2
825 1 equemene
        x2(1)=x1(Iat2)-x1(Iat1)
826 1 equemene
        y2(1)=y1(Iat2)-y1(Iat1)
827 1 equemene
        z2(1)=z1(Iat2)-z1(Iat1)
828 1 equemene
        Norm1=sqrt(x2(1)**2+y2(1)**2+z2(1)**2)
829 1 equemene
        Dist=-1.
830 1 equemene
        ! We scan all atoms to find one that is not aligned with Iat1-Iat2
831 1 equemene
        DO I=1,Nat
832 1 equemene
           if ((I.EQ.Iat1).OR.(I.EQ.Iat2)) Cycle
833 1 equemene
           x2(2)=x1(Iat2)-x1(I)
834 1 equemene
           y2(2)=y1(Iat2)-y1(I)
835 1 equemene
           z2(2)=z1(Iat2)-z1(I)
836 1 equemene
           Norm2=sqrt(x2(2)**2+y2(2)**2+z2(2)**2)
837 1 equemene
           ca=(x2(1)*x2(2)+y2(1)*y2(2)+z2(1)*Z2(2))/(Norm1*Norm2)
838 1 equemene
           if (abs(ca)<0.9) THEN
839 1 equemene
              IF (Norm2>Dist) THEN
840 1 equemene
                 Iat3=I
841 1 equemene
                 Dist=Norm2
842 1 equemene
              END IF
843 1 equemene
           END IF
844 1 equemene
        END DO
845 1 equemene
        ListAtFroz(Iat3)=.TRUE.
846 1 equemene
        if (debug) WRITE(*,*) "DBG Path, NFroz=1, third frozen=",Iat3
847 1 equemene
     END SELECT
848 1 equemene
849 1 equemene
     DO I=2,NGeomI
850 1 equemene
        ! First, we align the Ith geometry on the first one, using only
851 1 equemene
        ! the positions of the "frozen" atoms. (see above: it might be that
852 1 equemene
        ! ListAtFroz contains non frozen atoms usd to align the geometries
853 1 equemene
        x2(1:Nat)=XyzgeomI(I,1,1:Nat)
854 1 equemene
        y2(1:Nat)=XyzgeomI(I,2,1:Nat)
855 1 equemene
        z2(1:Nat)=XyzgeomI(I,3,1:Nat)
856 1 equemene
        Call Alignpartial(Nat,x1,y1,z1,x2,y2,z2,ListAtFroz,MRot)
857 1 equemene
858 1 equemene
859 1 equemene
        FChkFrozen=.FALSE.
860 1 equemene
        DO J=1,NFroz
861 1 equemene
           IAt=Frozen(J)
862 1 equemene
           IF ((abs(X1(Iat)-X2(Iat)).GT.FrozTol).OR. &
863 1 equemene
                (abs(y1(Iat)-y2(Iat)).GT.FrozTol).OR.  &
864 1 equemene
                (abs(z1(Iat)-z2(Iat)).GT.FrozTol))                     THEN
865 1 equemene
              IF (.NOT.FChkFrozen) WRITE(*,*) "*** WARNING ****"
866 1 equemene
              FChkFrozen=.TRUE.
867 1 equemene
              WRITE(*,*) "Atom ",Iat," is set to Frozen but its coordinates change"
868 1 equemene
              WRITE(*,*) "from geometry 1 to geometry ",I
869 1 equemene
           END IF
870 1 equemene
        END DO
871 1 equemene
     END DO
872 1 equemene
     IF (FChkFrozen) THEN
873 1 equemene
        WRITE(*,*) "Some frozen atoms are not frozen... check this and play again"
874 1 equemene
        STOP
875 1 equemene
     END IF
876 1 equemene
  END IF
877 1 equemene
878 1 equemene
879 1 equemene
  N3at=3*Nat
880 1 equemene
  NFree=N3at-6   ! ATTENTION: THIS IS NOT VALID FOR ALL TYPES OF COORDINATES.
881 1 equemene
882 1 equemene
  ! if prog=gaussian, we have to read a full input
883 1 equemene
  ! to mimic it later
884 1 equemene
  if (prog=='GAUSSIAN') THEN
885 1 equemene
     ! We read the Gaussian input file
886 1 equemene
     ! First, the root
887 1 equemene
     IF (DEBUG) WRITE(*,*) "Reading Gauss Root"
888 1 equemene
     ALLOCATE(Gauss_Root)
889 1 equemene
     NULLIFY(Gauss_Root%next)
890 1 equemene
     Current => Gauss_root
891 1 equemene
     LineL=1
892 1 equemene
     DO WHILE (LineL.NE.0)
893 1 equemene
        READ(IOIN,'(A)') Line
894 1 equemene
        Line=AdjustL(Line)
895 1 equemene
        LineL=len(Trim(Line))
896 1 equemene
        Idx=INDEX(Line,"chk")
897 1 equemene
        IF ((LineL.NE.0).AND.(Idx.EQ.0)) THEN
898 1 equemene
           current%Line=TRIM(Line)
899 1 equemene
           ALLOCATE(current%next)
900 1 equemene
           Current => Current%next
901 1 equemene
           Nullify(Current%next)
902 1 equemene
        END IF
903 1 equemene
     END DO
904 1 equemene
905 1 equemene
!     Current => Gauss_root
906 1 equemene
!     DO WHILE (ASSOCIATED(Current%next))
907 1 equemene
!        WRITE(*,'(1X,A)') Trim(current%line)
908 1 equemene
!        Current => current%next
909 1 equemene
!     END DO
910 1 equemene
911 1 equemene
     ! Now the comment...
912 1 equemene
     IF (DEBUG) WRITE(*,*) "Reading Gauss Comment"
913 1 equemene
     ALLOCATE(Gauss_Comment)
914 1 equemene
     NuLLIFY(Gauss_Comment%Next)
915 1 equemene
     Current => Gauss_comment
916 1 equemene
     LineL=1
917 1 equemene
     DO WHILE (LineL.NE.0)
918 1 equemene
        READ(IOIN,'(A)') Line
919 1 equemene
        Line=AdjustL(Line)
920 1 equemene
        LineL=len(Trim(Line))
921 1 equemene
        IF (LineL.NE.0) THEN
922 1 equemene
           current%Line=TRIM(Line)
923 1 equemene
           ALLOCATE(current%next)
924 1 equemene
           Current => Current%next
925 1 equemene
           Nullify(Current%next)
926 1 equemene
        END IF
927 1 equemene
     END DO
928 1 equemene
929 1 equemene
 !    Current => Gauss_comment
930 1 equemene
 !    DO WHILE (ASSOCIATED(Current%next))
931 1 equemene
 !       WRITE(*,'(1X,A)') Trim(current%line)
932 1 equemene
 !       Current => current%next
933 1 equemene
 !    END DO
934 1 equemene
935 1 equemene
     ! Now the charge
936 1 equemene
     IF (DEBUG) WRITE(*,*) "Reading Gauss Charge"
937 1 equemene
     READ(IOIN,'(A)') Gauss_Charge
938 1 equemene
!     WRITE(*,*) Gauss_charge
939 1 equemene
     ! We now read the Paste part...
940 1 equemene
     ALLOCATE(Gauss_Paste(NAt))
941 1 equemene
     LenLine=1
942 1 equemene
     Iat=0
943 1 equemene
     Gauss_paste=" "
944 1 equemene
     DO While (LenLine.GT.0)
945 1 equemene
        READ(IOIN,'(A)') Line
946 1 equemene
        Line=AdjustL(Line)
947 1 equemene
        LenLine=Len_TRIM(Line)
948 1 equemene
        IF (LenLine.GT.0) Iat=Iat+1
949 1 equemene
        Idx=Index(Line,'.',BACK=.TRUE.)
950 1 equemene
        !          WRITE(*,*) Idx,TRIM(Line)
951 1 equemene
        !          WRITE(*,*) Idx,TRIM(Line(Idx+1:))
952 1 equemene
        Line=ADJUSTL(Line(Idx+1:))
953 1 equemene
        Idx=Index(Line," ")
954 1 equemene
        LineL=LEN_TRIM(Line(Idx:))
955 1 equemene
        !          WRITE(*,*) LineL,TRIM(Line(Idx:))
956 1 equemene
        IF (LineL.GT.0) THEN
957 1 equemene
           Gauss_paste(Iat)=Line(Idx:)
958 1 equemene
        END IF
959 1 equemene
     END DO
960 1 equemene
     IF (Iat.NE.Nat) THEN
961 1 equemene
        WRITE(*,*) "I found ", Iat," lines for the geometry instead of ",Nat
962 1 equemene
        WRITE(*,*) "ERROR. STOP"
963 1 equemene
        WRITE(IOOUT,*) "I found ", Iat," lines for the geometry instead of ",Nat
964 1 equemene
        WRITE(IOOUT,*) "ERROR. STOP"
965 1 equemene
        STOP
966 1 equemene
     END IF
967 1 equemene
     ! We now read the last part
968 1 equemene
     IF (DEBUG) WRITE(*,*) "Reading Gauss End"
969 1 equemene
     !     READ(IOIN,'(A)') Line
970 1 equemene
     ALLOCATE(Gauss_End)
971 1 equemene
     NuLLIFY(Gauss_End%Next)
972 1 equemene
     Current => Gauss_End
973 1 equemene
     LineL=1
974 1 equemene
     DO WHILE (1.EQ.1)
975 1 equemene
        READ(IOIN,'(A)',END=999) Line
976 1 equemene
        Line=AdjustL(Line)
977 1 equemene
        LineL=len(Trim(Line))
978 1 equemene
        current%Line=TRIM(Line)
979 1 equemene
        ALLOCATE(current%next)
980 1 equemene
        Current => Current%next
981 1 equemene
        Nullify(Current%next)
982 1 equemene
     END DO
983 1 equemene
999  CONTINUE
984 1 equemene
985 1 equemene
     !     ! Write the gaussian input file for testing purposes
986 1 equemene
     !     Current => Gauss_root
987 1 equemene
     !     DO WHILE (ASSOCIATED(Current%next))
988 1 equemene
     !        WRITE(*,'(1X,A)') Trim(current%line)
989 1 equemene
     !        Current => current%next
990 1 equemene
     !     END DO
991 1 equemene
992 1 equemene
     !        WRITE(*,*)
993 1 equemene
     !        WRITE(*,*) 'Comment original'
994 1 equemene
995 1 equemene
     !        Current => Gauss_comment
996 1 equemene
     !        DO WHILE (ASSOCIATED(Current%next))
997 1 equemene
     !           WRITE(*,'(1X,A)') Trim(current%line)
998 1 equemene
     !           Current => current%next
999 1 equemene
     !        END DO
1000 1 equemene
1001 1 equemene
     !        WRITE(*,*)
1002 1 equemene
     !        WRITE(*,*) Trim(Gauss_charge)
1003 1 equemene
1004 1 equemene
     !        DO I=1,Nat
1005 1 equemene
     !           WRITE(*,'(1X,A10,3(1X,F15.8),A)') Trim(AtName(I)),XyzGeomI(1:3,I,1), TRIM(Gauss_Paste(I))
1006 1 equemene
     !        END DO
1007 1 equemene
1008 1 equemene
     !        WRITE(*,*)
1009 1 equemene
     !        Current => Gauss_End
1010 1 equemene
     !        DO WHILE (ASSOCIATED(Current%next))
1011 1 equemene
     !           WRITE(*,'(1X,A)') Trim(current%line)
1012 1 equemene
     !           Current => current%next
1013 1 equemene
     !        END DO
1014 1 equemene
1015 1 equemene
     !        WRITE(*,*)
1016 1 equemene
1017 1 equemene
  END IF
1018 1 equemene
1019 1 equemene
! if prog=mopac, we have to read a full input to reproduce it later
1020 1 equemene
! The structure is:
1021 1 equemene
! A MOPAC data set normally consists of one line of keywords, two lines of user-defined text, then the coordinates
1022 1 equemene
! Then  a blank line or a line of 0.
1023 1 equemene
! then the symmetry description.
1024 1 equemene
! comment lines start with * and can be anywhere !!!
1025 1 equemene
1026 1 equemene
  if (prog=='MOPAC') THEN
1027 1 equemene
     ! We read the Gaussian input file
1028 1 equemene
     ! First, the root
1029 1 equemene
     IF (DEBUG) WRITE(*,*) "Reading Mopac input"
1030 1 equemene
     ALLOCATE(Mopac_Root)
1031 1 equemene
     NULLIFY(Mopac_Root%next)
1032 1 equemene
     ALLOCATE(Mopac_Comment)
1033 1 equemene
     NULLIFY(Mopac_Comment%next)
1034 1 equemene
     ALLOCATE(Mopac_End)
1035 1 equemene
     NuLLIFY(Mopac_End%Next)
1036 1 equemene
     Current => Mopac_root
1037 1 equemene
     CurCom => Mopac_Comment
1038 1 equemene
     LineL=1
1039 1 equemene
     NTmp=0
1040 1 equemene
     DO WHILE (NTmp.LT.3)
1041 1 equemene
        READ(IOIN,'(A)') Line
1042 1 equemene
        Line=AdjustL(Line)
1043 1 equemene
        LineL=len(Trim(Line))
1044 1 equemene
        IF (Line(1:1)/="*") THEN
1045 1 equemene
           IF (NTmp==0) THEN
1046 1 equemene
              Line2=Line
1047 1 equemene
              Call UpCase(Line2)
1048 1 equemene
              Idx=Index(Line2,'GRADIENTS')
1049 1 equemene
              If (Idx==0) Line=TRIM(Line) // " GRADIENTS"
1050 1 equemene
              Idx=Index(Line2,'1SCF')
1051 1 equemene
              If (Idx==0) Line=TRIM(Line) // " 1SCF"
1052 1 equemene
           END IF
1053 1 equemene
           current%Line=TRIM(Line)
1054 1 equemene
           ALLOCATE(current%next)
1055 1 equemene
           Current => Current%next
1056 1 equemene
           Nullify(Current%next)
1057 1 equemene
           NTmp=NTmp+1
1058 1 equemene
        ELSE
1059 1 equemene
           CurCom%Line=TRIM(LINE)
1060 1 equemene
           ALLOCATE(CurCom%Next)
1061 1 equemene
           CurCom => CurCom%Next
1062 1 equemene
           NULLIFY(CurCom%Next)
1063 1 equemene
        END IF
1064 1 equemene
     END DO
1065 1 equemene
1066 1 equemene
!     Current => Mopac_root
1067 1 equemene
!     DO WHILE (ASSOCIATED(Current%next))
1068 1 equemene
!        WRITE(*,'(1X,A)') Trim(current%line)
1069 1 equemene
!        Current => current%next
1070 1 equemene
!     END DO
1071 1 equemene
1072 1 equemene
! Now the geometry... that we just skip :)
1073 1 equemene
     IF (DEBUG) WRITE(*,*) "Reading Mopac Geometry"
1074 1 equemene
     Mopac_EndGeom=""
1075 1 equemene
     LineL=1
1076 1 equemene
     DO WHILE (LineL.NE.0)
1077 1 equemene
        READ(IOIN,'(A)',END=989) Line
1078 1 equemene
        Line=AdjustL(Line)
1079 1 equemene
        LineL=len(Trim(Line))
1080 1 equemene
! The last line might be either blank or filled with 0
1081 1 equemene
        IF (Line(1:1)=="0") THEN
1082 1 equemene
           LineL=0
1083 1 equemene
           Mopac_EndGeom=Trim(Line)
1084 1 equemene
        END IF
1085 1 equemene
        IF (Line(1:1)=="*") THEN
1086 1 equemene
           CurCom%Line=TRIM(LINE)
1087 1 equemene
           ALLOCATE(CurCom%Next)
1088 1 equemene
           CurCom => CurCom%Next
1089 1 equemene
           NULLIFY(CurCom%Next)
1090 1 equemene
        END IF
1091 1 equemene
     END DO
1092 1 equemene
1093 1 equemene
! If we are here, there might be something else to read: Mopac_end
1094 1 equemene
1095 1 equemene
     ! We now read the last part
1096 1 equemene
     IF (DEBUG) WRITE(*,*) "Reading Mopac End"
1097 1 equemene
     !     READ(IOIN,'(A)') Line
1098 1 equemene
     Current => Mopac_End
1099 1 equemene
     LineL=1
1100 1 equemene
     DO WHILE (1.EQ.1)
1101 1 equemene
        READ(IOIN,'(A)',END=989) Line
1102 1 equemene
        Line=AdjustL(Line)
1103 1 equemene
        LineL=len(Trim(Line))
1104 1 equemene
        IF (Line(1:1)/="*") THEN
1105 1 equemene
           current%Line=TRIM(Line)
1106 1 equemene
           ALLOCATE(current%next)
1107 1 equemene
           Current => Current%next
1108 1 equemene
           Nullify(Current%next)
1109 1 equemene
           NTmp=NTmp+1
1110 1 equemene
        ELSE
1111 1 equemene
           CurCom%Line=TRIM(LINE)
1112 1 equemene
           ALLOCATE(CurCom%Next)
1113 1 equemene
           CurCom => CurCom%Next
1114 1 equemene
           NULLIFY(CurCom%Next)
1115 1 equemene
        END IF
1116 1 equemene
     END DO
1117 1 equemene
989  CONTINUE
1118 1 equemene
1119 1 equemene
  END IF ! IF (PROG="MOPAC")
1120 1 equemene
1121 1 equemene
  if ((Prog=="VASP").AND.(input/="VASP")) THEN
1122 1 equemene
     ! Input was not Vasp, so many parameters are missing like lattice
1123 1 equemene
     ! constants...
1124 1 equemene
     ! we read them now !
1125 1 equemene
     ALLOCATE(FFF(3,nat))
1126 1 equemene
     ! First geometry is a bit special for VASP as we have to set
1127 1 equemene
     ! many things
1128 1 equemene
     IF (DEBUG) WRITE(*,*) "Reading Vasp Parameters"
1129 1 equemene
     READ(IOIN,'(A)') Vasp_Title
1130 1 equemene
     READ(IOIN,*) Vasp_param
1131 1 equemene
1132 1 equemene
     READ(IOIN,*) Lat_a
1133 1 equemene
     READ(IOIN,*) Lat_b
1134 1 equemene
     READ(IOIN,*) Lat_c
1135 1 equemene
1136 1 equemene
     Lat_a=Lat_a*Vasp_param
1137 1 equemene
     Lat_b=Lat_b*Vasp_param
1138 1 equemene
     Lat_c=Lat_c*Vasp_param
1139 1 equemene
1140 1 equemene
     ALLOCATE(NbAtType(nat))
1141 1 equemene
     READ(IOIN,'(A)') Vasp_types
1142 1 equemene
     ! First, how many different types ?
1143 1 equemene
     NbAtType=0
1144 1 equemene
     READ(Vasp_types,*,END=998) NbAtType
1145 1 equemene
998  CONTINUE
1146 1 equemene
     NbType=0
1147 1 equemene
     DO WHILE (NbAtType(NbType+1).NE.0)
1148 1 equemene
        NbType=NbType+1
1149 1 equemene
     END DO
1150 1 equemene
1151 1 equemene
     ! Do we know the atom types ?
1152 1 equemene
     IF (AtTypes(1).EQ.'  ') THEN
1153 1 equemene
        ! user has not provided atom types... we have to find them ourselves
1154 1 equemene
        ! by looking into the POTCAR file...
1155 1 equemene
        INQUIRE(File="POTCAR", EXIST=Tchk)
1156 1 equemene
        IF (.NOT.Tchk) THEN
1157 1 equemene
           WRITE(*,*) "ERROR! No AtTypes provided, and POTCAR file not found"
1158 1 equemene
           STOP
1159 1 equemene
        END IF
1160 1 equemene
        OPEN(IOTMP,File="POTCAR")
1161 1 equemene
        DO I=1,NbType
1162 1 equemene
           Line='Empty'
1163 1 equemene
           DO WHILE (Line(1:2).NE.'US')
1164 1 equemene
              READ(IOTMP,'(A)') Line
1165 1 equemene
              Line=AdjustL(Line)
1166 1 equemene
           END DO
1167 1 equemene
           Line=adjustl(Line(3:))
1168 1 equemene
           AtTypes(I)=Line(1:2)
1169 1 equemene
        END DO
1170 1 equemene
        if (debug) WRITE(*,'(A,100(1X,A2))') "ReadG:VASP AtTypes",AtTypes(1:NbType)
1171 1 equemene
        CLOSE(IOTMP)
1172 1 equemene
1173 1 equemene
     ELSE  !AtTypes(1).EQ.'  '
1174 1 equemene
        ! user has provided atom types
1175 1 equemene
        NbTypeUser=0
1176 1 equemene
        DO WHILE (AtTypes(NbTypeUser+1).NE.'  ')
1177 1 equemene
           NbTypeUser=NbTypeUser+1
1178 1 equemene
        END DO
1179 1 equemene
        IF (NbType.NE.NbTypeUser) THEN
1180 1 equemene
           WRITE(*,*) "ERROR Read_Geom : NbType in POSCAR do not match AtTypes"
1181 1 equemene
           STOP
1182 1 equemene
        END IF
1183 1 equemene
     END IF
1184 1 equemene
1185 1 equemene
     IAt=1
1186 1 equemene
     DO I=1,NbType
1187 1 equemene
        DO J=1,NbAtType(I)
1188 1 equemene
           AtName(Iat)=AtTypes(I)
1189 1 equemene
           Iat=Iat+1
1190 1 equemene
        END DO
1191 1 equemene
     END DO
1192 1 equemene
     DEALLOCATE(NbAtType)
1193 1 equemene
1194 1 equemene
     NbTypes=NbType
1195 1 equemene
1196 1 equemene
     READ(IOIN,'(A)') Vasp_comment
1197 1 equemene
     READ(IOIN,'(A)') Vasp_direct
1198 1 equemene
     V_direct=Adjustl(Vasp_direct)
1199 1 equemene
     Call UpCase(V_direct)
1200 2 pfleura2
! PFL 2011 Mar 8 ->
1201 2 pfleura2
! We have to read the FFF flags :
1202 2 pfleura2
     IF (.NOT.ALLOCATED(FFF)) ALLOCATE(FFF(3,nat))
1203 2 pfleura2
     DO I=1,Nat
1204 2 pfleura2
        READ(IOIN,*) Xtmp,ytmp,ztmp,FFF(1:3,I)
1205 2 pfleura2
        DO J=1,3
1206 2 pfleura2
           FFF(J,I)=AdjustL(FFF(J,I))
1207 2 pfleura2
           CALL Upcase(FFF(J,I))
1208 2 pfleura2
        END DO
1209 2 pfleura2
     END DO
1210 2 pfleura2
! <- PFL 2011 Mar 8
1211 1 equemene
1212 1 equemene
  END IF
1213 1 equemene
1214 1 equemene
  ! In the case of VASP there is always the problem  of moving from one side
1215 1 equemene
  ! of the box to the other...
1216 2 pfleura2
! PFL 2011 Mar 14 ->
1217 2 pfleura2
! In fact, we have to make this check as soon as either
1218 2 pfleura2
! Input and/or Prog = VASP
1219 1 equemene
! PFL 2010 Dec 2 ->
1220 1 equemene
! Here we deal with input and not prog in fact
1221 1 equemene
!  if (prog.EQ.'VASP') THEN
1222 2 pfleura2
  if ((Input.EQ.'VASP').OR.(Prog.EQ.'VASP')) THEN
1223 1 equemene
! <- PFL 2010 Dec 2
1224 2 pfleura2
! <- PFL 2011 Mar 14
1225 1 equemene
     Renum=.TRUE.
1226 1 equemene
1227 1 equemene
     ! V_direct has been set in Read_geom
1228 1 equemene
     IF (V_direct(1:6).EQ.'DIRECT') THEN
1229 1 equemene
        Latr(1:3,1)=Lat_a
1230 1 equemene
        Latr(1:3,2)=Lat_b
1231 1 equemene
        Latr(1:3,3)=Lat_c
1232 1 equemene
        B=1.
1233 1 equemene
        CALL Gaussj(Latr,3,3,B,1,1)
1234 1 equemene
     ELSE
1235 1 equemene
        Latr=0.
1236 1 equemene
        Latr(1,1)=1.d0
1237 1 equemene
        Latr(2,2)=1.d0
1238 1 equemene
        Latr(3,3)=1.d0
1239 1 equemene
     END IF
1240 1 equemene
1241 1 equemene
     ! Actualization of Frozen using the FFFF...
1242 1 equemene
     ! Frozen has the advantage ie if given, it imposes _ALL_ the FFF flags.
1243 1 equemene
     IF (Frozen(1).NE.0) THEN
1244 1 equemene
        WRITE(IOOUT,*) "Frozen is given. Flags of the given POSCAR are overriden"
1245 1 equemene
        FFF='T'
1246 1 equemene
1247 1 equemene
        NFroz=0
1248 1 equemene
        DO WHILE (Frozen(NFroz+1).NE.0)
1249 1 equemene
           NFroz=NFroz+1
1250 1 equemene
           FFF(1:3,Frozen(NFroz))='F'
1251 1 equemene
        END DO
1252 1 equemene
     ELSE
1253 1 equemene
        WRITE(IOOUT,*) "Frozen not given : using  Flags of the given POSCAR"
1254 1 equemene
        NFroz=0
1255 1 equemene
        Frozen=0
1256 1 equemene
        DO I=1,Nat
1257 1 equemene
           IF ((FFF(1,I).EQ.'F').OR.(FFF(2,I).EQ.'F').OR.(FFF(3,I).EQ.'F')) THEN
1258 1 equemene
              FFF(1:3,I)='F'
1259 1 equemene
              NFroz=NFroz+1
1260 1 equemene
              Frozen(NFroz)=I
1261 1 equemene
           END IF
1262 1 equemene
        END DO
1263 1 equemene
        WRITE(IOOUT,*) "Frozen atoms:",Frozen(1:NFroz)
1264 1 equemene
     END IF
1265 1 equemene
1266 1 equemene
1267 1 equemene
  END IF
1268 1 equemene
1269 1 equemene
  IF (Prog=="VASP") THEN
1270 1 equemene
     IF (Vmd) THEN
1271 1 equemene
        if (debug) WRITE(*,*) "DBG MAIN, L803, VMD=T,NbTypes,AtTypes",NbTypes,AtTypes(1:NbTypes)
1272 1 equemene
        Line=""
1273 1 equemene
        DO I=1,NbTypes
1274 1 equemene
           Line=TRIM(Line) // " " // TRIM(AdjustL(AtTypes(I)))
1275 1 equemene
        END DO
1276 1 equemene
        Vasp_Title=Trim(Line) // " " // Trim(adjustL(Vasp_Title))
1277 1 equemene
        if (debug) WRITE(*,*) "DBG MAIN, L809, VMD=T, Vasp_Title=",TRIM(Vasp_Title)
1278 1 equemene
     END IF
1279 1 equemene
     Call CheckPeriodicBound
1280 1 equemene
  END IF
1281 1 equemene
1282 1 equemene
  IF (COORD=="MIXED") Call TestCart(AutoCart)
1283 1 equemene
1284 1 equemene
  SELECT CASE(NFroz)
1285 1 equemene
  CASE (2)
1286 1 equemene
     IntFroz=1
1287 1 equemene
  CASE (3)
1288 1 equemene
     IntFroz=3
1289 1 equemene
  CASE (4:)
1290 1 equemene
     IntFroz=(NFroz-2)*3  !(NFroz-3)*3+3
1291 1 equemene
  END SELECT
1292 1 equemene
1293 1 equemene
  if (debug) WRITE(*,'(1X,A,A,5I5)') "DBG Path, L825, Coord, NCart, NCoord, N3at, NFroz: "&
1294 1 equemene
       ,TRIM(COORD),Ncart,NCoord,N3at,NFroz
1295 1 equemene
  if (debug) WRITE(*,*) "DBG Path, L827, Cart",Cart
1296 1 equemene
1297 1 equemene
  if (((NCart+NFroz).EQ.0).AND.(Coord=="MIXED")) THEN
1298 1 equemene
     WRITE(IOOUT,*) "Coord=MIXED but Cart list empty: taking Coord=ZMAT."
1299 1 equemene
     COORD="ZMAT"
1300 1 equemene
  END IF
1301 1 equemene
1302 1 equemene
  IF ((Coord=="MIXED").AND.(NFroz.NE.0)) IntFroz=3*NFroz
1303 1 equemene
1304 1 equemene
  SELECT CASE(COORD)
1305 1 equemene
  CASE ('ZMAT')
1306 1 equemene
     NCoord=Nfree
1307 1 equemene
     ALLOCATE(dzdc(3,nat,3,nat))
1308 1 equemene
  CASE ('MIXED')
1309 1 equemene
     SELECT CASE (NCart+NFroz)
1310 1 equemene
     CASE (1)
1311 1 equemene
        NCoord=N3At-3
1312 1 equemene
     CASE (2)
1313 1 equemene
        NCoord=N3At-1
1314 1 equemene
     CASE (3:)
1315 1 equemene
        NCoord=N3At
1316 1 equemene
     END SELECT
1317 1 equemene
     ALLOCATE(dzdc(3,nat,3,nat))
1318 1 equemene
  CASE ('BAKER')
1319 1 equemene
     Symmetry_elimination=0
1320 1 equemene
     NCoord=3*Nat-6-Symmetry_elimination !NFree = 3*Nat-6
1321 1 equemene
     ALLOCATE(BMat_BakerT(3*Nat,NCoord))
1322 1 equemene
     ALLOCATE(BTransInv(NCoord,3*Nat))
1323 1 equemene
     ALLOCATE(BTransInv_local(NCoord,3*Nat))
1324 1 equemene
  CASE ('HYBRID')
1325 1 equemene
     NCoord=N3at
1326 1 equemene
  CASE ('CART')
1327 1 equemene
     NCoord=N3at
1328 1 equemene
  END SELECT
1329 1 equemene
1330 1 equemene
  if (debug) WRITE(*,*) "DBG Path, L826, Coord, NCart,NCoord, N3At",TRIM(COORD),Ncart, NCoord,N3at
1331 1 equemene
1332 1 equemene
  ALLOCATE(IntCoordI(NGeomI,NCoord),IntCoordF(NGeomF,NCoord))
1333 1 equemene
  ALLOCATE(XyzGeomF(NGeomF,3,Nat),XyzTangent(NGeomF,3*Nat))
1334 1 equemene
  ALLOCATE(Vfree(NCoord,NCoord),IntTangent(NGeomF,NCoord))
1335 1 equemene
  ALLOCATE(Energies(NgeomF),ZeroVec(NCoord)) ! Energies is declared in  Path_module.f90
1336 1 equemene
  ALLOCATE(Grad(NGeomF,NCoord),GeomTmp(NCoord),GradTmp(NCoord))
1337 1 equemene
  ALLOCATE(GeomOld_all(NGeomF,NCoord),GradOld(NGeomF,NCoord))
1338 1 equemene
  ALLOCATE(Hess(NGeomF,NCoord,NCoord),SGeom(NGeomF)) ! SGeom is declared in  Path_module.f90
1339 1 equemene
  ALLOCATE(EPathOld(NGeomF),MaxStep(NGeomF))
1340 1 equemene
1341 1 equemene
  ZeroVec=0.d0
1342 1 equemene
  DO I =1, NGeomF
1343 1 equemene
     IntTangent(I,:)=0.d0
1344 1 equemene
  END DO
1345 1 equemene
1346 1 equemene
  if (debug) THEN
1347 1 equemene
     Print *, 'L886, IntTangent(1,:)='
1348 1 equemene
     Print *, IntTangent(1,:)
1349 1 equemene
  END IF
1350 1 equemene
1351 1 equemene
  if (.NOT.OptReac) Energies(1)=Ereac
1352 1 equemene
  if (.NOT.OptProd) Energies(NGeomF)=EProd
1353 1 equemene
  MaxStep=SMax
1354 1 equemene
1355 1 equemene
  ! We initialize the mass array
1356 1 equemene
  if (MW) THEN
1357 1 equemene
     WRITE(*,*) 'Working in MW coordinates'
1358 1 equemene
     DO I=1,Nat
1359 1 equemene
        massAt(I)=Mass(Atome(I))
1360 1 equemene
     END DO
1361 1 equemene
  ELSE
1362 1 equemene
     DO I=1,Nat
1363 1 equemene
        MassAt(I)=1.d0
1364 1 equemene
     END DO
1365 1 equemene
  END IF
1366 1 equemene
1367 1 equemene
  WRITE(*,*) "Prog=",TRIM(PROG)
1368 1 equemene
1369 1 equemene
  ALLOCATE(FrozAtoms(Nat))
1370 1 equemene
1371 1 equemene
  !  IF (debug) WRITe(*,*) "DBG Main L940 NFroz",NFroz
1372 1 equemene
  !  IF (debug) WRITe(*,*) "DBG Main L940 Frozen",Frozen
1373 1 equemene
  !  IF (debug) WRITe(*,*) "DBG Main L940 FrozAtoms",FrozAtoms
1374 1 equemene
  IF (NFroz.EQ.0) THEN
1375 1 equemene
     FrozAtoms=.TRUE.
1376 1 equemene
  ELSE
1377 1 equemene
     I=1
1378 1 equemene
     NFr=0
1379 1 equemene
     FrozAtoms=.False.
1380 1 equemene
     DO WHILE (Frozen(I).NE.0)
1381 1 equemene
        IF (Frozen(I).LT.0) THEN
1382 1 equemene
           DO J=Frozen(I-1),abs(Frozen(I))
1383 1 equemene
              IF (.NOT.FrozAtoms(J)) THEN
1384 1 equemene
                 NFr=NFr+1
1385 1 equemene
                 FrozAtoms(J)=.TRUE.
1386 1 equemene
              END IF
1387 1 equemene
           END DO
1388 1 equemene
        ELSEIF (.NOT.FrozAtoms(Frozen(I))) THEN
1389 1 equemene
           FrozAtoms(Frozen(I))=.TRUE.
1390 1 equemene
           NFr=NFr+1
1391 1 equemene
        END IF
1392 1 equemene
        I=I+1
1393 1 equemene
     END DO
1394 1 equemene
     IF (NFr.NE.NFroz) THEN
1395 1 equemene
        WRITE(*,*) "Pb in PATH: Number of Frozen atoms not good :-( ",NFroz,NFr
1396 1 equemene
        STOP
1397 1 equemene
     END IF
1398 1 equemene
  END IF
1399 1 equemene
1400 1 equemene
  if (debug) THEN
1401 1 equemene
     !Print *, 'L968, IntTangent(1,:)='
1402 1 equemene
     !Print *, IntTangent(1,:)
1403 1 equemene
  END IF
1404 1 equemene
1405 1 equemene
  ! We have read everything we needed... time to work :-)
1406 1 equemene
  IOpt=0
1407 1 equemene
  FirstTimePathCreate = .TRUE. ! Initialized.
1408 1 equemene
  Call PathCreate(IOpt)    ! IntTangent is also computed in PathCreate.
1409 1 equemene
  FirstTimePathCreate = .FALSE.
1410 1 equemene
1411 1 equemene
  if (debug) THEN
1412 1 equemene
     Print *, 'L980, IntTangent(1,:)='
1413 1 equemene
     Print *, IntTangent(1,:)
1414 1 equemene
  END IF
1415 1 equemene
1416 1 equemene
  ! PFL 30 Mar 2008 ->
1417 1 equemene
  ! The following is now allocated in Calc_Baker. This is more logical to me
1418 1 equemene
  !   IF (COORD .EQ. "BAKER") Then
1419 1 equemene
  !      ALLOCATE(XprimitiveF(NgeomF,NbCoords))
1420 1 equemene
  !      ALLOCATE(UMatF(NGeomF,NbCoords,NCoord))
1421 1 equemene
  !      ALLOCATE(BTransInvF(NGeomF,NCoord,3*Nat))
1422 1 equemene
  !   END IF
1423 1 equemene
  ! <- PFL 30 mar 2008
1424 1 equemene
1425 1 equemene
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1426 1 equemene
  !
1427 1 equemene
  ! For Debugging purposes
1428 1 equemene
  !
1429 1 equemene
  ! OptGeom is the index of the geometry which is to be optimized.
1430 1 equemene
  IF (Optgeom.GT.0) THEN
1431 1 equemene
     Flag_Opt_Geom=.TRUE.
1432 1 equemene
     SELECT CASE(Coord)
1433 1 equemene
     CASE ('CART','HYBRID')
1434 1 equemene
!!! CAUTION : PFL 29.AUG.2008 ->
1435 1 equemene
        ! XyzGeomI/F stored in (NGeomI/F,3,Nat) and NOT (NGeomI/F,Nat,3)
1436 1 equemene
        ! This should be made  consistent !!!!!!!!!!!!!!!
1437 1 equemene
        GeomTmp=Reshape(reshape(XyzGeomF(OptGeom,:,:),(/Nat,3/),ORDER=(/2,1/)),(/3*Nat/))
1438 1 equemene
        !           GeomTmp=Reshape(XyzGeomF(IGeom,:,:),(/3*Nat/))
1439 1 equemene
!!! <- CAUTION : PFL 29.AUG.2008
1440 1 equemene
     CASE ('ZMAT','MIXED')
1441 1 equemene
        !GeomTmp=IntCoordF(OptGeom,:)
1442 1 equemene
        GeomTmp=IntCoordI(OptGeom,:)
1443 1 equemene
     CASE ('BAKER')
1444 1 equemene
        !GeomTmp=IntCoordF(OptGeom,:)
1445 1 equemene
        GeomTmp=IntCoordI(OptGeom,:)
1446 1 equemene
     CASE DEFAULT
1447 1 equemene
        WRITE(*,*) "Coord=",TRIM(COORD)," not recognized in Path L935.STOP"
1448 1 equemene
        STOP
1449 1 equemene
     END SELECT
1450 1 equemene
1451 1 equemene
     ! NCoord = NFree, Coord = Type of coordinate; e.g.: Baker
1452 1 equemene
     Flag_Opt_Geom = .TRUE.
1453 1 equemene
     Call Opt_geom(OptGeom,Nat,Ncoord,Coord,GeomTmp,E,Flag_Opt_Geom,Step_method)
1454 1 equemene
1455 1 equemene
     WRITE(Line,"('Geometry ',I3,' optimized')") Optgeom
1456 1 equemene
     WRITE(*,*) "Before PrintGeom, L1059, Path.f90"
1457 1 equemene
     Call PrintGeom(Line,Nat,NCoord,GeomTmp,Coord,IoOut,Atome,Order,OrderInv,IndZmat)
1458 1 equemene
     STOP
1459 1 equemene
  END IF ! IF (Optgeom.GT.0) THEN
1460 1 equemene
1461 1 equemene
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1462 1 equemene
  ! End of GeomOpt
1463 1 equemene
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1464 1 equemene
1465 1 equemene
  IF (PathOnly) THEN
1466 1 equemene
     WRITE(*,*) "PathOnly=.T. , Stop here"
1467 1 equemene
     Call Write_path(-1)
1468 1 equemene
     if ((prog.EQ.'VASP').OR.WriteVasp) Call Write_vasp(poscar)
1469 1 equemene
     STOP
1470 1 equemene
  END IF
1471 1 equemene
1472 1 equemene
  if ((debug.AND.(prog.EQ.'VASP')).OR.WriteVasp)  Call Write_vasp(poscar)
1473 1 equemene
1474 1 equemene
  DEALLOCATE(XyzGeomI,IntCoordI)
1475 1 equemene
  NGeomI=NGeomF
1476 1 equemene
  ALLOCATE(XyzGeomI(NGeomF,3,Nat),IntCoordI(NGeomF,NCoord))
1477 1 equemene
1478 1 equemene
  IF (DEBUG) WRITE(*,*) ' Back from PathCreate, L965, Path.f90'
1479 1 equemene
  ! we print this path, which is the first one :-) called Iteration0
1480 1 equemene
  ! we now have to calculate the gradient for each point (and the energy
1481 1 equemene
  ! if we work at 0K)
1482 1 equemene
1483 1 equemene
  if (DEBUG.AND.(COORD.EQ."BAKER")) THEN
1484 1 equemene
     DO IGeom=1,NGeomF
1485 1 equemene
        WRITE(*,*) "Before Calc_baker_allgeomf UMatF for IGeom=",IGeom
1486 1 equemene
        DO I=1,3*Nat-6
1487 1 equemene
           WRITE(*,'(50(1X,F12.8))') UMatF(IGeom,:,I)
1488 1 equemene
        END DO
1489 1 equemene
     END DO
1490 1 equemene
  END IF
1491 1 equemene
1492 1 equemene
  ! To calculate B^T^-1 for all extrapolated final geometries:
1493 1 equemene
  ! PFL 18 Jan 2008 ->
1494 1 equemene
  ! Added a test for COORD=BAKER before the call to calc_baker_allgeomF
1495 1 equemene
  IF (COORD.EQ."BAKER")   Call Calc_baker_allGeomF()
1496 1 equemene
  ! <-- PFL 18 Jan 2008
1497 1 equemene
1498 1 equemene
  if (DEBUG.AND.(COORD.EQ."BAKER")) THEN
1499 1 equemene
     DO IGeom=1,NGeomF
1500 1 equemene
        WRITE(*,*) "After Calc_baker_allgeomf UMatF for IGeom=",IGeom
1501 1 equemene
        DO I=1,3*Nat-6
1502 1 equemene
           WRITE(*,'(50(1X,F12.8))') UMatF(IGeom,:,I)
1503 1 equemene
        END DO
1504 1 equemene
     END DO
1505 1 equemene
  END IF
1506 1 equemene
1507 1 equemene
  IOpt=0
1508 1 equemene
  Call EgradPath(IOpt,Flag_Opt_Geom)
1509 1 equemene
1510 1 equemene
  if (debug)  WRITE(*,*) "Calling Write_path, L1002, Path.f90, IOpt=",IOpt
1511 1 equemene
  Call Write_path(IOpt)
1512 1 equemene
  if ((debug.AND.(prog.EQ.'VASP')).OR.WriteVasp)  Call Write_vasp(poscar)
1513 1 equemene
1514 1 equemene
  ! We have the geometries, the first gradients... we will generate the first hessian matrices :-)
1515 1 equemene
  ! ... v3.71 Only if IniHUp=.TRUE. which is not the default. In this version, we take the hessian
1516 1 equemene
  ! of end points as Unity matrices, and we update them along the path.
1517 1 equemene
1518 1 equemene
  ! By default, Hess=Id
1519 1 equemene
  Hess=0.
1520 1 equemene
  IF(Coord .EQ. "ZMAT") Then
1521 1 equemene
     ! We use the fact that we know that approximate good hessian values
1522 1 equemene
     ! are 0.5 for bonds, 0.1 for valence angle and 0.02 for dihedral angles
1523 1 equemene
     DO IGeom=1,NGeomF
1524 1 equemene
        Hess(IGeom,1,1)=0.5d0
1525 1 equemene
        Hess(IGeom,2,2)=0.5d0
1526 1 equemene
        Hess(IGeom,3,3)=0.1d0
1527 1 equemene
        DO J=1,Nat-3
1528 1 equemene
           Hess(IGeom,3*J+1,3*J+1)=0.5d0
1529 1 equemene
           Hess(IGeom,3*J+2,3*J+2)=0.1d0
1530 1 equemene
           Hess(IGeom,3*J+3,3*J+3)=0.02d0
1531 1 equemene
        END DO
1532 1 equemene
        IF (HInv) THEN
1533 1 equemene
           DO I=1,NCoord
1534 1 equemene
              Hess(IGeom,I,I)=1.d0/Hess(IGeom,I,I)
1535 1 equemene
           END DO
1536 1 equemene
        END IF
1537 1 equemene
     END DO
1538 1 equemene
  ELSE
1539 1 equemene
     DO I=1,NCoord
1540 1 equemene
        DO J=1,NGeomF
1541 1 equemene
           Hess(J,I,I)=1.d0
1542 1 equemene
        END DO
1543 1 equemene
     END DO
1544 1 equemene
  END IF
1545 1 equemene
1546 1 equemene
  IF (COORD .EQ. "BAKER") THEN
1547 1 equemene
     ! UMat(NPrim,NCoord)
1548 1 equemene
     ALLOCATE(Hprim(NPrim,NPrim),HprimU(NPrim,3*Nat-6))
1549 1 equemene
     Hprim=0.d0
1550 1 equemene
     ScanCoord=>Coordinate
1551 1 equemene
     I=0
1552 1 equemene
     DO WHILE (Associated(ScanCoord%next))
1553 1 equemene
        I=I+1
1554 1 equemene
        SELECT CASE (ScanCoord%Type)
1555 1 equemene
        CASE ('BOND')
1556 1 equemene
           !DO J=1,NGeomF ! why all geometries?? Should be only 1st and NGeomF??
1557 1 equemene
           Hprim(I,I) = 0.5d0
1558 1 equemene
           !END DO
1559 1 equemene
        CASE ('ANGLE')
1560 1 equemene
           Hprim(I,I) = 0.2d0
1561 1 equemene
        CASE ('DIHEDRAL')
1562 1 equemene
           Hprim(I,I) = 0.1d0
1563 1 equemene
        END SELECT
1564 1 equemene
        ScanCoord => ScanCoord%next
1565 1 equemene
     END DO
1566 1 equemene
1567 1 equemene
     ! HprimU = H^prim U:
1568 1 equemene
     HprimU=0.d0
1569 1 equemene
     DO I=1, 3*Nat-6
1570 1 equemene
        DO J=1,NPrim
1571 1 equemene
           HprimU(:,I) = HprimU(:,I) + Hprim(:,J)*UMat(J,I)
1572 1 equemene
        END DO
1573 1 equemene
     END DO
1574 1 equemene
1575 1 equemene
     ! Hess = U^T HprimU = U^T H^prim U:
1576 1 equemene
     Hess=0.d0
1577 1 equemene
     DO I=1, 3*Nat-6
1578 1 equemene
        DO J=1,NPrim
1579 1 equemene
           ! UMat^T is needed below.
1580 1 equemene
           Hess(1,:,I) = Hess(1,:,I) + UMat(J,:)*HprimU(J,I)
1581 1 equemene
        END DO
1582 1 equemene
     END DO
1583 1 equemene
     DO K=2,NGeomF
1584 1 equemene
        Hess(K,:,:)=Hess(1,:,:)
1585 1 equemene
     END DO
1586 1 equemene
     DEALLOCATE(Hprim,HprimU)
1587 1 equemene
  end if !  ends IF COORD=BAKER
1588 1 equemene
  ALLOCATE(GradTmp2(NCoord),GeomTmp2(NCoord))
1589 1 equemene
  ALLOCATE(HessTmp(NCoord,NCoord))
1590 1 equemene
1591 1 equemene
  IF (IniHUp) THEN
1592 1 equemene
     IF (FCalcHess) THEN
1593 1 equemene
        ! The numerical calculation of the Hessian has been switched on
1594 1 equemene
        DO IGeom=1,NGeomF
1595 1 equemene
           IF ((COORD.EQ.'ZMAT') .OR. (COORD.EQ.'BAKER')) THEN
1596 1 equemene
              GeomTmp=IntCoordF(IGeom,:)
1597 1 equemene
           ELSE
1598 1 equemene
              GeomTmp=Reshape(XyzGeomF(IGeom,:,:),(/3*Nat/))
1599 1 equemene
           END IF
1600 1 equemene
           Call CalcHess(NCoord,GeomTmp,Hess(IGeom,:,:),IGeom,Iopt)
1601 1 equemene
        END DO
1602 1 equemene
     ELSE
1603 1 equemene
        ! We generate a forward hessian and a backward one and we mix them.
1604 1 equemene
        ! First, the forward way:
1605 1 equemene
        DO IGeom=2,NGeomF-1
1606 1 equemene
           IF ((COORD.EQ.'ZMAT') .OR. (COORD.EQ.'BAKER')) THEN
1607 1 equemene
              GeomTmp=IntCoordF(IGeom,:)-IntCoordF(IGeom-1,:)
1608 1 equemene
           ELSE
1609 1 equemene
              GeomTmp=Reshape(XyzGeomF(IGeom,:,:),(/3*Nat/))-Reshape(XyzGeomF(IGeom-1,:,:),(/3*Nat/))
1610 1 equemene
           END IF
1611 1 equemene
           GradTmp=Grad(IGeom-1,:)-Grad(IGeom,:)
1612 1 equemene
           HessTmp=Hess(IGeom-1,:,:)
1613 1 equemene
           Call Hupdate_all(NCoord,GeomTmp,GradTmp,HessTmp)
1614 1 equemene
           Hess(IGeom,:,:)=HessTmp
1615 1 equemene
        END DO
1616 1 equemene
1617 1 equemene
        ! Now, the backward way:
1618 1 equemene
        HessTmp=Hess(NGeomF,:,:)
1619 1 equemene
        DO IGeom=NGeomF-1,2,-1
1620 1 equemene
           IF ((COORD.EQ.'ZMAT') .OR. (COORD.EQ.'BAKER')) THEN
1621 1 equemene
              GeomTmp=IntCoordF(IGeom,:)-IntCoordF(IGeom+1,:)
1622 1 equemene
           ELSE
1623 1 equemene
              GeomTmp=Reshape(XyzGeomF(IGeom,:,:),(/3*Nat/))-Reshape(XyzGeomF(IGeom+1,:,:),(/3*Nat/))
1624 1 equemene
           END IF
1625 1 equemene
           GradTmp=Grad(IGeom,:)-Grad(IGeom+1,:)
1626 1 equemene
           Call Hupdate_all(NCoord,GeomTmp,GradTmp,HessTmp)
1627 1 equemene
           alpha=0.5d0*Pi*(IGeom-1.)/(NGeomF-1.)
1628 1 equemene
           ca=cos(alpha)
1629 1 equemene
           sa=sin(alpha)
1630 1 equemene
           Hess(IGeom,:,:)=ca*Hess(IGeom,:,:)+sa*HessTmp(:,:)
1631 1 equemene
        END DO
1632 1 equemene
     END IF ! matches IF (FCalcHess)
1633 1 equemene
  END IF ! matches IF (IniHUp) THEN
1634 1 equemene
1635 1 equemene
  ! For debug purposes, we diagonalize the Hessian matrices
1636 1 equemene
  IF (debug) THEN
1637 1 equemene
     !WRITE(*,*) "DBG Main, L1104, - EigenSystem for Hessian matrices"
1638 1 equemene
     DO I=1,NGeomF
1639 1 equemene
        WRITE(*,*) "DBG Main - Point ",I
1640 1 equemene
        Call Jacobi(Hess(I,:,:),NCoord,GradTmp2,HessTmp,NCoord)
1641 1 equemene
        DO J=1,NCoord
1642 1 equemene
           WRITE(*,'(1X,I3,1X,F10.6," : ",20(1X,F8.4))') J,GradTmp2(J),HessTmp(J,1:min(20,NCoord))
1643 1 equemene
        END DO
1644 1 equemene
     END DO
1645 1 equemene
  END IF ! matches IF (debug) THEN
1646 1 equemene
1647 1 equemene
  ! we have the hessian matrices and the gradients, we can start the optimizations !
1648 1 equemene
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1649 1 equemene
  !
1650 1 equemene
  ! Main LOOP : Optimization of the Path
1651 1 equemene
  !
1652 1 equemene
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1653 1 equemene
  if (debug)   Print *, 'NGeomF=', NGeomF
1654 1 equemene
  allocation_flag = .TRUE.
1655 1 equemene
1656 1 equemene
  Fini=.FALSE.
1657 1 equemene
1658 1 equemene
  DO WHILE ((IOpt.LT.MaxCyc).AND.(.NOT. Fini))
1659 1 equemene
     if (debug) Print *, 'IOpt at the begining of the loop, L1128=', IOpt
1660 1 equemene
     IOpt=IOpt+1
1661 1 equemene
1662 1 equemene
     SELECT CASE (COORD)
1663 1 equemene
     CASE ('ZMAT','MIXED','BAKER')
1664 1 equemene
        GeomOld_all=IntCoordF
1665 1 equemene
     CASE ('CART','HYBRID')
1666 1 equemene
        GeomOld_all=Reshape(XyzGeomF,(/NGeomF,NCoord/))
1667 1 equemene
     CASE DEFAULT
1668 1 equemene
        WRITE(*,*) 'Coord=',TRIM(COORD),' not recognized. Path L1149.STOP'
1669 1 equemene
        STOP
1670 1 equemene
     END SELECT
1671 1 equemene
1672 1 equemene
     IF (((COORD.EQ.'ZMAT').OR.(COORD.EQ.'BAKER').OR.(COORD.EQ.'MIXED')).AND. &
1673 1 equemene
          valid("printtangent")) THEN
1674 1 equemene
        WRITE(*,*) "Visualization of tangents"
1675 1 equemene
        Idx=min(12,NCoord)
1676 1 equemene
        DO I=1,NGeomF
1677 1 equemene
           WRITE(*,'(12(1X,F12.5))') IntCoordF(I,1:Idx)-0.5d0*IntTangent(I,1:Idx)
1678 1 equemene
           WRITE(*,'(12(1X,F12.5))') IntCoordF(I,1:Idx)+0.5d0*IntTangent(I,1:Idx)
1679 1 equemene
           WRITE(*,*)
1680 1 equemene
        END DO
1681 1 equemene
        WRITE(*,*) "END of tangents"
1682 1 equemene
     END IF
1683 1 equemene
1684 1 equemene
     IF (((COORD.EQ.'ZMAT').OR.(COORD.EQ.'BAKER').OR.(COORD.EQ.'MIXED')).AND. &
1685 1 equemene
          valid("printgrad")) THEN
1686 1 equemene
        WRITE(*,*) "Visualization of gradients"
1687 1 equemene
        Idx=min(12,NCoord)
1688 1 equemene
        DO I=1,NGeomF
1689 1 equemene
           WRITE(*,'(12(1X,F12.5))') IntCoordF(I,1:Idx)-1.d0*Grad(I,1:Idx)
1690 1 equemene
           WRITE(*,'(12(1X,F12.5))') IntCoordF(I,1:Idx)+1.d0*Grad(I,1:Idx)
1691 1 equemene
           WRITe(*,*)
1692 1 equemene
        END DO
1693 1 equemene
        WRITE(*,*) "END of gradients"
1694 1 equemene
     END IF
1695 1 equemene
1696 1 equemene
     Fini=.TRUE.
1697 1 equemene
     IF (OptReac) THEN !OptReac: True if one wants to optimize the geometry of the reactants. Default is FALSE.
1698 1 equemene
        IGeom=1
1699 1 equemene
        if (debug) WRITE(*,*) '**************************************'
1700 1 equemene
        if (debug) WRITE(*,*) 'Optimizing reactant'
1701 1 equemene
        if (debug) WRITE(*,*) '**************************************'
1702 1 equemene
        SELECT CASE (COORD)
1703 1 equemene
        CASE ('ZMAT','MIXED','BAKER')
1704 1 equemene
           SELECT CASE (Step_method)
1705 1 equemene
           CASE ('RFO')
1706 1 equemene
              !GradTmp(NCoord) becomes Step in Step_RFO_all and has INTENT(OUT).
1707 1 equemene
              Call Step_RFO_all(NCoord,GradTmp,1,IntCoordF(1,:),Grad(1,:),Hess(1,:,:),ZeroVec)
1708 1 equemene
              Print *, GradTmp
1709 1 equemene
           CASE ('GDIIS')
1710 1 equemene
              ! GradTmp(NCoord) becomes "step" below and has INTENT(OUT).:
1711 1 equemene
              Call Step_DIIS_all(NGeomF,1,GradTmp,IntCoordF(1,:),Grad(1,:),HP,HEAT,&
1712 1 equemene
                   Hess(1,:,:),NCoord,allocation_flag,ZeroVec)
1713 1 equemene
              Print *, 'OptReac, Steps from GDIIS, GeomNew - IntCoordF(1,:)='
1714 1 equemene
              Print *, GradTmp
1715 1 equemene
           CASE ('GEDIIS')
1716 1 equemene
              ! GradTmp(NCoord) becomes "step" below and has INTENT(OUT).:
1717 1 equemene
              ! Energies are updated in EgradPath.f90
1718 1 equemene
              Call Step_GEDIIS_All(NGeomF,1,GradTmp,IntCoordF(1,:),Grad(1,:),Energies(1),Hess(1,:,:),&
1719 1 equemene
                   NCoord,allocation_flag,ZeroVec)
1720 1 equemene
              !Call Step_GEDIIS(GeomTmp,IntCoordF(1,:),Grad(1,:),Energies(1),Hess(1,:,:),NCoord,allocation_flag)
1721 1 equemene
              !GradTmp = GeomTmp - IntCoordF(1,:)
1722 1 equemene
              !Print *, 'Old Geometry:'
1723 1 equemene
              !Print *, IntCoordF(1,:)
1724 1 equemene
              Print *, 'OptReac, Steps from GEDIIS, GradTmp = GeomTmp - IntCoordF(1,:)='
1725 1 equemene
              Print *, GradTmp
1726 1 equemene
              !Print *, 'GeomTmp:'
1727 1 equemene
              !Print *, GeomTmp
1728 1 equemene
              GeomTmp(:) = GradTmp(:) + IntCoordF(1,:)
1729 1 equemene
           CASE DEFAULT
1730 1 equemene
              WRITE (*,*) "Step_method=",TRIM(Step_method)," not recognized, Path.f90, L1194. Stop"
1731 1 equemene
              STOP
1732 1 equemene
           END SELECT
1733 1 equemene
        CASE ('HYBRID','CART')
1734 1 equemene
           Call Step_RFO_all(NCoord,GradTmp,1,XyzGeomF(1,:,:),Grad(1,:),Hess(1,:,:),ZeroVec)
1735 1 equemene
        CASE DEFAULT
1736 1 equemene
           WRITE(*,*) 'Coord=',TRIM(COORD),' not recognized. Path L1200. STOP'
1737 1 equemene
           STOP
1738 1 equemene
        END SELECT
1739 1 equemene
1740 1 equemene
        IF (debug) THEN
1741 1 equemene
           WRITE(Line,*) 'DBG Path, L1227,', TRIM(Step_method), 'Step for IOpt=',IOpt, ', IGeom=1'
1742 1 equemene
           Call PrintGeom(Line,Nat,NCoord,GeomTmp,Coord,6,Atome,Order,OrderInv,IndZmat)
1743 1 equemene
        END IF
1744 1 equemene
1745 1 equemene
        ! we have the Newton+RFO step, we will check that the maximum displacement is not greater than Smax
1746 1 equemene
        NormStep=sqrt(DOT_Product(GradTmp,GradTmp))
1747 1 equemene
        FactStep=min(1.d0,MaxStep(Igeom)/NormStep)
1748 1 equemene
        Fini=(Fini.AND.(NormStep.LE.SThresh))
1749 1 equemene
        OptReac=(NormStep.GT.SThresh)
1750 1 equemene
        IF (debug) WRITE(*,*) "NormStep, SThresh, OptReac=",NormStep, SThresh, OptReac
1751 1 equemene
        NormGrad=sqrt(DOT_Product(reshape(Grad(1,:),(/Nfree/)),reshape(Grad(1,:),(/NFree/))))
1752 1 equemene
        Fini=(Fini.AND.(NormGrad.LE.GThresh))
1753 1 equemene
        OptReac=(OptReac.OR.(NormGrad.GT.GThresh))
1754 1 equemene
        !Print *, 'Grad(1,:):'
1755 1 equemene
        !Print *, Grad(1,:)
1756 1 equemene
        IF (debug) WRITE(*,*) "NormGrad, GThresh, OptReac=",NormGrad, GThresh, OptReac
1757 1 equemene
1758 1 equemene
        GradTmp=GradTmp*FactStep
1759 1 equemene
1760 1 equemene
        ! we take care that frozen atoms do not move.
1761 1 equemene
        IF (NFroz.NE.0) THEN
1762 1 equemene
           SELECT CASE (COORD)
1763 1 equemene
           CASE ('ZMAT','MIXED')
1764 1 equemene
              GradTmp(1:IntFroz)=0.d0
1765 1 equemene
           CASE ('CART','HYBRID')
1766 1 equemene
              DO I=1,Nat
1767 1 equemene
                 IF (FrozAtoms(I)) THEN
1768 1 equemene
                    Iat=Order(I)
1769 1 equemene
                    GradTmp(3*Iat-2:3*Iat)=0.d0
1770 1 equemene
                 END IF
1771 1 equemene
              END DO
1772 1 equemene
           CASE('BAKER')
1773 1 equemene
              GradTmp(1:IntFroz)=0.d0 !GradTmp is "step" in Step_RFO_all(..)
1774 1 equemene
           CASE DEFAULT
1775 1 equemene
              WRITE(*,*) 'Coord=',TRIM(COORD),' not recognized. Path L1323.STOP'
1776 1 equemene
              STOP
1777 1 equemene
           END SELECT
1778 1 equemene
        END IF ! matches IF (NFroz.NE.0) THEN
1779 1 equemene
1780 1 equemene
        IF (debug) THEN
1781 1 equemene
           !WRITE(Line,*) 'DBG Path, L1244, Step for IOpt=',IOpt, ', IGeom=1'
1782 1 equemene
           !Call PrintGeom(Line,Nat,NCoord,GradTmp,Coord,6,Atome,Order,OrderInv,IndZmat)
1783 1 equemene
        END IF
1784 1 equemene
1785 1 equemene
        IF (debug) THEN
1786 1 equemene
           !WRITE(*,*) "DBG Main, L1249, IOpt=",IOpt, ', IGeom=1'
1787 1 equemene
           IF ((COORD.EQ.'ZMAT') .OR. (COORD.EQ.'BAKER')) THEN
1788 1 equemene
              WRITE(*,'(12(1X,F8.3))') IntCoordF(1,1:min(12,NFree))
1789 1 equemene
           ELSE
1790 1 equemene
              DO Iat=1,Nat
1791 1 equemene
                 WRITE(*,'(1X,A5,3(1X,F11.6))') Nom(Atome(Iat)), &
1792 1 equemene
                      XyzGeomF(IGeom,1:3,Iat)
1793 1 equemene
              END DO
1794 1 equemene
           END IF
1795 1 equemene
        END IF ! matches IF (debug) THEN
1796 1 equemene
1797 1 equemene
        SELECT CASE (COORD)
1798 1 equemene
        CASE ('ZMAT','MIXED','BAKER')
1799 1 equemene
           IntcoordF(1,:)=IntcoordF(1,:)+GradTmp(:) !IGeom=1
1800 1 equemene
        CASE ('HYBRID','CART')
1801 1 equemene
           XyzGeomF(1,:,:)=XyzGeomF(1,:,:)+reshape(GradTmp(:),(/3,Nat/))
1802 1 equemene
        CASE DEFAULT
1803 1 equemene
           WRITE(*,*) 'Coord=',TRIM(COORD),' not recognized. Path L1201.STOP'
1804 1 equemene
           STOP
1805 1 equemene
        END SELECT
1806 1 equemene
1807 1 equemene
        IF (debug) THEN
1808 1 equemene
           WRITE(*,*) "DBG Main, L1271, IOpt=",IOpt, ', IGeom=1'
1809 1 equemene
           IF ((COORD.EQ.'ZMAT') .OR. (COORD.EQ.'BAKER')) THEN
1810 1 equemene
              WRITE(*,'(12(1X,F8.3))') IntCoordF(1,1:min(12,NFree))
1811 1 equemene
           ELSE
1812 1 equemene
              DO Iat=1,Nat
1813 1 equemene
1814 1 equemene
!!!!!!!!!! There was an OrderInv here... should I put it back ?
1815 1 equemene
                 ! It was with indzmat. IndZmat cannot appear here...
1816 1 equemene
                 WRITE(*,'(1X,A5,3(1X,F11.6))') Nom(Atome(Iat)), &
1817 1 equemene
                      XyzGeomF(IGeom,1:3,Iat)
1818 1 equemene
              END DO
1819 1 equemene
           END IF
1820 1 equemene
        END IF ! matches IF (debug) THEN
1821 1 equemene
1822 1 equemene
        IF (.NOT.OptReac) WRITE(*,*) "Reactants optimized"
1823 1 equemene
     ELSE ! Optreac
1824 1 equemene
        IF (debug) WRITE(*,*) "Reactants already optimized, Fini=",Fini
1825 1 equemene
     END IF ! matches IF (OptReac) THEN
1826 1 equemene
1827 1 equemene
     IF (OptProd) THEN !OptProd: True if one wants to optimize the geometry of the products. Default is FALSE.
1828 1 equemene
        IGeom=NGeomF
1829 1 equemene
        if (debug) WRITE(*,*) '******************'
1830 1 equemene
        if (debug) WRITE(*,*) 'Optimizing product'
1831 1 equemene
        if (debug) WRITE(*,*) '******************'
1832 1 equemene
        SELECT CASE (COORD)
1833 1 equemene
        CASE ('ZMAT','MIXED','BAKER')
1834 1 equemene
           Print *, 'Optimizing product'
1835 1 equemene
           SELECT CASE (Step_method)
1836 1 equemene
           CASE ('RFO')
1837 1 equemene
              !GradTmp(NCoord)) becomes "Step" in Step_RFO_all and has INTENT(OUT).
1838 1 equemene
              Call Step_RFO_all(NCoord,GradTmp,NGeomF,IntCoordF(NGeomF,:),Grad(NGeomF,:),Hess(NGeomF,:,:),ZeroVec)
1839 1 equemene
              Print *, GradTmp
1840 1 equemene
           CASE ('GDIIS')
1841 1 equemene
              ! GradTmp becomes "step" below and has INTENT(OUT):
1842 1 equemene
              Call Step_DIIS_all(NGeomF,NGeomF,GradTmp,IntCoordF(NGeomF,:),Grad(NGeomF,:),&
1843 1 equemene
                   HP,HEAT,Hess(NGeomF,:,:),NCoord,allocation_flag,ZeroVec)
1844 1 equemene
              Print *, 'OptProd, Steps from GDIIS, GeomNew - IntCoordF(NGeomF,:)='
1845 1 equemene
              Print *, GradTmp
1846 1 equemene
           CASE ('GEDIIS')
1847 1 equemene
              ! GradTmp(NCoord) becomes "step" below and has INTENT(OUT):
1848 1 equemene
              Call Step_GEDIIS_All(NGeomF,NGeomF,GradTmp,IntCoordF(NGeomF,:),Grad(NGeomF,:),Energies(NGeomF),&
1849 1 equemene
                   Hess(NGeomF,:,:),NCoord,allocation_flag,ZeroVec)
1850 1 equemene
              Print *, 'OptProd, Steps from GEDIIS, GeomNew - IntCoordF(NGeomF,:)='
1851 1 equemene
              Print *, GradTmp
1852 1 equemene
           CASE DEFAULT
1853 1 equemene
              WRITE (*,*) "Step_method=",TRIM(Step_method)," not recognized, Path.f90, L1309. Stop"
1854 1 equemene
              STOP
1855 1 equemene
           END SELECT
1856 1 equemene
        CASE ('HYBRID','CART')
1857 1 equemene
           Call Step_RFO_all(NCoord,GradTmp,IGeom,XyzGeomF(NGeomF,:,:),Grad(NGeomF,:),Hess(NGeomF,:,:),ZeroVec)
1858 1 equemene
        CASE DEFAULT
1859 1 equemene
           WRITE(*,*) 'Coord=',TRIM(COORD),' not recognized. Path L1460.STOP'
1860 1 equemene
           STOP
1861 1 equemene
        END SELECT
1862 1 equemene
1863 1 equemene
        ! we have the Newton+RFO step, we will check that the displacement is not greater than Smax
1864 1 equemene
        NormStep=sqrt(DOT_Product(GradTmp,GradTmp))
1865 1 equemene
        FactStep=min(1.d0,MaxStep(IGeom)/NormStep)
1866 1 equemene
        Fini=(Fini.AND.(NormStep.LE.SThresh))
1867 1 equemene
        OptProd=.NOT.(NormStep.LE.SThresh)
1868 1 equemene
        NormGrad=sqrt(DOT_Product(reshape(Grad(NGeomF,:),(/Nfree/)),reshape(Grad(NGeomF,:),(/NFree/))))
1869 1 equemene
        Fini=(Fini.AND.(NormGrad.LE.GThresh))
1870 1 equemene
        OptProd=(OptProd.OR.(NormGrad.GT.GThresh))
1871 1 equemene
        IF (debug) WRITE(*,*) "NormGrad, GThresh, OptProd=",NormGrad, GThresh, OptProd
1872 1 equemene
1873 1 equemene
        GradTmp=GradTmp*FactStep
1874 1 equemene
1875 1 equemene
        ! we take care that frozen atoms do not move
1876 1 equemene
        IF (NFroz.NE.0) THEN
1877 1 equemene
           SELECT CASE (COORD)
1878 1 equemene
           CASE ('ZMAT','MIXED','BAKER')
1879 1 equemene
              GradTmp(1:IntFroz)=0.d0
1880 1 equemene
           CASE ('CART','HYBRID')
1881 1 equemene
              DO I=1,Nat
1882 1 equemene
                 IF (FrozAtoms(I)) THEN
1883 1 equemene
                    Iat=Order(I)
1884 1 equemene
                    GradTmp(3*Iat-2:3*Iat)=0.d0
1885 1 equemene
                 END IF
1886 1 equemene
              END DO
1887 1 equemene
           CASE DEFAULT
1888 1 equemene
              WRITE(*,*) 'Coord=',TRIM(COORD),' not recognized. Path L1045.STOP'
1889 1 equemene
              STOP
1890 1 equemene
           END SELECT
1891 1 equemene
        END IF ! matches IF (NFroz.NE.0) THEN
1892 1 equemene
1893 1 equemene
        IF (debug) THEN
1894 1 equemene
           WRITE(*,*) "DBG Main, L1354, IGeom=, IOpt=",IGeom,IOpt
1895 1 equemene
           IF ((COORD.EQ.'ZMAT') .OR. (COORD.EQ.'BAKER')) THEN
1896 1 equemene
              WRITE(*,'(12(1X,F8.3))') IntCoordF(IGeom,1:min(12,NFree))
1897 1 equemene
           ELSE
1898 1 equemene
              DO Iat=1,Nat
1899 1 equemene
                 WRITE(*,'(1X,A5,3(1X,F11.6))') Nom(Atome(Iat)), &
1900 1 equemene
                      XyzGeomF(IGeom,1:3,Iat)
1901 1 equemene
              END DO
1902 1 equemene
           END IF
1903 1 equemene
        END IF
1904 1 equemene
1905 1 equemene
        SELECT CASE (COORD)
1906 1 equemene
        CASE ('ZMAT','MIXED','BAKER')
1907 1 equemene
           IntcoordF(NGeomF,:)=IntcoordF(NGeomF,:)+GradTmp(:) ! IGeom is NGeomF.
1908 1 equemene
        CASE ('HYBRID','CART')
1909 1 equemene
           XyzGeomF(IGeom,:,:)=XyzGeomF(IGeom,:,:)+reshape(GradTmp(:),(/3,Nat/))
1910 1 equemene
        CASE DEFAULT
1911 1 equemene
           WRITE(*,*) 'Coord=',TRIM(COORD),' not recognized. Path L1050.STOP'
1912 1 equemene
           STOP
1913 1 equemene
        END SELECT
1914 1 equemene
1915 1 equemene
        IF (debug) THEN
1916 1 equemene
           WRITE(*,*) "DBG Main, L1376, IGeom=, IOpt=",IGeom,IOpt
1917 1 equemene
           IF ((COORD.EQ.'ZMAT') .OR. (COORD.EQ.'BAKER')) THEN
1918 1 equemene
              WRITE(*,'(12(1X,F8.3))') IntCoordF(IGeom,1:min(12,NFree))
1919 1 equemene
           ELSE
1920 1 equemene
              DO Iat=1,Nat
1921 1 equemene
                 WRITE(*,'(1X,A5,3(1X,F11.6))') Nom(Atome(Iat)), &
1922 1 equemene
                      XyzGeomF(IGeom,1:3,Iat)
1923 1 equemene
              END DO
1924 1 equemene
           END IF
1925 1 equemene
        END IF
1926 1 equemene
     ELSE ! Optprod
1927 1 equemene
        IF (debug) WRITE(*,*) "Product already optimized, Fini=",Fini
1928 1 equemene
     END IF !matches IF (OptProd) THEN
1929 1 equemene
1930 1 equemene
     IF (debug) WRITE(*,*) "Fini before L1491 path:",Fini
1931 1 equemene
1932 1 equemene
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1933 1 equemene
     !
1934 1 equemene
     !  Optimizing other geometries
1935 1 equemene
     !
1936 1 equemene
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1937 1 equemene
1938 1 equemene
1939 1 equemene
1940 1 equemene
     DO IGeom=2,NGeomF-1 ! matches at L1556
1941 1 equemene
        if (debug) WRITE(*,*) '****************************'
1942 1 equemene
        if (debug) WRITE(*,*) 'All other geometries, IGeom=',IGeom
1943 1 equemene
        if (debug) WRITE(*,*) '****************************'
1944 1 equemene
1945 1 equemene
        SELECT CASE (COORD)
1946 1 equemene
        CASE ('ZMAT','BAKER','MIXED')
1947 1 equemene
           GradTmp2=reshape(IntTangent(IGeom,:),(/NCoord/))
1948 1 equemene
           ! PFL 6 Apr 2008 ->
1949 1 equemene
           ! Special case, if FTan=0. we do not consider Tangent at all.
1950 1 equemene
           ! To DO: add the full treatment of FTan
1951 1 equemene
           if (FTan==0.) GradTmp2=ZeroVec
1952 1 equemene
           ! <- PFL 6 Apr 2008
1953 1 equemene
           if (debug) THEN
1954 1 equemene
              Print *, 'L1500, IntTangent(',IGeom,',:)='
1955 1 equemene
              Print *, IntTangent(IGeom,:)
1956 1 equemene
           END IF
1957 1 equemene
           !GradTmp(NCoord)) is actually "Step" in Step_RFO_all and has INTENT(OUT).
1958 1 equemene
           SELECT CASE (Step_method)
1959 1 equemene
           CASE ('RFO')
1960 1 equemene
              Call Step_RFO_all(NCoord,GradTmp,IGeom,IntCoordF(IGeom,:),Grad(IGeom,:),Hess(IGeom,:,:),GradTmp2)
1961 1 equemene
           CASE ('GDIIS')
1962 1 equemene
              !The following has no effect at IOpt==1
1963 1 equemene
              !Print *, 'Before call of Step_diis_all, All other geometries, IGeom=', IGeom
1964 1 equemene
              Call Step_DIIS_all(NGeomF,IGeom,GradTmp,IntCoordF(IGeom,:),Grad(IGeom,:),HP,HEAT,&
1965 1 equemene
                   Hess(IGeom,:,:),NCoord,allocation_flag,GradTmp2)
1966 1 equemene
              Print *, 'All others, Steps from GDIIS, GeomNew - IntCoordF(IGeom,:)='
1967 1 equemene
              Print *, GradTmp
1968 1 equemene
           CASE ('GEDIIS')
1969 1 equemene
              ! GradTmp(NCoord) becomes "step" below and has INTENT(OUT):
1970 1 equemene
              Call Step_GEDIIS_All(NGeomF,IGeom,GradTmp,IntCoordF(IGeom,:),Grad(IGeom,:),Energies(IGeom),&
1971 1 equemene
                   Hess(IGeom,:,:),NCoord,allocation_flag,GradTmp2)
1972 1 equemene
              Print *, 'All others, Steps from GEDIIS, GeomNew - IntCoordF(IGeom,:)='
1973 1 equemene
              Print *, GradTmp
1974 1 equemene
           CASE DEFAULT
1975 1 equemene
              WRITE (*,*) "Step_method=",TRIM(Step_method)," not recognized, Path.f90, L1430. Stop"
1976 1 equemene
              STOP
1977 1 equemene
           END SELECT
1978 1 equemene
        CASE ('HYBRID','CART')
1979 1 equemene
           ! XyzTangent is implicitely in Nat,3... but all the rest is 3,Nat
1980 1 equemene
           ! so we change it
1981 1 equemene
           DO I=1,Nat
1982 1 equemene
              DO J=1,3
1983 1 equemene
                 GradTmp2(J+(I-1)*3)=XyzTangent(IGeom,(J-1)*Nat+I)
1984 1 equemene
              END DO
1985 1 equemene
           END DO
1986 1 equemene
           !           GradTmp2=XyzTangent(IGeom,:)
1987 1 equemene
           ! PFL 6 Apr 2008 ->
1988 1 equemene
           ! Special case, if FTan=0. we do not consider Tangent at all.
1989 1 equemene
           ! To DO: add the full treatment of FTan
1990 1 equemene
           if (FTan==0.) GradTmp2=ZeroVec
1991 1 equemene
           ! <- PFL 6 Apr 2008
1992 1 equemene
1993 1 equemene
           Call Step_RFO_all(NCoord,GradTmp,IGeom,XyzGeomF(IGeom,:,:),Grad(IGeom,:),Hess(IGeom,:,:),GradTmp2)
1994 1 equemene
        CASE DEFAULT
1995 1 equemene
           WRITE(*,*) 'Coord=',TRIM(COORD),' not recognized. Path L1083.STOP'
1996 1 equemene
           STOP
1997 1 equemene
        END SELECT
1998 1 equemene
1999 1 equemene
        ! we take care that frozen atoms do not move
2000 1 equemene
        IF (NFroz.NE.0) THEN
2001 1 equemene
           SELECT CASE (COORD)
2002 1 equemene
           CASE ('ZMAT','MIXED','BAKER')
2003 1 equemene
              IF (debug) THEN
2004 1 equemene
                 WRITE(*,*) 'Step computed. Coord=',Coord
2005 1 equemene
                 WRITE(*,*) 'Zeroing components for frozen atoms. Intfroz=', IntFroz
2006 1 equemene
              END IF
2007 1 equemene
              GradTmp(1:IntFroz)=0.d0
2008 1 equemene
           CASE ('CART','HYBRID')
2009 1 equemene
              if (debug) THEN
2010 1 equemene
                 WRITE(*,*) "DBG Path Zeroing components L1771. Step before zeroing"
2011 1 equemene
                 DO I=1,Nat
2012 1 equemene
                    WRITe(*,*) I,GradTmp(3*I-2:3*I)
2013 1 equemene
                 END DO
2014 1 equemene
              END IF
2015 1 equemene
              DO I=1,Nat
2016 1 equemene
                 IF (FrozAtoms(I)) THEN
2017 1 equemene
                    if (debug) THEN
2018 1 equemene
                       write(*,*) 'Step Computed. Coord=',Coord
2019 1 equemene
                       WRITE(*,*) 'Atom',I,' is frozen. Zeroing',Order(I)
2020 1 equemene
                    END IF
2021 1 equemene
                    Iat=Order(I)
2022 1 equemene
                    GradTmp(3*Iat-2:3*Iat)=0.d0
2023 1 equemene
                 END IF
2024 1 equemene
              END DO
2025 1 equemene
2026 1 equemene
                 if (debug) THEN
2027 1 equemene
                    WRITE(*,*) "DBG Path Zeroing components L1785. Step After zeroing"
2028 1 equemene
                    DO I=1,Nat
2029 1 equemene
                       WRITe(*,*) I,GradTmp(3*I-2:3*I)
2030 1 equemene
                    END DO
2031 1 equemene
                 END IF
2032 1 equemene
2033 1 equemene
           CASE DEFAULT
2034 1 equemene
              WRITE(*,*) 'Coord=',TRIM(COORD),' not recognized. Path L1338.STOP'
2035 1 equemene
              STOP
2036 1 equemene
           END SELECT
2037 1 equemene
        END IF !matches IF (NFroz.NE.0) THEN
2038 1 equemene
2039 1 equemene
        IF (debug) THEN
2040 1 equemene
           SELECT CASE (COORD)
2041 1 equemene
           CASE ('ZMAT','MIXED','BAKER')
2042 1 equemene
              WRITE(*,'(A,12(1X,F8.3))') 'Step tan:',IntTangent(IGeom,1:min(12,NFree))
2043 1 equemene
              WRITE(*,'(A,12(1X,F8.3))') 'Ortho Step:',GradTmp(1:min(12,NFree))
2044 1 equemene
           CASE ('CART','HYBRID')
2045 1 equemene
              WRITE(*,'(A,12(1X,F8.3))') 'Step tan:',XyzTangent(IGeom,1:min(12,NFree))
2046 1 equemene
               WRITE(*,'(A,12(1X,F8.3))') 'Ortho Step:',GradTmp(1:min(12,NFree))
2047 1 equemene
           CASE DEFAULT
2048 1 equemene
              WRITE(*,*) 'Coord=',TRIM(COORD),' not recognized. Path L1588.STOP'
2049 1 equemene
              STOP
2050 1 equemene
           END SELECT
2051 1 equemene
        END IF ! matches if (debug) THEN
2052 1 equemene
2053 1 equemene
        ! we check that the maximum displacement is not greater than Smax
2054 1 equemene
        If (debug) WRITE(*,*) "Fini before test:",Fini
2055 1 equemene
        NormStep=sqrt(DOT_Product(GradTmp,GradTmp))
2056 1 equemene
        FactStep=min(1.d0,maxStep(Igeom)/NormStep)
2057 1 equemene
        Fini=(Fini.AND.(NormStep.LE.SThresh))
2058 1 equemene
        IF (debug) WRITE(*,*) "IGeom,NormStep, SThresh,Fini",IGeom,NormStep, SThresh, Fini
2059 1 equemene
2060 1 equemene
        GradTmp=GraDTmp*FactStep
2061 1 equemene
2062 1 equemene
        if (debug) WRITE(*,*) "DBG Main, L1475, FactStep=",FactStep
2063 1 equemene
        if (debug.AND.(COORD.EQ.'ZMAT')) WRITE(*,'(A,12(1X,F10.6))') 'Scaled Step:',GradTmp(1:min(12,NFree))
2064 1 equemene
2065 1 equemene
        IF (debug) THEN
2066 1 equemene
           WRITE(*,*) "DBG Main, L1479, IGeom=, IOpt=",IGeom,IOpt
2067 1 equemene
           IF ((COORD.EQ.'ZMAT') .OR. (COORD.EQ.'BAKER')) THEN
2068 1 equemene
              WRITE(*,'(12(1X,F8.3))') IntCoordF(IGeom,1:min(12,NFree))
2069 1 equemene
           ELSE
2070 1 equemene
              DO Iat=1,Nat
2071 1 equemene
                 WRITE(*,'(1X,A5,3(1X,F11.6))') Nom(Atome(Iat)), &
2072 1 equemene
                      XyzGeomF(IGeom,1:3,Iat)
2073 1 equemene
              END DO
2074 1 equemene
           END IF
2075 1 equemene
        END IF ! matches if (debug) THEN
2076 1 equemene
2077 1 equemene
        SELECT CASE (COORD)
2078 1 equemene
        CASE ('ZMAT')
2079 1 equemene
           IntcoordF(IGeom,:)=IntcoordF(IGeom,:)+GradTmp(:)
2080 1 equemene
           if (debug) Print *, 'New Geom=IntcoordF(',IGeom,',:)=', IntcoordF(IGeom,:)
2081 1 equemene
           WRITE(IOOUT,"('Geometry ',I3,'/',I3,' for iteration ',I3)") IGeom,NgeomF,IOpt
2082 1 equemene
           WRITE(IOOUT,'(1X,A5,3(1X,I4,1X,F11.6))') Nom(Atome(OrderInv(indzmat(1,1))))
2083 1 equemene
           WRITE(IOOUT,'(1X,A5,3(1X,I4,1X,F11.6))') Nom(Atome(OrderInv(indzmat(2,1)))), &
2084 1 equemene
                OrderInv(indzmat(2,2)),IntcoordF(IGeom,1)
2085 1 equemene
           WRITE(IOOUT,'(1X,A5,3(1X,I4,1X,F11.6))') Nom(Atome(OrderInv(indzmat(3,1)))), &
2086 1 equemene
                OrderInv(indzmat(3,2)),IntcoordF(IGeom,2), OrderInv(indzmat(3,3)),IntcoordF(IGeom,3)*180./Pi
2087 1 equemene
           Idx=4
2088 1 equemene
           DO Iat=4,Nat
2089 1 equemene
              WRITE(IOOUT,'(1X,A5,3(1X,I4,1X,F11.6))') Nom(Atome(OrderInv(indzmat(iat,1)))), &
2090 1 equemene
                   OrderInv(indzmat(iat,2)),IntcoordF(IGeom,Idx), &
2091 1 equemene
                   OrderInv(indzmat(iat,3)),IntcoordF(IGeom,Idx+1)*180./pi, &
2092 1 equemene
                   OrderInv(indzmat(iat,4)),IntcoordF(IGeom,Idx+2)*180/Pi
2093 1 equemene
              Idx=Idx+3
2094 1 equemene
           END DO
2095 1 equemene
2096 1 equemene
        CASE ('BAKER')
2097 1 equemene
           IntcoordF(IGeom,:)=IntcoordF(IGeom,:)+GradTmp(:)
2098 1 equemene
           if (debug) Print *, 'New Geom=IntcoordF(',IGeom,',:)=', IntcoordF(IGeom,:)
2099 1 equemene
           WRITE(IOOUT,"('Geometry ',I3,'/',I3,' for iteration ',I3)") IGeom,NgeomF,IOpt
2100 1 equemene
           WRITE(IOOUT,*) "COORD=BAKER, printing IntCoordF is not meaningfull."
2101 1 equemene
2102 1 equemene
        CASE ('MIXED')
2103 1 equemene
           IntcoordF(IGeom,:)=IntcoordF(IGeom,:)+GradTmp(:)
2104 1 equemene
           if (debug) Print *, 'New Geom=IntcoordF(',IGeom,',:)=', IntcoordF(IGeom,:)
2105 1 equemene
           WRITE(IOOUT,"('Geometry ',I3,'/',I3,' for iteration ',I3)") IGeom,NgeomF,IOpt
2106 1 equemene
           DO Iat=1,NCart
2107 1 equemene
              WRITE(IOOUT,'(1X,A5,3(1X,F13.8))') Nom(Atome(OrderInv(indzmat(1,1)))),IntcoordF(IGeom,3*Iat-2:3*Iat)
2108 1 equemene
           END DO
2109 1 equemene
           Idx=3*NCart+1
2110 1 equemene
           IF (NCart.EQ.1) THEN
2111 1 equemene
              WRITE(IOOUT,'(1X,A5,3(1X,I4,1X,F11.6))') Nom(Atome(OrderInv(indzmat(2,1)))), &
2112 1 equemene
                   OrderInv(indzmat(2,2)),IntcoordF(IGeom,4)
2113 1 equemene
              WRITE(IOOUT,'(1X,A5,3(1X,I4,1X,F11.6))') Nom(Atome(OrderInv(indzmat(3,1)))), &
2114 1 equemene
                   OrderInv(indzmat(3,2)),IntcoordF(IGeom,5), OrderInv(indzmat(3,3)),IntcoordF(IGeom,6)*180./Pi
2115 1 equemene
2116 1 equemene
              Idx=7
2117 1 equemene
           END IF
2118 1 equemene
           IF (NCart.EQ.2) THEN
2119 1 equemene
              WRITE(IOOUT,'(1X,A5,3(1X,I4,1X,F11.6))') Nom(Atome(OrderInv(indzmat(3,1)))), &
2120 1 equemene
                   OrderInv(indzmat(3,2)),IntcoordF(IGeom,7), OrderInv(indzmat(3,3)),IntcoordF(IGeom,8)*180./Pi
2121 1 equemene
              Idx=9
2122 1 equemene
           END IF
2123 1 equemene
2124 1 equemene
2125 1 equemene
           DO Iat=max(NCart+1,4),Nat
2126 1 equemene
              WRITE(IOOUT,'(1X,A5,3(1X,I4,1X,F11.6))') Nom(Atome(OrderInv(indzmat(iat,1)))), &
2127 1 equemene
                   OrderInv(indzmat(iat,2)),IntcoordF(IGeom,Idx), &
2128 1 equemene
                   OrderInv(indzmat(iat,3)),IntcoordF(IGeom,Idx+1)*180./pi, &
2129 1 equemene
                   OrderInv(indzmat(iat,4)),IntcoordF(IGeom,Idx+2)*180/Pi
2130 1 equemene
              Idx=Idx+3
2131 1 equemene
           END DO
2132 1 equemene
           if (debug) Print *, 'New Geom=IntcoordF(',IGeom,',:)=', IntcoordF(IGeom,:)
2133 1 equemene
2134 1 equemene
        CASE ('HYBRID','CART')
2135 1 equemene
           XyzGeomF(IGeom,:,:)=XyzGeomF(IGeom,:,:)+reshape(GradTmp(:),(/3,Nat/))
2136 1 equemene
        CASE DEFAULT
2137 1 equemene
           WRITE(*,*) 'Coord=',TRIM(COORD),' not recognized. Path L1537.STOP'
2138 1 equemene
           STOP
2139 1 equemene
        END SELECT
2140 1 equemene
2141 1 equemene
        IF (debug) THEN
2142 1 equemene
           WRITE(*,*) "DBG Main, L1516, IGeom=, IOpt=",IGeom,IOpt
2143 1 equemene
           IF ((COORD.EQ.'ZMAT') .OR. (COORD.EQ.'BAKER')) THEN
2144 1 equemene
              WRITE(*,'(12(1X,F8.3))') IntCoordF(IGeom,1:min(12,NFree))
2145 1 equemene
           ELSE
2146 1 equemene
              DO Iat=1,Nat
2147 1 equemene
                 WRITE(*,'(1X,A5,3(1X,F11.6))') Nom(Atome(Iat)), &
2148 1 equemene
                      XyzGeomF(IGeom,1:3,Iat)
2149 1 equemene
              END DO
2150 1 equemene
           END IF
2151 1 equemene
        END IF ! matches if (debug) THEN
2152 1 equemene
2153 1 equemene
        ! We project out the tangential part of the gradient to know if we are done
2154 1 equemene
        GradTmp=Grad(IGeom,:)
2155 1 equemene
        NormGrad=sqrt(dot_product(GradTmp,GradTmp))
2156 1 equemene
        if (debug) WRITE(*,*) "Norm Grad tot=",NormGrad
2157 1 equemene
        SELECT CASE (COORD)
2158 1 equemene
        CASE ('ZMAT','MIXED','BAKER')
2159 1 equemene
           S=DOT_PRODUCT(GradTmp,IntTangent(IGeom,:))
2160 1 equemene
           Norm=DOT_PRODUCT(IntTangent(IGeom,:),IntTangent(IGeom,:))
2161 1 equemene
           GradTmp=GradTmp-S/Norm*IntTangent(IGeom,:)
2162 1 equemene
           Ca=S/(sqrt(Norm)*NormGrad)
2163 1 equemene
           S=DOT_PRODUCT(GradTmp,IntTangent(IGeom,:))
2164 1 equemene
           GradTmp=GradTmp-S/Norm*IntTangent(IGeom,:)
2165 1 equemene
        CASE ('CART','HYBRID')
2166 1 equemene
           S=DOT_PRODUCT(GradTmp,XyzTangent(IGeom,:))
2167 1 equemene
           Norm=DOT_PRODUCT(XyzTangent(IGeom,:),XyzTangent(IGeom,:))
2168 1 equemene
           Ca=S/(sqrt(Norm)*NormGrad)
2169 1 equemene
           GradTmp=GradTmp-S/Norm*XyzTangent(IGeom,:)
2170 1 equemene
           S=DOT_PRODUCT(GradTmp,XyzTangent(IGeom,:))
2171 1 equemene
           GradTmp=GradTmp-S/Norm*XyzTangent(IGeom,:)
2172 1 equemene
        CASE DEFAULT
2173 1 equemene
           WRITE(*,*) 'Coord=',TRIM(COORD),' not recognized. Path L1190.STOP'
2174 1 equemene
           STOP
2175 1 equemene
        END SELECT
2176 1 equemene
        IF (debug) WRITE(*,'(1X,A,3(1X,F10.6))') "cos and angle between grad and tangent",ca, acos(ca), acos(ca)*180./pi
2177 1 equemene
        NormGrad=sqrt(DOT_Product(GradTmp,GradTmp))
2178 1 equemene
        Fini=(Fini.AND.(NormGrad.LE.GThresh))
2179 1 equemene
        IF (debug) WRITE(*,*) "NormGrad_perp, GThresh, Fini=",NormGrad, GThresh, Fini
2180 1 equemene
2181 1 equemene
     END DO ! matches DO IGeom=2,NGeomF-1
2182 1 equemene
     ! we save the old gradients
2183 1 equemene
     GradOld=Grad
2184 1 equemene
     EPathOld=Energies
2185 1 equemene
2186 1 equemene
     ! Shall we re-parameterize the path ?
2187 1 equemene
     ! PFL 2007/Apr/10 ->
2188 1 equemene
     ! We call PathCreate in all cases, it will take care of the
2189 1 equemene
     ! reparameterization, as well as calculating the tangents.
2190 1 equemene
     !     IF (MOD(IOpt,IReparam).EQ.0) THEN
2191 1 equemene
     XyzGeomI=XyzGeomF
2192 1 equemene
     IntCoordI=IntCoordF
2193 1 equemene
2194 1 equemene
     Call PathCreate(IOpt)
2195 1 equemene
     !     END IF
2196 1 equemene
     ! <- PFL 2007/Apr/10
2197 1 equemene
2198 1 equemene
     if (debug) WRITE(*,'(1X,A,I5,A,I5,A,L2)')  'Path.f90, L1415, IOpt=', IOpt, 'MaxCyc=', MaxCyc,' Fini=', Fini
2199 1 equemene
     IF ((.NOT.Fini).AND.(IOpt.LT.MaxCyc)) THEN
2200 1 equemene
2201 1 equemene
        ! We have the new path, we calculate its energy and gradient
2202 1 equemene
2203 1 equemene
        Call EgradPath(IOpt,Flag_Opt_Geom)
2204 1 equemene
        !IF(IOPT .EQ. 10) Then
2205 1 equemene
        !	       Print *, 'Stopping at my checkpoint.'
2206 1 equemene
        !           STOP !This is my temporary checkpoint.
2207 1 equemene
        !ENDIF
2208 1 equemene
2209 1 equemene
        ! PFL 31 Mar 2008 ->
2210 1 equemene
        ! Taken from v3.99 but we added a flag...
2211 1 equemene
        ! Added in v3.99 : MaxStep is modified according to the evolution of energies
2212 1 equemene
        ! if Energies(IGeom)<=EPathOld then MaxStep is increased by 1.1
2213 1 equemene
        ! else it is decreased by 0.8
2214 1 equemene
2215 1 equemene
        if (DynMaxStep) THEN
2216 1 equemene
           if (debug) WRITE(*,*) "Dynamically updating the Maximum step"
2217 1 equemene
           if (OptReac) THEN
2218 1 equemene
              If (Energies(1)<EPathOld(1)) Then
2219 1 equemene
                 MaxStep(1)=min(1.1*MaxStep(1),2.*SMax)
2220 1 equemene
              ELSE
2221 1 equemene
                 MaxStep(1)=max(0.8*MaxStep(1),SMax/2.)
2222 1 equemene
              END IF
2223 1 equemene
           END IF
2224 1 equemene
2225 1 equemene
           if (OptProd) THEN
2226 1 equemene
              If (Energies(NGeomF)<EPathOld(NGeomF)) Then
2227 1 equemene
                 MaxStep(NGeomF)=min(1.1*MaxStep(NGeomF),2.*SMax)
2228 1 equemene
              ELSE
2229 1 equemene
                 MaxStep(NGeomF)=max(0.8*MaxStep(NGeomF),SMax/2.)
2230 1 equemene
              END IF
2231 1 equemene
           END IF
2232 1 equemene
2233 1 equemene
           DO IGeom=2,NGeomF-1
2234 1 equemene
              If (Energies(IGeom)<EPathOld(IGeom)) Then
2235 1 equemene
                 MaxStep(IGeom)=min(1.1*MaxStep(IGeom),2.*SMax)
2236 1 equemene
              ELSE
2237 1 equemene
                 MaxStep(IGeom)=max(0.8*MaxStep(IGeom),SMax/2.)
2238 1 equemene
              END IF
2239 1 equemene
           END DO
2240 1 equemene
           if (debug) WRITE(*,*) "Maximum step",MaxStep(1:NgeomF)
2241 1 equemene
        END IF ! test on DynMaxStep
2242 1 equemene
        if (debug) WRITE(*,*) "Maximum step",MaxStep(1:NgeomF)
2243 1 equemene
        ! <- PFL 31 MAr 2008
2244 1 equemene
        ! Also XyzGeomF is updated in EgradPath for Baker Case.
2245 1 equemene
        !  It should get updated for other cases too.
2246 1 equemene
2247 1 equemene
        DO IGeom=1,NGeomF
2248 1 equemene
           SELECT CASE (COORD)
2249 1 equemene
           CASE('ZMAT')
2250 1 equemene
              WRITE(IOOUT,"('Geometry ',I3,'/',I3,' for iteration ',I3)") IGeom,NgeomF,IOpt
2251 1 equemene
              GeomTmp=IntCoordF(IGeom,:)
2252 1 equemene
              WRITE(IOOUT,'(1X,A5,3(1X,I4,1X,F11.6))') Nom(Atome(OrderInv(indzmat(1,1))))
2253 1 equemene
              WRITE(IOOUT,'(1X,A5,3(1X,I4,1X,F11.6))') Nom(Atome(OrderInv(indzmat(2,1)))), &
2254 1 equemene
                   OrderInv(indzmat(2,2)),Geomtmp(1)
2255 1 equemene
              WRITE(IOOUT,'(1X,A5,3(1X,I4,1X,F11.6))') Nom(Atome(OrderInv(indzmat(3,1)))), &
2256 1 equemene
                   OrderInv(indzmat(3,2)),Geomtmp(2), &
2257 1 equemene
                   OrderInv(indzmat(3,3)),Geomtmp(3)*180./Pi
2258 1 equemene
              Idx=4
2259 1 equemene
              DO Iat=4,Nat
2260 1 equemene
                 WRITE(IOOUT,'(1X,A5,3(1X,I4,1X,F11.6))') Nom(Atome(OrderInv(indzmat(iat,1)))), &
2261 1 equemene
                      OrderInv(indzmat(iat,2)),Geomtmp(Idx), &
2262 1 equemene
                      OrderInv(indzmat(iat,3)),Geomtmp(Idx+1)*180./pi, &
2263 1 equemene
                      OrderInv(indzmat(iat,4)),Geomtmp(Idx+2)*180/Pi
2264 1 equemene
                 Idx=Idx+3
2265 1 equemene
              END DO
2266 1 equemene
           CASE('BAKER')
2267 1 equemene
              !WRITE(IOOUT,"('Geometry ',I3,'/',I3,' for iteration ',I3)") IGeom,NgeomF,IOpt
2268 1 equemene
              !GeomTmp=IntCoordF(IGeom,:)
2269 1 equemene
           CASE('CART','HYBRID','MIXED')
2270 1 equemene
              WRITE(IOOUT,'(1X,I5)') Nat
2271 1 equemene
              WRITE(IOOUT,"('Geometry ',I3,'/',I3,' for iteration ',I3)") IGeom,NgeomF,IOpt
2272 1 equemene
              GeomTmp=Reshape(XyzGeomF(IGeom,:,:),(/3*Nat/))
2273 1 equemene
              DO I=1,Nat
2274 1 equemene
                 Iat=I
2275 1 equemene
                 If (renum) Iat=OrderInv(I)
2276 1 equemene
                 WRITE(IOOUT,'(1X,A5,3(1X,F11.6))') Nom(Atome(iat)), Geomtmp(3*Iat-2:3*Iat)
2277 1 equemene
              END DO
2278 1 equemene
           CASE DEFAULT
2279 1 equemene
              WRITE(*,*) 'Coord=',TRIM(COORD),' not recognized. Path L1356.STOP'
2280 1 equemene
              STOP
2281 1 equemene
           END SELECT
2282 1 equemene
        END DO ! matches DO IGeom=1,NGeomF
2283 1 equemene
2284 1 equemene
        Call Write_path(IOpt)
2285 1 equemene
2286 1 equemene
        ! We update the Hessian matrices
2287 1 equemene
        IF (debug) WRITE(*,*) "Updating Hessian matrices",NCoord
2288 1 equemene
        ! First using the displacement from the old path
2289 1 equemene
        IGeom0=2
2290 1 equemene
        IGeomF=NGeomF-1
2291 1 equemene
        IF (OptReac) IGeom0=1
2292 1 equemene
        IF (OptProd) IGeomF=NGeomF
2293 1 equemene
2294 1 equemene
        IF (FCalcHess) THEN
2295 1 equemene
           DO IGeom=IGeom0,IGeomF
2296 1 equemene
              SELECT CASE (COORD)
2297 1 equemene
              CASE ('ZMAT','MIXED','BAKER')
2298 1 equemene
                 GeomTmp2=IntCoordF(IGeom,:)
2299 1 equemene
              CASE ('CART','HYBRID')
2300 1 equemene
                 GeomTmp2=Reshape(XyzGeomF(IGeom,:,:),(/3*Nat/))
2301 1 equemene
              CASE DEFAULT
2302 1 equemene
                 WRITE(*,*) "Coord=",TRIM(COORD)," not recognized. PATH L1267.STOP"
2303 1 equemene
                 STOP
2304 1 equemene
              END SELECT
2305 1 equemene
              Call CalcHess(NCoord,GeomTmp2,Hess(IGeom,:,:),IGeom,Iopt)
2306 1 equemene
           END DO
2307 1 equemene
        ELSE
2308 1 equemene
           DO IGeom=IGeom0,IGeomF
2309 1 equemene
              GeomTmp=GeomOld_all(IGeom,:)
2310 1 equemene
              SELECT CASE (COORD)
2311 1 equemene
              CASE ('ZMAT','MIXED','BAKER')
2312 1 equemene
                 GeomTmp2=IntCoordF(IGeom,:)
2313 1 equemene
              CASE ('CART','HYBRID')
2314 1 equemene
                 GeomTmp2=Reshape(XyzGeomF(IGeom,:,:),(/3*Nat/))
2315 1 equemene
              CASE DEFAULT
2316 1 equemene
                 WRITE(*,*) "Coord=",TRIM(COORD)," not recognized. PATH L1267.STOP"
2317 1 equemene
                 STOP
2318 1 equemene
              END SELECT
2319 1 equemene
              GeomTmp=GeomTmp2-GeomTmp
2320 1 equemene
              GradTmp=Grad(IGeom,:)-GradOld(IGeom,:)
2321 1 equemene
              HessTmp=Hess(IGeom,:,:)
2322 1 equemene
              Call Hupdate_all(NCoord,GeomTmp,GradTmp,HessTmp)
2323 1 equemene
              Hess(IGeom,:,:)=HessTmp
2324 1 equemene
           END DO ! matches DO IGeom=IGeom0,IGeomF
2325 1 equemene
2326 1 equemene
           ! Second using the neighbour points
2327 1 equemene
           IF (HupNeighbour) THEN
2328 1 equemene
              ! Only one point for end points.
2329 1 equemene
              IF (OptReac) THEN
2330 1 equemene
                 IF ((COORD.EQ.'ZMAT') .OR. (COORD.EQ.'BAKER')) THEN
2331 1 equemene
                    GeomTmp=IntCoordF(1,:)-IntCoordF(2,:)
2332 1 equemene
                 ELSE
2333 1 equemene
                    GeomTmp=Reshape(XyzGeomF(1,:,:),(/3*Nat/))-Reshape(XyzGeomF(2,:,:),(/3*Nat/))
2334 1 equemene
                 END IF
2335 1 equemene
                 GradTmp=Grad(1,:)-Grad(2,:)
2336 1 equemene
                 HessTmp=Hess(1,:,:)
2337 1 equemene
                 Call Hupdate_all(NCoord,GeomTmp,GradTmp,HessTmp)
2338 1 equemene
                 Hess(1,:,:)=HessTmp
2339 1 equemene
              END IF
2340 1 equemene
2341 1 equemene
              IF (OptProd) THEN
2342 1 equemene
                 IF ((COORD.EQ.'ZMAT') .OR. (COORD.EQ.'BAKER')) THEN
2343 1 equemene
                    GeomTmp=IntCoordF(NGeomF,:)-IntCoordF(NGeomF-1,:)
2344 1 equemene
                 ELSE
2345 1 equemene
                    GeomTmp=Reshape(XyzGeomF(NGeomF,:,:),(/3*Nat/))-Reshape(XyzGeomF(NGeomF-1,:,:),(/3*Nat/))
2346 1 equemene
                 END IF
2347 1 equemene
                 GradTmp=Grad(NGeomF,:)-Grad(NGeomF-1,:)
2348 1 equemene
                 HessTmp=Hess(NGeomF,:,:)
2349 1 equemene
                 Call Hupdate_all(NCoord,GeomTmp,GradTmp,HessTmp)
2350 1 equemene
                 Hess(NGeomF,:,:)=HessTmp
2351 1 equemene
              END IF
2352 1 equemene
2353 1 equemene
              ! Two points for the rest of the path
2354 1 equemene
              DO IGeom=2,NGeomF-1
2355 1 equemene
                 IF ((COORD.EQ.'ZMAT').OR.(COORD.EQ.'BAKER')) THEN
2356 1 equemene
                    GeomTmp=IntCoordF(IGeom,:)-IntCoordF(IGeom+1,:)
2357 1 equemene
                 ELSE
2358 1 equemene
                    GeomTmp=Reshape(XyzGeomF(IGeom,:,:),(/3*Nat/))-Reshape(XyzGeomF(IGeom+1,:,:),(/3*Nat/))
2359 1 equemene
                 END IF
2360 1 equemene
                 GradTmp=Grad(IGeom,:)-Grad(IGeom+1,:)
2361 1 equemene
                 HessTmp=Hess(IGeom,:,:)
2362 1 equemene
                 Call Hupdate_all(NCoord,GeomTmp,GradTmp,HessTmp)
2363 1 equemene
2364 1 equemene
                 IF ((COORD.EQ.'ZMAT') .OR. (COORD.EQ.'BAKER')) THEN
2365 1 equemene
                    GeomTmp=IntCoordF(IGeom,:)-IntCoordF(IGeom-1,:)
2366 1 equemene
                 ELSE
2367 1 equemene
                    GeomTmp=Reshape(XyzGeomF(IGeom,:,:),(/3*Nat/))-Reshape(XyzGeomF(IGeom-1,:,:),(/3*Nat/))
2368 1 equemene
                 END IF
2369 1 equemene
                 GradTmp=Grad(IGeom,:)-Grad(IGeom-1,:)
2370 1 equemene
2371 1 equemene
                 Call Hupdate_all(NCoord,GeomTmp,GradTmp,HessTmp)
2372 1 equemene
                 Hess(IGeom,:,:)=HessTmp
2373 1 equemene
              END DO ! matches DO IGeom=2,NGeomF-1
2374 1 equemene
           END IF !matches IF (HupNeighbour) THEN
2375 1 equemene
        END IF ! matches IF (FCalcHess)
2376 1 equemene
     END IF ! If (not.fini.).AND.(IOpt.LE.MaxCyc)
2377 1 equemene
  END DO ! matches DO WHILE ((IOpt.LT.MaxCyc).AND.(.NOT.Fini))
2378 1 equemene
2379 1 equemene
  IF (PROG=="GAUSSIAN") THEN
2380 1 equemene
     DEALLOCATE(Gauss_paste)
2381 1 equemene
     DEALLOCATE(Gauss_root,Gauss_comment,Gauss_end,current)
2382 1 equemene
  END IF
2383 1 equemene
  DEALLOCATE(XyzGeomF, IntCoordF)
2384 1 equemene
  DEALLOCATE(XyzGeomI, IntCoordI)
2385 1 equemene
  DEALLOCATE(XyzTangent,IntTangent)
2386 1 equemene
  DEALLOCATE(AtName,IndZmat,Order,Atome,MassAt)
2387 1 equemene
  DEALLOCATE(GeomOld_all)
2388 1 equemene
2389 1 equemene
  if (PROG=="GAUSSIAN") THEN
2390 1 equemene
     ! We de-allocate the Gauss_XX lists
2391 1 equemene
     ! transverse the list and deallocate each node
2392 1 equemene
     previous => Gauss_root ! make current point to head of list
2393 1 equemene
     DO
2394 1 equemene
        IF (.NOT. ASSOCIATED(previous)) EXIT ! exit if null pointer
2395 1 equemene
        current => previous%next ! make list point to next node of head
2396 1 equemene
        DEALLOCATE(previous) ! deallocate current head node
2397 1 equemene
        previous => current  ! make current point to new head
2398 1 equemene
     END DO
2399 1 equemene
2400 1 equemene
     previous => Gauss_comment ! make current point to head of list
2401 1 equemene
     DO
2402 1 equemene
        IF (.NOT. ASSOCIATED(previous)) EXIT ! exit if null pointer
2403 1 equemene
        current => previous%next ! make list point to next node of head
2404 1 equemene
        DEALLOCATE(previous) ! deallocate current head node
2405 1 equemene
        previous => current  ! make current point to new head
2406 1 equemene
     END DO
2407 1 equemene
2408 1 equemene
     previous => Gauss_end ! make current point to head of list
2409 1 equemene
     DO
2410 1 equemene
        IF (.NOT. ASSOCIATED(previous)) EXIT ! exit if null pointer
2411 1 equemene
        current => previous%next ! make list point to next node of head
2412 1 equemene
        DEALLOCATE(previous) ! deallocate current head node
2413 1 equemene
        previous => current  ! make current point to new head
2414 1 equemene
     END DO
2415 1 equemene
2416 1 equemene
     DEALLOCATE(current)
2417 1 equemene
  END IF
2418 1 equemene
2419 1 equemene
  DEALLOCATE(GeomTmp, Hess, GradTmp)
2420 1 equemene
  IF (COORD.EQ.'ZMAT')  DEALLOCATE(dzdc)
2421 1 equemene
  IF (COORD.EQ.'BAKER') THEN
2422 1 equemene
     DEALLOCATE(BMat_BakerT,BTransInv,BTransInv_local,Xprimitive_t)
2423 1 equemene
     DEALLOCATE(XprimitiveF,UMatF,BTransInvF,UMat,UMat_local)
2424 1 equemene
  END IF
2425 1 equemene
2426 1 equemene
  WRITE(IOOUT,*) "Exiting Path, IOpt=",IOpt
2427 1 equemene
2428 1 equemene
END PROGRAM PathOpt