Statistiques
| Révision :

root / src / Egrad_baker.f90 @ 2

Historique | Voir | Annoter | Télécharger (12,7 ko)

1
subroutine Egrad_baker(E,Geom,Grad,NCoord,IGeom,IOpt,GeomCart,Flag_Opt_Geom,GeomOld,GeomCart_old)
2

    
3
  ! This routines calculates the energy E and the gradient Grad of 
4
  ! a molecule with Geometry Geom (may be in internal coordinates),
5
  ! using for now, either Gaussian or Ext, more general later.
6

    
7
  use Path_module, only : Nat,AtName,Coord,dzdc,indzmat,Nom,Atome,massat,unit, &
8
       prog,NCart,XyzGeomF,IntCoordF,BTransInv, XyzGeomI, &
9
       GeomOld_all,BTransInvF,BTransInv_local,UMatF,UMat_local &
10
       , BprimT,a0,ScanCoord, Coordinate,NPrim,BMat_BakerT,BBT,BBT_inv &
11
      , Order,OrderInv, XPrimitiveF
12

    
13
  ! IntCoordF(NGeomF,NCoord),GeomOld_all(NGeomF,NCoord)
14
  ! allocated in Path.f90
15

    
16
  use Io_module
17
  IMPLICIT NONE
18

    
19
  ! Energy (calculated if F300K=.F., else estimated)
20
  REAL(KREAL), INTENT (OUT) :: E
21
  ! NCoord: Number of the degrees of freedom
22
  ! IGeom: index of the geometry.
23
  INTEGER(KINT), INTENT (IN) :: NCoord, IGeom, IOpt
24
  ! Geometry at which gradient is calculated (cf Factual also):
25
  REAL(KREAL), INTENT (INOUT) :: Geom(NCoord)
26
  REAL(KREAL), INTENT (INOUT) :: GeomOld(NCoord)
27
  ! Gradient calculated at Geom geometry:
28
  REAL(KREAL), INTENT (OUT) :: Grad(NCoord)
29
  ! Cartesian geometry corresponding to (Internal Geometry) Geom:
30
  REAL(KREAL), INTENT (OUT) :: GeomCart(Nat,3)
31
  REAL(KREAL), INTENT (IN) :: GeomCart_old(Nat,3)
32
  LOGICAL,INTENT (IN) :: Flag_Opt_Geom
33

    
34
  ! ======================================================================
35

    
36
  CHARACTER(LCHARS) :: LINE
37
  LOGICAL :: debug
38
  LOGICAL, SAVE :: first=.true.
39
  LOGICAL, ALLOCATABLE :: Done(:)
40
  REAL(KREAL), SAVE :: Eold=1.e6
41
  REAL(KREAL), ALLOCATABLE :: GradTmp(:)
42
  REAL(KREAL), ALLOCATABLE :: GradCart(:)
43
  REAL(KREAL), ALLOCATABLE :: x(:), y(:), z(:)
44
  REAL(KREAL) :: d, a_val, Pi
45

    
46
  INTEGER(KINT) :: iat, jat, kat, i, j, n3at,IBeg,Idx
47
  INTEGER(KINT), PARAMETER :: IOLOG=12, IOCOM=11
48

    
49
  CHARACTER(LCHARS) :: ListName, CH32SVAR1
50
  CHARACTER(VLCHARS), SAVE :: RstrtCopy, RunCommand
51
  LOGICAL, SAVE :: FCopyRstrt=.False., FOrderChecked=.False.
52
  LOGICAL   :: FTmp
53
  INTEGER(kint) :: NbLists,LastIt,Nat4,NStep, Firstit
54
  INTEGER(KINT), PARAMETER :: NbExtName=4
55

    
56
  REAL(KREAL), ALLOCATABLE :: XPrimRef(:), XPrim(:) ! NPrim
57

    
58
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
59
!
60
!!!!!!!! PFL Debug
61
!
62
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
63
  REAL(KREAL), ALLOCATABLE :: GeomTmp(:,:) !3,Nat
64
  REAL(KREAL), ALLOCATABLE :: V(:,:) ! (NCoord,NCoord)
65
  REAL(KREAL), ALLOCATABLE :: XyzTmp(:,:) ! xyzatm(3,nat)
66
  REAL(KREAL) :: tol
67
  LOGICAL :: FAIL , FALOBBT,FALOBPrimt,FAloBBTInv
68
  LOGICAL :: DebugPFL
69

    
70
  ! ======================================================================
71
  LOGICAL, EXTERNAL :: valid
72
  ! ======================================================================
73

    
74
  INTEGER(KINT) :: OptGeom
75
  Namelist/path/OptGeom
76

    
77
  Pi=dacos(-1.0d0)
78
  n3at=3*nat
79

    
80
  debug=valid('EGRAD_baker')
81
  debugPFL=valid('bakerPFL')
82
  if (debug) WRITE(*,*) '================ Entering Egrad_baker ================='
83
  if (debug) Print *, 'EGrad.f90, L73, IOpt=', IOpt, ' Flag_Opt_Geom=',Flag_Opt_Geom
84

    
85
  Grad=0.
86
  E=0.
87

    
88
  ALLOCATE(GradCart(3*Nat))
89
  ALLOCATE(x(Nat),y(Nat),z(Nat))
90
  ALLOCATE(XPrimRef(NPrim),XPrim(NPrim))
91

    
92
  SELECT CASE (COORD)
93
  CASE ('ZMAT')
94
     WRITE (*,*) "Coord=",TRIM(COORD),": use Egrad.f90, instead of Egrad_baker.f90. Stop"
95
  CASE ('BAKER')
96
     XPrimRef=XPrimitiveF(IGeom,:)
97
     IF (Flag_Opt_Geom) THEN
98
        IF (IOpt .EQ. 1) THEN
99
           GeomCart(:,1) = XyzGeomI(IGeom,1,:)
100
           GeomCart(:,2) = XyzGeomI(IGeom,2,:)
101
           GeomCart(:,3) = XyzGeomI(IGeom,3,:)
102
        ELSE
103
	   if (debug) WRITE(*,*) 'Before Call ConvertBakerInternal_cart; L82, Egrad.f90'
104
           WRITE(*,*) 'GeomOld='
105
           WRITE(*,'(12(1X,F6.3))') GeomOld
106
           WRITE(*,*) 'Geom='
107
           WRITE(*,'(12(1X,F6.3))') Geom
108
           WRITE(*,*) 'GeomCart_old='
109
           WRITE(*,'(20(1X,F6.3))') GeomCart_old
110
           Call ConvertBakerInternal_cart(GeomOld,Geom,GeomCart_old(:,1), &
111
                GeomCart_old(:,2),GeomCart_old(:,3),x,y,z,XPrim,XPrimRef)
112
           GeomCart(:,1) = x(:)
113
           GeomCart(:,2) = y(:)
114
           GeomCart(:,3) = z(:)
115
        END IF
116
     ELSE
117
        IF (IOpt .EQ. 0) THEN
118
           GeomCart(:,1) = XyzGeomF(IGeom,1,:)
119
           GeomCart(:,2) = XyzGeomF(IGeom,2,:)
120
           GeomCart(:,3) = XyzGeomF(IGeom,3,:)
121
        ELSE
122
           ! IntCoordF(NGeomF,NCoord), XyzGeomF(NGeomF,3,Nat)
123
           ! Geom has to be converted into x,y,z
124
           ! GeomOld_all and XyzGeomF are old geometry in internal and cartesian coords resp.
125
           DO I=1,NCoord ! these variables are used in ConvertBakerInternal_cart()
126
              BTransInv_local(I,:) = BTransInvF(IGeom,I,:)
127
              UMat_local(:,I) = UMatF(IGeom,:,I)
128
           END DO
129
           if (debug) Print *, 'I am before Call ConvertBakerInternal_cart; L108, Egrad.f90'
130
           WRITE(*,*) 'GeomOld='
131
           WRITE(*,'(12(1X,F6.3))') GeomOld
132
           WRITE(*,*) 'Geom='
133
           WRITE(*,'(12(1X,F6.3))') Geom
134
           WRITE(*,*) 'DBG Egrad_baker L129 GeomCart_old='
135
           DO I=1,Nat
136
              WRITE(*,'(3(1X,F12.8))') XyzGeomF(IGeom,:,I)
137
           END DO
138

    
139
           Call ConvertBakerInternal_cart(GeomOld_all(IGeom,:),Geom,XyzGeomF(IGeom,1,:), &
140
	        XyzGeomF(IGeom,2,:),XyzGeomF(IGeom,3,:),x,y,z,XPrim,XPrimRef)
141
           if (debug) Print *, 'I am after Call ConvertBakerInternal_cart; L111, Egrad.f90'
142
           DO I=1,NCoord ! these variables are used in ConvertBakerInternal_cart()
143
              BTransInvF(IGeom,I,:) = BTransInv_local(I,:)
144
           END DO
145
           ! GeomCart is actually XyzCoord and has INTENT(OUT) in this subroutine.
146
           GeomCart(:,1) = x(:)
147
           GeomCart(:,2) = y(:)
148
           GeomCart(:,3) = z(:)
149
        END IF ! matches IF (IOpt .EQ. 0) THEN
150
     END IF
151
  CASE ('MIXED')
152
     WRITE (*,*) "Coord=",TRIM(COORD),": use Egrad.f90, instead of Egrad_baker.f90. Stop"
153
  CASE ('CART')
154
     WRITE (*,*) "Coord=",TRIM(COORD),": use Egrad.f90, instead of Egrad_baker.f90. Stop"
155
  CASE ('HYBRID')
156
     WRITE (*,*) "Coord=",TRIM(COORD),": use Egrad.f90, instead of Egrad_baker.f90. Stop"
157
  CASE DEFAULT
158
     WRITE (*,*) "Coord=",TRIM(COORD)," not recognized. Stop"
159
     STOP
160
  END SELECT
161
  !WRITE(*,*) Nat
162
  !WRITE(*,*) 'GeomCart in Egrad_baker'
163
  !DO I=1,Nat
164
  !	WRITE(*,'(1X,A,3(1X,F12.8))') AtName(I),GeomCart(I,1:3)
165
  !END DO
166

    
167
  SELECT CASE (Prog)
168
  CASE ('GAUSSIAN')
169
     ! we call the Gaussian routine.
170
     ! it will return the energy and the gradient in cartesian coordinates.
171
     ! Gradient calculated at GeomCart geometry and stored in GradCart, which has INTENT(OUT)
172
     Call egrad_gaussian(E,GeomCart,GradCart)
173
  CASE ('MOPAC')
174
     ! we call the Mopac routine.
175
     ! it will return the energy and the gradient in cartesian coordinates.
176
     ! Gradient calculated at GeomCart geometry and stored in GradCart, which has INTENT(OUT)
177
     Call egrad_mopac(E,GeomCart,GradCart)
178
  CASE ('VASP')
179
     Call egrad_vasp(E,Geomcart,GradCart)
180
  CASE ('TURBOMOLE')
181
     Call egrad_turbomole(E,Geomcart,GradCart)
182
  CASE ('EXT')
183
     Call egrad_ext(E,Geomcart,GradCart)
184
  CASE ('TEST')
185
     Call egrad_test(Nat,E,Geomcart,GradCart)
186
  CASE ('CHAMFRE')
187
     Call egrad_chamfre(Nat,E,Geomcart,GradCart)
188
  END SELECT
189
  if (debug) THEN
190
     WRITE(*,*) 'DBG EGRAD, GradCart read'
191
     DO Iat=1,Nat
192
        WRITE(*,'(1X,A10,3(1X,F15.8),A)') Trim(AtName(Iat)),GradCart(3*Iat-2:3*Iat)
193
     END DO
194
  END IF
195

    
196
  !  If (PROG=="VASP") STOP
197

    
198
  ! We have the gradient in Cartesian coordinates... which is ok for COORD=Cart, Hybrid
199
  !  but we have to convert it into Zmat if COORD=Zmat
200
  SELECT CASE (COORD)
201
  CASE ("ZMAT")
202
     WRITE (*,*) "Coord=",TRIM(COORD),": use Egrad.f90, instead of Egrad_baker.f90. Stop"
203
  CASE ('BAKER')
204
     ! We have the gradient in Cartesian coordinates... which is ok for COORD=Cart, Hybrid
205
     ! but we have to convert it into internal coordinates if COORD=Baker	 
206
!!!!!!!!!!!!!!!!!!!!
207
     !
208
     !   PFL Debug
209
     !
210
!!!!!!!!!!!!!!!!!!!!
211
     if (debugPFL) THEN
212
        WRITE(*,*) "DBG PFL Egrad_Baker... computing dzdc"
213
     if (.not.ALLOCATED(indzmat)) THEN
214
        ALLOCATE(indzmat(Nat,5))
215
     IndZmat=0
216
     Indzmat(1,1)=1
217
     IndZmat(2,1)=2
218
     IndZmat(2,2)=1
219
     IndZmat(3,1)=3
220
     IndZmat(3,2)=2
221
     IndZmat(3,3)=1
222
     IndZmat(4,1)=4
223
     IndZmat(4,2)=3
224
     IndZmat(4,3)=2
225
     IndZmat(4,4)=1
226
     END IF
227
     IF (.NOT.ALLOCATED(DzDc)) THEN
228
        ALLOCATE(DzDc(3,nat,3,Nat))
229
     END IF
230
     if (.NOT.Allocated(GeomTmp)) Allocate(GeomTmp(3,Nat))                                            
231
     DO I=1,Nat
232
     GeomTmp(1,I)=GeomCart(OrderInv(I),1)
233
     GeomTmp(2,I)=GeomCart(OrderInv(i),2)
234
     GeomTmp(3,I)=GeomCart(OrderInv(i),3)
235
     END DO
236

    
237
     DzDc=0.d0
238
     CALL CalcBMat_int (nat, GeomTmp, indzmat, dzdc, massat,atome)     
239

    
240
     END IF ! if (debugPFL)
241
!!!!!!!!!!!!!!!!!!!!!!!!!
242
     ! Debugging PFL
243
!!!!!!!!!!!!!!!!!!!!!!!!
244

    
245
     WRITE(*,*) "BTransInv_local Trans that is used originally"
246
     DO J=1,3*Nat
247
        WRITE(*,'(50(1X,F12.8))') BTransInv_local(:,J)
248
     END DO
249

    
250
     WRITE(*,*) "Calculating actual values using GeomCart"
251
     if (.NOT.Allocated(GeomTmp)) Allocate(GeomTmp(3,Nat))
252
     GeomTmp(1,:)=GeomCart(1:Nat,1)
253
     GeomTmp(2,:)=GeomCart(1:Nat,2)
254
     GeomTmp(3,:)=GeomCart(1:Nat,3)
255

    
256
     ! Computing B^prim:
257
     FAloBBT=.NOT.ALLOCATED(BBT)
258
     FAloBBTInv=.NOT.ALLOCATED(BBT_inv)
259
     FAloBPrimT=.NOT.ALLOCATED(BprimT)
260
     if (FAloBPrimT) ALLOCATE(Bprimt(3*Nat,NPrim))
261
     if (FAloBBT) ALLOCATE(BBt(NCoord,NCoord))
262
     if (FAloBBTInv) ALLOCATE(BBt_inv(NCoord,NCoord))
263
     BprimT=0.d0
264
     ScanCoord=>Coordinate
265
     I=0
266
     DO WHILE (Associated(ScanCoord%next))
267
        I=I+1
268
        SELECT CASE (ScanCoord%Type)
269
        CASE ('BOND') 
270
           CALL CONSTRAINTS_BONDLENGTH_DER(Nat,ScanCoord%at1,ScanCoord%AT2,GeomTmp,BprimT(1,I))
271
        CASE ('ANGLE')
272
           CALL CONSTRAINTS_BONDANGLE_DER(Nat,ScanCoord%At1,ScanCoord%AT2,ScanCoord%At3,GeomTmp,BprimT(1,I))
273
        CASE ('DIHEDRAL')
274
           CALL CONSTRAINTS_TORSION_DER2(Nat,ScanCoord%At1,ScanCoord%AT2,ScanCoord%At3,ScanCoord%At4,GeomTmp,BprimT(1,I))
275
        END SELECT
276
        ScanCoord => ScanCoord%next
277
     END DO
278

    
279
     if (debug) THEN
280
        WRITE(*,*) "Bprim "
281
        DO J=1,3*Nat
282
           WRITE(*,'(50(1X,F12.6))') BprimT(J,:)
283
        END DO
284
     END IF
285

    
286
     BMat_BakerT = 0.d0
287
     DO I=1,NCoord
288
        DO J=1,NPrim
289
           !BprimT is transpose of B^prim.
290
           !B = UMat^T B^prim, B^T = (B^prim)^T UMat
291
           BMat_BakerT(:,I)=BMat_BakerT(:,I)+BprimT(:,J)*UMat_local(J,I)
292
        END DO
293
     END DO
294

    
295
     BBT = 0.d0
296
     DO I=1,NCoord
297
        DO J=1,3*Nat 	! BBT(:,I) forms BB^T
298
           BBT(:,I) = BBT(:,I) + BMat_BakerT(J,:)*BMat_BakerT(J,I)
299
        END DO
300
     END DO
301

    
302
     BBT_inv = 0.d0
303

    
304
     Call GenInv(NCoord,BBT,BBT_inv,NCoord)
305

    
306
!     ALLOCATE(V(NCoord,NCoord))
307
!     tol = 1e-10
308
!     ! BBT is destroyed by GINVSE
309
!     Call GINVSE(BBT,NCoord,NCoord,BBT_inv,NCoord,NCoord,NCoord,tol,V,NCoord,FAIL,IOOUT)
310
!     DEALLOCATE(V)
311
!     IF(Fail) Then
312
!        WRITE (*,*) "Failed in generalized inverse, L220, ConvertBaker...f90"
313
!        STOP
314
!     END IF
315

    
316
     !Print *, 'BBT_inv='
317
     DO J=1,NCoord
318
        ! WRITE(*,'(50(1X,F10.2))') BBT_inv(:,J)
319
        ! Print *, BBT_inv(:,J)
320
     END DO
321
     !Print *, 'End of BBT_inv'
322

    
323
     ! Calculation of (B^T)^-1 = (BB^T)^-1B:
324
     BTransInv_local = 0.d0
325
     DO I=1,3*Nat
326
        DO J=1,NCoord
327
           BTransInv_local(:,I)=BTransInv_local(:,I)+BBT_inv(:,J)*BMat_BakerT(I,J)
328
        END DO
329
     END DO
330

    
331
     Print *, 'BMat_BakerT='
332
     DO J=1,3*Nat
333
        WRITE(*,'(50(1X,F12.8))') BMat_BakerT(:,J)
334
     END DO
335

    
336
     WRITE(*,*) "BTransInv_local Trans corresponding to GeomCart"
337
     DO J=1,3*Nat
338
        WRITE(*,'(50(1X,F12.8))') BTransInv_local(:,J)
339
     END DO
340

    
341
     if (FAloBPrimT) DEALLOCATE(Bprimt)
342
     if (FAloBBT) DEALLOCATE(BBt)
343
     if (FAloBBTInv) DEALLOCATE(BBt_inv)
344

    
345
     Grad=0.d0
346
     DO I=1, 3*Nat
347
        ! Here Grad is gradient in Baker coordinates. GradCart(3*Nat)
348
        Grad(:) = Grad(:) + BTransInv_local(:,I)*GradCart(I) !BTransInv_local = BTransInv in Opt_Geom.f90
349
     END DO
350
     !WRITE(*,*) 'In Egrad.f90, L263, Gradient:' 
351
     !WRITE(*,'(12(1X,F8.4))') Grad(1:NCoord)
352
  CASE ('MIXED')
353
     WRITE (*,*) "Coord=",TRIM(COORD),": use Egrad.f90, instead of Egrad_baker.f90. Stop"
354
  CASE ("CART","HYBRID")
355
     WRITE (*,*) "Coord=",TRIM(COORD),": use Egrad.f90, instead of Egrad_baker.f90. Stop"
356
  CASE DEFAULT
357
     WRITE(*,*) "Coord=",AdjustL(Trim(COORD))," not yet implemented in Egradients. STOP"
358
     STOP
359
  END SELECT
360

    
361
  DEALLOCATE(GradCart)
362
  DEALLOCATE(x,y,z)
363
  IF (Debug) WRITE(*,*) 'DBG EGRAD_baker grad',grad(1:NCoord)
364

    
365
  if (debug) WRITE(*,*) '================  Egrad_baker Over ===================='
366

    
367
  !999 CONTINUE
368
  !if (.NOT.Ftmp) WRITE(*,*) 'We should not be here !!!!'
369
  !STOP
370
  ! ======================================================================
371
end subroutine Egrad_baker
372