Statistiques
| Révision :

root / src / Egrad.f90 @ 7

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

1 1 equemene
subroutine Egrad(E,Geom,Grad,NCoord,IGeom,IOpt,GeomCart)
2 1 equemene
3 1 equemene
  ! This routines calculates the energy E and the gradient Grad of
4 1 equemene
  ! a molecule with Geometry Geom (may be in internal coordinates),
5 1 equemene
  ! using for now, either gaussian or Ext, more general later.
6 1 equemene
7 1 equemene
  use Path_module, only : Nat,AtName,Coord,dzdc,indzmat,Nom,Atome,massat,unit, &
8 1 equemene
                          prog,NCart,XyzGeomF,IntCoordF,XyzGeomI, renum, OrderInv
9 4 pfleura2
              ! IntCoordF(NGeomF,NCoord),GeomOld_all(NGeomF,NCoord)
10 4 pfleura2
              ! allocated in Path.f90
11 1 equemene
  use Io_module
12 1 equemene
  IMPLICIT NONE
13 1 equemene
14 1 equemene
  ! Energy (calculated if F300K=.F., else estimated)
15 1 equemene
  REAL(KREAL), INTENT (OUT) :: E
16 1 equemene
  ! NCoord: Number of the degrees of freedom
17 1 equemene
  ! IGeom: index of the geometry.
18 1 equemene
  INTEGER(KINT), INTENT (IN) :: NCoord, IGeom, IOpt
19 1 equemene
  ! Geometry at which gradient is calculated (cf Factual also):
20 1 equemene
  REAL(KREAL), INTENT (INOUT) :: Geom(NCoord)
21 1 equemene
  ! Gradient calculated at Geom geometry:
22 1 equemene
  REAL(KREAL), INTENT (OUT) :: Grad(NCoord)
23 1 equemene
  ! Cartesian geometry corresponding to (Internal Geometry) Geom:
24 1 equemene
  REAL(KREAL), INTENT (OUT) :: GeomCart(Nat,3)
25 1 equemene
26 1 equemene
  ! ======================================================================
27 1 equemene
28 1 equemene
  CHARACTER(LCHARS) :: LINE
29 1 equemene
  LOGICAL :: debug
30 1 equemene
  LOGICAL, SAVE :: first=.true.
31 1 equemene
  REAL(KREAL), SAVE :: Eold=1.e6
32 1 equemene
  REAL(KREAL), ALLOCATABLE :: GradTmp(:)
33 1 equemene
  REAL(KREAL), ALLOCATABLE :: GradCart(:)
34 1 equemene
  REAL(KREAL), ALLOCATABLE :: x(:), y(:), z(:)
35 1 equemene
  REAL(KREAL) :: d, a_val, Pi
36 1 equemene
37 1 equemene
  INTEGER(KINT) :: iat,jat,kat,i,j,IBeg,Idx
38 1 equemene
  INTEGER(KINT), PARAMETER :: IOLOG=12, IOCOM=11
39 1 equemene
40 1 equemene
  CHARACTER(LCHARS) :: ListName, CH32SVAR1
41 1 equemene
  CHARACTER(VLCHARS), SAVE :: RstrtCopy, RunCommand
42 1 equemene
  LOGICAL, SAVE :: FCopyRstrt=.False., FOrderChecked=.False.
43 1 equemene
  LOGICAL   :: FTmp
44 1 equemene
  INTEGER(kint) :: NbLists,NStep
45 1 equemene
  INTEGER(KINT), PARAMETER :: NbExtName=4
46 1 equemene
47 1 equemene
48 1 equemene
  ! ======================================================================
49 1 equemene
  INTERFACE
50 1 equemene
     function valid(string) result (isValid)
51 1 equemene
       CHARACTER(*), intent(in) :: string
52 1 equemene
       logical                  :: isValid
53 1 equemene
     END function VALID
54 1 equemene
  END INTERFACE
55 1 equemene
  ! ======================================================================
56 1 equemene
57 1 equemene
  INTEGER(KINT) :: OptGeom
58 1 equemene
  Namelist/path/OptGeom
59 1 equemene
60 1 equemene
  Pi=dacos(-1.0d0)
61 1 equemene
62 1 equemene
  debug=valid('EGRAD')
63 1 equemene
  if (debug) Call header("Entering Egrad")
64 1 equemene
65 1 equemene
  Print *, 'EGrad.f90, L73, IOpt=', IOpt
66 1 equemene
67 1 equemene
  Grad=0.
68 1 equemene
  E=0.
69 1 equemene
70 1 equemene
  ALLOCATE(GradCart(3*Nat))
71 1 equemene
  ALLOCATE(x(Nat),y(Nat),z(Nat))
72 1 equemene
  SELECT CASE (COORD)
73 1 equemene
  CASE ('ZMAT')
74 1 equemene
     ! In order to avoid problem with numbering and linear angles/diehedral, we convert the
75 1 equemene
     ! zmat into cartesian coordinates
76 1 equemene
     ! A remplacer par Int2Cart :-)
77 1 equemene
     Call Int2Cart(nat,indzmat,Geom,GeomCart)
78 1 equemene
  CASE ('BAKER')
79 1 equemene
     WRITE (*,*) "Coord=",TRIM(COORD),": use Egrad_baker.f90, instead of Egrad.f90. Stop"
80 1 equemene
  CASE ('MIXED')
81 1 equemene
!  write(*,*) "Coucou 4-mixed"
82 1 equemene
     Call Mixed2Cart(Nat,indzmat,geom,GeomCart)
83 1 equemene
  CASE ('CART')
84 1 equemene
!  write(*,*) "Coucou 4-cart"
85 1 equemene
     if (debug) WRITE(*,*) "Coord=CART... in egrad"
86 1 equemene
     GeomCart=reshape(Geom,(/Nat,3/))
87 1 equemene
     DO Iat=1,Nat
88 1 equemene
        WRITE(IOTMP,'(1X,A10,3(1X,F15.8),A)') Trim(AtName(Iat)),Geom(3*Iat-2:3*Iat)
89 1 equemene
     END DO
90 1 equemene
  CASE ('HYBRID')
91 1 equemene
!  write(*,*) "Coucou 4-hybrid"
92 1 equemene
        GeomCart=reshape(Geom,(/Nat,3/))
93 1 equemene
  CASE DEFAULT
94 1 equemene
   WRITE (*,*) "Coord=",TRIM(COORD)," not recognized. Stop"
95 1 equemene
   STOP
96 1 equemene
  END SELECT
97 1 equemene
98 1 equemene
  SELECT CASE (Prog)
99 1 equemene
     CASE ('GAUSSIAN')
100 1 equemene
! we call the Gaussian routine.
101 1 equemene
! it will return the energy and the gradient in cartesian coordinates.
102 1 equemene
! Gradient calculated at GeomCart geometry and stored in GradCart, which has INTENT(OUT)
103 1 equemene
        Call egrad_gaussian(E,GeomCart,GradCart)
104 1 equemene
     CASE ('MOPAC')
105 1 equemene
! we call the Mopac routine.
106 1 equemene
! it will return the energy and the gradient in cartesian coordinates.
107 1 equemene
! Gradient calculated at GeomCart geometry and stored in GradCart, which has INTENT(OUT)
108 1 equemene
        Call egrad_mopac(E,GeomCart,GradCart)
109 1 equemene
     CASE ('VASP')
110 1 equemene
        Call egrad_vasp(E,Geomcart,GradCart)
111 1 equemene
     CASE ('TURBOMOLE')
112 1 equemene
        Call egrad_turbomole(E,Geomcart,GradCart)
113 1 equemene
     CASE ('EXT')
114 1 equemene
        Call egrad_ext(E,Geomcart,GradCart)
115 1 equemene
     CASE ('TEST')
116 1 equemene
        Call egrad_test(Nat,E,Geomcart,GradCart)
117 1 equemene
     CASE ('CHAMFRE')
118 1 equemene
        Call egrad_chamfre(Nat,E,Geomcart,GradCart)
119 1 equemene
  END SELECT
120 1 equemene
  if (debug) THEN
121 1 equemene
     WRITE(*,*) 'DBG EGRAD, GradCart read'
122 1 equemene
     DO I=1,Nat
123 1 equemene
        Iat=I
124 1 equemene
        if (renum) Iat=orderInv(I)
125 1 equemene
        WRITE(*,'(1X,A10,3(1X,F15.8),A)') Trim(AtName(Iat)),GradCart(3*I-2:3*I)
126 1 equemene
     END DO
127 1 equemene
  END IF
128 1 equemene
129 1 equemene
!  If (PROG=="VASP") STOP
130 1 equemene
131 1 equemene
  ! We have the gradient in Cartesian coordinates... which is ok for COORD=Cart, Hybrid
132 1 equemene
  !  but we have to convert it into Zmat if COORD=Zmat
133 1 equemene
  SELECT CASE (COORD)
134 1 equemene
     CASE ("ZMAT")
135 1 equemene
        ALLOCATE(GradTmp(3*Nat))
136 1 equemene
        if (debug) WRITE(*,*) "DBG EGRAD Calling CalcBMat_int"
137 1 equemene
        CALL CalcBMat_int (nat, reshape(GeomCart,(/3,Nat/),ORDER=(/2,1/)), indzmat, dzdc, massat,atome)
138 1 equemene
139 1 equemene
        if (debug) WRITE(*,*) "DBG EGRAD Calling ConvGrad_Cart2Int"
140 1 equemene
        CALL ConvGrad_Cart2Int(Nat,dzdc,IndZmat,GradCart,GradTmp)
141 1 equemene
142 1 equemene
        if (debug) WRITE(*,*) "DBG EGRAD Storing Grad"
143 1 equemene
     Grad(1)=GradTmp(4)
144 1 equemene
     Grad(2)=GradTmp(7)
145 1 equemene
! We might have troubles whith angles that are not in the [0:pi] range because,
146 1 equemene
! when converted to catesian coord, they do appear in the [0:Pi] range to gaussian...
147 1 equemene
! so that the derivative is not good, and a multiplicative factor should be added...
148 1 equemene
!
149 1 equemene
! This in fact should be taken care of in B mat calculation...
150 1 equemene
!
151 1 equemene
     IF ((Geom(3).LE.0).OR.(Geom(3).GE.Pi)) THEN
152 1 equemene
        Grad(3)=-1.0d0*GradTmp(8)
153 1 equemene
     ELSE
154 1 equemene
        Grad(3)=GradTmp(8)
155 1 equemene
     END IF
156 1 equemene
     Idx=4
157 1 equemene
     DO I=4,Nat
158 1 equemene
        Grad(Idx)=GradTmp(3*i-2)
159 1 equemene
        Grad(Idx+1)=GradTmp(3*i-1)
160 1 equemene
        Grad(Idx+2)=GradTmp(3*i)
161 1 equemene
        Idx=Idx+3
162 1 equemene
     END DO
163 1 equemene
     DEALLOCATE(GradTmp)
164 4 pfleura2
   CASE ('BAKER')
165 1 equemene
        WRITE (*,*) "Coord=",TRIM(COORD),": use Egrad_baker.f90, instead of Egrad.f90. Stop"
166 1 equemene
     CASE ('MIXED')
167 1 equemene
        ALLOCATE(GradTmp(3*Nat))
168 1 equemene
        if (debug) WRITE(*,*) "DBG EGRAD Calling CalcBMat_mixed"
169 1 equemene
        CALL CalcBMat_mixed (nat, reshape(GeomCart,(/3,Nat/),ORDER=(/2,1/)), indzmat, dzdc, massat,atome)
170 1 equemene
171 1 equemene
        if (Debug) THEN
172 1 equemene
           WRITE(*,*) "DzDc"
173 1 equemene
           DO I=1,Nat
174 1 equemene
              DO J=1,3
175 1 equemene
                 WRITE(*,'(50(1X,F12.6))') dzdc(J,I,:,:)
176 1 equemene
              END DO
177 1 equemene
           END DO
178 1 equemene
        END IF
179 1 equemene
180 1 equemene
181 1 equemene
        CALL ConvGrad_Cart2Int(Nat,dzdc,IndZmat,GradCart,GradTmp)
182 1 equemene
        DO I=1,Nat
183 1 equemene
           WRITE(*,'(1X,3(1X,F10.5))') GradTmp(3*I-2:3*I)
184 1 equemene
        END DO
185 1 equemene
        SELECT CASE (NCART)
186 1 equemene
           CASE (1)
187 1 equemene
              Grad(1:3)=GradTmp(1:3)
188 1 equemene
              Grad(4)=GradTmp(4)
189 1 equemene
              Grad(5)=GradTmp(7)
190 1 equemene
              Grad(6)=GradTmp(8)
191 1 equemene
              Idx=7
192 1 equemene
              IBeg=4
193 1 equemene
           CASE(2)
194 1 equemene
              Grad(1:3)=GradTmp(1:3)
195 1 equemene
              Grad(4:6)=GradTmp(4:6)
196 1 equemene
              Grad(7)=GradTmp(7)
197 1 equemene
              Grad(8)=GradTmp(8)
198 1 equemene
              Idx=9
199 1 equemene
              IBeg=4
200 1 equemene
            CASE DEFAULT
201 1 equemene
               Idx=1
202 1 equemene
               IBeg=1
203 1 equemene
            END SELECT
204 1 equemene
     DO I=IBeg,Nat
205 1 equemene
        Grad(Idx)=GradTmp(3*i-2)
206 1 equemene
        Grad(Idx+1)=GradTmp(3*i-1)
207 1 equemene
        Grad(Idx+2)=GradTmp(3*i)
208 1 equemene
        Idx=Idx+3
209 1 equemene
     END DO
210 1 equemene
     DEALLOCATE(GradTmp)
211 1 equemene
  CASE ("CART","HYBRID")
212 1 equemene
     Grad=GradCart
213 1 equemene
  CASE DEFAULT
214 1 equemene
     WRITE(*,*) "Coord=",AdjustL(Trim(COORD))," not yet implemented in Egradients. STOP"
215 1 equemene
     STOP
216 1 equemene
  END SELECT
217 1 equemene
218 1 equemene
  DEALLOCATE(GradCart)
219 1 equemene
  DEALLOCATE(x,y,z)
220 1 equemene
221 1 equemene
  IF (Debug) WRITE(*,*) 'DBG EGRAD grad',grad(1:NCoord)
222 1 equemene
  if (debug) Call Header("Egrad Over")
223 1 equemene
224 1 equemene
  !999 CONTINUE
225 1 equemene
  !if (.NOT.Ftmp) WRITE(*,*) 'We should not be here !!!!'
226 1 equemene
  !STOP
227 1 equemene
  ! ======================================================================
228 1 equemene
end subroutine Egrad