root / src / EgradPath.f90 @ 5
Historique | Voir | Annoter | Télécharger (26,48 ko)
1 |
SUBROUTINE EGradPath(Iopt,Flag_Opt_Geom) |
---|---|
2 |
|
3 |
! This subroutine calculates the energy+gradient for all points of |
4 |
! the path |
5 |
|
6 |
use Path_module, only : ProgExe, NCoord, PROG, Nat, NGeomF, Coord, IntCoordF, & |
7 |
IndZmat, XyzGeomF, Atome, Order, OrderInv, Latr, FrozAtoms, & |
8 |
Grad, Energies, renum, dzdc, massat, Pi, NCART, OptReac, & |
9 |
OptProd, IntCoordI, GeomOld_all, AtName, Unit, CalcEReac, CalcEProd |
10 |
! GeomOld_all(NGeomF,NCoord), BTransInv (3*Nat,NCoord): used for Baker case |
11 |
use Io_module |
12 |
|
13 |
IMPLICIT NONE |
14 |
|
15 |
INTEGER(KINT), INTENT(IN) :: Iopt |
16 |
LOGICAL, INTENT(IN) :: Flag_Opt_Geom |
17 |
|
18 |
INTEGER(KINT) :: IGeom,IGeom0,IGeomF |
19 |
CHARACTER(LCHARS) :: Line,FileInp,RunCommand |
20 |
CHARACTER(SCHARS) :: Line2 |
21 |
|
22 |
REAL(KREAL), ALLOCATABLE :: GeomTmp(:),GradTmp(:) ! NCoord |
23 |
REAL(KREAL), ALLOCATABLE :: GradCart(:) ! 3*Nat |
24 |
REAL(KREAL), ALLOCATABLE :: PathCart(:,:) ! (3*Nat,NGeomF) |
25 |
REAL(KREAL), ALLOCATABLE :: x(:), y(:), z(:) |
26 |
REAL(KREAL), ALLOCATABLE :: x_k(:), y_k(:), z_k(:) |
27 |
REAL(KREAL), ALLOCATABLE :: GeomCart(:,:) !(Nat,3) |
28 |
REAL(KREAL), ALLOCATABLE :: GeomOld_dummy(:),GeomCart_old_dummy(:,:) |
29 |
REAL(KREAL) :: E |
30 |
LOGICAL :: Debug |
31 |
LOGICAL, SAVE :: First=.TRUE. |
32 |
|
33 |
INTEGER(KINT) :: I, Iat, IBeg, Idx |
34 |
REAL(KREAL) :: RTmp1, RTmp2, RTmp3 |
35 |
INTEGER(KINT) :: Itmp1, ITmp2 |
36 |
|
37 |
INTERFACE |
38 |
function valid(string) result (isValid) |
39 |
CHARACTER(*), intent(in) :: string |
40 |
logical :: isValid |
41 |
END function VALID |
42 |
END INTERFACE |
43 |
|
44 |
debug=valid('EGradPath') |
45 |
|
46 |
if (debug) Call header("Entering EgradPath") |
47 |
|
48 |
ALLOCATE(GeomTmp(NCoord)) |
49 |
ALLOCATE(x(Nat),y(Nat),z(Nat)) |
50 |
ALLOCATE(x_k(Nat),y_k(Nat),z_k(Nat)) |
51 |
ALLOCATE(GeomOld_dummy(NCoord)) |
52 |
ALLOCATE(GeomCart_old_dummy(Nat,3)) |
53 |
|
54 |
|
55 |
IF (RunMode=="PARA") THEN ! matches at L315 |
56 |
|
57 |
ALLOCATE(GradCart(3*Nat),PathCart(3*Nat,NGeomF)) |
58 |
|
59 |
|
60 |
SELECT CASE(Prog) |
61 |
CASE ("VASP") |
62 |
! We will use the NEB routine of VASP to get all forces at once on Para8 queue |
63 |
|
64 |
! First, we create all the POSCAR into the 0x directories |
65 |
|
66 |
! With RunMode="Para" one cannot optimize reactants or products (due to Vasp constraints) |
67 |
! so this has been done beforehand :-) |
68 |
IGeom0=2 |
69 |
IGeomF=NGeomF-1 |
70 |
PathCart=0.d0 |
71 |
|
72 |
IF (First) THEN |
73 |
! For the first iteration, we do write a POSCAR into 00 and 0Final |
74 |
! Vasp needs it ! |
75 |
First=.FALSE. |
76 |
IGeom0=1 |
77 |
IGeomF=NGeomF |
78 |
END IF |
79 |
|
80 |
Line2="00" |
81 |
DO IGeom=IGeom0,IGeomF |
82 |
|
83 |
! NOTE THAT HERE IGeom0 (IGeomF) IS NOT 1 (NGeomF) FOR NON-FIRST OPTIMIZATION. |
84 |
! THIS WILL HAVE EFFECT ON XyzGeomF UPDATE IN BAKER CASE. |
85 |
WRITE(Line,'(I5)') IGeom-1 |
86 |
Idx=2-Len_TRIM(ADJUSTL(Line)) |
87 |
FileInp=Line2(1:Idx) // TRIM(AdjustL(Line)) // "/POSCAR" |
88 |
if (debug) WRITE(*,*) "Creating ",TRIM(FileInp) |
89 |
OPEN(IOTMP,File=TRIM(FileInp)) |
90 |
|
91 |
WRITE(Line,"('Geometry ',I3,'/',I3,' for iteration ',I3)") Igeom,NgeomF,Iopt |
92 |
if (debug) WRITE(*,*) Line |
93 |
SELECT CASE(Coord) |
94 |
CASE ('ZMAT') |
95 |
GeomTmp=IntCoordF(IGeom,:) |
96 |
Call Int2cart(nat,indzmat,geomTmp,PathCart(1,IGeom)) |
97 |
CASE ('BAKER') |
98 |
GeomTmp=IntCoordF(IGeom,:) |
99 |
! |
100 |
IF (IOpt .EQ. 0) THEN |
101 |
! EgradPath(...) is called only after the call of PathCreate(...) |
102 |
! and in PathCreate, IF (MOD(IOpt,IReparam).EQ.0) (which is always |
103 |
! true if IOpt==0), THEN ExtraPol_baker(...) is called. |
104 |
! In ExtraPol_baker(...), XyzGeomF(...) is calculated upon converting |
105 |
! the interpolated internal coordinates into cartesian coordinates. |
106 |
! Thus here we don't need to reconvert the internal coordinates again |
107 |
! to the cartesian coordinates. |
108 |
DO I=1,Nat |
109 |
PathCart(3*I-2,IGeom) = XyzGeomF(IGeom,1,I) |
110 |
PathCart(3*I-1,IGeom) = XyzGeomF(IGeom,2,I) |
111 |
PathCart(3*I,IGeom) = XyzGeomF(IGeom,3,I) |
112 |
END DO |
113 |
ELSE |
114 |
! XyzGeomF(NGeomF,3,Nat). |
115 |
x_k(:) = XyzGeomF(IGeom,1,:) |
116 |
y_k(:) = XyzGeomF(IGeom,2,:) |
117 |
z_k(:) = XyzGeomF(IGeom,3,:) |
118 |
|
119 |
!Call ConvertBakerInternal_cart(GeomOld_all(IGeom,:),IntCoordI(IGeom,:), & |
120 |
! x_k,y_k,z_k,x,y,z) |
121 |
! PathCart(3*Nat,NGeomF) |
122 |
DO I=1,Nat |
123 |
PathCart(3*I-2,IGeom) = x(I) |
124 |
PathCart(3*I-1,IGeom) = y(I) |
125 |
PathCart(3*I,IGeom) = z(I) |
126 |
END DO |
127 |
|
128 |
XyzGeomF(IGeom,1,:)=x(:) |
129 |
XyzGeomF(IGeom,2,:)=y(:) |
130 |
XyzGeomF(IGeom,3,:)=z(:) |
131 |
END IF |
132 |
CASE ('MIXED') |
133 |
GeomTmp=IntCoordF(IGeom,:) |
134 |
Call Mixed2cart(nat,indzmat,geomTmp,PathCart(1,IGeom)) |
135 |
CASE ('CART','HYBRID') |
136 |
!!! CAUTION : PFL 29.AUG.2008 -> |
137 |
! XyzGeomI/F stored in (NGeomI/F,3,Nat) and NOT (NGeomI/F,Nat,3) |
138 |
! This should be made consistent !!!!!!!!!!!!!!! |
139 |
GeomTmp=Reshape(reshape(XyzGeomF(IGeom,:,:),(/Nat,3/),ORDER=(/2,1/)),(/3*Nat/)) |
140 |
!!! <- CAUTION : PFL 29.AUG.2008 |
141 |
PathCart(:,IGeom)=GeomTmp |
142 |
CASE DEFAULT |
143 |
WRITE(*,*) "Coord=",TRIM(Coord)," not recognized. EgradPath L134. STOP" |
144 |
STOP |
145 |
END SELECT |
146 |
|
147 |
IF (debug) THEN |
148 |
WRITE(*,*) "Calling PrintGeomVasp for geom",Igeom |
149 |
Call PrintGeom(Line,Nat,NCoord,PathCart(1,Igeom),Coord,IoOut,Atome,Order,OrderInv,IndZmat) |
150 |
END IF |
151 |
Call PrintGeomVasp(Line,PathCart(1,IGeom),Latr,FrozAtoms,IoTmp) |
152 |
|
153 |
! IF (debug) THEN |
154 |
! WRITE(*,*) 'DBG MAin, COORD=',TRIM(COORD), ' Igeom=',IGeom |
155 |
! WRITE(*,'(3(1X,F9.4))') Reshape(Reshape(XyzGeomF(IGeom,:,:),(/Nat,3/),ORDER=(/2,1/)),(/3*Nat/)) |
156 |
! WRITE(*,'(3(1X,F9.4))') Reshape(XyzGeomF(IGeom,:,:),(/3*Nat/)) |
157 |
! DO Iat=1,Nat |
158 |
! WRITE(*,*) XyzGeomF(IGeom,1:3,Iat) |
159 |
! END DO |
160 |
! END IF |
161 |
|
162 |
IF (debug) THEN |
163 |
WRITE(*,*) 'DBG MAin, COORD=',TRIM(COORD),' Igeom=',IGeom,' Iopt=',Iopt |
164 |
WRITE(*,*) GeomTmp(1:min(NCoord,9)) |
165 |
END IF |
166 |
|
167 |
CLOSE(IOTMP) |
168 |
END DO ! matches DO IGeom=IGeom0,IGeomF |
169 |
|
170 |
!!!!!!!!!!!!!!!!!!! |
171 |
! |
172 |
! We calculate the energies and gradients |
173 |
! |
174 |
|
175 |
RunCommand=Trim(ProgExe) |
176 |
if (debug) WRITE(*,*) "Launching:", TRIM(RunCommand) |
177 |
call system(RunCommand) |
178 |
if (debug) WRITE(*,*) "Back from:", TRIM(RunCommand) |
179 |
|
180 |
!!!!!!!!!!!!! |
181 |
! |
182 |
! We read the gradients and energies |
183 |
! |
184 |
IGeom0=2 |
185 |
IGeomF=NGeomF-1 |
186 |
Grad=0.d0 |
187 |
|
188 |
Line2="00" |
189 |
DO IGeom=IGeom0,IGeomF |
190 |
WRITE(Line,'(I5)') IGeom-1 |
191 |
Idx=2-Len_TRIM(ADJUSTL(Line)) |
192 |
FileInp=Line2(1:Idx) // TRIM(AdjustL(Line)) // "/OUTCAR" |
193 |
if (debug) WRITE(*,*) "Reading E and forces from ", TRIM(FileInp) |
194 |
OPEN(IOTMP,File=TRIM(FileInp)) |
195 |
|
196 |
! We first search for the forces |
197 |
READ(IOTMP,'(A)',END=999,ERR=999) LINE |
198 |
! We search for the last part of the OUTCAR file, after wavefunction is converged |
199 |
DO WHILE (INDEX(LINE,'EDIFF is reached')==0) |
200 |
READ(IOTMP,'(A)',END=999,ERR=999) LINE |
201 |
END DO |
202 |
READ(IOTMP,'(A)',END=999,ERR=999) LINE |
203 |
DO WHILE (INDEX(LINE,'TOTEN')==0) |
204 |
READ(IOTMP,'(A)',END=999,ERR=999) LINE |
205 |
END DO |
206 |
Line=Line(26:) |
207 |
READ(LINE,*) E |
208 |
if (debug) WRITE(*,'(1X,A,I5,A,F20.6)') "DBG Egrad_VASP E(",Igeom,")=",E |
209 |
Energies(Igeom)=E |
210 |
|
211 |
! We search for the forces |
212 |
DO WHILE (INDEX(LINE,'TOTAL-FORCE')==0) |
213 |
READ(IOTMP,'(A)',END=999,ERR=999) LINE |
214 |
END DO |
215 |
READ(IOTMP,'(A)',END=999,ERR=999) LINE |
216 |
DO I=1,Nat |
217 |
Iat=I |
218 |
IF (renum) Iat=Order(I) |
219 |
READ(IOTMP,*,END=999,ERR=999) Rtmp1,RTmp2,RTmp3,GradCart(3*Iat-2:3*Iat) |
220 |
END DO |
221 |
|
222 |
Close(IoTmp) |
223 |
|
224 |
IF (debug) THEN |
225 |
WRITE(*,*) "DBG EGRAD_VASP - GradCart=FORCES - original order" |
226 |
DO I=1,Nat |
227 |
Iat=Order(I) |
228 |
WRITE(*,'(1X,I5,3(1X,F20.6))') I,GradCart(3*Iat-2:3*Iat) |
229 |
END DO |
230 |
WRITE(*,*) "DBG EGRAD_VASP - GradCart=FORCES - internal order" |
231 |
DO I=1,Nat |
232 |
Iat=Order(I) |
233 |
WRITE(*,'(3(1X,I5),3(1X,F20.6))') I,Iat,OrderInv(I),GradCart(3*I-2:3*I) |
234 |
END DO |
235 |
END IF |
236 |
|
237 |
! VASP gives the Forces in eV/Angstrom, so we convert it into the |
238 |
! gradient in ua/Angstrom |
239 |
GradCart=-1.0d0*ev2Au*GradCart |
240 |
|
241 |
! We convert it into the right coordinate system |
242 |
! This should be put into a subroutine (because it is also in egradient) |
243 |
SELECT CASE (COORD) |
244 |
CASE ("ZMAT") |
245 |
ALLOCATE(GradTmp(3*Nat)) |
246 |
if (debug) WRITE(*,*) "DBG EGRAD Calling CalcBMat_int" |
247 |
CALL CalcBmat_int(nat, PathCart(1:3*Nat,Igeom), indzmat, dzdc, massat,atome) |
248 |
CALL ConvGrad_Cart2Int(Nat,dzdc,IndZmat,GradCart,GradTmp) |
249 |
|
250 |
Grad(IGeom,1)=GradTmp(4) |
251 |
Grad(IGeom,2)=GradTmp(7) |
252 |
! We might have troubles whith angles that are not in the [0:pi] range because, |
253 |
! when converted to catesian coord, they do appear in the [0:Pi] range to gaussian... |
254 |
! so that the derivative is not good, and a multiplicative factor should be added... |
255 |
! |
256 |
! This in fact should be taken care of in calc Bmat ... |
257 |
! |
258 |
IF ((IntCoordF(Igeom,3).LE.0).OR.(IntCoordF(Igeom,3).GE.Pi)) THEN |
259 |
Grad(IGeom,3)=-1.0d0*GradTmp(8) |
260 |
ELSE |
261 |
Grad(IGeom,3)=GradTmp(8) |
262 |
END IF |
263 |
Idx=4 |
264 |
DO I=4,Nat |
265 |
Grad(IGeom,Idx)=GradTmp(3*i-2) |
266 |
Grad(IGeom,Idx+1)=GradTmp(3*i-1) |
267 |
Grad(IGeom,Idx+2)=GradTmp(3*i) |
268 |
Idx=Idx+3 |
269 |
END DO |
270 |
DEALLOCATE(GradTmp) |
271 |
! We have the gradient in Cartesian coordinates... which is ok for COORD=Cart, Hybrid |
272 |
! but we have to convert it into internal coordinates if COORD=Baker |
273 |
CASE ('BAKER') |
274 |
ALLOCATE(GradTmp(3*Nat)) |
275 |
GradTmp=0.d0 |
276 |
! Below is to be corrected. |
277 |
! This is inside 'IF ((PROG=="VASP").AND.(RunMode=="PARA")) THEN' |
278 |
!DO I=1, 3*Nat |
279 |
! here GradTmp and Grad are gradients in Baker coordinates |
280 |
! Not implemented IF ((PROG=="VASP").AND.(RunMode=="PARA")) |
281 |
! GradTmp(:) = GradTmp(:) + BTransInv(:,I)*GradCart(I) |
282 |
!END DO |
283 |
Grad(IGeom,:) = GradTmp |
284 |
DEALLOCATE(GradTmp) |
285 |
CASE ('MIXED') |
286 |
ALLOCATE(GradTmp(3*Nat)) |
287 |
if (debug) WRITE(*,*) "DBG EGRAD Calling CalcBMat_mixed" |
288 |
CALL CalcBMat_mixed (nat,PathCart(1:3*Nat,IGeom), indzmat, dzdc, massat,atome) |
289 |
CALL ConvGrad_Cart2Int(Nat,dzdc,IndZmat,GradCart,GradTmp) |
290 |
DO I=1,Nat |
291 |
WRITE(*,'(1X,3(1X,F10.5))') GradTmp(3*I-2:3*I) |
292 |
END DO |
293 |
SELECT CASE (NCART) |
294 |
CASE (1) |
295 |
Grad(IGeom,1:3)=GradTmp(1:3) |
296 |
Grad(IGeom,4)=GradTmp(4) |
297 |
Grad(IGeom,5)=GradTmp(7) |
298 |
Grad(IGeom,6)=GradTmp(8) |
299 |
Idx=7 |
300 |
IBeg=4 |
301 |
CASE(2) |
302 |
Grad(IGeom,1:3)=GradTmp(1:3) |
303 |
Grad(IGeom,4:6)=GradTmp(4:6) |
304 |
Grad(IGeom,7)=GradTmp(7) |
305 |
Grad(IGeom,8)=GradTmp(8) |
306 |
Idx=9 |
307 |
IBeg=4 |
308 |
CASE DEFAULT |
309 |
Idx=1 |
310 |
IBeg=1 |
311 |
END SELECT |
312 |
DO I=IBeg,Nat |
313 |
Grad(IGeom,Idx)=GradTmp(3*i-2) |
314 |
Grad(IGeom,Idx+1)=GradTmp(3*i-1) |
315 |
Grad(IGeom,Idx+2)=GradTmp(3*i) |
316 |
Idx=Idx+3 |
317 |
END DO |
318 |
DEALLOCATE(GradTmp) |
319 |
CASE ("CART","HYBRID") |
320 |
Grad(IGeom,:)=GradCart |
321 |
CASE DEFAULT |
322 |
WRITE(*,*) "Coord=",AdjustL(Trim(COORD))," not yet implemented in EgradPath.L257.STOP" |
323 |
STOP |
324 |
END SELECT |
325 |
|
326 |
IF (debug) THEN |
327 |
Line='DBG Path, GradTmp' |
328 |
Call PrintGeom(Line,Nat,NCoord,reshape(GRad(Igeom,1:NCoord),(/Ncoord/)),Coord,6,Atome,Order,OrderInv,IndZmat) |
329 |
END IF |
330 |
END DO ! matches DO IGeom=IGeom0,IGeomF |
331 |
|
332 |
CASE ("GAUSSIAN") |
333 |
! We create the output files. |
334 |
IGeom0=2 |
335 |
IGeomF=NGeomF-1 |
336 |
PathCart=0.d0 |
337 |
|
338 |
If (OptReac) IGeom0=1 |
339 |
If (OptProd) IGeomF=NGeomF |
340 |
|
341 |
OPEN(IOTMP2,File="ListJob",STATUS="REPLACE") |
342 |
|
343 |
DO Igeom=IGeom0,IGeomF |
344 |
! We first convert the geometry into a Cartesian one |
345 |
SELECT CASE(Coord) |
346 |
CASE ('ZMAT') |
347 |
GeomTmp=IntCoordF(IGeom,:) |
348 |
Call Int2cart(nat,indzmat,geomTmp,PathCart(1,IGeom)) |
349 |
CASE ('BAKER') |
350 |
GeomTmp=IntCoordF(IGeom,:) |
351 |
! |
352 |
IF (IOpt .EQ. 0) THEN |
353 |
! EgradPath(...) is called only after the call of PathCreate(...) |
354 |
! and in PathCreate, IF (MOD(IOpt,IReparam).EQ.0) (which is always |
355 |
! true if IOpt==0), THEN ExtraPol_baker(...) is called. |
356 |
! In ExtraPol_baker(...), XyzGeomF(...) is calculated upon converting |
357 |
! the interpolated internal coordinates into cartesian coordinates. |
358 |
! Thus here we don't need to reconvert the internal coordinates again |
359 |
! to the cartesian coordinates. |
360 |
DO I=1,Nat |
361 |
PathCart(3*I-2,IGeom) = XyzGeomF(IGeom,1,I) |
362 |
PathCart(3*I-1,IGeom) = XyzGeomF(IGeom,2,I) |
363 |
PathCart(3*I,IGeom) = XyzGeomF(IGeom,3,I) |
364 |
END DO |
365 |
ELSE |
366 |
|
367 |
! XyzGeomF(NGeomF,3,Nat). |
368 |
x_k(:) = XyzGeomF(IGeom,1,:) |
369 |
y_k(:) = XyzGeomF(IGeom,2,:) |
370 |
z_k(:) = XyzGeomF(IGeom,3,:) |
371 |
|
372 |
!Call ConvertBakerInternal_cart(GeomOld_all(IGeom,:),IntCoordI(IGeom,:), & |
373 |
! x_k,y_k,z_k,x,y,z) |
374 |
! PathCart(3*Nat,NGeomF) |
375 |
DO I=1,Nat |
376 |
PathCart(3*I-2,IGeom) = x(I) |
377 |
PathCart(3*I-1,IGeom) = y(I) |
378 |
PathCart(3*I,IGeom) = z(I) |
379 |
END DO |
380 |
|
381 |
XyzGeomF(IGeom,1,:)=x(:) |
382 |
XyzGeomF(IGeom,2,:)=y(:) |
383 |
XyzGeomF(IGeom,3,:)=z(:) |
384 |
END IF |
385 |
CASE ('MIXED') |
386 |
GeomTmp=IntCoordF(IGeom,:) |
387 |
Call Mixed2cart(nat,indzmat,geomTmp,PathCart(1,IGeom)) |
388 |
CASE ('CART','HYBRID') |
389 |
!!! CAUTION : PFL 29.AUG.2008 -> |
390 |
! XyzGeomI/F stored in (NGeomI/F,3,Nat) and NOT (NGeomI/F,Nat,3) |
391 |
! This should be made consistent !!!!!!!!!!!!!!! |
392 |
GeomTmp=Reshape(reshape(XyzGeomF(IGeom,:,:),(/Nat,3/),ORDER=(/2,1/)),(/3*Nat/)) |
393 |
!!! <- CAUTION : PFL 29.AUG.2008 |
394 |
PathCart(:,IGeom)=GeomTmp |
395 |
CASE DEFAULT |
396 |
WRITE(*,*) "Coord=",TRIM(Coord)," not recognized. EgradPath L75.STOP" |
397 |
STOP |
398 |
END SELECT |
399 |
|
400 |
WRITE(Line,'(I5)') IGeom |
401 |
FileInp="PathPar_" // TRIM(ADJUSTL(Line)) // ".com" |
402 |
WRITE(IOTMP2,'(1X,A)') TRIM(FileInp) |
403 |
|
404 |
OPEN(IOTMP,File=TRIM(FileInp)) |
405 |
Current => Gauss_root |
406 |
DO WHILE (ASSOCIATED(Current%next)) |
407 |
WRITE(IOTMP,'(1X,A)') Trim(current%line) |
408 |
WRITE(*,'(1X,A)') Trim(current%line) |
409 |
Current => current%next |
410 |
END DO |
411 |
|
412 |
WRITE(IOTMP,*) |
413 |
|
414 |
Current => Gauss_comment |
415 |
DO WHILE (ASSOCIATED(Current%next)) |
416 |
WRITE(IOTMP,'(1X,A)') Trim(current%line) |
417 |
Current => current%next |
418 |
END DO |
419 |
! WRITE(IOOUT,"('Geometry ',I3,'/',I3,' for iteration ',I3)"),Igeom,NgeomF,Iopt |
420 |
|
421 |
WRITE(IOTMP,*) |
422 |
WRITE(IOTMP,*) Trim(Gauss_charge) |
423 |
|
424 |
DO I=1,Nat |
425 |
If (renum) THEN |
426 |
Iat=Order(I) |
427 |
WRITE(IOTMP,'(1X,A10,3(1X,F15.8),A)') Trim(AtName(I)) & |
428 |
,PathCart(Iat,IGeom),PathCart(Iat+Nat,IGeom),PathCart(Iat+2*Nat,IGeom) & |
429 |
,TRIM(Gauss_Paste(I)) |
430 |
ELSE |
431 |
Iat=OrderInv(I) |
432 |
WRITE(IOTMP,'(1X,A10,3(1X,F15.8),A)') Trim(AtName(Iat)) & |
433 |
,PathCart(Iat,IGeom),PathCart(Iat+Nat,IGeom),PathCart(Iat+2*Nat,IGeom) & |
434 |
, TRIM(Gauss_Paste(Iat)) |
435 |
END IF |
436 |
END DO |
437 |
|
438 |
WRITE(IOTMP,*) |
439 |
|
440 |
Current => Gauss_End |
441 |
DO WHILE (ASSOCIATED(Current%next)) |
442 |
WRITE(IOTMP,'(1X,A)') Trim(current%line) |
443 |
Current => current%next |
444 |
END DO |
445 |
|
446 |
WRITE(IOTMP,*) |
447 |
CLOSE(IOTMP) |
448 |
|
449 |
END DO |
450 |
|
451 |
Close(IOTMP2) |
452 |
|
453 |
! We launch the parallel calculations |
454 |
|
455 |
Line=Trim(ProgExe) |
456 |
IF (DEBUG) WRITE(*,*)'RunCommand:',TRIM(Line) |
457 |
call system(Line) |
458 |
IF (DEBUG) WRITE(*,*)'Back from RunCommand:' |
459 |
|
460 |
! We read energies and gradients from the log files |
461 |
|
462 |
DO IGeom=IGeom0,IGeomF |
463 |
WRITE(Line,'(I5)') IGeom |
464 |
FileInp="PathPar_" // TRIM(ADJUSTL(Line)) // ".log" |
465 |
OPEN(IOTMP,File=TRIM(FileInp)) |
466 |
|
467 |
! We first search for the forces |
468 |
READ(IOTMP,'(A)') LINE |
469 |
DO WHILE (INDEX(LINE,'Forces (Hartrees/Bohr)')==0) |
470 |
! here, we have a problem, because there are so many ways to write E for Gaussian :-) |
471 |
! but we do not really need E except if we want to weight the different points |
472 |
! on the path... that will be done later :-) |
473 |
! And I should use ConvGaussXmol ... |
474 |
! PFL 3rd Jan 2008 -> |
475 |
! I have finally upgraded the energy reading phase so that it should be able to read |
476 |
! many formats corresponding to HF, DFT, MP2, AM1, PM3, ONIOM with or w/o PCM |
477 |
! |
478 |
|
479 |
! For MP2, energy is after the last = |
480 |
IF ((Line(2:9)=="E2 = ")) THEN |
481 |
Itmp1=Index(LINE,"=",BACK=.TRUE.)+1 |
482 |
READ(LINE(Itmp1:),*) e |
483 |
END IF |
484 |
! For other methods, it is after the first = |
485 |
IF ((LINE(2:9)=='Energy= ').OR.(Line(2:9)=="SCF Done").OR.(Line(2:9)=="ONIOM: e") & |
486 |
.OR.(Line(2:9)==" with al") & |
487 |
.OR.(Line(2:31)=="Counterpoise: corrected energy")) THEN |
488 |
Itmp1=Index(LINE,"=")+1 |
489 |
READ(LINE(Itmp1:),*) e |
490 |
END IF |
491 |
! <- PFL 3 Jan 2008 |
492 |
READ(IOTMP,'(A)') LINE |
493 |
END DO |
494 |
READ(IOTMP,'(A)') LINE |
495 |
READ(IOTMP,'(A)') LINE |
496 |
DO I=1,Nat |
497 |
Iat=I |
498 |
IF (renum) Iat=Order(I) |
499 |
READ(IOTMP,*) Itmp1,ITmp2, GradCart(3*Iat-2:3*Iat) |
500 |
END DO |
501 |
|
502 |
! Gaussian gives the Forces in ua/a0, so we convert it into the |
503 |
! gradient in ua/Angstrom |
504 |
gradCart=-1.0d0*Unit*gradCart |
505 |
|
506 |
CLOSE(IOTMP) |
507 |
Energies(IGeom)=E |
508 |
|
509 |
! We convert it into the right coordinate system |
510 |
! This should be put into a subroutine (because it is also in egradient) |
511 |
SELECT CASE (COORD) |
512 |
CASE ("ZMAT") |
513 |
ALLOCATE(GradTmp(3*Nat)) |
514 |
if (debug) WRITE(*,*) "DBG EGRAD Calling CalcBMat_int" |
515 |
CALL CalcBMat_int (nat, PathCart(1:3*Nat,Igeom), indzmat, dzdc, massat,atome) |
516 |
CALL ConvGrad_Cart2Int(Nat,dzdc,IndZmat,GradCart,GradTmp) |
517 |
|
518 |
Grad(IGeom,1)=GradTmp(4) |
519 |
Grad(IGeom,2)=GradTmp(7) |
520 |
! We might have troubles whith angles that are not in the [0:pi] range because, |
521 |
! when converted to catesian coord, they do appear in the [0:Pi] range to gaussian... |
522 |
! so that the derivative is not good, and a multiplicative factor should be added... |
523 |
! |
524 |
! This in fact should be taken care of in B-mat calculation... |
525 |
! |
526 |
IF ((IntCoordF(Igeom,3).LE.0).OR.(IntCoordF(Igeom,3).GE.Pi)) THEN |
527 |
Grad(IGeom,3)=-1.0d0*GradTmp(8) |
528 |
ELSE |
529 |
Grad(IGeom,3)=GradTmp(8) |
530 |
END IF |
531 |
Idx=4 |
532 |
DO I=4,Nat |
533 |
Grad(IGeom,Idx)=GradTmp(3*i-2) |
534 |
Grad(IGeom,Idx+1)=GradTmp(3*i-1) |
535 |
Grad(IGeom,Idx+2)=GradTmp(3*i) |
536 |
Idx=Idx+3 |
537 |
END DO |
538 |
DEALLOCATE(GradTmp) |
539 |
! We have the gradient in Cartesian coordinates... which is ok for COORD=Cart, Hybrid |
540 |
! but we have to convert it into internal coordinates if COORD=Baker |
541 |
CASE ('BAKER') |
542 |
ALLOCATE(GradTmp(3*Nat)) |
543 |
GradTmp=0.d0 |
544 |
! Below is to be corrected. |
545 |
! This is inside 'IF ((PROG=="VASP").AND.(RunMode=="PARA")) THEN' |
546 |
!DO I=1, 3*Nat |
547 |
! here GradTmp and Grad are gradients in Baker coordinates |
548 |
! Not implemented IF ((PROG=="VASP").AND.(RunMode=="PARA")) |
549 |
! GradTmp(:) = GradTmp(:) + BTransInv(:,I)*GradCart(I) |
550 |
!END DO |
551 |
Grad(IGeom,:) = GradTmp |
552 |
DEALLOCATE(GradTmp) |
553 |
CASE ('MIXED') |
554 |
ALLOCATE(GradTmp(3*Nat)) |
555 |
if (debug) WRITE(*,*) "DBG EGRAD Calling CalcBMat_mixed" |
556 |
CALL CalcBMat_mixed(nat,PathCart(1:3*Nat,IGeom), indzmat, dzdc, massat,atome) |
557 |
CALL ConvGrad_Cart2Int(Nat,dzdc,IndZmat,GradCart,GradTmp) |
558 |
DO I=1,Nat |
559 |
WRITE(*,'(1X,3(1X,F10.5))') GradTmp(3*I-2:3*I) |
560 |
END DO |
561 |
SELECT CASE (NCART) |
562 |
CASE (1) |
563 |
Grad(IGeom,1:3)=GradTmp(1:3) |
564 |
Grad(IGeom,4)=GradTmp(4) |
565 |
Grad(IGeom,5)=GradTmp(7) |
566 |
Grad(IGeom,6)=GradTmp(8) |
567 |
Idx=7 |
568 |
IBeg=4 |
569 |
CASE(2) |
570 |
Grad(IGeom,1:3)=GradTmp(1:3) |
571 |
Grad(IGeom,4:6)=GradTmp(4:6) |
572 |
Grad(IGeom,7)=GradTmp(7) |
573 |
Grad(IGeom,8)=GradTmp(8) |
574 |
Idx=9 |
575 |
IBeg=4 |
576 |
CASE DEFAULT |
577 |
Idx=1 |
578 |
IBeg=1 |
579 |
END SELECT |
580 |
DO I=IBeg,Nat |
581 |
Grad(IGeom,Idx)=GradTmp(3*i-2) |
582 |
Grad(IGeom,Idx+1)=GradTmp(3*i-1) |
583 |
Grad(IGeom,Idx+2)=GradTmp(3*i) |
584 |
Idx=Idx+3 |
585 |
END DO |
586 |
DEALLOCATE(GradTmp) |
587 |
CASE ("CART","HYBRID") |
588 |
Grad(IGeom,:)=GradCart |
589 |
CASE DEFAULT |
590 |
WRITE(*,*) "Coord=",AdjustL(Trim(COORD))," not yet implemented in EgradPath.L257.STOP" |
591 |
STOP |
592 |
END SELECT |
593 |
|
594 |
IF (debug) THEN |
595 |
Line='DBG Path, GradTmp' |
596 |
Call PrintGeom(Line,Nat,NCoord,reshape(GRad(Igeom,1:NCoord),(/Ncoord/)),Coord,6,Atome,Order,OrderInv,IndZmat) |
597 |
END IF |
598 |
|
599 |
END DO |
600 |
|
601 |
CASE DEFAULT |
602 |
WRITE(*,*) "Prog=",TRIM(Prog)," not yet supported for Para mode." |
603 |
STOP |
604 |
END SELECT |
605 |
|
606 |
DEALLOCATE(GradCart,PathCart) |
607 |
|
608 |
ELSE ! matches IF (RunMode=="PARA") THEN |
609 |
! We will launch all calculations sequentially |
610 |
ALLOCATE(GradTmp(NCoord)) |
611 |
GeomOld_dummy=0.d0 ! Internal coordinates |
612 |
GeomCart_old_dummy=0.d0 |
613 |
! We have the new path, we calculate its energy and gradient |
614 |
IGeom0=2 |
615 |
IGeomF=NGeomF-1 |
616 |
IF (OptReac.OR.CalcEReac) IGeom0=1 |
617 |
IF (OptProd.OR.CalcEProd) IGeomF=NGeomF |
618 |
CalcEReac=.FALSE. |
619 |
CalcEProd=.FALSE. |
620 |
ALLOCATE(GeomCart(Nat,3)) |
621 |
|
622 |
DO IGeom=IGeom0,IGeomF |
623 |
WRITE(Line,"('Geometry ',I3,'/',I3,' for iteration ',I3)") Igeom,NgeomF,Iopt |
624 |
if (debug) WRITE(*,*) Line |
625 |
SELECT CASE(Coord) |
626 |
CASE ('ZMAT','MIXED') |
627 |
GeomTmp=IntCoordF(IGeom,:) |
628 |
CASE ('BAKER') |
629 |
GeomTmp=IntCoordF(IGeom,:) |
630 |
CASE ('CART','HYBRID') |
631 |
!!! CAUTION : PFL 29.AUG.2008 -> |
632 |
! XyzGeomI/F stored in (NGeomI/F,3,Nat) and NOT (NGeomI/F,Nat,3) |
633 |
! This should be made consistent !!!!!!!!!!!!!!! |
634 |
GeomTmp=Reshape(reshape(XyzGeomF(IGeom,:,:),(/Nat,3/),ORDER=(/2,1/)),(/3*Nat/)) |
635 |
! GeomTmp=Reshape(XyzGeomF(IGeom,:,:),(/3*Nat/)) |
636 |
!!! <- CAUTION : PFL 29.AUG.2008 |
637 |
CASE DEFAULT |
638 |
WRITE(*,*) "Coord=",TRIM(Coord)," not recognized in EgradPath. L299" |
639 |
STOP |
640 |
END SELECT |
641 |
|
642 |
!if (debug) WRITE(*,*) "Calling PrintGeom" |
643 |
!Call PrintGeom(Line,Nat,NCoord,GeomTmp,Coord,IoOut,Atome,Order,OrderInv,IndZmat) |
644 |
|
645 |
! IF (debug) THEN |
646 |
! WRITE(*,*) 'DBG Main, COORD=',TRIM(COORD), ' Igeom=',IGeom |
647 |
! WRITE(*,'(3(1X,F9.4))') Reshape(Reshape(XyzGeomF(IGeom,:,:),(/Nat,3/),ORDER=(/2,1/)),(/3*Nat/)) |
648 |
! WRITE(*,'(3(1X,F9.4))') Reshape(XyzGeomF(IGeom,:,:),(/3*Nat/)) |
649 |
! DO Iat=1,Nat |
650 |
! WRITE(*,*) XyzGeomF(IGeom,1:3,Iat) |
651 |
! END DO |
652 |
! END IF |
653 |
|
654 |
IF (debug) THEN |
655 |
WRITE(*,*) 'DBG Main, COORD=',TRIM(COORD),' IGeom=',IGeom,' Iopt=',Iopt |
656 |
WRITE(*,*) GeomTmp(1:min(NCoord,12)) |
657 |
END IF |
658 |
|
659 |
GeomCart=0.d0 |
660 |
IF(IOpt .EQ. 1) Then |
661 |
Print *, 'GeomTmp=' |
662 |
WRITE(*,'(12(1X,F6.3))') GeomTmp |
663 |
Print *, 'GeomCart=' |
664 |
WRITE(*,'(12(1X,F6.3))') GeomCart |
665 |
END IF |
666 |
|
667 |
IF (COORD.EQ.'BAKER') THEN |
668 |
! GradTmp is gradient and calculated in Egrad.F, INTENT(OUT). |
669 |
! GeomCart has INTENT(OUT) |
670 |
Call EGrad_baker(E,GeomTmp,GradTmp,NCoord,IGeom,IOpt,GeomCart,Flag_Opt_Geom, & |
671 |
GeomOld_dummy,GeomCart_old_dummy) |
672 |
ELSE |
673 |
Call EGrad(E,GeomTmp,GradTmp,NCoord,IGeom,IOpt,GeomCart,Flag_Opt_Geom) !GeomTmp=IntCoordF(IGeom,:) |
674 |
END IF |
675 |
|
676 |
! Egrad calls ConvertBakerInternal_cart to convert GeomTmp=IntCoordF(IGeom,:) into |
677 |
! GeomCart (Cartesian Coordinates) so that energy and gradients can be calculated |
678 |
! for each geometry. |
679 |
XyzGeomF(IGeom,1,:)=GeomCart(:,1) |
680 |
XyzGeomF(IGeom,2,:)=GeomCart(:,2) |
681 |
XyzGeomF(IGeom,3,:)=GeomCart(:,3) |
682 |
|
683 |
Energies(IGeom)=E |
684 |
|
685 |
if (debug) THEN |
686 |
Line='DBG Path, GradTmp' |
687 |
Call PrintGeom(Line,Nat,NCoord,GRadTmp,Coord,6,Atome,Order,OrderInv,IndZmat) |
688 |
END IF |
689 |
Grad(IGeom,:)=GradTmp |
690 |
END DO ! matches DO IGeom=IGeom0,IGeomF |
691 |
DEALLOCATE(GradTmp,GeomCart) |
692 |
END IF ! matches IF (RunMode=="PARA") THEN AFTER ELSE |
693 |
|
694 |
DEALLOCATE(GeomTmp) |
695 |
DEALLOCATE(x,y,z) |
696 |
DEALLOCATE(x_k,y_k,z_k) |
697 |
DEALLOCATE(GeomOld_dummy,GeomCart_old_dummy) |
698 |
if (debug) Call header('Exiting EgradPath') |
699 |
RETURN |
700 |
999 WRITE(*,*) "EgradPath : We should not be here !" |
701 |
STOP |
702 |
|
703 |
END SUBROUTINE EGRADPATH |