Statistiques
| Révision :

root / src / EgradPath.f90 @ 6

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