Statistiques
| Révision :

root / src / EgradPath.f90 @ 1

Historique | Voir | Annoter | Télécharger (26,36 ko)

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