Statistiques
| Révision :

root / src / Egrad.f90 @ 1

Historique | Voir | Annoter | Télécharger (15,22 ko)

1 1 pfleura2
subroutine Egrad(E,Geom,Grad,NCoord,IGeom,IOpt,GeomCart,FOptGeom,GeomOld,GeomCart_old)
2 1 pfleura2
3 1 pfleura2
  ! This routines calculates the energy E and the gradient Grad of
4 1 pfleura2
  ! a molecule with Geometry Geom (may be in internal coordinates),
5 1 pfleura2
  ! using for now, either Gaussian or Ext, more general later.
6 1 pfleura2
7 1 pfleura2
  use Path_module, only : Nat,AtName,Coord,dzdc,indzmat,Nom,Atome,massat,unit, &
8 1 pfleura2
       prog,NCart,XyzGeomF,IntCoordF,BTransInv, XyzGeomI, renum, &
9 1 pfleura2
       GeomOld_all,BTransInvF,BTransInv_local,UMatF,UMat_local &
10 1 pfleura2
       , BprimT,a0,ScanCoord, Coordinate,NPrim,BMat_BakerT,BBT,BBT_inv &
11 1 pfleura2
      , Order,OrderInv, XPrimitiveF
12 1 pfleura2
13 1 pfleura2
  ! IntCoordF(NGeomF,NCoord),GeomOld_all(NGeomF,NCoord)
14 1 pfleura2
  ! allocated in Path.f90
15 1 pfleura2
16 1 pfleura2
  use Io_module
17 1 pfleura2
  IMPLICIT NONE
18 1 pfleura2
19 1 pfleura2
  ! Energy (calculated if F300K=.F., else estimated)
20 1 pfleura2
  REAL(KREAL), INTENT (OUT) :: E
21 1 pfleura2
  ! NCoord: Number of the degrees of freedom
22 1 pfleura2
  ! IGeom: index of the geometry.
23 1 pfleura2
  INTEGER(KINT), INTENT (IN) :: NCoord, IGeom, IOpt
24 1 pfleura2
  ! Geometry at which gradient is calculated (cf Factual also):
25 1 pfleura2
  REAL(KREAL), INTENT (INOUT) :: Geom(NCoord)
26 1 pfleura2
  ! Gradient calculated at Geom geometry:
27 1 pfleura2
  REAL(KREAL), INTENT (OUT) :: Grad(NCoord)
28 1 pfleura2
  ! Cartesian geometry corresponding to (Internal Geometry) Geom:
29 1 pfleura2
  REAL(KREAL), INTENT (OUT) :: GeomCart(Nat,3)
30 1 pfleura2
!!! Optional, just for geometry optimization with Baker coordinates
31 1 pfleura2
  REAL(KREAL), INTENT (IN), OPTIONAL :: GeomCart_old(Nat,3)
32 1 pfleura2
  REAL(KREAL), INTENT (INOUT), OPTIONAL :: GeomOld(NCoord)
33 1 pfleura2
! FOptGeom is a flag indicating if we are doing a geom optimization
34 1 pfleura2
! it can be omitted so that we use a local flag: Flag_Opt_Geom
35 1 pfleura2
  LOGICAL,INTENT (IN), OPTIONAL :: FOptGeom
36 1 pfleura2
! if FOptGeom is given Flag_Opt_Geom=FOptGeom, else Flag_Opt_Geom=F
37 1 pfleura2
  LOGICAL  :: Flag_Opt_Geom
38 1 pfleura2
39 1 pfleura2
  ! ======================================================================
40 1 pfleura2
41 1 pfleura2
  LOGICAL :: debug
42 1 pfleura2
  REAL(KREAL), ALLOCATABLE :: GradTmp(:)
43 1 pfleura2
  REAL(KREAL), ALLOCATABLE :: GradCart(:)
44 1 pfleura2
  REAL(KREAL), ALLOCATABLE :: x(:), y(:), z(:)
45 1 pfleura2
  REAL(KREAL) ::  Pi
46 1 pfleura2
47 1 pfleura2
  INTEGER(KINT) :: iat, i, j, IBeg,Idx
48 1 pfleura2
  INTEGER(KINT), PARAMETER :: IOLOG=12, IOCOM=11
49 1 pfleura2
50 1 pfleura2
  INTEGER(KINT), PARAMETER :: NbExtName=4
51 1 pfleura2
52 1 pfleura2
  REAL(KREAL), ALLOCATABLE :: XPrimRef(:), XPrim(:) ! NPrim
53 1 pfleura2
54 1 pfleura2
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
55 1 pfleura2
!
56 1 pfleura2
!!!!!!!! PFL Debug
57 1 pfleura2
!
58 1 pfleura2
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
59 1 pfleura2
  REAL(KREAL), ALLOCATABLE :: GeomTmp(:,:) !3,Nat
60 1 pfleura2
  LOGICAL ::  FALOBBT,FALOBPrimt,FAloBBTInv
61 1 pfleura2
  LOGICAL :: DebugPFL
62 1 pfleura2
63 1 pfleura2
  ! ======================================================================
64 1 pfleura2
  INTERFACE
65 1 pfleura2
     function valid(string) result (isValid)
66 1 pfleura2
       CHARACTER(*), intent(in) :: string
67 1 pfleura2
       logical                  :: isValid
68 1 pfleura2
     END function VALID
69 1 pfleura2
  END INTERFACE
70 1 pfleura2
  ! ======================================================================
71 1 pfleura2
72 1 pfleura2
  Pi=dacos(-1.0d0)
73 1 pfleura2
74 1 pfleura2
  if (present(FOptGeom)) THEN
75 1 pfleura2
     Flag_Opt_Geom=FOptGeom
76 1 pfleura2
  ELSE
77 1 pfleura2
     Flag_Opt_Geom=.FALSE.
78 1 pfleura2
  END IF
79 1 pfleura2
80 1 pfleura2
  debug=valid('EGRAD')
81 1 pfleura2
  debugPFL=valid('bakerPFL')
82 1 pfleura2
  if (debug) Call Header("Entering Egrad")
83 1 pfleura2
84 1 pfleura2
  if (debug) Print *, 'EGrad.f90, L73, IOpt=', IOpt, ' Flag_Opt_Geom=',Flag_Opt_Geom
85 1 pfleura2
86 1 pfleura2
  Grad=0.
87 1 pfleura2
  E=0.
88 1 pfleura2
89 1 pfleura2
90 1 pfleura2
  ALLOCATE(GradCart(3*Nat))
91 1 pfleura2
  ALLOCATE(x(Nat),y(Nat),z(Nat))
92 1 pfleura2
  ALLOCATE(XPrimRef(NPrim),XPrim(NPrim))
93 1 pfleura2
94 1 pfleura2
  SELECT CASE (COORD)
95 1 pfleura2
  CASE ('ZMAT')
96 1 pfleura2
     ! In order to avoid problem with numbering and linear angles/diehedral, we convert the
97 1 pfleura2
     ! zmat into cartesian coordinates
98 1 pfleura2
     ! A remplacer par Int2Cart :-)
99 1 pfleura2
     Call Int2Cart(nat,indzmat,Geom,GeomCart)
100 1 pfleura2
  CASE ('BAKER')
101 1 pfleura2
     XPrimRef=XPrimitiveF(IGeom,:)
102 1 pfleura2
     IF (Flag_Opt_Geom) THEN
103 1 pfleura2
        IF (IOpt .EQ. 1) THEN
104 1 pfleura2
           GeomCart(:,1) = XyzGeomI(IGeom,1,:)
105 1 pfleura2
           GeomCart(:,2) = XyzGeomI(IGeom,2,:)
106 1 pfleura2
           GeomCart(:,3) = XyzGeomI(IGeom,3,:)
107 1 pfleura2
        ELSE
108 1 pfleura2
           if (debug) WRITE(*,*) 'Before Call ConvertBakerInternal_cart; L125, Egrad.f90'
109 1 pfleura2
           if (.NOT.present(GeomOld)) THEN
110 1 pfleura2
              WRITE(*,*) "ERROR: GeomOld not passed as an argument"
111 1 pfleura2
              STOP
112 1 pfleura2
           END IF
113 1 pfleura2
           WRITE(*,*) 'GeomOld='
114 1 pfleura2
           WRITE(*,'(12(1X,F6.3))') GeomOld
115 1 pfleura2
           WRITE(*,*) 'Geom='
116 1 pfleura2
           WRITE(*,'(12(1X,F6.3))') Geom
117 1 pfleura2
           if (.NOT.present(GeomCart_Old)) THEN
118 1 pfleura2
              WRITE(*,*) "ERROR: GeomCart_Old not passed as an argument"
119 1 pfleura2
              STOP
120 1 pfleura2
           END IF
121 1 pfleura2
122 1 pfleura2
           WRITE(*,*) 'GeomCart_old='
123 1 pfleura2
           WRITE(*,'(20(1X,F6.3))') GeomCart_old(1:Nat,1:3)
124 1 pfleura2
           Call ConvertBakerInternal_cart(GeomOld,Geom,GeomCart_old(:,1), &
125 1 pfleura2
                GeomCart_old(:,2),GeomCart_old(:,3),x,y,z,XPrim,XPrimRef)
126 1 pfleura2
           GeomCart(:,1) = x(:)
127 1 pfleura2
           GeomCart(:,2) = y(:)
128 1 pfleura2
           GeomCart(:,3) = z(:)
129 1 pfleura2
        END IF
130 1 pfleura2
     ELSE
131 1 pfleura2
        IF (IOpt .EQ. 0) THEN
132 1 pfleura2
           GeomCart(:,1) = XyzGeomF(IGeom,1,:)
133 1 pfleura2
           GeomCart(:,2) = XyzGeomF(IGeom,2,:)
134 1 pfleura2
           GeomCart(:,3) = XyzGeomF(IGeom,3,:)
135 1 pfleura2
        ELSE
136 1 pfleura2
           ! IntCoordF(NGeomF,NCoord), XyzGeomF(NGeomF,3,Nat)
137 1 pfleura2
           ! Geom has to be converted into x,y,z
138 1 pfleura2
           ! GeomOld_all and XyzGeomF are old geometry in internal and cartesian coords resp.
139 1 pfleura2
           DO I=1,NCoord ! these variables are used in ConvertBakerInternal_cart()
140 1 pfleura2
              BTransInv_local(I,:) = BTransInvF(IGeom,I,:)
141 1 pfleura2
              UMat_local(:,I) = UMatF(IGeom,:,I)
142 1 pfleura2
           END DO
143 1 pfleura2
           if (debug) Print *, 'I am before Call ConvertBakerInternal_cart; L160, Egrad.f90'
144 1 pfleura2
           WRITE(*,*) 'GeomOld='
145 1 pfleura2
           WRITE(*,'(12(1X,F6.3))') GeomOld_all(IGeom,:)
146 1 pfleura2
           WRITE(*,*) 'Geom='
147 1 pfleura2
           WRITE(*,'(12(1X,F6.3))') Geom
148 1 pfleura2
           WRITE(*,*) 'DBG Egrad L165 GeomCart_old='
149 1 pfleura2
           DO I=1,Nat
150 1 pfleura2
              WRITE(*,'(3(1X,F12.8))') XyzGeomF(IGeom,:,I)
151 1 pfleura2
           END DO
152 1 pfleura2
153 1 pfleura2
           Call ConvertBakerInternal_cart(GeomOld_all(IGeom,:),Geom,XyzGeomF(IGeom,1,:), &
154 1 pfleura2
          XyzGeomF(IGeom,2,:),XyzGeomF(IGeom,3,:),x,y,z,XPrim,XPrimRef)
155 1 pfleura2
           if (debug) Print *, 'I am after Call ConvertBakerInternal_cart; L111, Egrad.f90'
156 1 pfleura2
           DO I=1,NCoord ! these variables are used in ConvertBakerInternal_cart()
157 1 pfleura2
              BTransInvF(IGeom,I,:) = BTransInv_local(I,:)
158 1 pfleura2
           END DO
159 1 pfleura2
           ! GeomCart is actually XyzCoord and has INTENT(OUT) in this subroutine.
160 1 pfleura2
           GeomCart(:,1) = x(:)
161 1 pfleura2
           GeomCart(:,2) = y(:)
162 1 pfleura2
           GeomCart(:,3) = z(:)
163 1 pfleura2
        END IF ! matches IF (IOpt .EQ. 0) THEN
164 1 pfleura2
     END IF
165 1 pfleura2
  CASE ('MIXED')
166 1 pfleura2
!  write(*,*) "Coucou 4-mixed"
167 1 pfleura2
     Call Mixed2Cart(Nat,indzmat,geom,GeomCart)
168 1 pfleura2
  CASE ('CART')
169 1 pfleura2
!  write(*,*) "Coucou 4-cart"
170 1 pfleura2
     if (debug) WRITE(*,*) "Coord=CART... in egrad"
171 1 pfleura2
     GeomCart=reshape(Geom,(/Nat,3/))
172 1 pfleura2
     DO Iat=1,Nat
173 1 pfleura2
        WRITE(IOTMP,'(1X,A10,3(1X,F15.8),A)') Trim(AtName(Iat)),Geom(3*Iat-2:3*Iat)
174 1 pfleura2
     END DO
175 1 pfleura2
  CASE ('HYBRID')
176 1 pfleura2
!  write(*,*) "Coucou 4-hybrid"
177 1 pfleura2
        GeomCart=reshape(Geom,(/Nat,3/))
178 1 pfleura2
  CASE DEFAULT
179 1 pfleura2
     WRITE (*,*) "Coord=",TRIM(COORD)," not recognized. Stop"
180 1 pfleura2
     STOP
181 1 pfleura2
  END SELECT
182 1 pfleura2
  !WRITE(*,*) Nat
183 1 pfleura2
  !WRITE(*,*) 'GeomCart in Egrad_baker'
184 1 pfleura2
  !DO I=1,Nat
185 1 pfleura2
  !  WRITE(*,'(1X,A,3(1X,F12.8))') AtName(I),GeomCart(I,1:3)
186 1 pfleura2
  !END DO
187 1 pfleura2
188 1 pfleura2
  SELECT CASE (Prog)
189 1 pfleura2
  CASE ('GAUSSIAN')
190 1 pfleura2
! we call the Gaussian routine.
191 1 pfleura2
! it will return the energy and the gradient in cartesian coordinates.
192 1 pfleura2
! Gradient calculated at GeomCart geometry and stored in GradCart, which has INTENT(OUT)
193 1 pfleura2
     Call egrad_gaussian(E,GeomCart,GradCart)
194 1 pfleura2
  CASE ('MOPAC')
195 1 pfleura2
! we call the Mopac routine.
196 1 pfleura2
! it will return the energy and the gradient in cartesian coordinates.
197 1 pfleura2
! Gradient calculated at GeomCart geometry and stored in GradCart, which has INTENT(OUT)
198 1 pfleura2
     Call egrad_mopac(E,GeomCart,GradCart)
199 1 pfleura2
  CASE ('VASP')
200 1 pfleura2
     Call egrad_vasp(E,Geomcart,GradCart)
201 1 pfleura2
  CASE ('TURBOMOLE')
202 1 pfleura2
     Call egrad_turbomole(E,Geomcart,GradCart)
203 1 pfleura2
  CASE ('EXT')
204 1 pfleura2
     Call egrad_ext(E,Geomcart,GradCart)
205 1 pfleura2
  CASE ('TEST')
206 1 pfleura2
     Call egrad_test(Nat,E,Geomcart,GradCart)
207 1 pfleura2
  CASE ('CHAMFRE')
208 1 pfleura2
     Call egrad_chamfre(Nat,E,Geomcart,GradCart)
209 1 pfleura2
  END SELECT
210 1 pfleura2
  if (debug) THEN
211 1 pfleura2
     WRITE(*,*) 'DBG EGRAD, GradCart read'
212 1 pfleura2
     DO I=1,Nat
213 1 pfleura2
        Iat=I
214 1 pfleura2
        if (renum) Iat=orderInv(I)
215 1 pfleura2
        WRITE(*,'(1X,A10,3(1X,F15.8),A)') Trim(AtName(Iat)),GradCart(3*I-2:3*I)
216 1 pfleura2
     END DO
217 1 pfleura2
  END IF
218 1 pfleura2
219 1 pfleura2
!  If (PROG=="VASP") STOP
220 1 pfleura2
221 1 pfleura2
222 1 pfleura2
  ! We have the gradient in Cartesian coordinates... which is ok for COORD=Cart, Hybrid
223 1 pfleura2
  !  but we have to convert it into Zmat if COORD=Zmat
224 1 pfleura2
  SELECT CASE (COORD)
225 1 pfleura2
     CASE ("ZMAT")
226 1 pfleura2
        ALLOCATE(GradTmp(3*Nat))
227 1 pfleura2
        if (debug) WRITE(*,*) "DBG EGRAD Calling CalcBMat_int"
228 1 pfleura2
        CALL CalcBMat_int (nat, reshape(GeomCart,(/3,Nat/),ORDER=(/2,1/)), indzmat, dzdc, massat,atome)
229 1 pfleura2
230 1 pfleura2
        if (debug) WRITE(*,*) "DBG EGRAD Calling ConvGrad_Cart2Int"
231 1 pfleura2
        CALL ConvGrad_Cart2Int(Nat,dzdc,IndZmat,GradCart,GradTmp)
232 1 pfleura2
233 1 pfleura2
        if (debug) WRITE(*,*) "DBG EGRAD Storing Grad"
234 1 pfleura2
     Grad(1)=GradTmp(4)
235 1 pfleura2
     Grad(2)=GradTmp(7)
236 1 pfleura2
! We might have troubles whith angles that are not in the [0:pi] range because,
237 1 pfleura2
! when converted to catesian coord, they do appear in the [0:Pi] range to gaussian...
238 1 pfleura2
! so that the derivative is not good, and a multiplicative factor should be added...
239 1 pfleura2
!
240 1 pfleura2
! This in fact should be taken care of in B mat calculation...
241 1 pfleura2
!
242 1 pfleura2
     IF ((Geom(3).LE.0).OR.(Geom(3).GE.Pi)) THEN
243 1 pfleura2
        Grad(3)=-1.0d0*GradTmp(8)
244 1 pfleura2
     ELSE
245 1 pfleura2
        Grad(3)=GradTmp(8)
246 1 pfleura2
     END IF
247 1 pfleura2
     Idx=4
248 1 pfleura2
     DO I=4,Nat
249 1 pfleura2
        Grad(Idx)=GradTmp(3*i-2)
250 1 pfleura2
        Grad(Idx+1)=GradTmp(3*i-1)
251 1 pfleura2
        Grad(Idx+2)=GradTmp(3*i)
252 1 pfleura2
        Idx=Idx+3
253 1 pfleura2
     END DO
254 1 pfleura2
     DEALLOCATE(GradTmp)
255 1 pfleura2
   CASE ('BAKER')
256 1 pfleura2
     ! We have the gradient in Cartesian coordinates... which is ok for COORD=Cart, Hybrid
257 1 pfleura2
     ! but we have to convert it into internal coordinates if COORD=Baker
258 1 pfleura2
!!!!!!!!!!!!!!!!!!!!
259 1 pfleura2
     !
260 1 pfleura2
     !   PFL Debug
261 1 pfleura2
     !
262 1 pfleura2
!!!!!!!!!!!!!!!!!!!!
263 1 pfleura2
     if (debugPFL) THEN
264 1 pfleura2
        WRITE(*,*) "DBG PFL Egrad_Baker... computing dzdc"
265 1 pfleura2
     if (.not.ALLOCATED(indzmat)) THEN
266 1 pfleura2
        ALLOCATE(indzmat(Nat,5))
267 1 pfleura2
     IndZmat=0
268 1 pfleura2
     Indzmat(1,1)=1
269 1 pfleura2
     IndZmat(2,1)=2
270 1 pfleura2
     IndZmat(2,2)=1
271 1 pfleura2
     IndZmat(3,1)=3
272 1 pfleura2
     IndZmat(3,2)=2
273 1 pfleura2
     IndZmat(3,3)=1
274 1 pfleura2
     IndZmat(4,1)=4
275 1 pfleura2
     IndZmat(4,2)=3
276 1 pfleura2
     IndZmat(4,3)=2
277 1 pfleura2
     IndZmat(4,4)=1
278 1 pfleura2
     END IF
279 1 pfleura2
     IF (.NOT.ALLOCATED(DzDc)) THEN
280 1 pfleura2
        ALLOCATE(DzDc(3,nat,3,Nat))
281 1 pfleura2
     END IF
282 1 pfleura2
     if (.NOT.Allocated(GeomTmp)) Allocate(GeomTmp(3,Nat))
283 1 pfleura2
     DO I=1,Nat
284 1 pfleura2
     GeomTmp(1,I)=GeomCart(OrderInv(I),1)
285 1 pfleura2
     GeomTmp(2,I)=GeomCart(OrderInv(i),2)
286 1 pfleura2
     GeomTmp(3,I)=GeomCart(OrderInv(i),3)
287 1 pfleura2
     END DO
288 1 pfleura2
289 1 pfleura2
     DzDc=0.d0
290 1 pfleura2
     CALL CalcBMat_int (nat, GeomTmp, indzmat, dzdc, massat,atome)
291 1 pfleura2
292 1 pfleura2
     END IF ! if (debugPFL)
293 1 pfleura2
!!!!!!!!!!!!!!!!!!!!!!!!!
294 1 pfleura2
     ! Debugging PFL
295 1 pfleura2
!!!!!!!!!!!!!!!!!!!!!!!!
296 1 pfleura2
297 1 pfleura2
     WRITE(*,*) "BTransInv_local Trans that is used originally"
298 1 pfleura2
     DO J=1,3*Nat
299 1 pfleura2
        WRITE(*,'(50(1X,F12.8))') BTransInv_local(:,J)
300 1 pfleura2
     END DO
301 1 pfleura2
302 1 pfleura2
     WRITE(*,*) "Calculating actual values using GeomCart"
303 1 pfleura2
     if (.NOT.Allocated(GeomTmp)) Allocate(GeomTmp(3,Nat))
304 1 pfleura2
     GeomTmp(1,:)=GeomCart(1:Nat,1)
305 1 pfleura2
     GeomTmp(2,:)=GeomCart(1:Nat,2)
306 1 pfleura2
     GeomTmp(3,:)=GeomCart(1:Nat,3)
307 1 pfleura2
308 1 pfleura2
     ! Computing B^prim:
309 1 pfleura2
     FAloBBT=.NOT.ALLOCATED(BBT)
310 1 pfleura2
     FAloBBTInv=.NOT.ALLOCATED(BBT_inv)
311 1 pfleura2
     FAloBPrimT=.NOT.ALLOCATED(BprimT)
312 1 pfleura2
     if (FAloBPrimT) ALLOCATE(Bprimt(3*Nat,NPrim))
313 1 pfleura2
     if (FAloBBT) ALLOCATE(BBt(NCoord,NCoord))
314 1 pfleura2
     if (FAloBBTInv) ALLOCATE(BBt_inv(NCoord,NCoord))
315 1 pfleura2
     BprimT=0.d0
316 1 pfleura2
     ScanCoord=>Coordinate
317 1 pfleura2
     I=0
318 1 pfleura2
     DO WHILE (Associated(ScanCoord%next))
319 1 pfleura2
        I=I+1
320 1 pfleura2
        SELECT CASE (ScanCoord%Type)
321 1 pfleura2
        CASE ('BOND')
322 1 pfleura2
           CALL CONSTRAINTS_BONDLENGTH_DER(Nat,ScanCoord%at1,ScanCoord%AT2,GeomTmp,BprimT(1,I))
323 1 pfleura2
        CASE ('ANGLE')
324 1 pfleura2
           CALL CONSTRAINTS_BONDANGLE_DER(Nat,ScanCoord%At1,ScanCoord%AT2,ScanCoord%At3,GeomTmp,BprimT(1,I))
325 1 pfleura2
        CASE ('DIHEDRAL')
326 1 pfleura2
           CALL CONSTRAINTS_TORSION_DER2(Nat,ScanCoord%At1,ScanCoord%AT2,ScanCoord%At3,ScanCoord%At4,GeomTmp,BprimT(1,I))
327 1 pfleura2
        END SELECT
328 1 pfleura2
        ScanCoord => ScanCoord%next
329 1 pfleura2
     END DO
330 1 pfleura2
331 1 pfleura2
     if (debug) THEN
332 1 pfleura2
        WRITE(*,*) "Bprim "
333 1 pfleura2
        DO J=1,3*Nat
334 1 pfleura2
           WRITE(*,'(50(1X,F12.6))') BprimT(J,:)
335 1 pfleura2
        END DO
336 1 pfleura2
     END IF
337 1 pfleura2
338 1 pfleura2
     BMat_BakerT = 0.d0
339 1 pfleura2
     DO I=1,NCoord
340 1 pfleura2
        DO J=1,NPrim
341 1 pfleura2
           !BprimT is transpose of B^prim.
342 1 pfleura2
           !B = UMat^T B^prim, B^T = (B^prim)^T UMat
343 1 pfleura2
           BMat_BakerT(:,I)=BMat_BakerT(:,I)+BprimT(:,J)*UMat_local(J,I)
344 1 pfleura2
        END DO
345 1 pfleura2
     END DO
346 1 pfleura2
347 1 pfleura2
     BBT = 0.d0
348 1 pfleura2
     DO I=1,NCoord
349 1 pfleura2
        DO J=1,3*Nat   ! BBT(:,I) forms BB^T
350 1 pfleura2
           BBT(:,I) = BBT(:,I) + BMat_BakerT(J,:)*BMat_BakerT(J,I)
351 1 pfleura2
        END DO
352 1 pfleura2
     END DO
353 1 pfleura2
354 1 pfleura2
     BBT_inv = 0.d0
355 1 pfleura2
356 1 pfleura2
     Call GenInv(NCoord,BBT,BBT_inv,NCoord)
357 1 pfleura2
358 1 pfleura2
!     ALLOCATE(V(NCoord,NCoord))
359 1 pfleura2
!     tol = 1e-10
360 1 pfleura2
!     ! BBT is destroyed by GINVSE
361 1 pfleura2
!     Call GINVSE(BBT,NCoord,NCoord,BBT_inv,NCoord,NCoord,NCoord,tol,V,NCoord,FAIL,IOOUT)
362 1 pfleura2
!     DEALLOCATE(V)
363 1 pfleura2
!     IF(Fail) Then
364 1 pfleura2
!        WRITE (*,*) "Failed in generalized inverse, L220, ConvertBaker...f90"
365 1 pfleura2
!        STOP
366 1 pfleura2
!     END IF
367 1 pfleura2
368 1 pfleura2
     !Print *, 'BBT_inv='
369 1 pfleura2
     DO J=1,NCoord
370 1 pfleura2
        ! WRITE(*,'(50(1X,F10.2))') BBT_inv(:,J)
371 1 pfleura2
        ! Print *, BBT_inv(:,J)
372 1 pfleura2
     END DO
373 1 pfleura2
     !Print *, 'End of BBT_inv'
374 1 pfleura2
375 1 pfleura2
     ! Calculation of (B^T)^-1 = (BB^T)^-1B:
376 1 pfleura2
     BTransInv_local = 0.d0
377 1 pfleura2
     DO I=1,3*Nat
378 1 pfleura2
        DO J=1,NCoord
379 1 pfleura2
           BTransInv_local(:,I)=BTransInv_local(:,I)+BBT_inv(:,J)*BMat_BakerT(I,J)
380 1 pfleura2
        END DO
381 1 pfleura2
     END DO
382 1 pfleura2
383 1 pfleura2
     Print *, 'BMat_BakerT='
384 1 pfleura2
     DO J=1,3*Nat
385 1 pfleura2
        WRITE(*,'(50(1X,F12.8))') BMat_BakerT(:,J)
386 1 pfleura2
     END DO
387 1 pfleura2
388 1 pfleura2
     WRITE(*,*) "BTransInv_local Trans corresponding to GeomCart"
389 1 pfleura2
     DO J=1,3*Nat
390 1 pfleura2
        WRITE(*,'(50(1X,F12.8))') BTransInv_local(:,J)
391 1 pfleura2
     END DO
392 1 pfleura2
393 1 pfleura2
     if (FAloBPrimT) DEALLOCATE(Bprimt)
394 1 pfleura2
     if (FAloBBT) DEALLOCATE(BBt)
395 1 pfleura2
     if (FAloBBTInv) DEALLOCATE(BBt_inv)
396 1 pfleura2
397 1 pfleura2
     Grad=0.d0
398 1 pfleura2
     DO I=1, 3*Nat
399 1 pfleura2
        ! Here Grad is gradient in Baker coordinates. GradCart(3*Nat)
400 1 pfleura2
        Grad(:) = Grad(:) + BTransInv_local(:,I)*GradCart(I) !BTransInv_local = BTransInv in Opt_Geom.f90
401 1 pfleura2
     END DO
402 1 pfleura2
     !WRITE(*,*) 'In Egrad.f90, L263, Gradient:'
403 1 pfleura2
     !WRITE(*,'(12(1X,F8.4))') Grad(1:NCoord)
404 1 pfleura2
405 1 pfleura2
406 1 pfleura2
     CASE ('MIXED')
407 1 pfleura2
        ALLOCATE(GradTmp(3*Nat))
408 1 pfleura2
        if (debug) WRITE(*,*) "DBG EGRAD Calling CalcBMat_mixed"
409 1 pfleura2
        CALL CalcBMat_mixed (nat, reshape(GeomCart,(/3,Nat/),ORDER=(/2,1/)), indzmat, dzdc, massat,atome)
410 1 pfleura2
411 1 pfleura2
        if (Debug) THEN
412 1 pfleura2
           WRITE(*,*) "DzDc"
413 1 pfleura2
           DO I=1,Nat
414 1 pfleura2
              DO J=1,3
415 1 pfleura2
                 WRITE(*,'(50(1X,F12.6))') dzdc(J,I,:,:)
416 1 pfleura2
              END DO
417 1 pfleura2
           END DO
418 1 pfleura2
        END IF
419 1 pfleura2
420 1 pfleura2
421 1 pfleura2
        CALL ConvGrad_Cart2Int(Nat,dzdc,IndZmat,GradCart,GradTmp)
422 1 pfleura2
        DO I=1,Nat
423 1 pfleura2
           WRITE(*,'(1X,3(1X,F10.5))') GradTmp(3*I-2:3*I)
424 1 pfleura2
        END DO
425 1 pfleura2
        SELECT CASE (NCART)
426 1 pfleura2
           CASE (1)
427 1 pfleura2
              Grad(1:3)=GradTmp(1:3)
428 1 pfleura2
              Grad(4)=GradTmp(4)
429 1 pfleura2
              Grad(5)=GradTmp(7)
430 1 pfleura2
              Grad(6)=GradTmp(8)
431 1 pfleura2
              Idx=7
432 1 pfleura2
              IBeg=4
433 1 pfleura2
           CASE(2)
434 1 pfleura2
              Grad(1:3)=GradTmp(1:3)
435 1 pfleura2
              Grad(4:6)=GradTmp(4:6)
436 1 pfleura2
              Grad(7)=GradTmp(7)
437 1 pfleura2
              Grad(8)=GradTmp(8)
438 1 pfleura2
              Idx=9
439 1 pfleura2
              IBeg=4
440 1 pfleura2
            CASE DEFAULT
441 1 pfleura2
               Idx=1
442 1 pfleura2
               IBeg=1
443 1 pfleura2
            END SELECT
444 1 pfleura2
     DO I=IBeg,Nat
445 1 pfleura2
        Grad(Idx)=GradTmp(3*i-2)
446 1 pfleura2
        Grad(Idx+1)=GradTmp(3*i-1)
447 1 pfleura2
        Grad(Idx+2)=GradTmp(3*i)
448 1 pfleura2
        Idx=Idx+3
449 1 pfleura2
     END DO
450 1 pfleura2
     DEALLOCATE(GradTmp)
451 1 pfleura2
  CASE ("CART","HYBRID")
452 1 pfleura2
     Grad=GradCart
453 1 pfleura2
  CASE DEFAULT
454 1 pfleura2
     WRITE(*,*) "Coord=",AdjustL(Trim(COORD))," not yet implemented in Egradients. STOP"
455 1 pfleura2
     STOP
456 1 pfleura2
  END SELECT
457 1 pfleura2
458 1 pfleura2
  DEALLOCATE(GradCart)
459 1 pfleura2
  DEALLOCATE(x,y,z)
460 1 pfleura2
461 1 pfleura2
  IF (Debug) WRITE(*,*) 'DBG EGRAD grad',grad(1:NCoord)
462 1 pfleura2
  if (debug) Call Header("Egrad Over")
463 1 pfleura2
464 1 pfleura2
  !999 CONTINUE
465 1 pfleura2
  !if (.NOT.Ftmp) WRITE(*,*) 'We should not be here !!!!'
466 1 pfleura2
  !STOP
467 1 pfleura2
  ! ======================================================================
468 1 pfleura2
end subroutine Egrad