4
1
mirror of https://github.com/pfloos/quack synced 2024-06-02 11:25:28 +02:00
quack/src/CI/CISD.f90

309 lines
9.1 KiB
Fortran
Raw Normal View History

subroutine CISD(dotest,singlet,triplet,nBasin,nCin,nOin,nVin,nRin,ERIin,eHFin,E0)
2020-04-20 12:28:19 +02:00
! Perform configuration interaction with singles and doubles
implicit none
include 'parameters.h'
! Input variables
logical,intent(in) :: dotest
logical,intent(in) :: singlet
logical,intent(in) :: triplet
2022-01-04 11:39:33 +01:00
integer,intent(in) :: nBasin
integer,intent(in) :: nCin
integer,intent(in) :: nOin
integer,intent(in) :: nVin
integer,intent(in) :: nRin
double precision,intent(in) :: eHFin(nBasin)
2022-01-04 11:39:33 +01:00
double precision,intent(in) :: ERIin(nBasin,nBasin,nBasin,nBasin)
double precision,intent(in) :: E0
2020-04-20 12:28:19 +02:00
! Local variables
2022-01-04 11:39:33 +01:00
integer :: nBas
integer :: nC
integer :: nO
integer :: nV
integer :: nR
double precision,allocatable :: eHF(:)
2022-01-04 11:39:33 +01:00
double precision,allocatable :: sERI(:,:,:,:)
double precision,allocatable :: ERI(:,:,:,:)
2020-04-20 12:28:19 +02:00
logical :: dump_trans = .false.
integer :: i,j,k,l
integer :: a,b,c,d
2022-01-04 11:39:33 +01:00
integer :: ia,kc,iajb,kcld
2020-04-20 12:28:19 +02:00
integer :: ishift,jshift
integer :: ispin
integer :: nS
integer :: nD
2022-01-04 11:39:33 +01:00
integer :: nH
integer :: maxH
2020-04-20 12:28:19 +02:00
double precision,external :: Kronecker_delta
2022-01-04 11:39:33 +01:00
double precision,allocatable :: H(:,:)
double precision,allocatable :: ECISD(:)
double precision :: tmp
2020-04-20 12:28:19 +02:00
! Hello world
write(*,*)
write(*,*)'******************************************************'
write(*,*)'| Configuration Interaction with Singles and Doubles |'
write(*,*)'******************************************************'
write(*,*)
2022-01-04 11:39:33 +01:00
! Spatial to spin orbitals
2020-04-20 12:28:19 +02:00
2022-01-04 11:39:33 +01:00
nBas = 2*nBasin
nC = 2*nCin
nO = 2*nOin
nV = 2*nVin
nR = 2*nRin
2020-04-20 12:28:19 +02:00
allocate(eHF(nBas),sERI(nBas,nBas,nBas,nBas))
2020-04-20 12:28:19 +02:00
call spatial_to_spin_MO_energy(nBasin,eHFin,nBas,eHF)
2022-01-04 11:39:33 +01:00
call spatial_to_spin_ERI(nBasin,ERIin,nBas,sERI)
2020-04-20 12:28:19 +02:00
2022-01-04 11:39:33 +01:00
! Antysymmetrize ERIs
2020-04-20 12:28:19 +02:00
2022-01-04 11:39:33 +01:00
allocate(ERI(nBas,nBas,nBas,nBas))
2020-04-20 12:28:19 +02:00
2022-01-04 11:39:33 +01:00
call antisymmetrize_ERI(2,nBas,sERI,ERI)
2020-04-20 12:28:19 +02:00
2022-01-04 11:39:33 +01:00
deallocate(sERI)
2020-04-20 12:28:19 +02:00
2022-01-04 11:39:33 +01:00
! Compute CISD matrix
2020-04-20 12:28:19 +02:00
2022-01-04 11:39:33 +01:00
nS = (nO - nC)*(nV - nR)
nD = (nO - nC)*(nO - nC - 1)/2*(nV - nR)*(nV - nR - 1)/2
nH = 1 + nS + nD
2020-04-20 12:28:19 +02:00
2022-01-04 11:39:33 +01:00
write(*,*) 'nS = ',nS
write(*,*) 'nD = ',nD
write(*,*) 'nH = ',nH
write(*,*)
2020-04-20 12:28:19 +02:00
2022-02-01 11:42:31 +01:00
maxH = min(nH,51)
2022-01-04 11:39:33 +01:00
! Memory allocation
allocate(H(nH,nH),ECISD(nH))
! 00 block
ishift = 0
jshift = 0
H(ishift+1,jshift+1) = E0
2022-01-17 08:02:11 +01:00
print*,'00 block done...'
2022-01-04 11:39:33 +01:00
! 0S blocks
ishift = 0
jshift = 1
ia = 0
do i=nC+1,nO
do a=1,nV-nR
ia = ia + 1
tmp = 0d0
2022-01-04 11:39:33 +01:00
H(ishift+1,jshift+ia) = tmp
H(jshift+ia,ishift+1) = tmp
end do
end do
print*,'0S blocks done...'
! 0D blocks
ishift = 0
jshift = 1 + nS
iajb = 0
do i=nC+1,nO
do a=1,nV-nR
do j=i+1,nO
do b=a+1,nV-nR
iajb = iajb + 1
tmp = ERI(i,j,nO+a,nO+b)
H(ishift+1,jshift+iajb) = tmp
H(jshift+iajb,ishift+1) = tmp
2020-04-20 12:28:19 +02:00
end do
end do
end do
2022-01-04 11:39:33 +01:00
end do
print*,'0D blocks done...'
2020-04-20 12:28:19 +02:00
2022-01-04 11:39:33 +01:00
! SS block
2020-04-20 12:28:19 +02:00
2022-01-04 11:39:33 +01:00
ishift = 1
jshift = 1
2020-04-20 12:28:19 +02:00
2022-01-04 11:39:33 +01:00
ia = 0
do i=nC+1,nO
do a=1,nV-nR
2020-04-20 12:28:19 +02:00
2022-01-04 11:39:33 +01:00
ia = ia + 1
kc = 0
do k=nC+1,nO
do c=1,nV-nR
2020-04-20 12:28:19 +02:00
2022-01-04 11:39:33 +01:00
kc = kc + 1
tmp = E0*Kronecker_delta(i,k)*Kronecker_delta(a,c) &
- eHF(i)*Kronecker_Delta(i,k)*Kronecker_delta(a,c) &
+ eHF(a)*Kronecker_delta(a,c)*Kronecker_delta(i,k) &
2022-01-04 11:39:33 +01:00
- ERI(nO+a,k,nO+c,i)
2020-04-20 12:28:19 +02:00
2022-01-04 11:39:33 +01:00
H(ishift+ia,jshift+kc) = tmp
2020-04-20 12:28:19 +02:00
end do
end do
2022-01-04 11:39:33 +01:00
2020-04-20 12:28:19 +02:00
end do
2022-01-04 11:39:33 +01:00
end do
2020-04-20 12:28:19 +02:00
2022-01-17 08:02:11 +01:00
print*,'SS block done...'
2020-04-20 12:28:19 +02:00
2022-01-04 11:39:33 +01:00
! SD blocks
2020-04-20 12:28:19 +02:00
2022-01-04 11:39:33 +01:00
ishift = 1
jshift = 1 + nS
2020-04-20 12:28:19 +02:00
2022-01-04 11:39:33 +01:00
ia = 0
do i=nC+1,nO
do a=1,nV-nR
2020-04-20 12:28:19 +02:00
2022-01-04 11:39:33 +01:00
ia = ia + 1
kcld = 0
2020-04-20 12:28:19 +02:00
2022-01-04 11:39:33 +01:00
do k=nC+1,nO
do c=1,nV-nR
do l=k+1,nO
do d=c+1,nV-nR
2020-04-20 12:28:19 +02:00
2022-01-04 11:39:33 +01:00
kcld = kcld + 1
tmp = - ERI(k,l,nO+d,i)*Kronecker_delta(a,c) &
2022-01-04 11:39:33 +01:00
+ ERI(k,l,nO+c,i)*Kronecker_delta(a,d) &
- ERI(nO+a,l,nO+c,nO+d)*Kronecker_delta(i,k) &
+ ERI(nO+a,k,nO+c,nO+d)*Kronecker_delta(i,l)
H(ishift+ia,jshift+kcld) = tmp
H(jshift+kcld,ishift+ia) = tmp
2020-04-20 12:28:19 +02:00
end do
end do
end do
end do
2022-01-04 11:39:33 +01:00
end do
end do
print*,'SD blocks done...'
! DD block
ishift = 1 + nS
jshift = 1 + nS
iajb = 0
do i=nC+1,nO
do a=1,nV-nR
do j=i+1,nO
do b=a+1,nV-nR
iajb = iajb + 1
kcld = 0
do k=nC+1,nO
do c=1,nV-nR
do l=k+1,nO
do d=c+1,nV-nR
kcld = kcld + 1
tmp = &
E0*Kronecker_delta(i,k)*Kronecker_delta(j,l)*Kronecker_delta(a,c)*Kronecker_delta(b,d) &
+ eHF(j)*Kronecker_delta(l,j)*Kronecker_delta(a,d)*Kronecker_delta(b,c)*Kronecker_delta(i,k) &
- eHF(j)*Kronecker_delta(l,j)*Kronecker_delta(a,c)*Kronecker_delta(b,d)*Kronecker_delta(i,k) &
- eHF(j)*Kronecker_delta(k,j)*Kronecker_delta(a,d)*Kronecker_delta(b,c)*Kronecker_delta(i,l) &
+ eHF(j)*Kronecker_delta(k,j)*Kronecker_delta(a,c)*Kronecker_delta(b,d)*Kronecker_delta(i,l) &
- eHF(i)*Kronecker_delta(l,i)*Kronecker_delta(a,d)*Kronecker_delta(b,c)*Kronecker_delta(j,k) &
+ eHF(i)*Kronecker_delta(l,i)*Kronecker_delta(a,c)*Kronecker_delta(b,d)*Kronecker_delta(j,k) &
+ eHF(i)*Kronecker_delta(k,i)*Kronecker_delta(a,d)*Kronecker_delta(b,c)*Kronecker_delta(j,l) &
- eHF(i)*Kronecker_delta(k,i)*Kronecker_delta(a,c)*Kronecker_delta(b,d)*Kronecker_delta(j,l) &
+ eHF(a)*Kronecker_delta(a,d)*Kronecker_delta(b,c)*Kronecker_delta(i,l)*Kronecker_delta(j,k) &
- eHF(a)*Kronecker_delta(a,c)*Kronecker_delta(b,d)*Kronecker_delta(i,l)*Kronecker_delta(j,k) &
- eHF(a)*Kronecker_delta(a,d)*Kronecker_delta(b,c)*Kronecker_delta(i,k)*Kronecker_delta(j,l) &
+ eHF(a)*Kronecker_delta(a,c)*Kronecker_delta(b,d)*Kronecker_delta(i,k)*Kronecker_delta(j,l) &
- eHF(b)*Kronecker_delta(b,d)*Kronecker_delta(a,c)*Kronecker_delta(i,l)*Kronecker_delta(j,k) &
+ eHF(b)*Kronecker_delta(b,c)*Kronecker_delta(a,d)*Kronecker_delta(i,l)*Kronecker_delta(j,k) &
+ eHF(b)*Kronecker_delta(b,d)*Kronecker_delta(a,c)*Kronecker_delta(i,k)*Kronecker_delta(j,l) &
- eHF(b)*Kronecker_delta(b,c)*Kronecker_delta(a,d)*Kronecker_delta(i,k)*Kronecker_delta(j,l) &
2022-01-04 11:39:33 +01:00
- ERI(k,l,i,j)*Kronecker_delta(a,d)*Kronecker_delta(b,c) &
+ ERI(k,l,i,j)*Kronecker_delta(a,c)*Kronecker_delta(b,d) &
+ ERI(nO+a,l,nO+d,j)*Kronecker_delta(b,c)*Kronecker_delta(i,k) &
- ERI(nO+a,l,nO+c,j)*Kronecker_delta(b,d)*Kronecker_delta(i,k) &
- ERI(nO+a,k,nO+d,j)*Kronecker_delta(b,c)*Kronecker_delta(i,l) &
+ ERI(nO+a,k,nO+c,j)*Kronecker_delta(b,d)*Kronecker_delta(i,l) &
- ERI(nO+a,l,nO+d,i)*Kronecker_delta(b,c)*Kronecker_delta(j,k) &
+ ERI(nO+a,l,nO+c,i)*Kronecker_delta(b,d)*Kronecker_delta(j,k) &
+ ERI(nO+a,k,nO+d,i)*Kronecker_delta(b,c)*Kronecker_delta(j,l) &
- ERI(nO+a,k,nO+c,i)*Kronecker_delta(b,d)*Kronecker_delta(j,l) &
- ERI(nO+b,l,nO+d,j)*Kronecker_delta(a,c)*Kronecker_delta(i,k) &
+ ERI(nO+b,l,nO+c,j)*Kronecker_delta(a,d)*Kronecker_delta(i,k) &
+ ERI(nO+b,k,nO+d,j)*Kronecker_delta(a,c)*Kronecker_delta(i,l) &
- ERI(nO+b,k,nO+c,j)*Kronecker_delta(a,d)*Kronecker_delta(i,l) &
+ ERI(nO+b,l,nO+d,i)*Kronecker_delta(a,c)*Kronecker_delta(j,k) &
- ERI(nO+b,l,nO+c,i)*Kronecker_delta(a,d)*Kronecker_delta(j,k) &
- ERI(nO+b,k,nO+d,i)*Kronecker_delta(a,c)*Kronecker_delta(j,l) &
+ ERI(nO+b,k,nO+c,i)*Kronecker_delta(a,d)*Kronecker_delta(j,l) &
- ERI(nO+a,nO+b,nO+c,nO+d)*Kronecker_delta(i,l)*Kronecker_delta(j,k) &
+ ERI(nO+a,nO+b,nO+c,nO+d)*Kronecker_delta(i,k)*Kronecker_delta(j,l)
H(ishift+iajb,jshift+kcld) = tmp
2020-04-20 12:28:19 +02:00
end do
end do
end do
end do
2022-01-04 11:39:33 +01:00
2020-04-20 12:28:19 +02:00
end do
end do
end do
2022-01-04 11:39:33 +01:00
end do
2020-04-20 12:28:19 +02:00
2022-01-17 08:02:11 +01:00
print*,'DD block done...'
2020-04-20 12:28:19 +02:00
2022-01-04 11:39:33 +01:00
write(*,*)
write(*,*) 'Diagonalizing CISD matrix...'
write(*,*)
2020-04-20 12:28:19 +02:00
2022-01-04 11:39:33 +01:00
call diagonalize_matrix(nH,H,ECISD)
2020-04-20 12:28:19 +02:00
2022-01-04 11:39:33 +01:00
print*,'CISD energies (au)'
call matout(maxH,1,ECISD)
write(*,*)
2020-04-20 12:28:19 +02:00
2022-01-04 11:39:33 +01:00
print*,'CISD excitation energies (eV)'
call matout(maxH-1,1,(ECISD(2:maxH)-ECISD(1))*HaToeV)
write(*,*)
2020-04-20 12:28:19 +02:00
2022-01-04 11:39:33 +01:00
if(dump_trans) then
print*,'Singlet CISD transition vectors'
call matout(nH,nH,H)
write(*,*)
2023-12-03 18:47:30 +01:00
end if
2020-04-20 12:28:19 +02:00
end subroutine