quack/src/LR/linear_response_pp.f90

119 lines
3.9 KiB
Fortran
Raw Normal View History

2021-10-18 23:12:43 +02:00
subroutine linear_response_pp(ispin,TDA,nBas,nC,nO,nV,nR,nOO,nVV,lambda,e,ERI,Omega1,X1,Y1,Omega2,X2,Y2,EcRPA)
2019-10-05 22:06:25 +02:00
2020-03-14 23:00:44 +01:00
! Compute the p-p channel of the linear response: see Scuseria et al. JCP 139, 104113 (2013)
2019-10-05 22:06:25 +02:00
implicit none
include 'parameters.h'
! Input variables
2021-10-18 22:05:26 +02:00
integer,intent(in) :: ispin
logical,intent(in) :: TDA
integer,intent(in) :: nBas
integer,intent(in) :: nC
integer,intent(in) :: nO
integer,intent(in) :: nV
integer,intent(in) :: nR
2019-10-06 22:35:36 +02:00
integer,intent(in) :: nOO
integer,intent(in) :: nVV
2021-10-18 23:12:43 +02:00
double precision,intent(in) :: lambda
2019-10-05 22:06:25 +02:00
double precision,intent(in) :: e(nBas)
double precision,intent(in) :: ERI(nBas,nBas,nBas,nBas)
! Local variables
2019-10-30 10:31:05 +01:00
integer :: ab,cd,ij,kl
2020-03-11 16:41:20 +01:00
integer :: p,q,r,s
2019-10-05 22:06:25 +02:00
double precision :: trace_matrix
2020-03-24 12:28:56 +01:00
double precision :: EcRPA1
double precision :: EcRPA2
2019-10-05 22:06:25 +02:00
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-06 22:35:36 +02:00
double precision,allocatable :: Omega(:)
2019-10-05 22:06:25 +02:00
! Output variables
2019-10-06 22:35:36 +02:00
double precision,intent(out) :: Omega1(nVV)
double precision,intent(out) :: X1(nVV,nVV)
double precision,intent(out) :: Y1(nOO,nVV)
double precision,intent(out) :: Omega2(nOO)
double precision,intent(out) :: X2(nVV,nOO)
double precision,intent(out) :: Y2(nOO,nOO)
2020-03-24 12:28:56 +01:00
double precision,intent(out) :: EcRPA
2019-10-05 23:09:20 +02:00
2019-10-05 22:06:25 +02:00
! Memory allocation
2019-10-06 22:35:36 +02:00
allocate(B(nVV,nOO),C(nVV,nVV),D(nOO,nOO),M(nOO+nVV,nOO+nVV),Z(nOO+nVV,nOO+nVV),Omega(nOO+nVV))
2019-10-05 22:06:25 +02:00
2021-10-18 22:05:26 +02:00
!-------------------------------------------------!
! Solve the p-p eigenproblem !
!-------------------------------------------------!
! !
2021-11-06 14:36:54 +01:00
! | C B | | X1 X2 | | w1 0 | | X1 X2 | !
2021-10-18 22:05:26 +02:00
! | | | | = | | | | !
2021-11-06 14:36:54 +01:00
! | -Bt -D | | Y1 Y2 | | 0 w2 | | Y1 Y2 | !
2021-10-18 22:05:26 +02:00
! !
!-------------------------------------------------!
2019-10-05 22:06:25 +02:00
! Build B, C and D matrices for the pp channel
2021-10-18 23:12:43 +02:00
call linear_response_C_pp(ispin,nBas,nC,nO,nV,nR,nOO,nVV,lambda,e,ERI,C)
call linear_response_D_pp(ispin,nBas,nC,nO,nV,nR,nOO,nVV,lambda,e,ERI,D)
2019-10-05 22:06:25 +02:00
2021-10-18 22:05:26 +02:00
if(TDA) then
2019-10-05 22:06:25 +02:00
2021-10-18 22:05:26 +02:00
X1(:,:) = +C(:,:)
Y1(:,:) = 0d0
call diagonalize_matrix(nVV,X1,Omega1)
X2(:,:) = 0d0
Y2(:,:) = -D(:,:)
call diagonalize_matrix(nOO,Y2,Omega2)
2019-10-05 22:06:25 +02:00
2021-10-18 22:05:26 +02:00
else
2019-10-05 22:06:25 +02:00
2021-10-18 23:12:43 +02:00
call linear_response_B_pp(ispin,nBas,nC,nO,nV,nR,nOO,nVV,lambda,e,ERI,B)
2019-10-05 22:06:25 +02:00
2021-10-18 22:05:26 +02:00
! Diagonal blocks
2019-10-05 22:06:25 +02:00
2021-10-18 22:05:26 +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)
2020-03-14 23:00:44 +01:00
2021-10-18 22:05:26 +02:00
! Off-diagonal blocks
2020-03-14 23:00:44 +01:00
2021-10-18 22:05:26 +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-28 16:34:09 +01:00
2021-10-18 22:05:26 +02:00
! Diagonalize the p-h matrix
2019-10-05 22:06:25 +02:00
2021-10-18 22:05:26 +02:00
if(nOO+nVV > 0) call diagonalize_general_matrix(nOO+nVV,M,Omega,Z)
2019-10-05 22:06:25 +02:00
2021-10-18 22:05:26 +02:00
! Split the various quantities in p-p and h-h parts
2020-04-16 17:02:01 +02:00
2021-10-18 22:05:26 +02:00
call sort_ppRPA(nOO,nVV,Omega(:),Z(:,:),Omega1(:),X1(:,:),Y1(:,:),Omega2(:),X2(:,:),Y2(:,:))
2019-10-05 22:06:25 +02:00
! print*,'Omega1'
! call matout(nVV,1,Omega1)
! print*,'X1t.X1 - Y1t.Y1'
! call matout(nVV,nVV,matmul(transpose(X1),X1) - matmul(transpose(Y1),Y1))
! print*,'Omega2'
! call matout(nOO,1,Omega2)
! print*,'Y2t.Y2 - X2t.X2'
! call matout(nOO,nOO,matmul(transpose(Y2),Y2) - matmul(transpose(X2),X2))
2021-10-18 22:05:26 +02:00
end if
2020-04-16 17:02:01 +02:00
2019-10-05 22:06:25 +02:00
! Compute the RPA correlation energy
2020-03-24 12:28:56 +01:00
EcRPA = 0.5d0*( sum(Omega1(:)) - sum(Omega2(:)) - trace_matrix(nVV,C(:,:)) - trace_matrix(nOO,D(:,:)) )
EcRPA1 = +sum(Omega1(:)) - trace_matrix(nVV,C(:,:))
EcRPA2 = -sum(Omega2(:)) - trace_matrix(nOO,D(:,:))
2020-03-25 21:10:21 +01:00
if(abs(EcRPA - EcRPA1) > 1d-6 .or. abs(EcRPA - EcRPA2) > 1d-6) &
2020-03-24 12:28:56 +01:00
print*,'!!! Issue in pp-RPA linear reponse calculation RPA1 != RPA2 !!!'
2019-10-05 22:06:25 +02:00
end subroutine linear_response_pp