2021-10-18 21:41:03 +02:00
|
|
|
subroutine sort_ppRPA(nOO,nVV,Omega,Z,Omega1,X1,Y1,Omega2,X2,Y2)
|
2019-10-15 23:13:00 +02:00
|
|
|
|
|
|
|
! Compute the metric matrix for pp-RPA
|
|
|
|
|
|
|
|
implicit none
|
|
|
|
include 'parameters.h'
|
|
|
|
|
|
|
|
! Input variables
|
|
|
|
|
|
|
|
integer,intent(in) :: nOO
|
|
|
|
integer,intent(in) :: nVV
|
|
|
|
double precision,intent(in) :: Omega(nOO+nVV)
|
|
|
|
double precision,intent(in) :: Z(nOO+nVV,nOO+nVV)
|
|
|
|
|
|
|
|
! Local variables
|
|
|
|
|
|
|
|
integer :: pq,ab,ij
|
2022-09-28 16:09:09 +02:00
|
|
|
! integer :: deg1,ab_start,ab_end
|
|
|
|
! integer :: deg2,ij_start,ij_end
|
2020-03-07 08:58:50 +01:00
|
|
|
double precision,allocatable :: M(:,:)
|
|
|
|
double precision,allocatable :: Z1(:,:)
|
|
|
|
double precision,allocatable :: Z2(:,:)
|
|
|
|
double precision,allocatable :: S1(:,:)
|
|
|
|
double precision,allocatable :: S2(:,:)
|
|
|
|
double precision,allocatable :: O1(:,:)
|
2023-06-14 16:53:16 +02:00
|
|
|
double precision,allocatable :: O2(:,:)
|
|
|
|
double precision,allocatable :: tmp1(:,:)
|
|
|
|
double precision,allocatable :: tmp2(:,:)
|
2019-10-15 23:13:00 +02:00
|
|
|
|
2020-03-25 21:10:21 +01:00
|
|
|
integer,allocatable :: order1(:)
|
|
|
|
integer,allocatable :: order2(:)
|
|
|
|
|
2019-10-15 23:13:00 +02:00
|
|
|
! Output variables
|
|
|
|
|
|
|
|
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-07 08:58:50 +01:00
|
|
|
! Memory allocation
|
|
|
|
|
|
|
|
allocate(M(nOO+nVV,nOO+nVV), &
|
|
|
|
Z1(nOO+nVV,nVV),Z2(nOO+nVV,nOO), &
|
2020-03-25 21:10:21 +01:00
|
|
|
order1(nVV),order2(nOO))
|
2020-03-07 08:58:50 +01:00
|
|
|
|
2019-10-15 23:13:00 +02:00
|
|
|
! Initializatiom
|
|
|
|
|
|
|
|
Omega1(:) = 0d0
|
2019-10-28 16:34:09 +01:00
|
|
|
X1(:,:) = 0d0
|
|
|
|
Y1(:,:) = 0d0
|
|
|
|
|
2019-10-15 23:13:00 +02:00
|
|
|
Omega2(:) = 0d0
|
2019-10-28 16:34:09 +01:00
|
|
|
X2(:,:) = 0d0
|
|
|
|
Y2(:,:) = 0d0
|
2019-10-15 23:13:00 +02:00
|
|
|
|
2020-03-07 08:58:50 +01:00
|
|
|
! Compute metric
|
|
|
|
|
|
|
|
M(:,:) = 0d0
|
|
|
|
|
|
|
|
do ab=1,nVV
|
|
|
|
M(ab,ab) = 1d0
|
|
|
|
end do
|
|
|
|
|
|
|
|
do ij=1,nOO
|
|
|
|
M(nVV+ij,nVV+ij) = -1d0
|
|
|
|
end do
|
|
|
|
|
|
|
|
! Start sorting eigenvectors
|
|
|
|
|
2019-10-15 23:13:00 +02:00
|
|
|
ab = 0
|
|
|
|
ij = 0
|
2019-10-22 23:03:01 +02:00
|
|
|
|
2019-10-15 23:13:00 +02:00
|
|
|
do pq=1,nOO+nVV
|
|
|
|
|
|
|
|
if(Omega(pq) > 0d0) then
|
|
|
|
|
|
|
|
ab = ab + 1
|
|
|
|
Omega1(ab) = Omega(pq)
|
2020-03-07 08:58:50 +01:00
|
|
|
Z1(1:nOO+nVV,ab) = Z(1:nOO+nVV,pq)
|
2019-10-15 23:13:00 +02:00
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
ij = ij + 1
|
|
|
|
Omega2(ij) = Omega(pq)
|
2020-03-07 08:58:50 +01:00
|
|
|
Z2(1:nOO+nVV,ij) = Z(1:nOO+nVV,pq)
|
2019-10-15 23:13:00 +02:00
|
|
|
|
|
|
|
end if
|
|
|
|
|
2023-06-14 16:53:16 +02:00
|
|
|
end do
|
2019-10-15 23:13:00 +02:00
|
|
|
|
|
|
|
if(minval(Omega1(:)) < 0d0 .or. ab /= nVV) call print_warning('You may have instabilities in pp-RPA!!')
|
|
|
|
if(maxval(Omega2(:)) > 0d0 .or. ij /= nOO) call print_warning('You may have instabilities in pp-RPA!!')
|
|
|
|
|
2020-03-25 21:10:21 +01:00
|
|
|
|
2020-03-25 22:11:00 +01:00
|
|
|
if(nVV > 0) then
|
|
|
|
|
|
|
|
do ab=1,nVV
|
|
|
|
order1(ab) = ab
|
|
|
|
end do
|
|
|
|
|
|
|
|
call quick_sort(Omega1(:),order1(:),nVV)
|
|
|
|
call set_order(Z1(:,:),order1(:),nOO+nVV,nVV)
|
|
|
|
|
|
|
|
end if
|
|
|
|
|
|
|
|
if(nOO > 0) then
|
|
|
|
|
|
|
|
do ij=1,nOO
|
|
|
|
order2(ij) = ij
|
|
|
|
end do
|
2020-03-25 21:10:21 +01:00
|
|
|
|
2020-03-25 22:11:00 +01:00
|
|
|
call quick_sort(Omega2(:),order2(:),nOO)
|
|
|
|
call set_order(Z2(:,:),order2(:),nOO+nVV,nOO)
|
2020-03-25 21:10:21 +01:00
|
|
|
|
2023-06-14 16:53:16 +02:00
|
|
|
end if
|
2020-03-25 21:10:21 +01:00
|
|
|
|
2020-03-07 08:58:50 +01:00
|
|
|
! Orthogonalize eigenvectors
|
|
|
|
|
2021-10-21 22:40:20 +02:00
|
|
|
! deg1 = 1
|
|
|
|
! ab_start = 1
|
2020-03-25 21:10:21 +01:00
|
|
|
|
2021-10-21 22:40:20 +02:00
|
|
|
! do ab=2,nVV
|
2020-03-25 21:10:21 +01:00
|
|
|
|
2021-10-21 22:40:20 +02:00
|
|
|
! if(abs(Omega1(ab-1) - Omega1(ab)) < 1d-6) then
|
2020-03-25 21:10:21 +01:00
|
|
|
|
2021-10-21 22:40:20 +02:00
|
|
|
! deg1 = deg1 + 1
|
2020-03-25 21:10:21 +01:00
|
|
|
|
2021-10-21 22:40:20 +02:00
|
|
|
! if(ab == nVV) then
|
2020-03-25 21:10:21 +01:00
|
|
|
|
2021-10-21 22:40:20 +02:00
|
|
|
! ab_end = ab
|
2020-04-13 20:13:38 +02:00
|
|
|
|
2021-10-21 22:40:20 +02:00
|
|
|
! allocate(S1(deg1,deg1),O1(deg1,deg1))
|
2020-04-13 20:13:38 +02:00
|
|
|
|
2021-10-21 22:40:20 +02:00
|
|
|
! S1 = matmul(transpose(Z1(:,ab_start:ab_end)),matmul(M,Z1(:,ab_start:ab_end)))
|
|
|
|
! call orthogonalization_matrix(1,deg1,S1,O1)
|
|
|
|
! Z1(:,ab_start:ab_end) = matmul(Z1(:,ab_start:ab_end),O1)
|
2020-04-13 20:13:38 +02:00
|
|
|
|
2021-10-21 22:40:20 +02:00
|
|
|
! deallocate(S1,O1)
|
2020-04-13 20:13:38 +02:00
|
|
|
|
2021-10-21 22:40:20 +02:00
|
|
|
! end if
|
2020-04-13 20:13:38 +02:00
|
|
|
|
2021-10-21 22:40:20 +02:00
|
|
|
! else
|
2020-04-13 20:13:38 +02:00
|
|
|
|
2021-10-21 22:40:20 +02:00
|
|
|
! ab_end = ab - 1
|
2020-04-13 20:13:38 +02:00
|
|
|
|
2021-10-21 22:40:20 +02:00
|
|
|
! allocate(S1(deg1,deg1),O1(deg1,deg1))
|
2020-03-25 21:10:21 +01:00
|
|
|
|
2021-10-21 22:40:20 +02:00
|
|
|
! S1 = matmul(transpose(Z1(:,ab_start:ab_end)),matmul(M,Z1(:,ab_start:ab_end)))
|
|
|
|
! call orthogonalization_matrix(1,deg1,S1,O1)
|
|
|
|
! Z1(:,ab_start:ab_end) = matmul(Z1(:,ab_start:ab_end),O1)
|
2020-04-13 20:13:38 +02:00
|
|
|
|
2021-10-21 22:40:20 +02:00
|
|
|
! deallocate(S1,O1)
|
2020-04-13 20:13:38 +02:00
|
|
|
|
2021-10-21 22:40:20 +02:00
|
|
|
! deg1 = 1
|
|
|
|
! ab_start = ab
|
2020-04-13 20:13:38 +02:00
|
|
|
|
2021-10-21 22:40:20 +02:00
|
|
|
! end if
|
|
|
|
! end do
|
2020-04-13 20:13:38 +02:00
|
|
|
|
2021-10-21 22:40:20 +02:00
|
|
|
! deg2 = 1
|
|
|
|
! ij_start = 1
|
2020-03-25 21:10:21 +01:00
|
|
|
|
2021-10-21 22:40:20 +02:00
|
|
|
! do ij=2,nOO
|
2020-03-25 21:10:21 +01:00
|
|
|
|
2021-10-21 22:40:20 +02:00
|
|
|
! if(abs(Omega2(ij-1) - Omega2(ij)) < 1d-6) then
|
2020-03-25 21:10:21 +01:00
|
|
|
|
2021-10-21 22:40:20 +02:00
|
|
|
! deg2 = deg2 + 1
|
2020-03-25 21:10:21 +01:00
|
|
|
|
2021-10-21 22:40:20 +02:00
|
|
|
! if(ij == nOO) then
|
2020-03-25 21:10:21 +01:00
|
|
|
|
2021-10-21 22:40:20 +02:00
|
|
|
! ij_end = ij
|
|
|
|
!
|
|
|
|
! allocate(S2(deg2,deg2),O2(deg2,deg2))
|
|
|
|
!
|
|
|
|
! S2 = - matmul(transpose(Z2(:,ij_start:ij_end)),matmul(M,Z2(:,ij_start:ij_end)))
|
|
|
|
! call orthogonalization_matrix(1,deg2,S2,O2)
|
|
|
|
! Z2(:,ij_start:ij_end) = matmul(Z2(:,ij_start:ij_end),O2)
|
|
|
|
!
|
|
|
|
! deallocate(S2,O2)
|
2020-03-25 21:10:21 +01:00
|
|
|
|
2021-10-21 22:40:20 +02:00
|
|
|
! end if
|
2020-03-25 21:10:21 +01:00
|
|
|
|
2021-10-21 22:40:20 +02:00
|
|
|
! else
|
2020-03-25 21:10:21 +01:00
|
|
|
|
2021-10-21 22:40:20 +02:00
|
|
|
! ij_end = ij - 1
|
2020-03-25 21:10:21 +01:00
|
|
|
|
2021-10-21 22:40:20 +02:00
|
|
|
! allocate(S2(deg2,deg2),O2(deg2,deg2))
|
2020-03-25 21:10:21 +01:00
|
|
|
|
2021-10-21 22:40:20 +02:00
|
|
|
! S2 = - matmul(transpose(Z2(:,ij_start:ij_end)),matmul(M,Z2(:,ij_start:ij_end)))
|
|
|
|
! call orthogonalization_matrix(1,deg2,S2,O2)
|
|
|
|
! Z2(:,ij_start:ij_end) = matmul(Z2(:,ij_start:ij_end),O2)
|
2020-03-25 21:10:21 +01:00
|
|
|
|
2021-10-21 22:40:20 +02:00
|
|
|
! deallocate(S2,O2)
|
2020-03-25 21:10:21 +01:00
|
|
|
|
2021-10-21 22:40:20 +02:00
|
|
|
! deg2 = 1
|
|
|
|
! ij_start = ij
|
2020-03-25 21:10:21 +01:00
|
|
|
|
2021-10-21 22:40:20 +02:00
|
|
|
! end if
|
2023-06-14 16:53:16 +02:00
|
|
|
! end do
|
|
|
|
|
2021-10-21 22:40:20 +02:00
|
|
|
allocate(S1(nVV,nVV),S2(nOO,nOO),O1(nVV,nVV),O2(nOO,nOO))
|
2023-06-14 16:53:16 +02:00
|
|
|
allocate(tmp1(nOO+nVV,nVV),tmp2(nOO+nVV,nOO))
|
|
|
|
|
2023-07-02 16:21:14 +02:00
|
|
|
if(nVV > 0) call dgemm ('N', 'N', nOO+nVV, nVV, nOO+nVV, 1d0, M, nOO+nVV, Z1, nOO+nVV, 0d0, tmp1, nOO+nVV)
|
|
|
|
if(nVV > 0) call dgemm ('T', 'N', nVV , nVV, nOO+nVV, 1d0, Z1, nOO+nVV, tmp1, nOO+nVV, 0d0, S1, nVV)
|
2023-06-30 16:47:26 +02:00
|
|
|
!S1 = + matmul(transpose(Z1),matmul(M,Z1))
|
|
|
|
|
2023-07-02 16:21:14 +02:00
|
|
|
if(nOO > 0) call dgemm ('N', 'N', nOO+nVV, nOO, nOO+nVV, 1d0, M, nOO+nVV, -1d0*Z2, nOO+nVV, 0d0, tmp2, nOO+nVV)
|
|
|
|
if(nOO > 0) call dgemm ('T', 'N', nOO , nOO, nOO+nVV, 1d0, Z2, nOO+nVV, tmp2, nOO+nVV, 0d0, S2, nOO)
|
2023-06-30 16:47:26 +02:00
|
|
|
! S2 = - matmul(transpose(Z2),matmul(M,Z2))
|
2020-03-25 21:10:21 +01:00
|
|
|
|
2021-10-21 22:40:20 +02:00
|
|
|
if(nVV > 0) call orthogonalization_matrix(1,nVV,S1,O1)
|
|
|
|
if(nOO > 0) call orthogonalization_matrix(1,nOO,S2,O2)
|
2020-03-07 08:58:50 +01:00
|
|
|
|
2023-06-30 16:47:26 +02:00
|
|
|
!Z1 = matmul(Z1,O1)
|
2023-07-02 16:21:14 +02:00
|
|
|
if(nVV > 0) call dgemm ('N', 'N', nOO+nVV,nVV,nVV, 1d0, Z1, nOO+nVV, O1, nVV,0d0, tmp1, nOO+nVV)
|
2023-06-30 16:47:26 +02:00
|
|
|
Z1 = tmp1
|
2023-07-02 16:21:14 +02:00
|
|
|
if(nOO > 0) call dgemm ('N', 'N', nOO+nVV,nOO,nOO, 1d0, Z2, nOO+nVV, O2, nOO,0d0, tmp2, nOO+nVV)
|
2023-06-30 16:47:26 +02:00
|
|
|
Z2 = tmp2
|
2020-03-21 16:31:39 +01:00
|
|
|
|
2020-03-24 12:28:56 +01:00
|
|
|
! Define submatrices X1, Y1, X2, & Y2
|
2020-03-07 08:58:50 +01:00
|
|
|
|
2020-03-24 12:28:56 +01:00
|
|
|
X1(1:nVV,1:nVV) = + Z1( 1: nVV,1:nVV)
|
|
|
|
Y1(1:nOO,1:nVV) = - Z1(nVV+1:nOO+nVV,1:nVV)
|
|
|
|
|
|
|
|
X2(1:nVV,1:nOO) = + Z2( 1: nVV,1:nOO)
|
|
|
|
Y2(1:nOO,1:nOO) = - Z2(nVV+1:nOO+nVV,1:nOO)
|
2020-03-07 08:58:50 +01:00
|
|
|
|
2022-11-28 10:52:06 +01:00
|
|
|
! call matout(nVV,nVV,X1)
|
|
|
|
! call matout(nOO,nVV,Y1)
|
|
|
|
|
|
|
|
! call matout(nVV,nOO,X2)
|
|
|
|
! call matout(nOO,nOO,Y2)
|
|
|
|
|
2023-07-18 14:59:18 +02:00
|
|
|
end subroutine
|