-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathderiv.f
274 lines (274 loc) · 9.35 KB
/
deriv.f
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
SUBROUTINE DERIV(GEO,GRAD)
IMPLICIT DOUBLE PRECISION (A-H,O-Z)
INCLUDE 'SIZES'
DIMENSION GRAD(*), GEO(3,*)
************************************************************************
*
* DERIV CALCULATES THE DERIVATIVES OF THE ENERGY WITH RESPECT TO THE
* INTERNAL COORDINATES. THIS IS DONE BY FINITE DIFFERENCES.
*
* THE MAIN ARRAYS IN DERIV ARE:
* LOC INTEGER ARRAY, LOC(1,I) CONTAINS THE ADDRESS OF THE ATOM
* INTERNAL COORDINATE LOC(2,I) IS TO BE USED IN THE
* DERIVATIVE CALCULATION.
* GEO ARRAY \GEO\ HOLDS THE INTERNAL COORDINATES.
* GRAD ON EXIT, CONTAINS THE DERIVATIVES
*
************************************************************************
COMMON / EULER/ TVEC(3,3), ID
COMMON /OKMANY/ ISOK
COMMON /GEOVAR/ NVAR,LOC(2,MAXPAR), IDUMY, DUMMY(MAXPAR)
COMMON /MOLKST/ NUMAT,NAT(NUMATM),NFIRST(NUMATM),NMIDLE(NUMATM),
1 NLAST(NUMATM), NORBS, NELECS,NALPHA,NBETA,
2 NCLOSE,NOPEN,NDUMY,FRACT
COMMON /GEOKST/ NATOMS,LABELS(NUMATM),
1NA(NUMATM),NB(NUMATM),NC(NUMATM)
COMMON /GRAVEC/ COSINE
COMMON /GEOSYM/ NDEP, LOCPAR(MAXPAR), IDEPFN(MAXPAR),
1LOCDEP(MAXPAR)
COMMON /PATH / LATOM,LPARAM,REACT(200)
COMMON /UCELL / L1L,L2L,L3L,L1U,L2U,L3U
COMMON /XYZGRA/ DXYZ(9*NUMATM)
COMMON /ENUCLR/ ENUCLR
COMMON /NUMCAL/ NUMCAL
COMMON /HMATRX/ H(MPACK)
COMMON /ATHEAT/ ATHEAT
COMMON /KEYWRD/ KEYWRD
COMMON /ERRFN / ERRFN(MAXPAR), AICORR(MAXPAR)
COMMON /WORK3 / WORK2(4*MPACK)
COMMON /GENRAL/ COORD(3,NUMATM), COLD(3,NUMATM*3), GOLD(MAXPAR),
1 XPARAM(MAXPAR)
CHARACTER*241 KEYWRD, LINE*80, GETNAM*80
DIMENSION CHANGE(3), XJUC(3), AIDREF(MAXPAR)
SAVE SCF1, HALFE, IDELTA, SLOW
LOGICAL DEBUG, HALFE, SCF1, CI, PRECIS, SLOW, AIC, NOANCI,
1AIFRST, ISOK, GEOOK, INT
DATA ICALCN /0/
IF(ICALCN.NE.NUMCAL) THEN
AIFRST= (INDEX(KEYWRD,'RESTART').EQ.0)
DEBUG = (INDEX(KEYWRD,'DERIV') .NE. 0)
PRECIS= (INDEX(KEYWRD,'PREC') .NE. 0)
INT = (INDEX(KEYWRD,' XYZ') .EQ. 0)
GEOOK = (INDEX(KEYWRD,'GEO-OK') .NE. 0)
CI = (INDEX(KEYWRD,'C.I.') .NE. 0)
SCF1 = (INDEX(KEYWRD,'1SCF') .NE. 0)
AIC=(INDEX(KEYWRD,'AIDER').NE.0)
ICAPA=ICHAR('A')
ILOWA=ICHAR('a')
ILOWZ=ICHAR('z')
IF(AIC.AND.AIFRST)THEN
OPEN(UNIT=5,FILE=GETNAM('FOR005'),STATUS='OLD',BLANK='ZERO')
REWIND 5
C
C ISOK IS SET FALSE: ONLY ONE SYSTEM ALLOWED
C
ISOK=.FALSE.
DO 10 I=1,3
10 READ(5,'(A)')LINE
DO 30 J=1,1000
READ(5,'(A)',END=40,ERR=40)LINE
************************************************************************
DO 20 I=1,80
ILINE=ICHAR(LINE(I:I))
IF(ILINE.GE.ILOWA.AND.ILINE.LE.ILOWZ) THEN
LINE(I:I)=CHAR(ILINE+ICAPA-ILOWA)
ENDIF
20 CONTINUE
************************************************************************
30 IF(INDEX(LINE,'AIDER').NE.0)GOTO 60
40 WRITE(6,'(//,A)')' KEYWORD "AIDER" SPECIFIED, BUT NOT'
WRITE(6,'(A)')' PRESENT AFTER Z-MATRIX. JOB STOPPED'
STOP
50 WRITE(6,'(//,A)')' FAULT IN READ OF AB INITIO DERIVATIVES'
WRITE(6,'(A)')' DERIVATIVES READ IN ARE AS FOLLOWS'
WRITE(6,'(6F12.6)')(AIDREF(J),J=1,I)
STOP
60 CONTINUE
IF(NATOMS.GT.2)THEN
J=3*NATOMS-6
ELSE
J=1
ENDIF
READ(5,*,END=50,ERR=50)(AIDREF(I),I=1,J)
WRITE(6,'(/,A,/)')
1' AB-INITIO DERIVATIVES IN KCAL/MOL/(ANGSTROM OR RADIAN)'
WRITE(6,'(5F12.6)')(AIDREF(I),I=1,J)
DO 70 I=1,NVAR
IF(LOC(1,I).GT.3)THEN
J=3*LOC(1,I)+LOC(2,I)-9
ELSEIF(LOC(1,I).EQ.3)THEN
J=LOC(2,I)+1
ELSE
J=1
ENDIF
70 AIDREF(I)=AIDREF(J)
WRITE(6,'(/,A,/)')
1' AB-INITIO DERIVATIVES FOR VARIABLES'
WRITE(6,'(5F12.6)')(AIDREF(I),I=1,NVAR)
IF(NDEP.NE.0)THEN
DO 90 I=1,NVAR
SUM=AIDREF(I)
DO 80 J=1,NDEP
IF(LOC(1,I).EQ.LOCPAR(J).AND.(LOC(2,I).EQ.IDEPFN(J)
1.OR.LOC(2,I).EQ.3.AND.IDEPFN(J).EQ.14)) AIDREF(I)=AIDREF(I)+SUM
80 CONTINUE
90 CONTINUE
WRITE(6,'(/,A,/)')
1' AB-INITIO DERIVATIVES AFTER SYMMETRY WEIGHTING'
WRITE(6,'(5F12.6)')(AIDREF(J),J=1,NVAR)
ENDIF
ENDIF
ICALCN=NUMCAL
IF(INDEX(KEYWRD,'RESTART') .EQ. 0) THEN
DO 100 I=1,NVAR
100 ERRFN(I)=0.D0
ENDIF
GRLIM=0.01D0
IF(PRECIS)GRLIM=0.0001D0
HALFE = (NOPEN.GT.NCLOSE.AND.FRACT.NE.2.D0.AND.FRACT.NE.0.D0
1 .OR. CI)
IDELTA=-7
*
* IDELTA IS A MACHINE-PRECISION DEPENDANT INTEGER
*
CHANGE(1)= 10.D0**IDELTA
CHANGE(2)= 10.D0**IDELTA
CHANGE(3)= 10.D0**IDELTA
C
C CHANGE(I) IS THE STEP SIZE USED IN CALCULATING THE DERIVATIVES.
C FOR "CARTESIAN" DERIVATIVES, CALCULATED USING DCART,AN
C INFINITESIMAL STEP, HERE 0.000001, IS ACCEPTABLE. IN THE
C HALF-ELECTRON METHOD A QUITE LARGE STEP IS NEEDED AS FULL SCF
C CALCULATIONS ARE NEEDED, AND THE DIFFERENCE BETWEEN THE TOTAL
C ENERGIES IS USED. THE STEP CANNOT BE VERY LARGE, AS THE SECOND
C DERIVITIVE IN FLEPO IS CALCULATED FROM THE DIFFERENCES OF TWO
C FIRST DERIVATIVES. CHANGE(1) IS FOR CHANGE IN BOND LENGTH,
C (2) FOR ANGLE, AND (3) FOR DIHEDRAL.
C
ENDIF
IF(NVAR.EQ.0) RETURN
IF(DEBUG)THEN
WRITE(6,'('' GEO AT START OF DERIV'')')
WRITE(6,'(F19.5,2F12.5)')((GEO(J,I),J=1,3),I=1,NATOMS)
ENDIF
GNORM=0.D0
DO 110 I=1,NVAR
GOLD(I)=GRAD(I)
XPARAM(I)=GEO(LOC(2,I),LOC(1,I))
110 GNORM=GNORM+GRAD(I)**2
GNORM=SQRT(GNORM)
SLOW=.FALSE.
NOANCI=.FALSE.
IF(HALFE) THEN
NOANCI=(INDEX(KEYWRD,'NOANCI').NE.0 .OR. NOPEN.EQ.NORBS)
SLOW=(NOANCI.AND.(GNORM .LT. GRLIM .OR. SCF1))
ENDIF
IF(NDEP.NE.0) CALL SYMTRY
CALL GMETRY(GEO,COORD)
C
C COORD NOW HOLDS THE CARTESIAN COORDINATES
C
IF(HALFE.AND..NOT.NOANCI) THEN
IF(DEBUG)WRITE(6,*) 'DOING ANALYTICAL C.I. DERIVATIVES'
CALL DERNVO(COORD,DXYZ)
ELSE
IF(DEBUG)WRITE(6,*) 'DOING VARIATIONALLY OPIMIZED DERIVATIVES'
CALL DCART(COORD,DXYZ)
ENDIF
IJ=0
DO 150 II=1,NUMAT
DO 140 IL=L1L,L1U
DO 140 JL=L2L,L2U
DO 140 KL=L3L,L3U
C$DOIT ASIS
DO 120 LL=1,3
120 XJUC(LL)=COORD(LL,II)+TVEC(LL,1)*IL+TVEC(LL,2)*JL+TVEC
1(LL,3)*KL
IJ=IJ+1
C$DOIT ASIS
DO 130 KK=1,3
COLD(KK,IJ)=XJUC(KK)
130 CONTINUE
140 CONTINUE
150 CONTINUE
STEP=CHANGE(1)
CALL JCARIN (COORD,XPARAM,STEP,PRECIS,WORK2,NCOL)
CALL MXM (WORK2,NVAR,DXYZ,NCOL,GRAD,1)
IF (PRECIS) THEN
STEP=0.5D0/STEP
ELSE
STEP=1.0D0/STEP
ENDIF
DO 160 I=1,NVAR
160 GRAD(I)=GRAD(I)*STEP
C
C NOW TO ENSURE THAT INTERNAL DERIVATIVES ACCURATELY REFLECT CARTESIAN
C DERIVATIVES
C
IF(INT.AND. .NOT. GEOOK .AND. NVAR.GE.NUMAT*3-6.AND.ID.EQ.0)THEN
C
C NUMBER OF VARIABLES LOOKS O.K.
C
SUM=DOT(GRAD,GRAD,NVAR)
IF(SUM.LT.2.D0.AND.DOT(DXYZ,DXYZ,3*NUMAT).GT.MAX(4.D0,SUM*4.D0)
1)THEN
C
C OOPS, LOOKS LIKE AN ERROR.
C
DO 170 I=1,NVAR
J=XPARAM(I)/3.141D0
IF(LOC(2,I).EQ.2.AND.LOC(1,I).GT.3.AND.
1 ABS(XPARAM(I)-J*3.1415926D0).LT.0.005D0 )THEN
C
C ERROR LOCATED, BUT CANNOT CORRECT IN THIS RUN
C
WRITE(6,'(//,3(A,/),I3,A)')
1' INTERNAL COORDINATE DERIVATIVES DO NOT REFLECT',
2' CARTESIAN COORDINATE DERIVATIVES',
3' TO CORRECT ERROR, INCREASE DIHEDRAL OF ATOM',LOC(1,I),
4' BY 90 DEGREES'
WRITE(6,'(//,A)')' CURRENT GEOMETRY'
CALL GEOUT(6)
STOP
ENDIF
170 CONTINUE
ENDIF
ENDIF
C
C THIS CODE IS ONLY USED IF THE KEYWORD NOANCI IS SPECIFIED
IF(SLOW)THEN
IF(DEBUG)WRITE(6,*) 'DOING FULL SCF DERIVATIVES'
CALL DERITR(ERRFN,GEO)
C
C THE ARRAY ERRFN HOLDS THE EXACT DERIVATIVES MINUS THE APPROXIMATE
C DERIVATIVES
DO 180 I=1,NVAR
180 ERRFN(I)=ERRFN(I)-GRAD(I)
ENDIF
COSINE=DOT(GRAD,GOLD,NVAR)/
1SQRT(DOT(GRAD,GRAD,NVAR)*DOT(GOLD,GOLD,NVAR)+1.D-20)
DO 190 I=1,NVAR
190 GRAD(I)=GRAD(I)+ERRFN(I)
IF(AIC)THEN
IF(AIFRST)THEN
AIFRST=.FALSE.
DO 200 I=1,NVAR
200 AICORR(I)=-AIDREF(I)-GRAD(I)
ENDIF
C# WRITE(6,'('' GRADIENTS BEFORE AI CORRECTION'')')
C# WRITE(6,'(10F8.3)')(GRAD(I),I=1,NVAR)
DO 210 I=1,NVAR
210 GRAD(I)=GRAD(I)+AICORR(I)
ENDIF
220 IF(DEBUG) THEN
WRITE(6,'('' GRADIENTS'')')
WRITE(6,'(10F8.3)')(GRAD(I),I=1,NVAR)
IF(SLOW)THEN
WRITE(6,'('' ERROR FUNCTION'')')
WRITE(6,'(10F8.3)')(ERRFN(I),I=1,NVAR)
ENDIF
ENDIF
IF(DEBUG)
1WRITE(6,'('' COSINE OF SEARCH DIRECTION ='',F30.6)')COSINE
RETURN
END