Skip to content

Commit 15f4110

Browse files
Source code (Fortran 90 format) for Appendix B. (#64)
* Source code (Fortran 90 format) for Appendix B. 1. Removed the jump and rewrote the DO and IF. 2. Retained the variables and the electronic integral calculation from the original code. 3. Diagonalization is performed using LAPACK; some variables are redundant and have not been removed. * Rename HeH.f90 to AppendixBcode_revised.f90 * Adding the README.md file for source code * Update README with revised code details * Revise README for Appendix B code updates Updated README to include revised code details and requirements. * Update README with Appendix B source code details * add output for AppendixBcode_revised.f90
1 parent 7563184 commit 15f4110

3 files changed

Lines changed: 691 additions & 0 deletions

File tree

code/AppendixBcode_revised.f90

Lines changed: 383 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,383 @@
1+
!****************************************************************************
2+
!
3+
! PROGRAM: HeHSCF
4+
!
5+
!****************************************************************************
6+
7+
program HeHSCF
8+
implicit none
9+
real*8 :: IOP, R, ZETA1, ZETA2, ZA, ZB
10+
integer :: N
11+
IOP=3
12+
N=3
13+
R=1.4632D0
14+
ZETA1=2.0925D0
15+
ZETA2=1.24D0
16+
ZA=2.0D0
17+
ZB=1.0D0
18+
CALL HFCALC(IOP, N, R, ZETA1, ZETA2, ZA, ZB)
19+
end program HeHSCF
20+
21+
subroutine HFCALC(IOP, N, R, ZETA1, ZETA2, ZA, ZB)
22+
implicit none
23+
real*8 :: IOP, R, ZETA1, ZETA2, ZA, ZB
24+
integer :: N
25+
if (IOP /= 0) then
26+
write(*, 10) N, ZA, ZB
27+
endif
28+
call INTGRL(IOP, N, R, ZETA1, ZETA2, ZA, ZB)
29+
call COLECT(IOP, N, R, ZETA1, ZETA2, ZA, ZB)
30+
call SCF(IOP, N, R, ZETA1, ZETA2, ZA, ZB)
31+
10 format(' ',2X,'STO-',I1,'G FOR ATOMIC NUMBERS ',F5.2,' AND ',F5.2//)
32+
return
33+
end subroutine HFCALC
34+
35+
subroutine INTGRL(IOP,N,R,ZETA1,ZETA2,ZA,ZB)
36+
implicit none
37+
real*8 :: IOP, R, ZETA1, ZETA2, ZA, ZB
38+
integer :: N
39+
real*8 :: R2,RAP,RBP,RAQ,RBQ,RPQ,RAP2,RBP2,RAQ2,RBQ2,RPQ2
40+
real*8 :: S12,T11,T12,T22,V11A,V12A,V22A,V11B,V12B,V22B,V1111,V2111,V2121,V2211,V2221,V2222
41+
common /INT/ S12,T11,T12,T22,V11A,V12A,V22A,V11B,V12B,V22B,V1111,V2111,V2121,V2211,V2221,V2222
42+
real*8 :: COEF(3,3),EXPON(3,3),D1(3),A1(3),D2(3),A2(3)
43+
real*8 :: PI=3.1415926535898D0
44+
integer I,J,K,L
45+
real*8, external :: S,T,V,TWOE
46+
DATA COEF,EXPON /1.0D0,2*0.0D0,0.678914D0,0.430129D0,0.0D0,0.444635D0,0.535328D0,0.154329D0,&
47+
0.270950D0,2*0.0D0,0.151623D0,0.851819D0,0.0D0,0.109818D0,0.405771D0,2.22766D0/
48+
R2=R*R
49+
do I=1,N
50+
A1(I)=EXPON(I,N)*(ZETA1**2)
51+
D1(I)=COEF(I,N)*((2.0D0*A1(I)/PI)**0.75D0)
52+
A2(I)=EXPON(I,N)*(ZETA2**2)
53+
D2(I)=COEF(I,N)*((2.0D0*A2(I)/PI)**0.75D0)
54+
end do
55+
! Calculate electron integrals
56+
S12=0.0D0
57+
T11=0.0D0
58+
T12=0.0D0
59+
T22=0.0D0
60+
V11A=0.0D0
61+
V12A=0.0D0
62+
V22A=0.0D0
63+
V11B=0.0D0
64+
V12B=0.0D0
65+
V22B=0.0D0
66+
V1111=0.0D0
67+
V2111=0.0D0
68+
V2121=0.0D0
69+
V2211=0.0D0
70+
V2221=0.0D0
71+
V2222=0.0D0
72+
! one-electron integrals I for atom1, J for atom2
73+
do I=1,N
74+
do J=1,N
75+
! R1=0 R2=2
76+
RAP=A2(J)*R/(A1(I)+A2(J))
77+
RAP2=RAP**2
78+
RBP2=(R-RAP)**2
79+
S12=S12+S(A1(I),A2(J),R2)*D1(I)*D2(J)
80+
T11=T11+T(A1(I),A1(J),0.0D0)*D1(I)*D1(J)
81+
T12=T12+T(A1(I),A2(J),R2)*D1(I)*D2(J)
82+
T22=T22+T(A2(I),A2(J),0.0D0)*D2(I)*D2(J)
83+
V11A=V11A+V(A1(I),A1(J),0.0D0,0.0D0,ZA)*D1(I)*D1(J)
84+
V12A=V12A+V(A1(I),A2(J),R2,RAP2,ZA)*D1(I)*D2(J)
85+
V22A=V22A+V(A2(I),A2(J),0.0D0,R2,ZA)*D2(I)*D2(J)
86+
V11B=V11B+V(A1(I),A1(J),0.0D0,R2,ZB)*D1(I)*D1(J)
87+
V12B=V12B+V(A1(I),A2(J),R2,RBP2,ZB)*D1(I)*D2(J)
88+
V22B=V22B+V(A2(I),A2(J),0.0D0,0.0D0,ZB)*D2(I)*D2(J)
89+
end do
90+
end do
91+
do I=1,N
92+
do J=1,N
93+
do K=1,N
94+
do L=1,N
95+
RAP=A2(I)*R/(A2(I)+A1(J))
96+
RBP=R-RAP
97+
RAQ=A2(K)*R/(A2(K)+A1(L))
98+
RBQ=R-RAQ
99+
RPQ=RAP-RAQ
100+
RAP2=RAP*RAP
101+
RBP2=RBP*RBP
102+
RAQ2=RAQ*RAQ
103+
RBQ2=RBQ*RBQ
104+
RPQ2=RPQ*RPQ
105+
V1111=V1111+TWOE(A1(I),A1(J),A1(K),A1(L),0.0D0,0.0D0,0.0D0)*D1(I)*D1(J)*D1(K)*D1(L)
106+
V2111=V2111+TWOE(A2(I),A1(J),A1(K),A1(L),R2,0.0D0,RAP2)*D2(I)*D1(J)*D1(K)*D1(L)
107+
V2121=V2121+TWOE(A2(I),A1(J),A2(K),A1(L),R2,R2,RPQ2)*D2(I)*D1(J)*D2(K)*D1(L)
108+
V2211=V2211+TWOE(A2(I),A2(J),A1(K),A1(L),0.0D0,0.0D0,R2)*D2(I)*D2(J)*D1(K)*D1(L)
109+
V2221=V2221+TWOE(A2(I),A2(J),A2(K),A1(L),0.0D0,R2,RBQ2)*D2(I)*D2(J)*D2(K)*D1(L)
110+
V2222=V2222+TWOE(A2(I),A2(J),A2(K),A2(L),0.0D0,0.0D0,0.0D0)*D2(I)*D2(J)*D2(K)*D2(L)
111+
end do
112+
end do
113+
end do
114+
end do
115+
if (IOP .EQ. 0) return
116+
write(*,40)
117+
40 FORMAT(3X,'R',10X,'ZETA1',6X,'ZETA2',6X,'S12',8X,'T11'/)
118+
write(*,50) R,ZETA1,ZETA2,S12,T11
119+
50 FORMAT(5F11.6//)
120+
write(*,60)
121+
60 FORMAT(3X,'T12',8X,'T22',8X,'V11A',7X,'V12A',7X,'V22A'/)
122+
write(*,50) T12,T22,V11A,V12A,V22A
123+
write(*,70)
124+
70 FORMAT(3X,4HV11B,7X,4HV12B,7X,4HV22B,7X,'V1111',6X,'V2111'/)
125+
write(*,50) V11B,V12B,V22B,V1111,V2111
126+
write(*,80)
127+
80 FORMAT(3X,5HV2121,6X,5HV2211,6X,5HV2221,6X,5HV2222/)
128+
write(*,50) V2121,V2211,V2221,V2222
129+
return
130+
end subroutine
131+
132+
! Calculate the F FUNCTION F0 ONLY (s-type ORBITALS)
133+
function F0(ARG)
134+
implicit none
135+
real*8 ::ARG
136+
real*8 :: PI=3.1415926535898D0
137+
real*8 :: F0
138+
if (ARG < 1.0D-6) then
139+
F0=1.0D0-ARG/3.0D0
140+
else
141+
F0=DSQRT(PI/ARG)*ERF(DSQRT(ARG))/2.0D0
142+
end if
143+
return
144+
end function
145+
146+
! Calculate overlaps S
147+
function S(A,B,RAB2)
148+
implicit none
149+
real*8 :: A,B,RAB2
150+
real*8 :: S
151+
real*8 :: PI=3.1415926535898D0
152+
S=(PI/(A+B))**1.5D0*DEXP(-A*B*RAB2/(A+B))
153+
return
154+
end function
155+
156+
! Calculate kinetic energy integrals
157+
function T(A,B,RAB2)
158+
implicit none
159+
real*8 :: A,B,RAB2
160+
real*8 :: T
161+
real*8 :: PI=3.1415926535898D0
162+
T=A*B/(A+B)*(3.0D0-2.0D0*A*B*RAB2/(A+B))*(PI/(A+B))**1.5D0*DEXP(-A*B*RAB2/(A+B))
163+
return
164+
end function
165+
166+
! Calculate nuclear attraction integrals
167+
function V(A,B,RAB2,RCP2,ZC)
168+
implicit none
169+
real*8 :: A,B,RAB2,RCP2,ZC
170+
real*8, external :: F0
171+
real*8 :: V
172+
real*8 :: PI=3.1415926535898D0
173+
V=2.0D0*PI/(A+B)*F0((A+B)*RCP2)*DEXP(-A*B*RAB2/(A+B))
174+
V=-V*ZC
175+
return
176+
end function
177+
178+
! Calculate two-electron integrals
179+
function TWOE(A,B,C,D,RAB2,RCD2,RPQ2)
180+
implicit none
181+
real*8 :: A,B,C,D,RAB2,RCD2,RPQ2
182+
real*8, external :: F0
183+
real*8 :: TWOE
184+
real*8 :: PI=3.1415926535898D0
185+
TWOE=2.0D0*(PI**2.5D0)/((A+B)*(C+D)*DSQRT(A+B+C+D))*F0((A+B)*(C+D)*RPQ2/(A+B+C+D))*DEXP(-A*B*RAB2/(A+B)-C*D*RCD2/(C+D))
186+
return
187+
end function
188+
189+
! THIS TAKES THE BASIC INTEGRALS FROM COMMON AND ASSEMBLES THE RELEVENT MATRICES
190+
subroutine COLECT(IOP,N,R,ZETA1,ZETA2,ZA,ZB)
191+
implicit none
192+
real*8 :: IOP,R,ZETA1,ZETA2,ZA,ZB
193+
integer :: N
194+
real*8 :: S(2,2),X(2,2),XT(2,2),H(2,2),F(2,2),G(2,2),C(2,2),FPRIME(2,2),CPRIME(2,2),P(2,2),OLDP(2,2),TT(2,2,2,2),E(2,2)
195+
common /MATRIX/ S,X,XT,H,F,G,C,FPRIME,CPRIME,P,OLDP,TT,E
196+
real*8 :: S12,T11,T12,T22,V11A,V12A,V22A,V11B,V12B,V22B,V1111,V2111,V2121,V2211,V2221,V2222
197+
common /INT/ S12,T11,T12,T22,V11A,V12A,V22A,V11B,V12B,V22B,V1111,V2111,V2121,V2211,V2221,V2222
198+
integer :: I,J,K,L
199+
! core Hamiltonian
200+
H(1,1)=T11+V11A+V11B
201+
H(1,2)=T12+V12A+V12B
202+
H(2,1)=H(1,2)
203+
H(2,2)=T22+V22A+V22B
204+
! S Matrix
205+
S(1,1)=1.0D0
206+
S(1,2)=S12
207+
S(2,1)=S(1,2)
208+
S(2,2)=1.0D0
209+
! Schmidt orthogonalization for S Matrix
210+
X(1,1)=1.0D0/DSQRT(2.0D0*(1.0D0+S12))
211+
X(2,1)=X(1,1)
212+
X(1,2)=1.0D0/DSQRT(2.0D0*(1.0D0-S12))
213+
X(2,2)=-X(1,2)
214+
! Transpose of X
215+
XT=transpose(X)
216+
! Matrix of Two-electron integrals
217+
TT(1,1,1,1)=V1111
218+
TT(2,1,1,1)=V2111
219+
TT(1,2,1,1)=V2111
220+
TT(1,1,2,1)=V2111
221+
TT(1,1,1,2)=V2111
222+
TT(2,1,2,1)=V2121
223+
TT(1,2,2,1)=V2121
224+
TT(2,1,1,2)=V2121
225+
TT(1,2,1,2)=V2121
226+
TT(2,2,1,1)=V2211
227+
TT(1,1,2,2)=V2211
228+
TT(2,2,2,1)=V2221
229+
TT(2,2,1,2)=V2221
230+
TT(2,1,2,2)=V2221
231+
TT(1,2,2,2)=V2221
232+
TT(2,2,2,2)=V2222
233+
if (IOP /= 0) then
234+
CALL MATOUT(S,2,2,2,2,'S')
235+
CALL MATOUT(X,2,2,2,2,'X')
236+
CALL MATOUT(H,2,2,2,2,'H')
237+
write(*,10)
238+
do I=1,2
239+
do J=1,2
240+
do K=1,2
241+
do L=1,2
242+
write(*,20) I,J,K,L,TT(I,J,K,L)
243+
end do
244+
end do
245+
end do
246+
end do
247+
end if
248+
10 FORMAT(//)
249+
20 FORMAT(3X,'(',4I2,')',F10.6)
250+
end subroutine
251+
252+
subroutine SCF(IOP,N,R,ZETA1,ZETA2,ZA,ZB)
253+
implicit none
254+
real*8 :: IOP,R,ZETA1,ZETA2,ZA,ZB
255+
integer :: N
256+
real*8 :: S(2,2),X(2,2),XT(2,2),H(2,2),F(2,2),G(2,2),C(2,2),FPRIME(2,2),CPRIME(2,2),P(2,2),OLDP(2,2),TT(2,2,2,2),E(2,2)
257+
common /MATRIX/ S,X,XT,H,F,G,C,FPRIME,CPRIME,P,OLDP,TT,E
258+
real*8 :: PI=3.1415926535898D0
259+
real*8 :: CRIT=1.0D-6
260+
integer :: max_iter=120,ITER,i,j,k,l,lwork,info
261+
real*8 :: energy,evals(2),dummy(1),ENT,delta
262+
real*8, allocatable :: work(:)
263+
! Initial guess
264+
P = 0.0D0
265+
! SCF cyclo
266+
do iter=1, max_iter
267+
write(*,'(///,4X,A,I2)') 'START OF ITERATION NUMBER =',iter
268+
! Construct F Matrix
269+
! F_uv = H_uv + Sum_ls P_ls * [ (uv|sl) - 0.5 * (ul|sv) ]
270+
F = H
271+
do i=1,2
272+
do j=1,2
273+
do k=1,2
274+
do l=1,2
275+
F(i,j)=F(i,j)+P(k,l)*(TT(i,j,l,k)-0.5D0*TT(i,k,l,j))
276+
end do
277+
end do
278+
end do
279+
end do
280+
281+
! Calculate energy
282+
energy = 0.0D0
283+
do i = 1,2
284+
do j = 1,2
285+
energy = energy+0.5D0*P(i,j)*(H(i,j)+F(i,j))
286+
end do
287+
end do
288+
write(*,'(/,4X,A,D20.12)') 'ELECTRONIC ENERGY = ', energy
289+
290+
! Transition Fock matrix
291+
FPRIME=matmul(XT,matmul(F,X))
292+
293+
! DSYEV
294+
lwork=-1
295+
call dsyev('V','U',2,FPRIME,2,evals,dummy,lwork,info)
296+
lwork=int(dummy(1))
297+
if (allocated(work)) deallocate(work)
298+
allocate(work(lwork))
299+
call dsyev('V','U',2,FPRIME,2,evals,work,lwork,info)
300+
E(1,1)=evals(1)
301+
E(2,2)=evals(2)
302+
! r transition C
303+
C=matmul(X, FPRIME)
304+
305+
! Construct new P
306+
OLDP=P
307+
do i=1,2
308+
do j=1,2
309+
P(i,j)=0.0D0
310+
do k=1,1
311+
P(i,j)=P(i,j)+2.0D0*C(i,k)*C(j,k)
312+
end do
313+
end do
314+
end do
315+
if (IOP > 2) then
316+
CALL MATOUT(F,2,2,2,2,'F')
317+
CALL MATOUT(E,2,2,2,2,'E')
318+
CALL MATOUT(C,2,2,2,2,'C')
319+
CALL MATOUT(P,2,2,2,2,'P')
320+
end if
321+
! Calculate delta
322+
delta=0.0D0
323+
delta = sum((p(:,:) - oldp(:,:))**2)
324+
delta=DSQRT(delta/4.0D0)
325+
if (IOP > 0) then
326+
write(*,'(/,4X,A,F10.6,/)') 'DELTA(CONVERGENCE OF DENSITY MATRIX) =',delta
327+
end if
328+
if (delta<CRIT) exit
329+
if (iter==max_iter .and. delta>CRIT) then
330+
write(*,'(4X,A)') 'NO CONVERGENCE IN SCF'
331+
end if
332+
end do
333+
ENT=energy+ZA*ZB/R
334+
if (IOP /= 0) then
335+
write(*, '(//,4X,A,//,4X,A,D20.12,//,4X,A,D20.12)') &
336+
'CALCULATION CONVERGED', &
337+
'ELECTRONIC ENERGY = ', energy, &
338+
'TOTAL ENERGY = ', ENT
339+
end if
340+
if (IOP == 1) then
341+
call MATOUT(F, 2, 2, 2, 2, 'F')
342+
call MATOUT(C, 2, 2, 2, 2, 'C')
343+
call MATOUT(P, 2, 2, 2, 2, 'P')
344+
end if
345+
OLDP=matmul(P,S)
346+
if (IOP /= 0) then
347+
call MATOUT(OLDP, 2, 2, 2, 2, 'PS')
348+
end if
349+
return
350+
end subroutine
351+
352+
! Print Matrix of size M by N
353+
subroutine MATOUT(A,IM,INP,M,N,LABEL)
354+
IMPLICIT NONE
355+
INTEGER, INTENT(IN) :: IM, INP, M, N
356+
DOUBLE PRECISION, INTENT(IN) :: A(IM, INP)
357+
CHARACTER(LEN=*), INTENT(IN) :: LABEL
358+
INTEGER :: I, J, LOW, IHIGH
359+
CHARACTER(LEN=100) :: FMT_HEADER, FMT_ROW
360+
361+
IHIGH = 0
362+
363+
do
364+
LOW = IHIGH + 1
365+
IHIGH = IHIGH + 5
366+
IHIGH = MIN(IHIGH, N)
367+
write(*, '(/3X, "THE ", A, " ARRAY")') TRIM(LABEL)
368+
write(*, '(15X)', ADVANCE='NO')
369+
do I = LOW, IHIGH
370+
write(*, '(10X, I3, 6X)', ADVANCE='NO') I
371+
end do
372+
write(*, *)
373+
374+
do I = 1, M
375+
write(*, '(I10, 5X)', ADVANCE='NO') I
376+
do J = LOW, IHIGH
377+
write(*, '(1X, D18.10)', ADVANCE='NO') A(I, J)
378+
end do
379+
write(*, *)
380+
end do
381+
IF (IHIGH >= N) EXIT
382+
end do
383+
end subroutine

0 commit comments

Comments
 (0)