Statistiques
| Révision :

root / src / egrad_gaussian.f90 @ 4

Historique | Voir | Annoter | Télécharger (6,63 ko)

1 1 equemene
subroutine egrad_gaussian(e,geomcart,gradcart)
2 1 equemene
3 1 equemene
  ! This routines calculates the energy and the gradient of
4 1 equemene
  ! a molecule, using Gaussian
5 1 equemene
6 1 equemene
  use Path_module, only : Nat, renum,Order,OrderInv,AtName, Coord, dzdc, indzmat,Nom,Atome, massat, unit,ProgExe
7 1 equemene
  use Io_module
8 1 equemene
9 1 equemene
  IMPLICIT NONE
10 1 equemene
11 1 equemene
  ! Energy (calculated if F300K=.F., else estimated)
12 1 equemene
  REAL(KREAL), INTENT (OUT) :: e
13 1 equemene
  ! Nb degree of freedom
14 1 equemene
  REAL(KREAL), INTENT (IN) :: geomcart(Nat,3)
15 1 equemene
  ! Gradient calculated at Geom geometry
16 1 equemene
  REAL(KREAL), INTENT (OUT) :: gradcart(3*NAt)
17 1 equemene
18 1 equemene
  ! ======================================================================
19 1 equemene
20 1 equemene
  character(LCHARS) :: LINE
21 1 equemene
22 1 equemene
  logical           :: debug, G03Ok
23 1 equemene
  LOGICAL :: fexist, FSim
24 1 equemene
  LOGICAL, SAVE :: first=.true.
25 1 equemene
  LOGICAL, ALLOCATABLE :: Done(:)
26 1 equemene
27 1 equemene
  REAL(KREAL), SAVE :: Eold=1.e6
28 1 equemene
  REAL(KREAL), ALLOCATABLE :: GradTmp(:)
29 1 equemene
30 1 equemene
  REAL(KREAL) :: d, a_val, Pi
31 1 equemene
32 1 equemene
  REAL(KREAL) :: coef,x
33 1 equemene
  INTEGER(KINT) :: ItG03
34 1 equemene
  INTEGER(KINT) :: iat, jat, kat, i, j, n3at, absidg, absidg2
35 1 equemene
  INTEGER(KINT) :: kTmp, Istart,ITmp1,ITmp2, Idx
36 1 equemene
  INTEGER(KINT), PARAMETER :: IOLOG=12, IOCOM=11
37 1 equemene
38 1 equemene
  CHARACTER(132) :: FileIn, FileOut, FileChk
39 1 equemene
40 1 equemene
  CHARACTER(3) :: SepIn=' < ', SepOut=' > '
41 1 equemene
  CHARACTER(LCHARS) :: ListName, TitleTmp, CH32SVAR1
42 1 equemene
  CHARACTER(VLCHARS), SAVE :: RstrtCopy, RunCommand
43 1 equemene
  LOGICAL, SAVE :: FCopyRstrt=.False., FOrderChecked=.False.
44 1 equemene
  LOGICAL   :: FRdyn,FStopNucl, FTmp, Tchk,Tchk1
45 1 equemene
  INTEGER(kint) :: NbLists,LastIt,Nat4,NStep, Firstit
46 1 equemene
  INTEGER(KINT) :: NStepAd,NStepTmp
47 1 equemene
  INTEGER(KINT) :: IShowTmp
48 1 equemene
  REAL(KREAL)   :: FricPsiMin,FricPsiT, FricNuclTmp
49 1 equemene
50 1 equemene
  INTEGER(KINT), PARAMETER :: NbExtName=4
51 1 equemene
52 1 equemene
  INTEGER(KINT) :: ICouc
53 1 equemene
54 1 equemene
  INTEGER(KINT) :: ILine
55 1 equemene
  INTEGER(KINT) :: NPulses, PulseLen, NStepWarm,NStepAv,NStepEq,NStepTot
56 1 equemene
  REAL(KREAL) :: TempWarm,Mean,Slope,Dev,RTmp1,RTmp2
57 1 equemene
58 1 equemene
  ! ======================================================================
59 1 equemene
60 1 equemene
  LOGICAL, EXTERNAL :: valid
61 1 equemene
62 1 equemene
  ! ======================================================================
63 1 equemene
64 1 equemene
  Pi=dacos(-1.0d0)
65 1 equemene
  n3at=3*nat
66 1 equemene
67 1 equemene
  debug=valid('EGRAD')
68 1 equemene
  if (debug) Call Header("Entering Egrad_gaussian")
69 1 equemene
70 1 equemene
  if (first) THEN
71 1 equemene
     First=.FALSE.
72 1 equemene
     call system("uname > Path.tmp")
73 1 equemene
     OPEN(IOTMP,FILE='Path.tmp')
74 1 equemene
     READ(IOTMP,'(A)') Line
75 1 equemene
     CLOSE(IOTMP)
76 1 equemene
     IF (index(Line,'CYGWIN').NE.0) THEN
77 1 equemene
        SepIn='   '
78 1 equemene
        SepOut='   '
79 1 equemene
     END IF
80 1 equemene
  END IF
81 1 equemene
82 1 equemene
  gradcart=0.
83 1 equemene
  E=0.
84 1 equemene
  FileIn=Trim(CalcName) // "." // Trim(ISuffix)
85 1 equemene
  FileOut=Trim(CalcName) // "." // Trim(OSuffix)
86 1 equemene
  FileChk=Trim(CalcName) // ".chk"
87 1 equemene
  RunCommand=Trim(ProgExe) // SepIn // Trim(FileIn) // SepOut // Trim(FileOut)
88 1 equemene
89 1 equemene
  IF (DEBUG) WRITE(*,*)'RunCommand:',TRIM(RunCommand)
90 1 equemene
91 1 equemene
  ! we create the input file
92 1 equemene
93 1 equemene
  OPEN(IOTMP,File=FileIn)
94 1 equemene
95 1 equemene
  Current => Gauss_root
96 1 equemene
  DO WHILE (ASSOCIATED(Current%next))
97 1 equemene
     WRITE(IOTMP,'(1X,A)') Trim(current%line)
98 1 equemene
     WRITE(*,'(1X,A)') Trim(current%line)
99 1 equemene
     Current => current%next
100 1 equemene
  END DO
101 1 equemene
102 1 equemene
  WRITE(IOTMP,*)
103 1 equemene
104 1 equemene
  Current => Gauss_comment
105 1 equemene
  DO WHILE (ASSOCIATED(Current%next))
106 1 equemene
     WRITE(IOTMP,'(1X,A)') Trim(current%line)
107 1 equemene
     Current => current%next
108 1 equemene
  END DO
109 1 equemene
  !  WRITE(IOOUT,"('Geometry ',I3,'/',I3,' for iteration ',I3)"),Igeom,NgeomF,Iopt
110 1 equemene
111 1 equemene
  WRITE(IOTMP,*)
112 1 equemene
  WRITE(IOTMP,*) Trim(Gauss_charge)
113 1 equemene
114 1 equemene
  DO I=1,Nat
115 1 equemene
     If (renum) THEN
116 1 equemene
        Iat=Order(I)
117 1 equemene
        WRITE(IOTMP,'(1X,A10,3(1X,F15.8),A)') Trim(AtName(I)),GeomCart(Iat,:), TRIM(Gauss_Paste(I))
118 1 equemene
     ELSE
119 1 equemene
        Iat=OrderInv(I)
120 1 equemene
        WRITE(IOTMP,'(1X,A10,3(1X,F15.8),A)') Trim(AtName(Iat)),GeomCart(I,:), TRIM(Gauss_Paste(Iat))
121 1 equemene
     END IF
122 1 equemene
  END DO
123 1 equemene
124 1 equemene
  WRITE(IOTMP,*)
125 1 equemene
126 1 equemene
  Current => Gauss_End
127 1 equemene
  DO WHILE (ASSOCIATED(Current%next))
128 1 equemene
     WRITE(IOTMP,'(1X,A)') Trim(current%line)
129 1 equemene
     Current => current%next
130 1 equemene
  END DO
131 1 equemene
132 1 equemene
  WRITE(IOTMP,*)
133 1 equemene
  CLOSE(IOTMP)
134 1 equemene
135 1 equemene
  IF (debug) THEN
136 1 equemene
     WRITE(*,*) 'DBG EGRAD ' //  Trim(FileIn),' COORD=',TRIM(COORD)
137 1 equemene
     call system('cat ' // Trim(FileIn))
138 1 equemene
  END IF
139 1 equemene
140 1 equemene
!!! PFL 15th March 2008 ->
141 1 equemene
! Sometimes for unknown reasons G03 fails.
142 1 equemene
! We thus add one test to check that Gaussian has finisehd properly.
143 1 equemene
! We also check that we do not run an infinite loop...
144 1 equemene
145 1 equemene
 G03Ok=.FALSE.
146 1 equemene
 ItG03=0
147 1 equemene
148 1 equemene
  DO WHILE ((.NOT.G03Ok).AND.(ItG03<3))
149 1 equemene
   ItG03=ItG03+1
150 1 equemene
  call system(RunCommand)
151 1 equemene
 OPEN(IOTMP,FILE=FileOut, STATUS='old', POSITION='APPEND')
152 1 equemene
 BACKSPACE(IOTMP)
153 1 equemene
 READ(IOTMP,'(A)') Line
154 1 equemene
 IF (LINE(2:19).EQ.'Normal termination')  G03Ok=.TRUE.
155 1 equemene
  END DO
156 1 equemene
  CLOSE(IOTMP)
157 1 equemene
  IF (.NOT.G03Ok) THEN
158 1 equemene
     WRITE(*,*) "Egrad_gaussian Failed..."
159 1 equemene
     WRITE(*,*) "Wrong termination of Gaussian after 3 tries. Check Input and geometry"
160 1 equemene
     STOP
161 1 equemene
  END IF
162 1 equemene
163 1 equemene
  if (debug) WRITE(*,*) 'DBG EGRAD, back from calculation'
164 1 equemene
165 1 equemene
  ! Whatever the coordinate system, we read the cartesian gradient
166 1 equemene
  ! and we convert it to Zmat or other if needed
167 1 equemene
168 1 equemene
  OPEN(IOTMP,FILE=FileOut, STATUS='old')
169 1 equemene
  ! We first search for the forces
170 1 equemene
  READ(IOTMP,'(A)') LINE
171 1 equemene
  DO WHILE (INDEX(LINE,'Forces (Hartrees/Bohr)')==0)
172 1 equemene
     ! here, we have a problem, because there are so many ways to write E for Gaussian :-)
173 1 equemene
     ! but we do not really need E except if we want to weight the different points
174 1 equemene
     ! on the path... that will be done later :-)
175 1 equemene
     ! And I should use ConvGaussXmol ...
176 1 equemene
! PFL 3rd Jan 2008 ->
177 1 equemene
! I have finally upgraded the energy reading phase so that it should be able to read
178 1 equemene
! many formats corresponding to HF, DFT, MP2, AM1, PM3, ONIOM with or w/o PCM
179 1 equemene
180 1 equemene
! For MP2, energy is after the last =
181 1 equemene
     IF ((Line(2:9)=="E2 =    ")) THEN
182 4 pfleura2
      Itmp1=Index(LINE,"=",BACK=.TRUE.)+1
183 4 pfleura2
    READ(LINE(Itmp1:),*) e
184 1 equemene
      END IF
185 1 equemene
! For other methods, it is after the first =
186 1 equemene
     IF ((LINE(2:9)=='Energy= ').OR.(Line(2:9)=="SCF Done").OR.(Line(2:9)=="ONIOM: e") &
187 4 pfleura2
   .OR.(Line(2:9)==" with al") &
188 1 equemene
         .OR.(Line(2:31)=="Counterpoise: corrected energy")) THEN
189 4 pfleura2
      Itmp1=Index(LINE,"=")+1
190 4 pfleura2
    READ(LINE(Itmp1:),*) e
191 4 pfleura2
  END IF
192 1 equemene
! <- PFL 3 Jan 2008
193 1 equemene
     READ(IOTMP,'(A)') LINE
194 1 equemene
  END DO
195 1 equemene
  if (debug) WRITE(*,*) "GradCart reading - renum=",Renum
196 1 equemene
  READ(IOTMP,'(A)') LINE
197 1 equemene
  READ(IOTMP,'(A)') LINE
198 1 equemene
  DO I=1,Nat
199 1 equemene
     Iat=I
200 1 equemene
     IF (renum) Iat=Order(I)
201 1 equemene
     READ(IOTMP,*)  Itmp1,ITmp2, GradCart(3*Iat-2:3*Iat)
202 1 equemene
     if (debug) WRITE(*,*) "I,Iat,GradCart:",I,Iat,GradCart(3*Iat-2:3*Iat)
203 1 equemene
  END DO
204 1 equemene
205 1 equemene
! Gaussian gives the Forces in ua/a0, so we convert it into the
206 1 equemene
! gradient in ua/Angstrom
207 1 equemene
  gradCart=-1.0d0*gradCart*Unit
208 1 equemene
209 1 equemene
!  if (debug.AND.(COORD.EQ.'ZMAT')) THEN
210 1 equemene
!     DO WHILE (INDEX(LINE,'Internal Coordinate Forces')==0)
211 1 equemene
!        READ(IOTMP,'(A)') LINE
212 1 equemene
!!        WRITE(*,*) 'Pas bon:' // TRIM(LINE)
213 1 equemene
!     END DO
214 1 equemene
!     WRITE(*,*) TRIM(LINE)
215 1 equemene
!     DO I=1,Nat+2
216 1 equemene
!        READ(IOTMP,'(A)') LINE
217 1 equemene
!        WRITE(*,*) TRIM(LINE)
218 1 equemene
!     END DO
219 1 equemene
!  END IF
220 1 equemene
221 1 equemene
  CLOSE(IOTMP)
222 1 equemene
223 1 equemene
  if (debug) Call header("Egrad_gaussian Over")
224 1 equemene
225 1 equemene
  RETURN
226 1 equemene
227 1 equemene
999 CONTINUE
228 1 equemene
  if (.NOT.Ftmp) WRITE(*,*) 'We should not be here !!!!'
229 1 equemene
  STOP
230 1 equemene
  ! ======================================================================
231 1 equemene
end subroutine egrad_gaussian