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 |