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