2019-10-05 23:09:20 +02:00
|
|
|
subroutine linear_response_pp(ispin,dRPA,TDA,BSE,nBas,nC,nO,nV,nR,nS,e,ERI,rho,Ec_ppRPA)
|
2019-10-05 22:06:25 +02:00
|
|
|
|
2019-10-06 20:08:38 +02:00
|
|
|
! Compute the p-p channel of the linear response: see Scueria et al. JCP 139, 104113 (2013)
|
2019-10-05 22:06:25 +02:00
|
|
|
|
|
|
|
implicit none
|
|
|
|
include 'parameters.h'
|
|
|
|
|
|
|
|
! Input variables
|
|
|
|
|
|
|
|
logical,intent(in) :: dRPA
|
|
|
|
logical,intent(in) :: TDA
|
|
|
|
logical,intent(in) :: BSE
|
|
|
|
integer,intent(in) :: ispin,nBas,nC,nO,nV,nR,nS
|
|
|
|
double precision,intent(in) :: e(nBas)
|
|
|
|
double precision,intent(in) :: ERI(nBas,nBas,nBas,nBas)
|
|
|
|
double precision,intent(in) :: rho(nBas,nBas,nS)
|
|
|
|
|
|
|
|
! Local variables
|
|
|
|
|
|
|
|
integer :: nOO
|
|
|
|
integer :: nVV
|
|
|
|
double precision :: trace_matrix
|
|
|
|
double precision,allocatable :: B(:,:)
|
|
|
|
double precision,allocatable :: C(:,:)
|
|
|
|
double precision,allocatable :: D(:,:)
|
|
|
|
double precision,allocatable :: M(:,:)
|
2019-10-06 20:08:38 +02:00
|
|
|
double precision,allocatable :: Z(:,:)
|
2019-10-05 22:06:25 +02:00
|
|
|
double precision,allocatable :: w(:)
|
2019-10-06 20:08:38 +02:00
|
|
|
double precision,allocatable :: w1(:)
|
|
|
|
double precision,allocatable :: w2(:)
|
|
|
|
double precision,allocatable :: X1(:,:)
|
|
|
|
double precision,allocatable :: Y1(:,:)
|
|
|
|
double precision,allocatable :: X2(:,:)
|
|
|
|
double precision,allocatable :: Y2(:,:)
|
2019-10-05 22:06:25 +02:00
|
|
|
|
|
|
|
! Output variables
|
|
|
|
|
2019-10-05 23:09:20 +02:00
|
|
|
double precision,intent(out) :: Ec_ppRPA
|
|
|
|
|
2019-10-05 22:06:25 +02:00
|
|
|
! Useful quantities
|
|
|
|
|
2019-10-06 20:08:38 +02:00
|
|
|
nOO = nO*(nO-1)/2
|
|
|
|
nVV = nV*(nV-1)/2
|
2019-10-05 22:06:25 +02:00
|
|
|
|
|
|
|
! Memory allocation
|
|
|
|
|
2019-10-06 20:08:38 +02:00
|
|
|
allocate(B(nVV,nOO),C(nVV,nVV),D(nOO,nOO),M(nOO+nVV,nOO+nVV),Z(nOO+nVV,nOO+nVV),w(nOO+nVV), &
|
|
|
|
w1(nVV),w2(nOO),X1(nVV,nVV),Y1(nVV,nOO),X2(nOO,nVV),Y2(nOO,nOO))
|
2019-10-05 22:06:25 +02:00
|
|
|
|
|
|
|
! Build B, C and D matrices for the pp channel
|
|
|
|
|
|
|
|
call linear_response_B_pp(ispin,dRPA,nBas,nC,nO,nV,nR,nOO,nVV,e,ERI,B)
|
|
|
|
call linear_response_C_pp(ispin,dRPA,nBas,nC,nO,nV,nR,nOO,nVV,e,ERI,C)
|
|
|
|
call linear_response_D_pp(ispin,dRPA,nBas,nC,nO,nV,nR,nOO,nVV,e,ERI,D)
|
|
|
|
|
|
|
|
!------------------------------------------------------------------------
|
|
|
|
! Solve the p-p eigenproblem
|
|
|
|
!------------------------------------------------------------------------
|
|
|
|
!
|
|
|
|
! | C -B | | X1 X2 | | w1 0 | | X1 X2 |
|
|
|
|
! | | | | = | | | |
|
|
|
|
! | Bt -D | | Y1 Y2 | | 0 w2 | | Y1 Y2 |
|
|
|
|
!
|
|
|
|
|
|
|
|
! Diagonal blocks
|
|
|
|
|
2019-10-06 20:08:38 +02:00
|
|
|
M( 1:nVV , 1:nVV) = + C(1:nVV,1:nVV)
|
|
|
|
M(nVV+1:nVV+nOO,nVV+1:nVV+nOO) = - D(1:nOO,1:nOO)
|
2019-10-05 22:06:25 +02:00
|
|
|
|
|
|
|
! Off-diagonal blocks
|
|
|
|
|
2019-10-05 23:09:20 +02:00
|
|
|
M( 1:nVV ,nVV+1:nOO+nVV) = - B(1:nVV,1:nOO)
|
|
|
|
M(nVV+1:nOO+nVV, 1:nVV) = + transpose(B(1:nVV,1:nOO))
|
2019-10-05 22:06:25 +02:00
|
|
|
|
2019-10-05 23:09:20 +02:00
|
|
|
! print*, 'pp-RPA matrix'
|
|
|
|
! call matout(nOO+nVV,nOO+nVV,M(:,:))
|
2019-10-05 22:06:25 +02:00
|
|
|
|
|
|
|
! Diagonalize the p-h matrix
|
|
|
|
|
2019-10-06 20:08:38 +02:00
|
|
|
Z(:,:) = M(:,:)
|
|
|
|
call diagonalize_matrix(nOO+nVV,Z(:,:),w(:))
|
2019-10-05 22:06:25 +02:00
|
|
|
|
2019-10-06 20:08:38 +02:00
|
|
|
write(*,*) 'pp-RPA excitation energies'
|
|
|
|
call matout(nOO+nVV,1,w(:))
|
|
|
|
write(*,*)
|
2019-10-05 22:06:25 +02:00
|
|
|
|
2019-10-06 20:08:38 +02:00
|
|
|
! Split the various quantities in p-p and h-h parts
|
2019-10-05 22:06:25 +02:00
|
|
|
|
2019-10-06 20:08:38 +02:00
|
|
|
w1(:) = w(nOO+1:nOO+nVV)
|
|
|
|
w2(:) = w(1:nOO)
|
2019-10-05 22:06:25 +02:00
|
|
|
|
2019-10-06 20:08:38 +02:00
|
|
|
X1(:,:) = Z(nOO+1:nOO+nVV, 1:nVV )
|
|
|
|
Y1(:,:) = Z(nOO+1:nOO+nVV,nVV+1:nOO+nVV)
|
|
|
|
X2(:,:) = Z( 1:nOO , 1:nVV )
|
|
|
|
Y2(:,:) = Z( 1:nOO ,nVV+1:nOO+nVV)
|
|
|
|
|
|
|
|
if(minval(w1(:)) < 0d0) call print_warning('You may have instabilities in pp-RPA!!')
|
|
|
|
if(maxval(w2(:)) > 0d0) call print_warning('You may have instabilities in pp-RPA!!')
|
2019-10-05 22:06:25 +02:00
|
|
|
|
|
|
|
! Compute the RPA correlation energy
|
|
|
|
|
2019-10-06 20:08:38 +02:00
|
|
|
Ec_ppRPA = 0.5d0*( sum(w1(:)) - sum(w2(:)) - trace_matrix(nVV,C(:,:)) - trace_matrix(nOO,D(:,:)) )
|
2019-10-05 22:06:25 +02:00
|
|
|
|
|
|
|
print*,'Ec(pp-RPA) = ',Ec_ppRPA
|
2019-10-06 20:08:38 +02:00
|
|
|
print*,'Ec(pp-RPA) = ',0.5d0*( sum(abs(w(:))) - trace_matrix(nVV*nOO,M(:,:)))
|
|
|
|
print*,'Ec(pp-RPA) = ',+sum(w1(:)) - trace_matrix(nVV,C(:,:))
|
|
|
|
print*,'Ec(pp-RPA) = ',-sum(w2(:)) - trace_matrix(nOO,D(:,:))
|
2019-10-05 22:06:25 +02:00
|
|
|
|
|
|
|
end subroutine linear_response_pp
|