mirror of
https://github.com/QuantumPackage/qp2.git
synced 2024-12-23 12:03:30 +01:00
merged version: ok
This commit is contained in:
parent
0bea180fc6
commit
8bed36e93e
@ -76,14 +76,16 @@ END_PROVIDER
|
|||||||
|
|
||||||
! ---
|
! ---
|
||||||
|
|
||||||
|
|
||||||
BEGIN_PROVIDER [ double precision, overlap_mo_r, (mo_num, mo_num)]
|
BEGIN_PROVIDER [ double precision, overlap_mo_r, (mo_num, mo_num)]
|
||||||
&BEGIN_PROVIDER [ double precision, overlap_mo_l, (mo_num, mo_num)]
|
&BEGIN_PROVIDER [ double precision, overlap_mo_l, (mo_num, mo_num)]
|
||||||
implicit none
|
|
||||||
BEGIN_DOC
|
BEGIN_DOC
|
||||||
! overlap_mo_r_mo(j,i) = <MO_i|MO_R_j>
|
! overlap_mo_r_mo(j,i) = <MO_i|MO_R_j>
|
||||||
END_DOC
|
END_DOC
|
||||||
|
|
||||||
|
implicit none
|
||||||
integer :: i, j, p, q
|
integer :: i, j, p, q
|
||||||
|
|
||||||
overlap_mo_r = 0.d0
|
overlap_mo_r = 0.d0
|
||||||
overlap_mo_l = 0.d0
|
overlap_mo_l = 0.d0
|
||||||
do i = 1, mo_num
|
do i = 1, mo_num
|
||||||
@ -96,15 +98,21 @@ END_PROVIDER
|
|||||||
enddo
|
enddo
|
||||||
enddo
|
enddo
|
||||||
enddo
|
enddo
|
||||||
|
|
||||||
END_PROVIDER
|
END_PROVIDER
|
||||||
|
|
||||||
|
! ---
|
||||||
|
|
||||||
BEGIN_PROVIDER [ double precision, overlap_mo_r_mo, (mo_num, mo_num)]
|
BEGIN_PROVIDER [ double precision, overlap_mo_r_mo, (mo_num, mo_num)]
|
||||||
&BEGIN_PROVIDER [ double precision, overlap_mo_l_mo, (mo_num, mo_num)]
|
&BEGIN_PROVIDER [ double precision, overlap_mo_l_mo, (mo_num, mo_num)]
|
||||||
implicit none
|
|
||||||
BEGIN_DOC
|
BEGIN_DOC
|
||||||
! overlap_mo_r_mo(j,i) = <MO_j|MO_R_i>
|
! overlap_mo_r_mo(j,i) = <MO_j|MO_R_i>
|
||||||
END_DOC
|
END_DOC
|
||||||
|
|
||||||
|
implicit none
|
||||||
integer :: i, j, p, q
|
integer :: i, j, p, q
|
||||||
|
|
||||||
overlap_mo_r_mo = 0.d0
|
overlap_mo_r_mo = 0.d0
|
||||||
overlap_mo_l_mo = 0.d0
|
overlap_mo_l_mo = 0.d0
|
||||||
do i = 1, mo_num
|
do i = 1, mo_num
|
||||||
@ -117,16 +125,23 @@ END_PROVIDER
|
|||||||
enddo
|
enddo
|
||||||
enddo
|
enddo
|
||||||
enddo
|
enddo
|
||||||
|
|
||||||
END_PROVIDER
|
END_PROVIDER
|
||||||
|
|
||||||
|
! ---
|
||||||
|
|
||||||
BEGIN_PROVIDER [ double precision, angle_left_right, (mo_num)]
|
BEGIN_PROVIDER [ double precision, angle_left_right, (mo_num)]
|
||||||
&BEGIN_PROVIDER [ double precision, max_angle_left_right]
|
&BEGIN_PROVIDER [ double precision, max_angle_left_right]
|
||||||
implicit none
|
|
||||||
BEGIN_DOC
|
BEGIN_DOC
|
||||||
! angle_left_right(i) = angle between the left-eigenvector chi_i and the right-eigenvector phi_i
|
! angle_left_right(i) = angle between the left-eigenvector chi_i and the right-eigenvector phi_i
|
||||||
END_DOC
|
END_DOC
|
||||||
|
|
||||||
|
implicit none
|
||||||
integer :: i, j
|
integer :: i, j
|
||||||
double precision :: left, right, arg
|
double precision :: left, right, arg
|
||||||
|
double precision :: angle(mo_num)
|
||||||
|
|
||||||
do i = 1, mo_num
|
do i = 1, mo_num
|
||||||
left = overlap_mo_l(i,i)
|
left = overlap_mo_l(i,i)
|
||||||
right = overlap_mo_r(i,i)
|
right = overlap_mo_r(i,i)
|
||||||
@ -134,9 +149,12 @@ END_PROVIDER
|
|||||||
arg = max(arg, -1.d0)
|
arg = max(arg, -1.d0)
|
||||||
angle_left_right(i) = dacos(arg) * 180.d0/dacos(-1.d0)
|
angle_left_right(i) = dacos(arg) * 180.d0/dacos(-1.d0)
|
||||||
enddo
|
enddo
|
||||||
double precision :: angle(mo_num)
|
|
||||||
angle(1:mo_num) = dabs(angle_left_right(1:mo_num))
|
angle(1:mo_num) = dabs(angle_left_right(1:mo_num))
|
||||||
max_angle_left_right = maxval(angle)
|
max_angle_left_right = maxval(angle)
|
||||||
|
|
||||||
END_PROVIDER
|
END_PROVIDER
|
||||||
|
|
||||||
|
! ---
|
||||||
|
|
||||||
|
|
||||||
|
@ -732,7 +732,10 @@ subroutine fill_buffer_double(i_generator, sp, h1, h2, bannedOrb, banned, fock_d
|
|||||||
if (delta_E < 0.d0) then
|
if (delta_E < 0.d0) then
|
||||||
tmp = -tmp
|
tmp = -tmp
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
!e_pert(istate) = alpha_h_psi * alpha_h_psi / (E0(istate) - Hii)
|
||||||
e_pert(istate) = 0.5d0 * (tmp - delta_E)
|
e_pert(istate) = 0.5d0 * (tmp - delta_E)
|
||||||
|
|
||||||
if (dabs(alpha_h_psi) > 1.d-4) then
|
if (dabs(alpha_h_psi) > 1.d-4) then
|
||||||
coef(istate) = e_pert(istate) / alpha_h_psi
|
coef(istate) = e_pert(istate) / alpha_h_psi
|
||||||
else
|
else
|
||||||
|
@ -252,7 +252,7 @@ end subroutine non_hrmt_real_diag_new
|
|||||||
|
|
||||||
! ---
|
! ---
|
||||||
|
|
||||||
subroutine non_hrmt_bieig(n, A, leigvec, reigvec, n_real_eigv, eigval)
|
subroutine non_hrmt_bieig(n, A, thr_d, thr_nd, leigvec, reigvec, n_real_eigv, eigval)
|
||||||
|
|
||||||
BEGIN_DOC
|
BEGIN_DOC
|
||||||
!
|
!
|
||||||
@ -266,13 +266,14 @@ subroutine non_hrmt_bieig(n, A, leigvec, reigvec, n_real_eigv, eigval)
|
|||||||
implicit none
|
implicit none
|
||||||
integer, intent(in) :: n
|
integer, intent(in) :: n
|
||||||
double precision, intent(in) :: A(n,n)
|
double precision, intent(in) :: A(n,n)
|
||||||
|
double precision, intent(in) :: thr_d, thr_nd
|
||||||
integer, intent(out) :: n_real_eigv
|
integer, intent(out) :: n_real_eigv
|
||||||
double precision, intent(out) :: reigvec(n,n), leigvec(n,n), eigval(n)
|
double precision, intent(out) :: reigvec(n,n), leigvec(n,n), eigval(n)
|
||||||
|
|
||||||
integer :: i, j
|
integer :: i, j
|
||||||
integer :: n_good
|
integer :: n_good
|
||||||
double precision :: thr, thr_cut, thr_diag, thr_norm
|
double precision :: thr, thr_cut, thr_diag, thr_norm
|
||||||
double precision :: accu_d, accu_nd, thr_d, thr_nd
|
double precision :: accu_d, accu_nd
|
||||||
|
|
||||||
integer, allocatable :: list_good(:), iorder(:)
|
integer, allocatable :: list_good(:), iorder(:)
|
||||||
double precision, allocatable :: WR(:), WI(:), VL(:,:), VR(:,:)
|
double precision, allocatable :: WR(:), WI(:), VL(:,:), VR(:,:)
|
||||||
@ -393,22 +394,22 @@ subroutine non_hrmt_bieig(n, A, leigvec, reigvec, n_real_eigv, eigval)
|
|||||||
! -------------------------------------------------------------------------------------
|
! -------------------------------------------------------------------------------------
|
||||||
! check bi-orthogonality
|
! check bi-orthogonality
|
||||||
|
|
||||||
thr_d = 1d-10 ! -7
|
thr_diag = 10.d0
|
||||||
thr_nd = 1d-10 ! -7
|
thr_norm = 1d+10
|
||||||
|
|
||||||
allocate( S(n_real_eigv,n_real_eigv) )
|
allocate( S(n_real_eigv,n_real_eigv) )
|
||||||
call check_biorthog(n, n_real_eigv, leigvec, reigvec, accu_d, accu_nd, S, .false.)
|
call check_biorthog(n, n_real_eigv, leigvec, reigvec, accu_d, accu_nd, S, thr_d, thr_nd, .false.)
|
||||||
|
|
||||||
if( (accu_nd .lt. thr_nd) .and. (dabs(accu_d-dble(n_real_eigv)) .lt. thr_d) ) then
|
if( (accu_nd .lt. thr_nd) .and. (dabs(accu_d-dble(n_real_eigv))/dble(n_real_eigv) .lt. thr_d) ) then
|
||||||
|
|
||||||
print *, ' lapack vectors are normalized and bi-orthogonalized'
|
print *, ' lapack vectors are normalized and bi-orthogonalized'
|
||||||
deallocate(S)
|
deallocate(S)
|
||||||
return
|
return
|
||||||
|
|
||||||
elseif( (accu_nd .lt. thr_nd) .and. (dabs(accu_d-dble(n_real_eigv)) .gt. thr_d) ) then
|
elseif( (accu_nd .lt. thr_nd) .and. (dabs(accu_d-dble(n_real_eigv))/dble(n_real_eigv) .gt. thr_d) ) then
|
||||||
|
|
||||||
print *, ' lapack vectors are not normalized but bi-orthogonalized'
|
print *, ' lapack vectors are not normalized but bi-orthogonalized'
|
||||||
call check_biorthog_binormalize(n, n_real_eigv, leigvec, reigvec, .true.)
|
call check_biorthog_binormalize(n, n_real_eigv, leigvec, reigvec, thr_d, thr_nd, .true.)
|
||||||
|
|
||||||
call check_EIGVEC(n, n, A, eigval, leigvec, reigvec, thr_diag, thr_norm, .true.)
|
call check_EIGVEC(n, n, A, eigval, leigvec, reigvec, thr_diag, thr_norm, .true.)
|
||||||
|
|
||||||
@ -427,17 +428,17 @@ subroutine non_hrmt_bieig(n, A, leigvec, reigvec, n_real_eigv, eigval)
|
|||||||
call impose_biorthog_degen_eigvec(n, eigval, leigvec, reigvec)
|
call impose_biorthog_degen_eigvec(n, eigval, leigvec, reigvec)
|
||||||
|
|
||||||
|
|
||||||
!call impose_orthog_biorthog_degen_eigvec(n, eigval, leigvec, reigvec)
|
!call impose_orthog_biorthog_degen_eigvec(n, thr_d, thr_nd, eigval, leigvec, reigvec)
|
||||||
|
|
||||||
!call impose_unique_biorthog_degen_eigvec(n, eigval, mo_coef, ao_overlap, leigvec, reigvec)
|
!call impose_unique_biorthog_degen_eigvec(n, eigval, mo_coef, ao_overlap, leigvec, reigvec)
|
||||||
|
|
||||||
! ---
|
! ---
|
||||||
|
|
||||||
call check_biorthog(n, n_real_eigv, leigvec, reigvec, accu_d, accu_nd, S, .false.)
|
call check_biorthog(n, n_real_eigv, leigvec, reigvec, accu_d, accu_nd, S, thr_d, thr_nd, .false.)
|
||||||
if( (accu_nd .lt. thr_nd) .and. (dabs(accu_d-dble(n_real_eigv)) .gt. thr_d) ) then
|
if( (accu_nd .lt. thr_nd) .and. (dabs(accu_d-dble(n_real_eigv)) .gt. thr_d) ) then
|
||||||
call check_biorthog_binormalize(n, n_real_eigv, leigvec, reigvec, .true.)
|
call check_biorthog_binormalize(n, n_real_eigv, leigvec, reigvec, thr_d, thr_nd, .true.)
|
||||||
endif
|
endif
|
||||||
call check_biorthog(n, n_real_eigv, leigvec, reigvec, accu_d, accu_nd, S, .true.)
|
call check_biorthog(n, n_real_eigv, leigvec, reigvec, accu_d, accu_nd, S, thr_d, thr_nd, .true.)
|
||||||
|
|
||||||
!call impose_biorthog_qr(n, n_real_eigv, leigvec, reigvec)
|
!call impose_biorthog_qr(n, n_real_eigv, leigvec, reigvec)
|
||||||
!call impose_biorthog_lu(n, n_real_eigv, leigvec, reigvec)
|
!call impose_biorthog_lu(n, n_real_eigv, leigvec, reigvec)
|
||||||
|
@ -573,21 +573,22 @@ end subroutine non_hrmt_general_real_diag
|
|||||||
|
|
||||||
! ---
|
! ---
|
||||||
|
|
||||||
subroutine impose_biorthog_qr(m, n, Vl, Vr)
|
subroutine impose_biorthog_qr(m, n, thr_d, thr_nd, Vl, Vr)
|
||||||
|
|
||||||
implicit none
|
implicit none
|
||||||
integer, intent(in) :: m, n
|
integer, intent(in) :: m, n
|
||||||
|
double precision, intent(in) :: thr_d, thr_nd
|
||||||
double precision, intent(inout) :: Vl(m,n), Vr(m,n)
|
double precision, intent(inout) :: Vl(m,n), Vr(m,n)
|
||||||
|
|
||||||
integer :: i, j
|
integer :: i, j
|
||||||
integer :: LWORK, INFO
|
integer :: LWORK, INFO
|
||||||
double precision :: accu_nd, accu_d, thr_nd, thr_d
|
double precision :: accu_nd, accu_d
|
||||||
double precision, allocatable :: TAU(:), WORK(:)
|
double precision, allocatable :: TAU(:), WORK(:)
|
||||||
double precision, allocatable :: S(:,:), R(:,:), tmp(:,:)
|
double precision, allocatable :: S(:,:), R(:,:), tmp(:,:)
|
||||||
|
|
||||||
! ---
|
! ---
|
||||||
|
|
||||||
call check_biorthog_binormalize(m, n, Vl, Vr, .false.)
|
call check_biorthog_binormalize(m, n, Vl, Vr, thr_d, thr_nd, .false.)
|
||||||
|
|
||||||
! ---
|
! ---
|
||||||
|
|
||||||
@ -609,9 +610,7 @@ subroutine impose_biorthog_qr(m, n, Vl, Vr)
|
|||||||
enddo
|
enddo
|
||||||
accu_nd = dsqrt(accu_nd)
|
accu_nd = dsqrt(accu_nd)
|
||||||
|
|
||||||
thr_d = 1d-10
|
if((accu_nd .lt. thr_nd) .and. (dabs(accu_d-dble(n))/dble(n) .lt. thr_d)) then
|
||||||
thr_nd = 1d-08
|
|
||||||
if((accu_nd .lt. thr_nd) .and. (dabs(accu_d-dble(n)) .lt. thr_d)) then
|
|
||||||
print *, ' bi-orthogonal vectors without QR !'
|
print *, ' bi-orthogonal vectors without QR !'
|
||||||
deallocate(S)
|
deallocate(S)
|
||||||
return
|
return
|
||||||
@ -1011,7 +1010,7 @@ subroutine check_degen(n, m, eigval, leigvec, reigvec)
|
|||||||
double precision :: ei, ej, de, de_thr, accu_nd
|
double precision :: ei, ej, de, de_thr, accu_nd
|
||||||
double precision, allocatable :: S(:,:)
|
double precision, allocatable :: S(:,:)
|
||||||
|
|
||||||
de_thr = 1d-7
|
de_thr = 1d-6
|
||||||
|
|
||||||
do i = 1, m-1
|
do i = 1, m-1
|
||||||
ei = eigval(i)
|
ei = eigval(i)
|
||||||
@ -1082,7 +1081,7 @@ subroutine impose_weighted_orthog_svd(n, m, W, C)
|
|||||||
double precision, allocatable :: S(:,:), tmp(:,:)
|
double precision, allocatable :: S(:,:), tmp(:,:)
|
||||||
double precision, allocatable :: U(:,:), Vt(:,:), D(:)
|
double precision, allocatable :: U(:,:), Vt(:,:), D(:)
|
||||||
|
|
||||||
print *, ' apply SVD to orthogonalize vectors'
|
print *, ' apply SVD to orthogonalize & normalize weighted vectors'
|
||||||
|
|
||||||
! ---
|
! ---
|
||||||
|
|
||||||
@ -1097,7 +1096,7 @@ subroutine impose_weighted_orthog_svd(n, m, W, C)
|
|||||||
, 0.d0, S, size(S, 1) )
|
, 0.d0, S, size(S, 1) )
|
||||||
deallocate(tmp)
|
deallocate(tmp)
|
||||||
|
|
||||||
print *, ' eigenvec overlap bef SVD: '
|
print *, ' overlap bef SVD: '
|
||||||
do i = 1, m
|
do i = 1, m
|
||||||
write(*, '(1000(F16.10,X))') S(i,:)
|
write(*, '(1000(F16.10,X))') S(i,:)
|
||||||
enddo
|
enddo
|
||||||
@ -1160,7 +1159,7 @@ subroutine impose_weighted_orthog_svd(n, m, W, C)
|
|||||||
, 0.d0, S, size(S, 1) )
|
, 0.d0, S, size(S, 1) )
|
||||||
deallocate(tmp)
|
deallocate(tmp)
|
||||||
|
|
||||||
print *, ' eigenvec overlap aft SVD: '
|
print *, ' overlap aft SVD: '
|
||||||
do i = 1, m
|
do i = 1, m
|
||||||
write(*, '(1000(F16.10,X))') S(i,:)
|
write(*, '(1000(F16.10,X))') S(i,:)
|
||||||
enddo
|
enddo
|
||||||
@ -1185,7 +1184,7 @@ subroutine impose_orthog_svd(n, m, C)
|
|||||||
double precision, allocatable :: S(:,:), tmp(:,:)
|
double precision, allocatable :: S(:,:), tmp(:,:)
|
||||||
double precision, allocatable :: U(:,:), Vt(:,:), D(:)
|
double precision, allocatable :: U(:,:), Vt(:,:), D(:)
|
||||||
|
|
||||||
print *, ' apply SVD to orthogonalize vectors'
|
print *, ' apply SVD to orthogonalize & normalize vectors'
|
||||||
|
|
||||||
! ---
|
! ---
|
||||||
|
|
||||||
@ -1379,7 +1378,7 @@ subroutine impose_orthog_GramSchmidt(n, m, C)
|
|||||||
double precision, allocatable :: S(:,:)
|
double precision, allocatable :: S(:,:)
|
||||||
|
|
||||||
print *, ''
|
print *, ''
|
||||||
print *, ' apply Gram-Schmidt to orthogonalize vectors'
|
print *, ' apply Gram-Schmidt to orthogonalize & normalize vectors'
|
||||||
print *, ''
|
print *, ''
|
||||||
|
|
||||||
! ---
|
! ---
|
||||||
@ -1663,22 +1662,19 @@ end subroutine get_halfinv_svd
|
|||||||
|
|
||||||
! ---
|
! ---
|
||||||
|
|
||||||
subroutine check_biorthog_binormalize(n, m, Vl, Vr, stop_ifnot)
|
subroutine check_biorthog_binormalize(n, m, Vl, Vr, thr_d, thr_nd, stop_ifnot)
|
||||||
|
|
||||||
implicit none
|
implicit none
|
||||||
|
|
||||||
integer, intent(in) :: n, m
|
integer, intent(in) :: n, m
|
||||||
logical, intent(in) :: stop_ifnot
|
logical, intent(in) :: stop_ifnot
|
||||||
|
double precision, intent(in) :: thr_d, thr_nd
|
||||||
double precision, intent(inout) :: Vl(n,m), Vr(n,m)
|
double precision, intent(inout) :: Vl(n,m), Vr(n,m)
|
||||||
|
|
||||||
integer :: i, j
|
integer :: i, j
|
||||||
double precision :: thr_d, thr_nd
|
|
||||||
double precision :: accu_d, accu_nd, s_tmp
|
double precision :: accu_d, accu_nd, s_tmp
|
||||||
double precision, allocatable :: S(:,:)
|
double precision, allocatable :: S(:,:)
|
||||||
|
|
||||||
thr_d = 1d-6
|
|
||||||
thr_nd = 1d-7
|
|
||||||
|
|
||||||
print *, ' check bi-orthonormality'
|
print *, ' check bi-orthonormality'
|
||||||
|
|
||||||
! ---
|
! ---
|
||||||
@ -1713,7 +1709,7 @@ subroutine check_biorthog_binormalize(n, m, Vl, Vr, stop_ifnot)
|
|||||||
endif
|
endif
|
||||||
enddo
|
enddo
|
||||||
enddo
|
enddo
|
||||||
accu_nd = dsqrt(accu_nd)
|
accu_nd = dsqrt(accu_nd) / dble(m)
|
||||||
print*, ' diag acc: ', accu_d
|
print*, ' diag acc: ', accu_d
|
||||||
print*, ' nondiag acc: ', accu_nd
|
print*, ' nondiag acc: ', accu_nd
|
||||||
|
|
||||||
@ -1755,7 +1751,7 @@ subroutine check_biorthog_binormalize(n, m, Vl, Vr, stop_ifnot)
|
|||||||
endif
|
endif
|
||||||
enddo
|
enddo
|
||||||
enddo
|
enddo
|
||||||
accu_nd = dsqrt(accu_nd)
|
accu_nd = dsqrt(accu_nd) / dble(m)
|
||||||
print *, ' diag acc: ', accu_d
|
print *, ' diag acc: ', accu_d
|
||||||
print *, ' nondiag acc: ', accu_nd
|
print *, ' nondiag acc: ', accu_nd
|
||||||
|
|
||||||
@ -1774,22 +1770,19 @@ end subroutine check_biorthog_binormalize
|
|||||||
|
|
||||||
! ---
|
! ---
|
||||||
|
|
||||||
subroutine check_weighted_biorthog(n, m, W, Vl, Vr, accu_d, accu_nd, S, stop_ifnot)
|
subroutine check_weighted_biorthog(n, m, W, Vl, Vr, thr_d, thr_nd, accu_d, accu_nd, S, stop_ifnot)
|
||||||
|
|
||||||
implicit none
|
implicit none
|
||||||
|
|
||||||
integer, intent(in) :: n, m
|
integer, intent(in) :: n, m
|
||||||
double precision, intent(in) :: Vl(n,m), Vr(n,m), W(n,n)
|
double precision, intent(in) :: Vl(n,m), Vr(n,m), W(n,n)
|
||||||
|
double precision, intent(in) :: thr_d, thr_nd
|
||||||
logical, intent(in) :: stop_ifnot
|
logical, intent(in) :: stop_ifnot
|
||||||
double precision, intent(out) :: accu_d, accu_nd, S(m,m)
|
double precision, intent(out) :: accu_d, accu_nd, S(m,m)
|
||||||
|
|
||||||
integer :: i, j
|
integer :: i, j
|
||||||
double precision :: thr_d, thr_nd
|
|
||||||
double precision, allocatable :: SS(:,:), tmp(:,:)
|
double precision, allocatable :: SS(:,:), tmp(:,:)
|
||||||
|
|
||||||
thr_d = 1d-6
|
|
||||||
thr_nd = 1d-08
|
|
||||||
|
|
||||||
print *, ' check weighted bi-orthogonality'
|
print *, ' check weighted bi-orthogonality'
|
||||||
|
|
||||||
! ---
|
! ---
|
||||||
@ -1841,22 +1834,19 @@ end subroutine check_weighted_biorthog
|
|||||||
|
|
||||||
! ---
|
! ---
|
||||||
|
|
||||||
subroutine check_biorthog(n, m, Vl, Vr, accu_d, accu_nd, S, stop_ifnot)
|
subroutine check_biorthog(n, m, Vl, Vr, accu_d, accu_nd, S, thr_d, thr_nd, stop_ifnot)
|
||||||
|
|
||||||
implicit none
|
implicit none
|
||||||
|
|
||||||
integer, intent(in) :: n, m
|
integer, intent(in) :: n, m
|
||||||
double precision, intent(in) :: Vl(n,m), Vr(n,m)
|
double precision, intent(in) :: Vl(n,m), Vr(n,m)
|
||||||
logical, intent(in) :: stop_ifnot
|
logical, intent(in) :: stop_ifnot
|
||||||
|
double precision, intent(in) :: thr_d, thr_nd
|
||||||
double precision, intent(out) :: accu_d, accu_nd, S(m,m)
|
double precision, intent(out) :: accu_d, accu_nd, S(m,m)
|
||||||
|
|
||||||
integer :: i, j
|
integer :: i, j
|
||||||
double precision :: thr_d, thr_nd
|
|
||||||
double precision, allocatable :: SS(:,:)
|
double precision, allocatable :: SS(:,:)
|
||||||
|
|
||||||
thr_d = 1d-6
|
|
||||||
thr_nd = 1d-08
|
|
||||||
|
|
||||||
print *, ' check bi-orthogonality'
|
print *, ' check bi-orthogonality'
|
||||||
|
|
||||||
! ---
|
! ---
|
||||||
@ -1880,7 +1870,7 @@ subroutine check_biorthog(n, m, Vl, Vr, accu_d, accu_nd, S, stop_ifnot)
|
|||||||
endif
|
endif
|
||||||
enddo
|
enddo
|
||||||
enddo
|
enddo
|
||||||
accu_nd = dsqrt(accu_nd)
|
accu_nd = dsqrt(accu_nd) / dble(m)
|
||||||
|
|
||||||
print *, ' accu_nd = ', accu_nd
|
print *, ' accu_nd = ', accu_nd
|
||||||
print *, ' accu_d = ', dabs(accu_d-dble(m))/dble(m)
|
print *, ' accu_d = ', dabs(accu_d-dble(m))/dble(m)
|
||||||
@ -2029,7 +2019,7 @@ subroutine impose_biorthog_degen_eigvec(n, e0, L0, R0)
|
|||||||
|
|
||||||
call impose_biorthog_svd(n, m, L, R)
|
call impose_biorthog_svd(n, m, L, R)
|
||||||
|
|
||||||
!call impose_biorthog_qr(n, m, L, R)
|
!call impose_biorthog_qr(n, m, thr_d, thr_nd, L, R)
|
||||||
|
|
||||||
! ---
|
! ---
|
||||||
|
|
||||||
@ -2047,11 +2037,12 @@ end subroutine impose_biorthog_degen_eigvec
|
|||||||
|
|
||||||
! ---
|
! ---
|
||||||
|
|
||||||
subroutine impose_orthog_biorthog_degen_eigvec(n, e0, L0, R0)
|
subroutine impose_orthog_biorthog_degen_eigvec(n, thr_d, thr_nd, e0, L0, R0)
|
||||||
|
|
||||||
implicit none
|
implicit none
|
||||||
|
|
||||||
integer, intent(in) :: n
|
integer, intent(in) :: n
|
||||||
|
double precision, intent(in) :: thr_d, thr_nd
|
||||||
double precision, intent(in) :: e0(n)
|
double precision, intent(in) :: e0(n)
|
||||||
double precision, intent(inout) :: L0(n,n), R0(n,n)
|
double precision, intent(inout) :: L0(n,n), R0(n,n)
|
||||||
|
|
||||||
@ -2116,12 +2107,12 @@ subroutine impose_orthog_biorthog_degen_eigvec(n, e0, L0, R0)
|
|||||||
|
|
||||||
! ---
|
! ---
|
||||||
|
|
||||||
call impose_biorthog_qr(n, m, L, R)
|
call impose_biorthog_qr(n, m, thr_d, thr_nd, L, R)
|
||||||
|
|
||||||
allocate(S(m,m))
|
allocate(S(m,m))
|
||||||
call check_biorthog(n, m, L, R, accu_d, accu_nd, S, .true.)
|
call check_biorthog(n, m, L, R, accu_d, accu_nd, S, thr_d, thr_nd, .true.)
|
||||||
!call check_biorthog(n, m, L, L, accu_d, accu_nd, S, .true.)
|
!call check_biorthog(n, m, L, L, accu_d, accu_nd, S, thr_d, thr_nd, .true.)
|
||||||
!call check_biorthog(n, m, R, R, accu_d, accu_nd, S, .false.)
|
!call check_biorthog(n, m, R, R, accu_d, accu_nd, S, thr_d, thr_nd, .false.)
|
||||||
deallocate(S)
|
deallocate(S)
|
||||||
|
|
||||||
! ---
|
! ---
|
||||||
@ -2140,11 +2131,12 @@ end subroutine impose_orthog_biorthog_degen_eigvec
|
|||||||
|
|
||||||
! ---
|
! ---
|
||||||
|
|
||||||
subroutine impose_unique_biorthog_degen_eigvec(n, e0, C0, W0, L0, R0)
|
subroutine impose_unique_biorthog_degen_eigvec(n, thr_d, thr_nd, e0, C0, W0, L0, R0)
|
||||||
|
|
||||||
implicit none
|
implicit none
|
||||||
|
|
||||||
integer, intent(in) :: n
|
integer, intent(in) :: n
|
||||||
|
double precision, intent(in) :: thr_d, thr_nd
|
||||||
double precision, intent(in) :: e0(n), W0(n,n), C0(n,n)
|
double precision, intent(in) :: e0(n), W0(n,n), C0(n,n)
|
||||||
double precision, intent(inout) :: L0(n,n), R0(n,n)
|
double precision, intent(inout) :: L0(n,n), R0(n,n)
|
||||||
|
|
||||||
@ -2255,7 +2247,7 @@ subroutine impose_unique_biorthog_degen_eigvec(n, e0, C0, W0, L0, R0)
|
|||||||
call get_inv_half_nonsymmat_diago(S, m, S_inv_half, complex_root)
|
call get_inv_half_nonsymmat_diago(S, m, S_inv_half, complex_root)
|
||||||
if(complex_root)then
|
if(complex_root)then
|
||||||
call impose_biorthog_svd(n, m, L, R)
|
call impose_biorthog_svd(n, m, L, R)
|
||||||
!call impose_biorthog_qr(n, m, L, R)
|
!call impose_biorthog_qr(n, m, thr_d, thr_nd, L, R)
|
||||||
else
|
else
|
||||||
call bi_ortho_s_inv_half(m, L, R, S_inv_half)
|
call bi_ortho_s_inv_half(m, L, R, S_inv_half)
|
||||||
endif
|
endif
|
||||||
@ -2502,8 +2494,288 @@ end subroutine impose_biorthog_svd
|
|||||||
|
|
||||||
! ---
|
! ---
|
||||||
|
|
||||||
|
subroutine impose_weighted_biorthog_qr(m, n, thr_d, thr_nd, Vl, W, Vr)
|
||||||
|
|
||||||
subroutine impose_biorthog_svd_overlap(n, m, overlap, L, R)
|
implicit none
|
||||||
|
integer, intent(in) :: m, n
|
||||||
|
double precision, intent(in) :: thr_d, thr_nd
|
||||||
|
double precision, intent(inout) :: Vl(m,n), W(m,m), Vr(m,n)
|
||||||
|
|
||||||
|
integer :: i, j
|
||||||
|
integer :: LWORK, INFO
|
||||||
|
double precision :: accu_nd, accu_d
|
||||||
|
double precision, allocatable :: TAU(:), WORK(:)
|
||||||
|
double precision, allocatable :: S(:,:), R(:,:), tmp(:,:), Stmp(:,:)
|
||||||
|
|
||||||
|
|
||||||
|
call check_weighted_biorthog_binormalize(m, n, Vl, W, Vr, thr_d, thr_nd, .false.)
|
||||||
|
|
||||||
|
! ---
|
||||||
|
|
||||||
|
allocate(Stmp(n,m), S(n,n))
|
||||||
|
call dgemm( 'T', 'N', n, m, m, 1.d0 &
|
||||||
|
, Vl, size(Vl, 1), W, size(W, 1) &
|
||||||
|
, 0.d0, Stmp, size(Stmp, 1) )
|
||||||
|
call dgemm( 'N', 'N', n, n, m, 1.d0 &
|
||||||
|
, Stmp, size(Stmp, 1), Vr, size(Vr, 1) &
|
||||||
|
, 0.d0, S, size(S, 1) )
|
||||||
|
deallocate(Stmp)
|
||||||
|
|
||||||
|
accu_nd = 0.d0
|
||||||
|
accu_d = 0.d0
|
||||||
|
do i = 1, n
|
||||||
|
do j = 1, n
|
||||||
|
if(i==j) then
|
||||||
|
accu_d += S(j,i)
|
||||||
|
else
|
||||||
|
accu_nd = accu_nd + S(j,i) * S(j,i)
|
||||||
|
endif
|
||||||
|
enddo
|
||||||
|
enddo
|
||||||
|
accu_nd = dsqrt(accu_nd)
|
||||||
|
|
||||||
|
if((accu_nd .lt. thr_nd) .and. (dabs(accu_d-dble(n))/dble(n) .lt. thr_d)) then
|
||||||
|
print *, ' bi-orthogonal vectors without QR !'
|
||||||
|
deallocate(S)
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
! -------------------------------------------------------------------------------------
|
||||||
|
! QR factorization of S: S = Q x R
|
||||||
|
|
||||||
|
|
||||||
|
print *, ' apply QR decomposition ...'
|
||||||
|
|
||||||
|
allocate( TAU(n), WORK(1) )
|
||||||
|
|
||||||
|
LWORK = -1
|
||||||
|
call dgeqrf(n, n, S, n, TAU, WORK, LWORK, INFO)
|
||||||
|
if(INFO .ne. 0) then
|
||||||
|
print*,'dgeqrf failed !!', INFO
|
||||||
|
stop
|
||||||
|
endif
|
||||||
|
|
||||||
|
LWORK = max(n, int(WORK(1)))
|
||||||
|
deallocate(WORK)
|
||||||
|
|
||||||
|
allocate( WORK(LWORK) )
|
||||||
|
call dgeqrf(n, n, S, n, TAU, WORK, LWORK, INFO)
|
||||||
|
if(INFO .ne. 0) then
|
||||||
|
print*,'dgeqrf failed !!', INFO
|
||||||
|
stop
|
||||||
|
endif
|
||||||
|
|
||||||
|
! save the upper triangular R
|
||||||
|
allocate( R(n,n) )
|
||||||
|
R(:,:) = S(:,:)
|
||||||
|
|
||||||
|
! get Q
|
||||||
|
LWORK = -1
|
||||||
|
call dorgqr(n, n, n, S, n, TAU, WORK, LWORK, INFO)
|
||||||
|
if(INFO .ne. 0) then
|
||||||
|
print*,'dorgqr failed !!', INFO
|
||||||
|
stop
|
||||||
|
endif
|
||||||
|
|
||||||
|
LWORK = max(n, int(WORK(1)))
|
||||||
|
deallocate(WORK)
|
||||||
|
|
||||||
|
allocate( WORK(LWORK) )
|
||||||
|
call dorgqr(n, n, n, S, n, TAU, WORK, LWORK, INFO)
|
||||||
|
if(INFO .ne. 0) then
|
||||||
|
print*,'dorgqr failed !!', INFO
|
||||||
|
stop
|
||||||
|
endif
|
||||||
|
|
||||||
|
deallocate( WORK, TAU )
|
||||||
|
|
||||||
|
!
|
||||||
|
! -------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
! ---
|
||||||
|
|
||||||
|
! -------------------------------------------------------------------------------------
|
||||||
|
! get bi-orhtog left & right vectors:
|
||||||
|
! Vr' = Vr x inv(R)
|
||||||
|
! Vl' = inv(Q) x Vl = Q.T x Vl
|
||||||
|
|
||||||
|
! Q.T x Vl, where Q = S
|
||||||
|
|
||||||
|
allocate( tmp(n,m) )
|
||||||
|
call dgemm( 'T', 'T', n, m, n, 1.d0 &
|
||||||
|
, S, size(S, 1), Vl, size(Vl, 1) &
|
||||||
|
, 0.d0, tmp, size(tmp, 1) )
|
||||||
|
|
||||||
|
do i = 1, n
|
||||||
|
do j = 1, m
|
||||||
|
Vl(j,i) = tmp(i,j)
|
||||||
|
enddo
|
||||||
|
enddo
|
||||||
|
deallocate(tmp)
|
||||||
|
|
||||||
|
! ---
|
||||||
|
|
||||||
|
! inv(R)
|
||||||
|
!print *, ' inversing upper triangular matrix ...'
|
||||||
|
call dtrtri("U", "N", n, R, n, INFO)
|
||||||
|
if(INFO .ne. 0) then
|
||||||
|
print*,'dtrtri failed !!', INFO
|
||||||
|
stop
|
||||||
|
endif
|
||||||
|
!print *, ' inversing upper triangular matrix OK'
|
||||||
|
|
||||||
|
do i = 1, n-1
|
||||||
|
do j = i+1, n
|
||||||
|
R(j,i) = 0.d0
|
||||||
|
enddo
|
||||||
|
enddo
|
||||||
|
|
||||||
|
!print *, ' inv(R):'
|
||||||
|
!do i = 1, n
|
||||||
|
! write(*, '(1000(F16.10,X))') R(i,:)
|
||||||
|
!enddo
|
||||||
|
|
||||||
|
! Vr x inv(R)
|
||||||
|
allocate( tmp(m,n) )
|
||||||
|
call dgemm( 'N', 'N', m, n, n, 1.d0 &
|
||||||
|
, Vr, size(Vr, 1), R, size(R, 1) &
|
||||||
|
, 0.d0, tmp, size(tmp, 1) )
|
||||||
|
deallocate( R )
|
||||||
|
|
||||||
|
do i = 1, n
|
||||||
|
do j = 1, m
|
||||||
|
Vr(j,i) = tmp(j,i)
|
||||||
|
enddo
|
||||||
|
enddo
|
||||||
|
deallocate(tmp)
|
||||||
|
|
||||||
|
call check_weighted_biorthog_binormalize(m, n, Vl, W, Vr, thr_d, thr_nd, .false.)
|
||||||
|
|
||||||
|
return
|
||||||
|
end subroutine impose_weighted_biorthog_qr
|
||||||
|
|
||||||
|
! ---
|
||||||
|
|
||||||
|
subroutine check_weighted_biorthog_binormalize(n, m, Vl, W, Vr, thr_d, thr_nd, stop_ifnot)
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
|
||||||
|
integer, intent(in) :: n, m
|
||||||
|
logical, intent(in) :: stop_ifnot
|
||||||
|
double precision, intent(in) :: thr_d, thr_nd
|
||||||
|
double precision, intent(inout) :: Vl(n,m), W(n,n), Vr(n,m)
|
||||||
|
|
||||||
|
integer :: i, j
|
||||||
|
double precision :: accu_d, accu_nd, s_tmp
|
||||||
|
double precision, allocatable :: S(:,:), Stmp(:,:)
|
||||||
|
|
||||||
|
print *, ' check weighted bi-orthonormality'
|
||||||
|
|
||||||
|
! ---
|
||||||
|
|
||||||
|
allocate(Stmp(m,n), S(m,m))
|
||||||
|
call dgemm( 'T', 'N', m, n, n, 1.d0 &
|
||||||
|
, Vl, size(Vl, 1), W, size(W, 1) &
|
||||||
|
, 0.d0, Stmp, size(Stmp, 1) )
|
||||||
|
call dgemm( 'N', 'N', m, m, n, 1.d0 &
|
||||||
|
, Stmp, size(Stmp, 1), Vr, size(Vr, 1) &
|
||||||
|
, 0.d0, S, size(S, 1) )
|
||||||
|
deallocate(Stmp)
|
||||||
|
!print *, ' overlap matrix before:'
|
||||||
|
!do i = 1, m
|
||||||
|
! write(*,'(1000(F16.10,X))') S(i,:)
|
||||||
|
!enddo
|
||||||
|
|
||||||
|
! S(i,i) = -1
|
||||||
|
do i = 1, m
|
||||||
|
if( (S(i,i) + 1.d0) .lt. thr_d ) then
|
||||||
|
do j = 1, n
|
||||||
|
Vl(j,i) = -1.d0 * Vl(j,i)
|
||||||
|
enddo
|
||||||
|
S(i,i) = 1.d0
|
||||||
|
endif
|
||||||
|
enddo
|
||||||
|
|
||||||
|
accu_d = 0.d0
|
||||||
|
accu_nd = 0.d0
|
||||||
|
do i = 1, m
|
||||||
|
do j = 1, m
|
||||||
|
if(i==j) then
|
||||||
|
accu_d = accu_d + S(i,i)
|
||||||
|
else
|
||||||
|
accu_nd = accu_nd + S(j,i) * S(j,i)
|
||||||
|
endif
|
||||||
|
enddo
|
||||||
|
enddo
|
||||||
|
accu_nd = dsqrt(accu_nd) / dble(m)
|
||||||
|
print*, ' diag acc: ', accu_d
|
||||||
|
print*, ' nondiag acc: ', accu_nd
|
||||||
|
|
||||||
|
! ---
|
||||||
|
|
||||||
|
if( (accu_nd .lt. thr_nd) .and. (dabs(accu_d-dble(m))/dble(m) .gt. thr_d) ) then
|
||||||
|
|
||||||
|
do i = 1, m
|
||||||
|
print *, i, S(i,i)
|
||||||
|
if(dabs(S(i,i) - 1.d0) .gt. thr_d) then
|
||||||
|
s_tmp = 1.d0 / dsqrt(S(i,i))
|
||||||
|
do j = 1, n
|
||||||
|
Vl(j,i) = Vl(j,i) * s_tmp
|
||||||
|
Vr(j,i) = Vr(j,i) * s_tmp
|
||||||
|
enddo
|
||||||
|
endif
|
||||||
|
enddo
|
||||||
|
|
||||||
|
endif
|
||||||
|
|
||||||
|
! ---
|
||||||
|
|
||||||
|
allocate(Stmp(m,n))
|
||||||
|
call dgemm( 'T', 'N', m, n, n, 1.d0 &
|
||||||
|
, Vl, size(Vl, 1), W, size(W, 1) &
|
||||||
|
, 0.d0, Stmp, size(Stmp, 1) )
|
||||||
|
call dgemm( 'N', 'N', m, m, n, 1.d0 &
|
||||||
|
, Stmp, size(Stmp, 1), Vr, size(Vr, 1) &
|
||||||
|
, 0.d0, S, size(S, 1) )
|
||||||
|
deallocate(Stmp)
|
||||||
|
!print *, ' overlap matrix after:'
|
||||||
|
!do i = 1, m
|
||||||
|
! write(*,'(1000(F16.10,X))') S(i,:)
|
||||||
|
!enddo
|
||||||
|
|
||||||
|
accu_d = 0.d0
|
||||||
|
accu_nd = 0.d0
|
||||||
|
do i = 1, m
|
||||||
|
do j = 1, m
|
||||||
|
if(i==j) then
|
||||||
|
accu_d = accu_d + S(i,i)
|
||||||
|
else
|
||||||
|
accu_nd = accu_nd + S(j,i) * S(j,i)
|
||||||
|
endif
|
||||||
|
enddo
|
||||||
|
enddo
|
||||||
|
accu_nd = dsqrt(accu_nd) / dble(m)
|
||||||
|
print *, ' diag acc: ', accu_d
|
||||||
|
print *, ' nondiag acc: ', accu_nd
|
||||||
|
|
||||||
|
deallocate(S)
|
||||||
|
|
||||||
|
! ---
|
||||||
|
|
||||||
|
if( stop_ifnot .and. ((accu_nd .gt. thr_nd) .or. (dabs(accu_d-dble(m))/dble(m) .gt. thr_d)) ) then
|
||||||
|
print *, accu_nd, thr_nd
|
||||||
|
print *, dabs(accu_d-dble(m))/dble(m), thr_d
|
||||||
|
print *, ' weighted biorthog_binormalize failed !'
|
||||||
|
stop
|
||||||
|
endif
|
||||||
|
|
||||||
|
end subroutine check_weighted_biorthog_binormalize
|
||||||
|
|
||||||
|
! ---
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
subroutine impose_weighted_biorthog_svd(n, m, overlap, L, R)
|
||||||
|
|
||||||
implicit none
|
implicit none
|
||||||
|
|
||||||
@ -2527,6 +2799,7 @@ subroutine impose_biorthog_svd_overlap(n, m, overlap, L, R)
|
|||||||
call dgemm( 'T', 'N', m, m, n, 1.d0 &
|
call dgemm( 'T', 'N', m, m, n, 1.d0 &
|
||||||
, L, size(L, 1), Stmp, size(Stmp, 1) &
|
, L, size(L, 1), Stmp, size(Stmp, 1) &
|
||||||
, 0.d0, S, size(S, 1) )
|
, 0.d0, S, size(S, 1) )
|
||||||
|
deallocate(Stmp)
|
||||||
|
|
||||||
print *, ' overlap bef SVD: '
|
print *, ' overlap bef SVD: '
|
||||||
do i = 1, m
|
do i = 1, m
|
||||||
@ -2598,10 +2871,7 @@ subroutine impose_biorthog_svd_overlap(n, m, overlap, L, R)
|
|||||||
|
|
||||||
! ---
|
! ---
|
||||||
|
|
||||||
allocate(S(m,m))
|
allocate(S(m,m),Stmp(n,m))
|
||||||
! call dgemm( 'T', 'N', m, m, n, 1.d0 &
|
|
||||||
! , L, size(L, 1), R, size(R, 1) &
|
|
||||||
! , 0.d0, S, size(S, 1) )
|
|
||||||
! S = C.T x overlap x C
|
! S = C.T x overlap x C
|
||||||
call dgemm( 'N', 'N', n, m, n, 1.d0 &
|
call dgemm( 'N', 'N', n, m, n, 1.d0 &
|
||||||
, overlap, size(overlap, 1), R, size(R, 1) &
|
, overlap, size(overlap, 1), R, size(R, 1) &
|
||||||
@ -2609,6 +2879,7 @@ subroutine impose_biorthog_svd_overlap(n, m, overlap, L, R)
|
|||||||
call dgemm( 'T', 'N', m, m, n, 1.d0 &
|
call dgemm( 'T', 'N', m, m, n, 1.d0 &
|
||||||
, L, size(L, 1), Stmp, size(Stmp, 1) &
|
, L, size(L, 1), Stmp, size(Stmp, 1) &
|
||||||
, 0.d0, S, size(S, 1) )
|
, 0.d0, S, size(S, 1) )
|
||||||
|
deallocate(Stmp)
|
||||||
|
|
||||||
print *, ' overlap aft SVD with overlap: '
|
print *, ' overlap aft SVD with overlap: '
|
||||||
do i = 1, m
|
do i = 1, m
|
||||||
@ -2618,7 +2889,7 @@ subroutine impose_biorthog_svd_overlap(n, m, overlap, L, R)
|
|||||||
|
|
||||||
! ---
|
! ---
|
||||||
|
|
||||||
end subroutine impose_biorthog_svd
|
end subroutine impose_weighted_biorthog_svd
|
||||||
|
|
||||||
! ---
|
! ---
|
||||||
|
|
||||||
|
@ -1,37 +1,50 @@
|
|||||||
|
|
||||||
|
! ---
|
||||||
|
|
||||||
BEGIN_PROVIDER [ double precision, natorb_tc_reigvec_mo, (mo_num, mo_num)]
|
BEGIN_PROVIDER [ double precision, natorb_tc_reigvec_mo, (mo_num, mo_num)]
|
||||||
&BEGIN_PROVIDER [ double precision, natorb_tc_leigvec_mo, (mo_num, mo_num)]
|
&BEGIN_PROVIDER [ double precision, natorb_tc_leigvec_mo, (mo_num, mo_num)]
|
||||||
&BEGIN_PROVIDER [ double precision, natorb_tc_eigval, (mo_num)]
|
&BEGIN_PROVIDER [ double precision, natorb_tc_eigval, (mo_num)]
|
||||||
implicit none
|
|
||||||
BEGIN_DOC
|
BEGIN_DOC
|
||||||
|
!
|
||||||
! natorb_tc_reigvec_mo : RIGHT eigenvectors of the ground state transition matrix (equivalent of natural orbitals)
|
! natorb_tc_reigvec_mo : RIGHT eigenvectors of the ground state transition matrix (equivalent of natural orbitals)
|
||||||
! natorb_tc_leigvec_mo : LEFT eigenvectors of the ground state transition matrix (equivalent of natural orbitals)
|
! natorb_tc_leigvec_mo : LEFT eigenvectors of the ground state transition matrix (equivalent of natural orbitals)
|
||||||
! natorb_tc_eigval : eigenvalues of the ground state transition matrix (equivalent of the occupation numbers). WARNINING :: can be negative !!
|
! natorb_tc_eigval : eigenvalues of the ground state transition matrix (equivalent of the occupation numbers). WARNINING :: can be negative !!
|
||||||
|
!
|
||||||
END_DOC
|
END_DOC
|
||||||
double precision, allocatable :: dm_tmp(:,:),fock_diag(:)
|
|
||||||
double precision :: thr_deg
|
implicit none
|
||||||
integer :: i, j, k, n_real
|
integer :: i, j, k, n_real
|
||||||
|
double precision :: thr_d, thr_nd, thr_deg, accu
|
||||||
|
double precision :: accu_d, accu_nd
|
||||||
|
double precision, allocatable :: dm_tmp(:,:), fock_diag(:)
|
||||||
|
|
||||||
allocate(dm_tmp(mo_num,mo_num), fock_diag(mo_num))
|
allocate(dm_tmp(mo_num,mo_num), fock_diag(mo_num))
|
||||||
|
|
||||||
dm_tmp(:,:) = -tc_transition_matrix(:,:,1,1)
|
dm_tmp(:,:) = -tc_transition_matrix(:,:,1,1)
|
||||||
|
|
||||||
print *, ' dm_tmp'
|
print *, ' dm_tmp'
|
||||||
do i = 1, mo_num
|
do i = 1, mo_num
|
||||||
fock_diag(i) = fock_matrix_tc_mo_tot(i,i)
|
fock_diag(i) = fock_matrix_tc_mo_tot(i,i)
|
||||||
write(*, '(100(F16.10,X))') -dm_tmp(:,i)
|
write(*, '(100(F16.10,X))') -dm_tmp(:,i)
|
||||||
enddo
|
enddo
|
||||||
|
|
||||||
|
thr_d = 1.d-6
|
||||||
|
thr_nd = 1.d-6
|
||||||
thr_deg = 1.d-3
|
thr_deg = 1.d-3
|
||||||
call diag_mat_per_fock_degen(fock_diag,dm_tmp,mo_num,thr_deg,&
|
call diag_mat_per_fock_degen( fock_diag, dm_tmp, mo_num, thr_d, thr_nd, thr_deg &
|
||||||
natorb_tc_leigvec_mo,natorb_tc_reigvec_mo,&
|
, natorb_tc_leigvec_mo, natorb_tc_reigvec_mo, natorb_tc_eigval)
|
||||||
natorb_tc_eigval)
|
|
||||||
! call non_hrmt_bieig( mo_num, dm_tmp&
|
! call non_hrmt_bieig( mo_num, dm_tmp&
|
||||||
! , natorb_tc_leigvec_mo, natorb_tc_reigvec_mo&
|
! , natorb_tc_leigvec_mo, natorb_tc_reigvec_mo&
|
||||||
! , n_real, natorb_tc_eigval )
|
! , n_real, natorb_tc_eigval )
|
||||||
double precision :: accu
|
|
||||||
accu = 0.d0
|
accu = 0.d0
|
||||||
do i = 1, n_real
|
do i = 1, n_real
|
||||||
print*,'natorb_tc_eigval(i) = ',-natorb_tc_eigval(i)
|
print*,'natorb_tc_eigval(i) = ',-natorb_tc_eigval(i)
|
||||||
accu += -natorb_tc_eigval(i)
|
accu += -natorb_tc_eigval(i)
|
||||||
enddo
|
enddo
|
||||||
print *, ' accu = ', accu
|
print *, ' accu = ', accu
|
||||||
|
|
||||||
dm_tmp = 0.d0
|
dm_tmp = 0.d0
|
||||||
do i = 1, n_real
|
do i = 1, n_real
|
||||||
accu = 0.d0
|
accu = 0.d0
|
||||||
@ -47,7 +60,7 @@
|
|||||||
enddo
|
enddo
|
||||||
enddo
|
enddo
|
||||||
enddo
|
enddo
|
||||||
double precision :: accu_d, accu_nd
|
|
||||||
accu_d = 0.d0
|
accu_d = 0.d0
|
||||||
accu_nd = 0.d0
|
accu_nd = 0.d0
|
||||||
do i = 1, mo_num
|
do i = 1, mo_num
|
||||||
@ -61,19 +74,27 @@
|
|||||||
print *, ' Trace of the overlap between TC natural orbitals ', accu_d
|
print *, ' Trace of the overlap between TC natural orbitals ', accu_d
|
||||||
print *, ' L1 norm of extra diagonal elements of overlap matrix ', accu_nd
|
print *, ' L1 norm of extra diagonal elements of overlap matrix ', accu_nd
|
||||||
|
|
||||||
|
deallocate(dm_tmp, fock_diag)
|
||||||
|
|
||||||
END_PROVIDER
|
END_PROVIDER
|
||||||
|
|
||||||
|
! ---
|
||||||
|
|
||||||
BEGIN_PROVIDER [ double precision, fock_diag_sorted_r_natorb, (mo_num, mo_num)]
|
BEGIN_PROVIDER [ double precision, fock_diag_sorted_r_natorb, (mo_num, mo_num)]
|
||||||
&BEGIN_PROVIDER [ double precision, fock_diag_sorted_l_natorb, (mo_num, mo_num)]
|
&BEGIN_PROVIDER [ double precision, fock_diag_sorted_l_natorb, (mo_num, mo_num)]
|
||||||
&BEGIN_PROVIDER [ double precision, fock_diag_sorted_v_natorb, (mo_num)]
|
&BEGIN_PROVIDER [ double precision, fock_diag_sorted_v_natorb, (mo_num)]
|
||||||
|
|
||||||
implicit none
|
implicit none
|
||||||
integer :: i,j,k
|
integer :: i,j,k
|
||||||
|
integer, allocatable :: iorder(:)
|
||||||
|
double precision, allocatable :: fock_diag(:)
|
||||||
|
|
||||||
print *, ' Diagonal elements of the Fock matrix before '
|
print *, ' Diagonal elements of the Fock matrix before '
|
||||||
|
|
||||||
do i = 1, mo_num
|
do i = 1, mo_num
|
||||||
write(*,*) i, Fock_matrix_tc_mo_tot(i,i)
|
write(*,*) i, Fock_matrix_tc_mo_tot(i,i)
|
||||||
enddo
|
enddo
|
||||||
double precision, allocatable :: fock_diag(:)
|
|
||||||
allocate(fock_diag(mo_num))
|
allocate(fock_diag(mo_num))
|
||||||
fock_diag = 0.d0
|
fock_diag = 0.d0
|
||||||
do i = 1, mo_num
|
do i = 1, mo_num
|
||||||
@ -84,16 +105,19 @@
|
|||||||
enddo
|
enddo
|
||||||
enddo
|
enddo
|
||||||
enddo
|
enddo
|
||||||
integer, allocatable :: iorder(:)
|
|
||||||
allocate(iorder(mo_num))
|
allocate(iorder(mo_num))
|
||||||
do i = 1, mo_num
|
do i = 1, mo_num
|
||||||
iorder(i) = i
|
iorder(i) = i
|
||||||
enddo
|
enddo
|
||||||
call dsort(fock_diag, iorder, mo_num)
|
call dsort(fock_diag, iorder, mo_num)
|
||||||
|
|
||||||
print *, ' Diagonal elements of the Fock matrix after '
|
print *, ' Diagonal elements of the Fock matrix after '
|
||||||
do i = 1, mo_num
|
do i = 1, mo_num
|
||||||
write(*,*) i, fock_diag(i)
|
write(*,*) i, fock_diag(i)
|
||||||
enddo
|
enddo
|
||||||
|
deallocate(fock_diag)
|
||||||
|
|
||||||
do i = 1, mo_num
|
do i = 1, mo_num
|
||||||
fock_diag_sorted_v_natorb(i) = natorb_tc_eigval(iorder(i))
|
fock_diag_sorted_v_natorb(i) = natorb_tc_eigval(iorder(i))
|
||||||
do j = 1, mo_num
|
do j = 1, mo_num
|
||||||
@ -101,10 +125,11 @@
|
|||||||
fock_diag_sorted_l_natorb(j,i) = natorb_tc_leigvec_mo(j,iorder(i))
|
fock_diag_sorted_l_natorb(j,i) = natorb_tc_leigvec_mo(j,iorder(i))
|
||||||
enddo
|
enddo
|
||||||
enddo
|
enddo
|
||||||
|
deallocate(iorder)
|
||||||
|
|
||||||
END_PROVIDER
|
END_PROVIDER
|
||||||
|
|
||||||
|
! ---
|
||||||
|
|
||||||
BEGIN_PROVIDER [ double precision, natorb_tc_reigvec_ao, (ao_num, mo_num)]
|
BEGIN_PROVIDER [ double precision, natorb_tc_reigvec_ao, (ao_num, mo_num)]
|
||||||
&BEGIN_PROVIDER [ double precision, natorb_tc_leigvec_ao, (ao_num, mo_num)]
|
&BEGIN_PROVIDER [ double precision, natorb_tc_leigvec_ao, (ao_num, mo_num)]
|
||||||
|
@ -11,18 +11,22 @@
|
|||||||
integer :: n_real_tc
|
integer :: n_real_tc
|
||||||
integer :: i, k, l
|
integer :: i, k, l
|
||||||
double precision :: accu_d, accu_nd, accu_tmp
|
double precision :: accu_d, accu_nd, accu_tmp
|
||||||
|
double precision :: thr_d, thr_nd
|
||||||
double precision :: norm
|
double precision :: norm
|
||||||
double precision, allocatable :: eigval_right_tmp(:)
|
double precision, allocatable :: eigval_right_tmp(:)
|
||||||
|
|
||||||
|
thr_d = 1d-6
|
||||||
|
thr_nd = 1d-6
|
||||||
|
|
||||||
allocate( eigval_right_tmp(mo_num) )
|
allocate( eigval_right_tmp(mo_num) )
|
||||||
|
|
||||||
PROVIDE Fock_matrix_tc_mo_tot
|
PROVIDE Fock_matrix_tc_mo_tot
|
||||||
|
|
||||||
call non_hrmt_bieig( mo_num, Fock_matrix_tc_mo_tot &
|
call non_hrmt_bieig( mo_num, Fock_matrix_tc_mo_tot, thr_d, thr_nd &
|
||||||
, fock_tc_leigvec_mo, fock_tc_reigvec_mo &
|
, fock_tc_leigvec_mo, fock_tc_reigvec_mo &
|
||||||
, n_real_tc, eigval_right_tmp )
|
, n_real_tc, eigval_right_tmp )
|
||||||
!if(max_ov_tc_scf)then
|
!if(max_ov_tc_scf)then
|
||||||
! call non_hrmt_fock_mat( mo_num, Fock_matrix_tc_mo_tot &
|
! call non_hrmt_fock_mat( mo_num, Fock_matrix_tc_mo_tot, thr_d, thr_nd &
|
||||||
! , fock_tc_leigvec_mo, fock_tc_reigvec_mo &
|
! , fock_tc_leigvec_mo, fock_tc_reigvec_mo &
|
||||||
! , n_real_tc, eigval_right_tmp )
|
! , n_real_tc, eigval_right_tmp )
|
||||||
!else
|
!else
|
||||||
@ -59,7 +63,7 @@
|
|||||||
else
|
else
|
||||||
accu_tmp = overlap_fock_tc_eigvec_mo(k,i)
|
accu_tmp = overlap_fock_tc_eigvec_mo(k,i)
|
||||||
accu_nd += accu_tmp * accu_tmp
|
accu_nd += accu_tmp * accu_tmp
|
||||||
if(dabs(overlap_fock_tc_eigvec_mo(k,i)).gt.1.d-10)then
|
if(dabs(overlap_fock_tc_eigvec_mo(k,i)) .gt. thr_nd)then
|
||||||
print *, 'k,i', k, i, overlap_fock_tc_eigvec_mo(k,i)
|
print *, 'k,i', k, i, overlap_fock_tc_eigvec_mo(k,i)
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
@ -67,9 +71,9 @@
|
|||||||
enddo
|
enddo
|
||||||
accu_nd = dsqrt(accu_nd)/accu_d
|
accu_nd = dsqrt(accu_nd)/accu_d
|
||||||
|
|
||||||
if( accu_nd .gt. 1d-8 ) then
|
if(accu_nd .gt. thr_nd) then
|
||||||
print *, ' bi-orthog failed'
|
print *, ' bi-orthog failed'
|
||||||
print*,'accu_nd MO = ', accu_nd
|
print*,'accu_nd MO = ', accu_nd, thr_nd
|
||||||
print*,'overlap_fock_tc_eigvec_mo = '
|
print*,'overlap_fock_tc_eigvec_mo = '
|
||||||
do i = 1, mo_num
|
do i = 1, mo_num
|
||||||
write(*,'(100(F16.10,X))') overlap_fock_tc_eigvec_mo(i,:)
|
write(*,'(100(F16.10,X))') overlap_fock_tc_eigvec_mo(i,:)
|
||||||
@ -77,13 +81,13 @@
|
|||||||
stop
|
stop
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if( dabs(accu_d - dble(mo_num)) .gt. 1e-7 ) then
|
if( dabs(accu_d - dble(mo_num))/dble(mo_num) .gt. thr_d ) then
|
||||||
print *, 'mo_num = ', mo_num
|
print *, 'mo_num = ', mo_num
|
||||||
print *, 'accu_d MO = ', accu_d
|
print *, 'accu_d MO = ', accu_d, thr_d
|
||||||
print *, 'normalizing vectors ...'
|
print *, 'normalizing vectors ...'
|
||||||
do i = 1, mo_num
|
do i = 1, mo_num
|
||||||
norm = dsqrt(dabs(overlap_fock_tc_eigvec_mo(i,i)))
|
norm = dsqrt(dabs(overlap_fock_tc_eigvec_mo(i,i)))
|
||||||
if( norm.gt.1e-7 ) then
|
if(norm .gt. thr_d) then
|
||||||
do k = 1, mo_num
|
do k = 1, mo_num
|
||||||
fock_tc_reigvec_mo(k,i) *= 1.d0/norm
|
fock_tc_reigvec_mo(k,i) *= 1.d0/norm
|
||||||
fock_tc_leigvec_mo(k,i) *= 1.d0/norm
|
fock_tc_leigvec_mo(k,i) *= 1.d0/norm
|
||||||
|
@ -116,17 +116,23 @@ BEGIN_PROVIDER [ double precision, Fock_matrix_tc_mo_beta, (mo_num,mo_num) ]
|
|||||||
endif
|
endif
|
||||||
END_PROVIDER
|
END_PROVIDER
|
||||||
|
|
||||||
|
! ---
|
||||||
|
|
||||||
BEGIN_PROVIDER [ double precision, Fock_matrix_tc_mo_tot, (mo_num, mo_num)]
|
BEGIN_PROVIDER [ double precision, Fock_matrix_tc_mo_tot, (mo_num, mo_num)]
|
||||||
implicit none
|
|
||||||
BEGIN_DOC
|
BEGIN_DOC
|
||||||
! Total alpha+beta TC Fock matrix : h_c + Two-e^TC terms on the MO basis
|
! Total alpha+beta TC Fock matrix : h_c + Two-e^TC terms on the MO basis
|
||||||
END_DOC
|
END_DOC
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
|
||||||
Fock_matrix_tc_mo_tot = 0.5d0 * (Fock_matrix_tc_mo_alpha + Fock_matrix_tc_mo_beta)
|
Fock_matrix_tc_mo_tot = 0.5d0 * (Fock_matrix_tc_mo_alpha + Fock_matrix_tc_mo_beta)
|
||||||
if(three_body_h_tc) then
|
if(three_body_h_tc) then
|
||||||
Fock_matrix_tc_mo_tot += fock_3_mat
|
Fock_matrix_tc_mo_tot += fock_3_mat
|
||||||
endif
|
endif
|
||||||
|
|
||||||
!call restore_symmetry(mo_num, mo_num, Fock_matrix_tc_mo_tot, mo_num, 1.d-10)
|
!call restore_symmetry(mo_num, mo_num, Fock_matrix_tc_mo_tot, mo_num, 1.d-10)
|
||||||
|
|
||||||
END_PROVIDER
|
END_PROVIDER
|
||||||
|
|
||||||
! ---
|
! ---
|
||||||
|
@ -73,7 +73,7 @@ subroutine maximize_overlap()
|
|||||||
|
|
||||||
! ---
|
! ---
|
||||||
|
|
||||||
call rotate_degen_eigvec(n, m, e, C, W, L, R)
|
call rotate_degen_eigvec_to_maximize_overlap(n, m, e, C, W, L, R)
|
||||||
|
|
||||||
! ---
|
! ---
|
||||||
|
|
||||||
@ -115,7 +115,7 @@ end subroutine maximize_overlap
|
|||||||
|
|
||||||
! ---
|
! ---
|
||||||
|
|
||||||
subroutine rotate_degen_eigvec(n, m, e0, C0, W0, L0, R0)
|
subroutine rotate_degen_eigvec_to_maximize_overlap(n, m, e0, C0, W0, L0, R0)
|
||||||
|
|
||||||
implicit none
|
implicit none
|
||||||
|
|
||||||
@ -124,7 +124,7 @@ subroutine rotate_degen_eigvec(n, m, e0, C0, W0, L0, R0)
|
|||||||
double precision, intent(inout) :: L0(n,m), R0(n,m)
|
double precision, intent(inout) :: L0(n,m), R0(n,m)
|
||||||
|
|
||||||
|
|
||||||
integer :: i, j, k, kk, mm, id1
|
integer :: i, j, k, kk, mm, id1, tot_deg
|
||||||
double precision :: ei, ej, de, de_thr
|
double precision :: ei, ej, de, de_thr
|
||||||
integer, allocatable :: deg_num(:)
|
integer, allocatable :: deg_num(:)
|
||||||
double precision, allocatable :: L(:,:), R(:,:), C(:,:), Lnew(:,:), Rnew(:,:), tmp(:,:)
|
double precision, allocatable :: L(:,:), R(:,:), C(:,:), Lnew(:,:), Rnew(:,:), tmp(:,:)
|
||||||
@ -162,12 +162,19 @@ subroutine rotate_degen_eigvec(n, m, e0, C0, W0, L0, R0)
|
|||||||
enddo
|
enddo
|
||||||
enddo
|
enddo
|
||||||
|
|
||||||
|
tot_deg = 0
|
||||||
do i = 1, m
|
do i = 1, m
|
||||||
if(deg_num(i).gt.1) then
|
if(deg_num(i).gt.1) then
|
||||||
print *, ' degen on', i, deg_num(i)
|
print *, ' degen on', i, deg_num(i)
|
||||||
|
tot_deg = tot_deg + 1
|
||||||
endif
|
endif
|
||||||
enddo
|
enddo
|
||||||
|
|
||||||
|
if(tot_deg .eq. 0) then
|
||||||
|
print *, ' no degen'
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
! ---
|
! ---
|
||||||
|
|
||||||
do i = 1, m
|
do i = 1, m
|
||||||
@ -243,6 +250,122 @@ subroutine rotate_degen_eigvec(n, m, e0, C0, W0, L0, R0)
|
|||||||
|
|
||||||
deallocate(S, Snew, T)
|
deallocate(S, Snew, T)
|
||||||
|
|
||||||
end subroutine rotate_degen_eigvec
|
end subroutine rotate_degen_eigvec_to_maximize_overlap
|
||||||
|
|
||||||
|
! ---
|
||||||
|
|
||||||
|
subroutine fix_right_to_one()
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
integer :: i, j, m, n, mm, tot_deg
|
||||||
|
double precision :: accu_d, accu_nd
|
||||||
|
double precision :: de_thr, ei, ej, de
|
||||||
|
double precision :: thr_d, thr_nd
|
||||||
|
integer, allocatable :: deg_num(:)
|
||||||
|
double precision, allocatable :: R0(:,:), L0(:,:), W(:,:), e0(:)
|
||||||
|
double precision, allocatable :: R(:,:), L(:,:), S(:,:), Stmp(:,:), tmp(:,:)
|
||||||
|
|
||||||
|
thr_d = 1d-7
|
||||||
|
thr_nd = 1d-7
|
||||||
|
|
||||||
|
n = ao_num
|
||||||
|
m = mo_num
|
||||||
|
|
||||||
|
allocate(L0(n,m), R0(n,m), W(n,n), e0(m))
|
||||||
|
L0 = mo_l_coef
|
||||||
|
R0 = mo_r_coef
|
||||||
|
W = ao_overlap
|
||||||
|
|
||||||
|
print*, ' fock matrix diag elements'
|
||||||
|
do i = 1, m
|
||||||
|
e0(i) = Fock_matrix_tc_mo_tot(i,i)
|
||||||
|
print*, e0(i)
|
||||||
|
enddo
|
||||||
|
|
||||||
|
! ---
|
||||||
|
|
||||||
|
allocate( deg_num(m) )
|
||||||
|
do i = 1, m
|
||||||
|
deg_num(i) = 1
|
||||||
|
enddo
|
||||||
|
|
||||||
|
de_thr = 1d-6
|
||||||
|
|
||||||
|
do i = 1, m-1
|
||||||
|
ei = e0(i)
|
||||||
|
|
||||||
|
! already considered in degen vectors
|
||||||
|
if(deg_num(i).eq.0) cycle
|
||||||
|
|
||||||
|
do j = i+1, m
|
||||||
|
ej = e0(j)
|
||||||
|
de = dabs(ei - ej)
|
||||||
|
|
||||||
|
if(de .lt. de_thr) then
|
||||||
|
deg_num(i) = deg_num(i) + 1
|
||||||
|
deg_num(j) = 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
enddo
|
||||||
|
enddo
|
||||||
|
|
||||||
|
deallocate(e0)
|
||||||
|
|
||||||
|
tot_deg = 0
|
||||||
|
do i = 1, m
|
||||||
|
if(deg_num(i).gt.1) then
|
||||||
|
print *, ' degen on', i, deg_num(i)
|
||||||
|
tot_deg = tot_deg + 1
|
||||||
|
endif
|
||||||
|
enddo
|
||||||
|
|
||||||
|
if(tot_deg .eq. 0) then
|
||||||
|
print *, ' no degen'
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
! ---
|
||||||
|
|
||||||
|
do i = 1, m
|
||||||
|
mm = deg_num(i)
|
||||||
|
|
||||||
|
if(mm .gt. 1) then
|
||||||
|
|
||||||
|
allocate(L(n,mm), R(n,mm))
|
||||||
|
do j = 1, mm
|
||||||
|
L(1:n,j) = L0(1:n,i+j-1)
|
||||||
|
R(1:n,j) = R0(1:n,i+j-1)
|
||||||
|
enddo
|
||||||
|
|
||||||
|
! ---
|
||||||
|
|
||||||
|
call impose_weighted_orthog_svd(n, mm, W, R)
|
||||||
|
call impose_weighted_biorthog_qr(n, mm, thr_d, thr_nd, R, W, L)
|
||||||
|
|
||||||
|
! ---
|
||||||
|
|
||||||
|
do j = 1, mm
|
||||||
|
L0(1:n,i+j-1) = L(1:n,j)
|
||||||
|
R0(1:n,i+j-1) = R(1:n,j)
|
||||||
|
enddo
|
||||||
|
deallocate(L, R)
|
||||||
|
|
||||||
|
endif
|
||||||
|
enddo
|
||||||
|
|
||||||
|
call check_weighted_biorthog_binormalize(n, m, L0, W, R0, thr_d, thr_nd, .true.)
|
||||||
|
|
||||||
|
deallocate(W, deg_num)
|
||||||
|
|
||||||
|
mo_l_coef = L0
|
||||||
|
mo_r_coef = R0
|
||||||
|
deallocate(L0, R0)
|
||||||
|
|
||||||
|
call ezfio_set_bi_ortho_mos_mo_l_coef(mo_l_coef)
|
||||||
|
call ezfio_set_bi_ortho_mos_mo_r_coef(mo_r_coef)
|
||||||
|
print *, ' orbitals are rotated '
|
||||||
|
|
||||||
|
return
|
||||||
|
end subroutine fix_right_to_one
|
||||||
|
|
||||||
! ---
|
! ---
|
||||||
|
@ -1,13 +1,20 @@
|
|||||||
subroutine minimize_tc_orb_angles
|
|
||||||
|
! ---
|
||||||
|
|
||||||
|
subroutine minimize_tc_orb_angles()
|
||||||
|
|
||||||
implicit none
|
implicit none
|
||||||
double precision :: thr_deg
|
|
||||||
logical :: good_angles
|
logical :: good_angles
|
||||||
integer :: i
|
integer :: i
|
||||||
|
double precision :: thr_deg
|
||||||
|
|
||||||
good_angles = .False.
|
good_angles = .False.
|
||||||
thr_deg = thr_degen_tc
|
thr_deg = thr_degen_tc
|
||||||
call print_energy_and_mos
|
|
||||||
i = 1
|
call print_energy_and_mos()
|
||||||
|
|
||||||
print *, ' Minimizing the angles between the TC orbitals'
|
print *, ' Minimizing the angles between the TC orbitals'
|
||||||
|
i = 1
|
||||||
do while (.not. good_angles)
|
do while (.not. good_angles)
|
||||||
print *, ' iteration = ', i
|
print *, ' iteration = ', i
|
||||||
call routine_save_rotated_mos(thr_deg, good_angles)
|
call routine_save_rotated_mos(thr_deg, good_angles)
|
||||||
@ -17,31 +24,49 @@ subroutine minimize_tc_orb_angles
|
|||||||
print *, ' minimize_tc_orb_angles does not seem to converge ..'
|
print *, ' minimize_tc_orb_angles does not seem to converge ..'
|
||||||
print *, ' Something is weird in the tc orbitals ...'
|
print *, ' Something is weird in the tc orbitals ...'
|
||||||
print *, ' STOPPING'
|
print *, ' STOPPING'
|
||||||
|
stop
|
||||||
endif
|
endif
|
||||||
enddo
|
enddo
|
||||||
print *, ' Converged ANGLES MINIMIZATION !!'
|
print *, ' Converged ANGLES MINIMIZATION !!'
|
||||||
call print_angles_tc
|
|
||||||
call print_energy_and_mos
|
call print_angles_tc()
|
||||||
|
call print_energy_and_mos()
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
! ---
|
||||||
|
|
||||||
subroutine routine_save_rotated_mos(thr_deg, good_angles)
|
subroutine routine_save_rotated_mos(thr_deg, good_angles)
|
||||||
|
|
||||||
implicit none
|
implicit none
|
||||||
|
|
||||||
double precision, intent(in) :: thr_deg
|
double precision, intent(in) :: thr_deg
|
||||||
logical, intent(out) :: good_angles
|
logical, intent(out) :: good_angles
|
||||||
good_angles = .False.
|
|
||||||
integer :: i, j, k, n_degen_list, m, n, n_degen, ilast, ifirst
|
integer :: i, j, k, n_degen_list, m, n, n_degen, ilast, ifirst
|
||||||
|
double precision :: max_angle, norm
|
||||||
|
integer, allocatable :: list_degen(:,:)
|
||||||
|
double precision, allocatable :: new_angles(:)
|
||||||
double precision, allocatable :: mo_r_coef_good(:,:), mo_l_coef_good(:,:)
|
double precision, allocatable :: mo_r_coef_good(:,:), mo_l_coef_good(:,:)
|
||||||
allocate(mo_l_coef_good(ao_num, mo_num), mo_r_coef_good(ao_num,mo_num))
|
|
||||||
double precision, allocatable :: mo_r_coef_new(:,:)
|
double precision, allocatable :: mo_r_coef_new(:,:)
|
||||||
double precision :: norm
|
double precision, allocatable :: fock_diag(:),s_mat(:,:)
|
||||||
|
double precision, allocatable :: stmp(:,:), T(:,:), Snew(:,:), smat2(:,:)
|
||||||
|
double precision, allocatable :: mo_l_coef_tmp(:,:), mo_r_coef_tmp(:,:), mo_l_coef_new(:,:)
|
||||||
|
|
||||||
|
good_angles = .False.
|
||||||
|
|
||||||
|
allocate(mo_l_coef_good(ao_num, mo_num), mo_r_coef_good(ao_num,mo_num))
|
||||||
|
|
||||||
print *, ' ***************************************'
|
print *, ' ***************************************'
|
||||||
print *, ' ***************************************'
|
print *, ' ***************************************'
|
||||||
print *, ' THRESHOLD FOR DEGENERACIES ::: ', thr_deg
|
print *, ' THRESHOLD FOR DEGENERACIES ::: ', thr_deg
|
||||||
print *, ' ***************************************'
|
print *, ' ***************************************'
|
||||||
print *, ' ***************************************'
|
print *, ' ***************************************'
|
||||||
print *, ' Starting with the following TC energy gradient :', grad_non_hermit
|
print *, ' Starting with the following TC energy gradient :', grad_non_hermit
|
||||||
|
|
||||||
mo_r_coef_good = mo_r_coef
|
mo_r_coef_good = mo_r_coef
|
||||||
mo_l_coef_good = mo_l_coef
|
mo_l_coef_good = mo_l_coef
|
||||||
|
|
||||||
allocate(mo_r_coef_new(ao_num, mo_num))
|
allocate(mo_r_coef_new(ao_num, mo_num))
|
||||||
mo_r_coef_new = mo_r_coef
|
mo_r_coef_new = mo_r_coef
|
||||||
do i = 1, mo_num
|
do i = 1, mo_num
|
||||||
@ -50,12 +75,12 @@ subroutine routine_save_rotated_mos(thr_deg,good_angles)
|
|||||||
mo_r_coef_new(j,i) *= norm
|
mo_r_coef_new(j,i) *= norm
|
||||||
enddo
|
enddo
|
||||||
enddo
|
enddo
|
||||||
double precision, allocatable :: fock_diag(:),s_mat(:,:)
|
|
||||||
integer, allocatable :: list_degen(:,:)
|
|
||||||
allocate(list_degen(mo_num,0:mo_num), s_mat(mo_num,mo_num), fock_diag(mo_num))
|
allocate(list_degen(mo_num,0:mo_num), s_mat(mo_num,mo_num), fock_diag(mo_num))
|
||||||
do i = 1, mo_num
|
do i = 1, mo_num
|
||||||
fock_diag(i) = Fock_matrix_tc_mo_tot(i,i)
|
fock_diag(i) = Fock_matrix_tc_mo_tot(i,i)
|
||||||
enddo
|
enddo
|
||||||
|
|
||||||
! compute the overlap between the left and rescaled right
|
! compute the overlap between the left and rescaled right
|
||||||
call build_s_matrix(ao_num, mo_num, mo_r_coef_new, mo_r_coef_new, ao_overlap, s_mat)
|
call build_s_matrix(ao_num, mo_num, mo_r_coef_new, mo_r_coef_new, ao_overlap, s_mat)
|
||||||
! call give_degen(fock_diag,mo_num,thr_deg,list_degen,n_degen_list)
|
! call give_degen(fock_diag,mo_num,thr_deg,list_degen,n_degen_list)
|
||||||
@ -69,12 +94,13 @@ subroutine routine_save_rotated_mos(thr_deg,good_angles)
|
|||||||
! ifirst = list_degen(1,i)
|
! ifirst = list_degen(1,i)
|
||||||
! ilast = list_degen(2,i)
|
! ilast = list_degen(2,i)
|
||||||
! n_degen = ilast - ifirst +1
|
! n_degen = ilast - ifirst +1
|
||||||
|
|
||||||
n_degen = list_degen(i,0)
|
n_degen = list_degen(i,0)
|
||||||
double precision, allocatable :: stmp(:,:),T(:,:),Snew(:,:),smat2(:,:)
|
|
||||||
double precision, allocatable :: mo_l_coef_tmp(:,:),mo_r_coef_tmp(:,:),mo_l_coef_new(:,:)
|
|
||||||
allocate(stmp(n_degen,n_degen), smat2(n_degen,n_degen))
|
allocate(stmp(n_degen,n_degen), smat2(n_degen,n_degen))
|
||||||
allocate(mo_r_coef_tmp(ao_num,n_degen), mo_l_coef_tmp(ao_num,n_degen), mo_l_coef_new(ao_num,n_degen))
|
allocate(mo_r_coef_tmp(ao_num,n_degen), mo_l_coef_tmp(ao_num,n_degen), mo_l_coef_new(ao_num,n_degen))
|
||||||
allocate(T(n_degen,n_degen), Snew(n_degen,n_degen))
|
allocate(T(n_degen,n_degen), Snew(n_degen,n_degen))
|
||||||
|
|
||||||
do j = 1, n_degen
|
do j = 1, n_degen
|
||||||
mo_r_coef_tmp(1:ao_num,j) = mo_r_coef_new(1:ao_num,list_degen(i,j))
|
mo_r_coef_tmp(1:ao_num,j) = mo_r_coef_new(1:ao_num,list_degen(i,j))
|
||||||
mo_l_coef_tmp(1:ao_num,j) = mo_l_coef(1:ao_num,list_degen(i,j))
|
mo_l_coef_tmp(1:ao_num,j) = mo_l_coef(1:ao_num,list_degen(i,j))
|
||||||
@ -88,12 +114,14 @@ subroutine routine_save_rotated_mos(thr_deg,good_angles)
|
|||||||
print *, ' Orthogonalization of LEFT functions'
|
print *, ' Orthogonalization of LEFT functions'
|
||||||
print *, ' ------------------------------------'
|
print *, ' ------------------------------------'
|
||||||
call orthog_functions(ao_num, n_degen, mo_l_coef_tmp, ao_overlap)
|
call orthog_functions(ao_num, n_degen, mo_l_coef_tmp, ao_overlap)
|
||||||
|
|
||||||
print *, ' Overlap lef-right '
|
print *, ' Overlap lef-right '
|
||||||
call build_s_matrix(ao_num, n_degen, mo_r_coef_tmp, mo_l_coef_tmp, ao_overlap, stmp)
|
call build_s_matrix(ao_num, n_degen, mo_r_coef_tmp, mo_l_coef_tmp, ao_overlap, stmp)
|
||||||
do j = 1, n_degen
|
do j = 1, n_degen
|
||||||
write(*,'(100(F8.4,X))') stmp(:,j)
|
write(*,'(100(F8.4,X))') stmp(:,j)
|
||||||
enddo
|
enddo
|
||||||
call build_s_matrix(ao_num, n_degen, mo_l_coef_tmp, mo_l_coef_tmp, ao_overlap, stmp)
|
call build_s_matrix(ao_num, n_degen, mo_l_coef_tmp, mo_l_coef_tmp, ao_overlap, stmp)
|
||||||
|
|
||||||
!print*,'LEFT/LEFT OVERLAP '
|
!print*,'LEFT/LEFT OVERLAP '
|
||||||
!do j = 1, n_degen
|
!do j = 1, n_degen
|
||||||
! write(*,'(100(F16.10,X))')stmp(:,j)
|
! write(*,'(100(F16.10,X))')stmp(:,j)
|
||||||
@ -103,6 +131,7 @@ subroutine routine_save_rotated_mos(thr_deg,good_angles)
|
|||||||
!do j = 1, n_degen
|
!do j = 1, n_degen
|
||||||
! write(*,'(100(F16.10,X))')stmp(:,j)
|
! write(*,'(100(F16.10,X))')stmp(:,j)
|
||||||
!enddo
|
!enddo
|
||||||
|
|
||||||
if(maxovl_tc) then
|
if(maxovl_tc) then
|
||||||
T = 0.d0
|
T = 0.d0
|
||||||
Snew = 0.d0
|
Snew = 0.d0
|
||||||
@ -122,70 +151,77 @@ subroutine routine_save_rotated_mos(thr_deg,good_angles)
|
|||||||
else
|
else
|
||||||
mo_l_coef_new = mo_l_coef_tmp
|
mo_l_coef_new = mo_l_coef_tmp
|
||||||
endif
|
endif
|
||||||
call impose_biorthog_svd_overlap(ao_num, n_degen, ao_overlap, mo_l_coef_new, mo_r_coef_tmp)
|
|
||||||
call build_s_matrix(ao_num,n_degen,mo_l_coef_new,mo_r_coef_tmp,ao_overlap,stmp)
|
call impose_weighted_biorthog_svd(ao_num, n_degen, ao_overlap, mo_l_coef_new, mo_r_coef_tmp)
|
||||||
|
|
||||||
|
!call build_s_matrix(ao_num, n_degen, mo_l_coef_new, mo_r_coef_tmp, ao_overlap, stmp)
|
||||||
!print*,'LAST OVERLAP '
|
!print*,'LAST OVERLAP '
|
||||||
!do j = 1, n_degen
|
!do j = 1, n_degen
|
||||||
! write(*,'(100(F16.10,X))')stmp(:,j)
|
! write(*,'(100(F16.10,X))')stmp(:,j)
|
||||||
!enddo
|
!enddo
|
||||||
call build_s_matrix(ao_num,n_degen,mo_l_coef_new,mo_l_coef_new,ao_overlap,stmp)
|
!call build_s_matrix(ao_num, n_degen, mo_l_coef_new, mo_l_coef_new, ao_overlap, stmp)
|
||||||
!print*,'LEFT OVERLAP '
|
!print*,'LEFT OVERLAP '
|
||||||
!do j = 1, n_degen
|
!do j = 1, n_degen
|
||||||
! write(*,'(100(F16.10,X))')stmp(:,j)
|
! write(*,'(100(F16.10,X))')stmp(:,j)
|
||||||
!enddo
|
!enddo
|
||||||
call build_s_matrix(ao_num,n_degen,mo_r_coef_tmp,mo_r_coef_tmp,ao_overlap,stmp)
|
!call build_s_matrix(ao_num, n_degen, mo_r_coef_tmp, mo_r_coef_tmp, ao_overlap, stmp)
|
||||||
!print*,'RIGHT OVERLAP '
|
!print*,'RIGHT OVERLAP '
|
||||||
!do j = 1, n_degen
|
!do j = 1, n_degen
|
||||||
! write(*,'(100(F16.10,X))')stmp(:,j)
|
! write(*,'(100(F16.10,X))')stmp(:,j)
|
||||||
!enddo
|
!enddo
|
||||||
do j = 1, n_degen
|
do j = 1, n_degen
|
||||||
! mo_l_coef_good(1:ao_num,j+ifirst-1) = mo_l_coef_new(1:ao_num,j)
|
!!! mo_l_coef_good(1:ao_num,j+ifirst-1) = mo_l_coef_new(1:ao_num,j)
|
||||||
! mo_r_coef_good(1:ao_num,j+ifirst-1) = mo_r_coef_tmp(1:ao_num,j)
|
!!! mo_r_coef_good(1:ao_num,j+ifirst-1) = mo_r_coef_tmp(1:ao_num,j)
|
||||||
mo_l_coef_good(1:ao_num,list_degen(i,j)) = mo_l_coef_new(1:ao_num,j)
|
mo_l_coef_good(1:ao_num,list_degen(i,j)) = mo_l_coef_new(1:ao_num,j)
|
||||||
mo_r_coef_good(1:ao_num,list_degen(i,j)) = mo_r_coef_tmp(1:ao_num,j)
|
mo_r_coef_good(1:ao_num,list_degen(i,j)) = mo_r_coef_tmp(1:ao_num,j)
|
||||||
enddo
|
enddo
|
||||||
|
|
||||||
deallocate(stmp, smat2)
|
deallocate(stmp, smat2)
|
||||||
deallocate(mo_r_coef_tmp, mo_l_coef_tmp, mo_l_coef_new)
|
deallocate(mo_r_coef_tmp, mo_l_coef_tmp, mo_l_coef_new)
|
||||||
deallocate(T, Snew)
|
deallocate(T, Snew)
|
||||||
enddo
|
enddo
|
||||||
|
|
||||||
allocate(stmp(mo_num, mo_num))
|
!allocate(stmp(mo_num, mo_num))
|
||||||
call build_s_matrix(ao_num,mo_num,mo_l_coef_good,mo_r_coef_good,ao_overlap,stmp)
|
!call build_s_matrix(ao_num, mo_num, mo_l_coef_good, mo_r_coef_good, ao_overlap, stmp)
|
||||||
!print*,'LEFT/RIGHT OVERLAP '
|
!print*,'LEFT/RIGHT OVERLAP '
|
||||||
!do j = 1, mo_num
|
!do j = 1, mo_num
|
||||||
! write(*,'(100(F16.10,X))')stmp(:,j)
|
! write(*,'(100(F16.10,X))')stmp(:,j)
|
||||||
!enddo
|
!enddo
|
||||||
call build_s_matrix(ao_num,mo_num,mo_l_coef_good,mo_l_coef_good,ao_overlap,stmp)
|
!call build_s_matrix(ao_num, mo_num, mo_l_coef_good, mo_l_coef_good, ao_overlap, stmp)
|
||||||
!print*,'LEFT/LEFT OVERLAP '
|
!print*,'LEFT/LEFT OVERLAP '
|
||||||
!do j = 1, mo_num
|
!do j = 1, mo_num
|
||||||
! write(*,'(100(F16.10,X))')stmp(:,j)
|
! write(*,'(100(F16.10,X))')stmp(:,j)
|
||||||
!enddo
|
!enddo
|
||||||
call build_s_matrix(ao_num,mo_num,mo_r_coef_good,mo_r_coef_good,ao_overlap,stmp)
|
!call build_s_matrix(ao_num, mo_num, mo_r_coef_good, mo_r_coef_good, ao_overlap, stmp)
|
||||||
!print*,'RIGHT/RIGHT OVERLAP '
|
!print*,'RIGHT/RIGHT OVERLAP '
|
||||||
!do j = 1, mo_num
|
!do j = 1, mo_num
|
||||||
! write(*,'(100(F16.10,X))')stmp(:,j)
|
! write(*,'(100(F16.10,X))')stmp(:,j)
|
||||||
!enddo
|
!enddo
|
||||||
|
|
||||||
mo_r_coef = mo_r_coef_good
|
mo_r_coef = mo_r_coef_good
|
||||||
mo_l_coef = mo_l_coef_good
|
mo_l_coef = mo_l_coef_good
|
||||||
call ezfio_set_bi_ortho_mos_mo_l_coef(mo_l_coef)
|
call ezfio_set_bi_ortho_mos_mo_l_coef(mo_l_coef)
|
||||||
call ezfio_set_bi_ortho_mos_mo_r_coef(mo_r_coef)
|
call ezfio_set_bi_ortho_mos_mo_r_coef(mo_r_coef)
|
||||||
TOUCH mo_l_coef mo_r_coef
|
TOUCH mo_l_coef mo_r_coef
|
||||||
double precision, allocatable :: new_angles(:)
|
|
||||||
allocate(new_angles(mo_num))
|
allocate(new_angles(mo_num))
|
||||||
new_angles(1:mo_num) = dabs(angle_left_right(1:mo_num))
|
new_angles(1:mo_num) = dabs(angle_left_right(1:mo_num))
|
||||||
double precision :: max_angle
|
|
||||||
max_angle = maxval(new_angles)
|
max_angle = maxval(new_angles)
|
||||||
good_angles = max_angle.lt.45.d0
|
good_angles = max_angle.lt.45.d0
|
||||||
print *, ' max_angle = ', max_angle
|
print *, ' max_angle = ', max_angle
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
! ---
|
||||||
|
|
||||||
subroutine build_s_matrix(m, n, C1, C2, overlap, smat)
|
subroutine build_s_matrix(m, n, C1, C2, overlap, smat)
|
||||||
|
|
||||||
implicit none
|
implicit none
|
||||||
integer, intent(in) :: m, n
|
integer, intent(in) :: m, n
|
||||||
double precision, intent(in) :: C1(m,n), C2(m,n), overlap(m,m)
|
double precision, intent(in) :: C1(m,n), C2(m,n), overlap(m,m)
|
||||||
double precision, intent(out) :: smat(n,n)
|
double precision, intent(out) :: smat(n,n)
|
||||||
integer :: i, j, k, l
|
integer :: i, j, k, l
|
||||||
|
|
||||||
smat = 0.D0
|
smat = 0.D0
|
||||||
do i = 1, n
|
do i = 1, n
|
||||||
do j = 1, n
|
do j = 1, n
|
||||||
@ -196,8 +232,11 @@ subroutine build_s_matrix(m,n,C1,C2,overlap,smat)
|
|||||||
enddo
|
enddo
|
||||||
enddo
|
enddo
|
||||||
enddo
|
enddo
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
! ---
|
||||||
|
|
||||||
subroutine orthog_functions(m,n,coef,overlap)
|
subroutine orthog_functions(m,n,coef,overlap)
|
||||||
implicit none
|
implicit none
|
||||||
integer, intent(in) :: m,n
|
integer, intent(in) :: m,n
|
||||||
@ -217,16 +256,24 @@ subroutine orthog_functions(m,n,coef,overlap)
|
|||||||
coef(1,:m) *= 1.d0/dsqrt(stmp(j,j))
|
coef(1,:m) *= 1.d0/dsqrt(stmp(j,j))
|
||||||
enddo
|
enddo
|
||||||
call build_s_matrix(m,n,coef,coef,overlap,stmp)
|
call build_s_matrix(m,n,coef,coef,overlap,stmp)
|
||||||
|
|
||||||
!print*,'overlap after'
|
!print*,'overlap after'
|
||||||
!do j = 1, n
|
!do j = 1, n
|
||||||
! write(*,'(100(F16.10,X))')stmp(:,j)
|
! write(*,'(100(F16.10,X))')stmp(:,j)
|
||||||
!enddo
|
!enddo
|
||||||
|
|
||||||
|
deallocate(stmp)
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
subroutine print_angles_tc
|
! ---
|
||||||
|
|
||||||
|
subroutine print_angles_tc()
|
||||||
|
|
||||||
implicit none
|
implicit none
|
||||||
integer :: i, j
|
integer :: i, j
|
||||||
double precision :: left, right
|
double precision :: left, right
|
||||||
|
|
||||||
print *, ' product of norms, angle between vectors'
|
print *, ' product of norms, angle between vectors'
|
||||||
do i = 1, mo_num
|
do i = 1, mo_num
|
||||||
left = overlap_mo_l(i,i)
|
left = overlap_mo_l(i,i)
|
||||||
@ -234,15 +281,21 @@ subroutine print_angles_tc
|
|||||||
! print*,Fock_matrix_tc_mo_tot(i,i),left*right,angle_left_right(i)
|
! print*,Fock_matrix_tc_mo_tot(i,i),left*right,angle_left_right(i)
|
||||||
print *, left*right, angle_left_right(i)
|
print *, left*right, angle_left_right(i)
|
||||||
enddo
|
enddo
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
subroutine print_energy_and_mos
|
! ---
|
||||||
|
|
||||||
|
subroutine print_energy_and_mos()
|
||||||
|
|
||||||
implicit none
|
implicit none
|
||||||
integer :: i
|
integer :: i
|
||||||
|
|
||||||
print *, ' '
|
print *, ' '
|
||||||
print *, ' TC energy = ', TC_HF_energy
|
print *, ' TC energy = ', TC_HF_energy
|
||||||
print *, ' TC SCF energy gradient = ', grad_non_hermit
|
print *, ' TC SCF energy gradient = ', grad_non_hermit
|
||||||
print *, ' Max angle Left/right = ', max_angle_left_right
|
print *, ' Max angle Left/right = ', max_angle_left_right
|
||||||
|
|
||||||
if(max_angle_left_right .lt. 45.d0) then
|
if(max_angle_left_right .lt. 45.d0) then
|
||||||
print *, ' Maximum angle BELOW 45 degrees, everthing is OK !'
|
print *, ' Maximum angle BELOW 45 degrees, everthing is OK !'
|
||||||
else if(max_angle_left_right .gt. 45.d0 .and. max_angle_left_right .lt. 75.d0) then
|
else if(max_angle_left_right .gt. 45.d0 .and. max_angle_left_right .lt. 75.d0) then
|
||||||
@ -250,12 +303,16 @@ subroutine print_energy_and_mos
|
|||||||
else if(max_angle_left_right .gt. 75.d0) then
|
else if(max_angle_left_right .gt. 75.d0) then
|
||||||
print *, ' Maximum angle between ABOVE 75 degrees, YOU WILL CERTAINLY FIND TROUBLES IN TC-CI calculations ...'
|
print *, ' Maximum angle between ABOVE 75 degrees, YOU WILL CERTAINLY FIND TROUBLES IN TC-CI calculations ...'
|
||||||
endif
|
endif
|
||||||
|
|
||||||
print *, ' Diag Fock elem, product of left/right norm, angle left/right '
|
print *, ' Diag Fock elem, product of left/right norm, angle left/right '
|
||||||
do i = 1, mo_num
|
do i = 1, mo_num
|
||||||
write(*, '(I3,X,100(F16.10,X))') i, Fock_matrix_tc_mo_tot(i,i), overlap_mo_l(i,i)*overlap_mo_r(i,i), angle_left_right(i)
|
write(*, '(I3,X,100(F16.10,X))') i, Fock_matrix_tc_mo_tot(i,i), overlap_mo_l(i,i)*overlap_mo_r(i,i), angle_left_right(i)
|
||||||
enddo
|
enddo
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
! ---
|
||||||
|
|
||||||
subroutine sort_by_tc_fock
|
subroutine sort_by_tc_fock
|
||||||
implicit none
|
implicit none
|
||||||
integer, allocatable :: iorder(:)
|
integer, allocatable :: iorder(:)
|
||||||
@ -276,3 +333,4 @@ subroutine sort_by_tc_fock
|
|||||||
touch mo_l_coef mo_r_coef
|
touch mo_l_coef mo_r_coef
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
330
src/tools/print_he_energy.irp.f
Normal file
330
src/tools/print_he_energy.irp.f
Normal file
@ -0,0 +1,330 @@
|
|||||||
|
|
||||||
|
! ---
|
||||||
|
|
||||||
|
program print_he_energy
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
|
||||||
|
!call print_energy1()
|
||||||
|
call print_energy2()
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
! ---
|
||||||
|
|
||||||
|
subroutine print_energy1()
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
integer :: i, j, k, l
|
||||||
|
double precision :: e, n, e_tmp, n_tmp
|
||||||
|
double precision, external :: ao_two_e_integral
|
||||||
|
|
||||||
|
e = 0.d0
|
||||||
|
n = 0.d0
|
||||||
|
|
||||||
|
! --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
|
||||||
|
|
||||||
|
! < phi_1 phi_1 | h1 | phi_1 phi_1 >
|
||||||
|
|
||||||
|
e_tmp = 0.d0
|
||||||
|
n_tmp = 0.d0
|
||||||
|
do i = 1, ao_num
|
||||||
|
do j = 1, ao_num
|
||||||
|
e_tmp += mo_coef(i,1) * ao_one_e_integrals(i,j) * mo_coef(j,1)
|
||||||
|
n_tmp += mo_coef(i,1) * ao_overlap(i,j) * mo_coef(j,1)
|
||||||
|
enddo
|
||||||
|
enddo
|
||||||
|
|
||||||
|
e += e_tmp * n_tmp
|
||||||
|
|
||||||
|
! ---
|
||||||
|
|
||||||
|
! < phi_1 phi_1 | h2 | phi_1 phi_1 >
|
||||||
|
|
||||||
|
e_tmp = 0.d0
|
||||||
|
n_tmp = 0.d0
|
||||||
|
do i = 1, ao_num
|
||||||
|
do j = 1, ao_num
|
||||||
|
n_tmp += mo_coef(i,1) * ao_overlap(i,j) * mo_coef(j,1)
|
||||||
|
e_tmp += mo_coef(i,1) * ao_one_e_integrals(i,j) * mo_coef(j,1)
|
||||||
|
enddo
|
||||||
|
enddo
|
||||||
|
|
||||||
|
e += e_tmp * n_tmp
|
||||||
|
|
||||||
|
! ---
|
||||||
|
|
||||||
|
! --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
|
||||||
|
|
||||||
|
! ---
|
||||||
|
|
||||||
|
do i = 1, ao_num
|
||||||
|
do j = 1, ao_num
|
||||||
|
do k = 1, ao_num
|
||||||
|
do l = 1, ao_num
|
||||||
|
|
||||||
|
! ( phi_1 phi_1 | phi_1 phi_1 )
|
||||||
|
e += mo_coef(i,1) * mo_coef(j,1) * ao_two_e_integral(i,j,k,l) * mo_coef(k,1) * mo_coef(l,1)
|
||||||
|
|
||||||
|
enddo
|
||||||
|
enddo
|
||||||
|
enddo
|
||||||
|
enddo
|
||||||
|
|
||||||
|
! ---
|
||||||
|
|
||||||
|
! --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
|
||||||
|
|
||||||
|
! ---
|
||||||
|
|
||||||
|
! < phi_1 phi_1 | phi_1 phi_1 >
|
||||||
|
e_tmp = 0.d0
|
||||||
|
n_tmp = 0.d0
|
||||||
|
do i = 1, ao_num
|
||||||
|
do j = 1, ao_num
|
||||||
|
e_tmp += mo_coef(i,1) * ao_overlap(i,j) * mo_coef(j,1)
|
||||||
|
n_tmp += mo_coef(i,1) * ao_overlap(i,j) * mo_coef(j,1)
|
||||||
|
enddo
|
||||||
|
enddo
|
||||||
|
|
||||||
|
n += e_tmp * n_tmp
|
||||||
|
|
||||||
|
! ---
|
||||||
|
|
||||||
|
! --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
|
||||||
|
|
||||||
|
e = e / n
|
||||||
|
print *, ' energy = ', e
|
||||||
|
|
||||||
|
end subroutine print_energy1
|
||||||
|
|
||||||
|
! ---
|
||||||
|
|
||||||
|
subroutine print_energy2()
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
integer :: i, j, k, l
|
||||||
|
double precision :: e, n, e_tmp, n_tmp
|
||||||
|
double precision, external :: ao_two_e_integral
|
||||||
|
|
||||||
|
e = 0.d0
|
||||||
|
n = 0.d0
|
||||||
|
|
||||||
|
! --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
|
||||||
|
|
||||||
|
! < phi_1 phi_2 | h1 | phi_1 phi_2 >
|
||||||
|
|
||||||
|
e_tmp = 0.d0
|
||||||
|
n_tmp = 0.d0
|
||||||
|
do i = 1, ao_num
|
||||||
|
do j = 1, ao_num
|
||||||
|
e_tmp += mo_coef(i,1) * ao_one_e_integrals(i,j) * mo_coef(j,1)
|
||||||
|
n_tmp += mo_coef(i,2) * ao_overlap(i,j) * mo_coef(j,2)
|
||||||
|
enddo
|
||||||
|
enddo
|
||||||
|
|
||||||
|
e += e_tmp * n_tmp
|
||||||
|
|
||||||
|
! ---
|
||||||
|
|
||||||
|
! < phi_1 phi_2 | h1 | phi_2 phi_1 >
|
||||||
|
|
||||||
|
e_tmp = 0.d0
|
||||||
|
n_tmp = 0.d0
|
||||||
|
do i = 1, ao_num
|
||||||
|
do j = 1, ao_num
|
||||||
|
e_tmp += mo_coef(i,1) * ao_one_e_integrals(i,j) * mo_coef(j,2)
|
||||||
|
n_tmp += mo_coef(i,2) * ao_overlap(i,j) * mo_coef(j,1)
|
||||||
|
enddo
|
||||||
|
enddo
|
||||||
|
|
||||||
|
e -= e_tmp * n_tmp
|
||||||
|
|
||||||
|
! ---
|
||||||
|
|
||||||
|
! < phi_2 phi_1 | h1 | phi_1 phi_2 >
|
||||||
|
|
||||||
|
e_tmp = 0.d0
|
||||||
|
n_tmp = 0.d0
|
||||||
|
do i = 1, ao_num
|
||||||
|
do j = 1, ao_num
|
||||||
|
e_tmp += mo_coef(i,2) * ao_one_e_integrals(i,j) * mo_coef(j,1)
|
||||||
|
n_tmp += mo_coef(i,1) * ao_overlap(i,j) * mo_coef(j,2)
|
||||||
|
enddo
|
||||||
|
enddo
|
||||||
|
|
||||||
|
e -= e_tmp * n_tmp
|
||||||
|
|
||||||
|
! ---
|
||||||
|
|
||||||
|
! < phi_2 phi_1 | h1 | phi_2 phi_1 >
|
||||||
|
|
||||||
|
e_tmp = 0.d0
|
||||||
|
n_tmp = 0.d0
|
||||||
|
do i = 1, ao_num
|
||||||
|
do j = 1, ao_num
|
||||||
|
e_tmp += mo_coef(i,2) * ao_one_e_integrals(i,j) * mo_coef(j,2)
|
||||||
|
n_tmp += mo_coef(i,1) * ao_overlap(i,j) * mo_coef(j,1)
|
||||||
|
enddo
|
||||||
|
enddo
|
||||||
|
|
||||||
|
e += e_tmp * n_tmp
|
||||||
|
|
||||||
|
! ---
|
||||||
|
|
||||||
|
! < phi_1 phi_2 | h2 | phi_1 phi_2 >
|
||||||
|
|
||||||
|
e_tmp = 0.d0
|
||||||
|
n_tmp = 0.d0
|
||||||
|
do i = 1, ao_num
|
||||||
|
do j = 1, ao_num
|
||||||
|
n_tmp += mo_coef(i,1) * ao_overlap(i,j) * mo_coef(j,1)
|
||||||
|
e_tmp += mo_coef(i,2) * ao_one_e_integrals(i,j) * mo_coef(j,2)
|
||||||
|
enddo
|
||||||
|
enddo
|
||||||
|
|
||||||
|
e += e_tmp * n_tmp
|
||||||
|
|
||||||
|
! ---
|
||||||
|
|
||||||
|
! < phi_1 phi_2 | h2 | phi_2 phi_1 >
|
||||||
|
|
||||||
|
e_tmp = 0.d0
|
||||||
|
n_tmp = 0.d0
|
||||||
|
do i = 1, ao_num
|
||||||
|
do j = 1, ao_num
|
||||||
|
n_tmp += mo_coef(i,1) * ao_overlap(i,j) * mo_coef(j,2)
|
||||||
|
e_tmp += mo_coef(i,2) * ao_one_e_integrals(i,j) * mo_coef(j,1)
|
||||||
|
enddo
|
||||||
|
enddo
|
||||||
|
|
||||||
|
e -= e_tmp * n_tmp
|
||||||
|
|
||||||
|
! ---
|
||||||
|
|
||||||
|
! < phi_2 phi_1 | h2 | phi_1 phi_2 >
|
||||||
|
|
||||||
|
e_tmp = 0.d0
|
||||||
|
n_tmp = 0.d0
|
||||||
|
do i = 1, ao_num
|
||||||
|
do j = 1, ao_num
|
||||||
|
n_tmp += mo_coef(i,2) * ao_overlap(i,j) * mo_coef(j,1)
|
||||||
|
e_tmp += mo_coef(i,1) * ao_one_e_integrals(i,j) * mo_coef(j,2)
|
||||||
|
enddo
|
||||||
|
enddo
|
||||||
|
|
||||||
|
e -= e_tmp * n_tmp
|
||||||
|
|
||||||
|
! ---
|
||||||
|
|
||||||
|
! < phi_2 phi_1 | h2 | phi_2 phi_1 >
|
||||||
|
|
||||||
|
e_tmp = 0.d0
|
||||||
|
n_tmp = 0.d0
|
||||||
|
do i = 1, ao_num
|
||||||
|
do j = 1, ao_num
|
||||||
|
n_tmp += mo_coef(i,2) * ao_overlap(i,j) * mo_coef(j,2)
|
||||||
|
e_tmp += mo_coef(i,1) * ao_one_e_integrals(i,j) * mo_coef(j,1)
|
||||||
|
enddo
|
||||||
|
enddo
|
||||||
|
|
||||||
|
e += e_tmp * n_tmp
|
||||||
|
|
||||||
|
! ---
|
||||||
|
|
||||||
|
! --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
|
||||||
|
|
||||||
|
! ---
|
||||||
|
|
||||||
|
do i = 1, ao_num
|
||||||
|
do j = 1, ao_num
|
||||||
|
do k = 1, ao_num
|
||||||
|
do l = 1, ao_num
|
||||||
|
|
||||||
|
! ( phi_1 phi_1 | phi_2 phi_2 )
|
||||||
|
e += mo_coef(i,1) * mo_coef(j,1) * ao_two_e_integral(i,j,k,l) * mo_coef(k,2) * mo_coef(l,2)
|
||||||
|
|
||||||
|
! ( phi_1 phi_2 | phi_2 phi_1 )
|
||||||
|
e -= mo_coef(i,1) * mo_coef(j,2) * ao_two_e_integral(i,j,k,l) * mo_coef(k,2) * mo_coef(l,1)
|
||||||
|
|
||||||
|
! ( phi_2 phi_1 | phi_1 phi_2 )
|
||||||
|
e -= mo_coef(i,2) * mo_coef(j,1) * ao_two_e_integral(i,j,k,l) * mo_coef(k,1) * mo_coef(l,2)
|
||||||
|
|
||||||
|
! ( phi_2 phi_2 | phi_1 phi_1 )
|
||||||
|
e += mo_coef(i,2) * mo_coef(j,2) * ao_two_e_integral(i,j,k,l) * mo_coef(k,1) * mo_coef(l,1)
|
||||||
|
|
||||||
|
enddo
|
||||||
|
enddo
|
||||||
|
enddo
|
||||||
|
enddo
|
||||||
|
|
||||||
|
! ---
|
||||||
|
|
||||||
|
! --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
|
||||||
|
|
||||||
|
! ---
|
||||||
|
|
||||||
|
! < phi_1 phi_2 | phi_1 phi_2 >
|
||||||
|
e_tmp = 0.d0
|
||||||
|
n_tmp = 0.d0
|
||||||
|
do i = 1, ao_num
|
||||||
|
do j = 1, ao_num
|
||||||
|
e_tmp += mo_coef(i,1) * ao_overlap(i,j) * mo_coef(j,1)
|
||||||
|
n_tmp += mo_coef(i,2) * ao_overlap(i,j) * mo_coef(j,2)
|
||||||
|
enddo
|
||||||
|
enddo
|
||||||
|
|
||||||
|
n += e_tmp * n_tmp
|
||||||
|
|
||||||
|
! ---
|
||||||
|
|
||||||
|
! < phi_1 phi_2 | phi_2 phi_1 >
|
||||||
|
e_tmp = 0.d0
|
||||||
|
n_tmp = 0.d0
|
||||||
|
do i = 1, ao_num
|
||||||
|
do j = 1, ao_num
|
||||||
|
e_tmp += mo_coef(i,1) * ao_overlap(i,j) * mo_coef(j,2)
|
||||||
|
n_tmp += mo_coef(i,2) * ao_overlap(i,j) * mo_coef(j,1)
|
||||||
|
enddo
|
||||||
|
enddo
|
||||||
|
|
||||||
|
n -= e_tmp * n_tmp
|
||||||
|
|
||||||
|
! ---
|
||||||
|
|
||||||
|
! < phi_2 phi_1 | phi_1 phi_2 >
|
||||||
|
e_tmp = 0.d0
|
||||||
|
n_tmp = 0.d0
|
||||||
|
do i = 1, ao_num
|
||||||
|
do j = 1, ao_num
|
||||||
|
e_tmp += mo_coef(i,2) * ao_overlap(i,j) * mo_coef(j,1)
|
||||||
|
n_tmp += mo_coef(i,1) * ao_overlap(i,j) * mo_coef(j,2)
|
||||||
|
enddo
|
||||||
|
enddo
|
||||||
|
|
||||||
|
n -= e_tmp * n_tmp
|
||||||
|
|
||||||
|
! ---
|
||||||
|
|
||||||
|
! < phi_2 phi_1 | phi_2 phi_1 >
|
||||||
|
e_tmp = 0.d0
|
||||||
|
n_tmp = 0.d0
|
||||||
|
do i = 1, ao_num
|
||||||
|
do j = 1, ao_num
|
||||||
|
e_tmp += mo_coef(i,2) * ao_overlap(i,j) * mo_coef(j,2)
|
||||||
|
n_tmp += mo_coef(i,1) * ao_overlap(i,j) * mo_coef(j,1)
|
||||||
|
enddo
|
||||||
|
enddo
|
||||||
|
|
||||||
|
n += e_tmp * n_tmp
|
||||||
|
|
||||||
|
! ---
|
||||||
|
|
||||||
|
! --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
|
||||||
|
|
||||||
|
e = e / n
|
||||||
|
print *, ' energy = ', e
|
||||||
|
|
||||||
|
end subroutine print_energy2
|
||||||
|
|
||||||
|
! ---
|
@ -1,10 +1,9 @@
|
|||||||
|
|
||||||
subroutine diag_mat_per_fock_degen(fock_diag,mat_ref,n,thr_deg,leigvec,reigvec,eigval)
|
subroutine diag_mat_per_fock_degen(fock_diag, mat_ref, n, thr_d, thr_nd, thr_deg, leigvec, reigvec, eigval)
|
||||||
implicit none
|
|
||||||
integer, intent(in) :: n
|
|
||||||
double precision, intent(in) :: fock_diag(n),mat_ref(n,n),thr_deg
|
|
||||||
double precision, intent(out):: leigvec(n,n),reigvec(n,n),eigval(n)
|
|
||||||
BEGIN_DOC
|
BEGIN_DOC
|
||||||
|
!
|
||||||
! subroutine that diagonalizes a matrix mat_ref BY BLOCK
|
! subroutine that diagonalizes a matrix mat_ref BY BLOCK
|
||||||
!
|
!
|
||||||
! the blocks are defined by the elements having the SAME DEGENERACIES in the entries "fock_diag"
|
! the blocks are defined by the elements having the SAME DEGENERACIES in the entries "fock_diag"
|
||||||
@ -16,12 +15,21 @@ subroutine diag_mat_per_fock_degen(fock_diag,mat_ref,n,thr_deg,leigvec,reigvec,e
|
|||||||
! : all elements having degeneracy 3 in fock_diag (i.e. two elements are equal) will be treated together
|
! : all elements having degeneracy 3 in fock_diag (i.e. two elements are equal) will be treated together
|
||||||
!
|
!
|
||||||
! etc... the advantage is to guarentee no spurious mixing because of numerical problems.
|
! etc... the advantage is to guarentee no spurious mixing because of numerical problems.
|
||||||
|
!
|
||||||
END_DOC
|
END_DOC
|
||||||
double precision, allocatable :: leigvec_unsrtd(:,:),reigvec_unsrtd(:,:),eigval_unsrtd(:)
|
|
||||||
integer, allocatable :: list_degen(:,:),list_same_degen(:)
|
implicit none
|
||||||
integer, allocatable :: iorder(:),list_degen_sorted(:)
|
integer, intent(in) :: n
|
||||||
|
double precision, intent(in) :: fock_diag(n), mat_ref(n,n), thr_d, thr_nd, thr_deg
|
||||||
|
double precision, intent(out) :: leigvec(n,n), reigvec(n,n), eigval(n)
|
||||||
|
|
||||||
integer :: n_degen_list, n_degen,size_mat, i, j, k, icount, m, index_degen
|
integer :: n_degen_list, n_degen,size_mat, i, j, k, icount, m, index_degen
|
||||||
integer :: ii, jj, i_good, j_good, n_real
|
integer :: ii, jj, i_good, j_good, n_real
|
||||||
|
integer :: icount_eigval
|
||||||
|
logical, allocatable :: is_ok(:)
|
||||||
|
integer, allocatable :: list_degen(:,:), list_same_degen(:)
|
||||||
|
integer, allocatable :: iorder(:), list_degen_sorted(:)
|
||||||
|
double precision, allocatable :: leigvec_unsrtd(:,:), reigvec_unsrtd(:,:), eigval_unsrtd(:)
|
||||||
double precision, allocatable :: mat_tmp(:,:), eigval_tmp(:), leigvec_tmp(:,:), reigvec_tmp(:,:)
|
double precision, allocatable :: mat_tmp(:,:), eigval_tmp(:), leigvec_tmp(:,:), reigvec_tmp(:,:)
|
||||||
|
|
||||||
allocate(leigvec_unsrtd(n,n), reigvec_unsrtd(n,n), eigval_unsrtd(n))
|
allocate(leigvec_unsrtd(n,n), reigvec_unsrtd(n,n), eigval_unsrtd(n))
|
||||||
@ -29,38 +37,44 @@ subroutine diag_mat_per_fock_degen(fock_diag,mat_ref,n,thr_deg,leigvec,reigvec,e
|
|||||||
reigvec_unsrtd = 0.d0
|
reigvec_unsrtd = 0.d0
|
||||||
eigval_unsrtd = 0.d0
|
eigval_unsrtd = 0.d0
|
||||||
|
|
||||||
allocate(list_degen(n,0:n))
|
|
||||||
|
|
||||||
! obtain degeneracies
|
! obtain degeneracies
|
||||||
|
allocate(list_degen(n,0:n))
|
||||||
call give_degen_full_list(fock_diag, n, thr_deg, list_degen, n_degen_list)
|
call give_degen_full_list(fock_diag, n, thr_deg, list_degen, n_degen_list)
|
||||||
|
|
||||||
allocate(iorder(n_degen_list), list_degen_sorted(n_degen_list))
|
allocate(iorder(n_degen_list), list_degen_sorted(n_degen_list))
|
||||||
do i = 1, n_degen_list
|
do i = 1, n_degen_list
|
||||||
n_degen = list_degen(i,0)
|
n_degen = list_degen(i,0)
|
||||||
list_degen_sorted(i) = n_degen
|
list_degen_sorted(i) = n_degen
|
||||||
iorder(i) = i
|
iorder(i) = i
|
||||||
enddo
|
enddo
|
||||||
|
|
||||||
! sort by number of degeneracies
|
! sort by number of degeneracies
|
||||||
call isort(list_degen_sorted, iorder, n_degen_list)
|
call isort(list_degen_sorted, iorder, n_degen_list)
|
||||||
integer :: icount_eigval
|
|
||||||
logical, allocatable :: is_ok(:)
|
|
||||||
allocate(is_ok(n_degen_list))
|
allocate(is_ok(n_degen_list))
|
||||||
is_ok = .True.
|
is_ok = .True.
|
||||||
icount_eigval = 0
|
icount_eigval = 0
|
||||||
|
|
||||||
! loop over degeneracies
|
! loop over degeneracies
|
||||||
do i = 1, n_degen_list
|
do i = 1, n_degen_list
|
||||||
if(.not.is_ok(i)) cycle
|
if(.not.is_ok(i)) cycle
|
||||||
|
|
||||||
is_ok(i) = .False.
|
is_ok(i) = .False.
|
||||||
n_degen = list_degen_sorted(i)
|
n_degen = list_degen_sorted(i)
|
||||||
|
|
||||||
print *, ' diagonalizing for n_degen = ', n_degen
|
print *, ' diagonalizing for n_degen = ', n_degen
|
||||||
|
|
||||||
k = 1
|
k = 1
|
||||||
|
|
||||||
! group all the entries having the same degeneracies
|
! group all the entries having the same degeneracies
|
||||||
! do while (list_degen_sorted(i+k)==n_degen)
|
!! do while (list_degen_sorted(i+k)==n_degen)
|
||||||
do m = i+1, n_degen_list
|
do m = i+1, n_degen_list
|
||||||
if(list_degen_sorted(m)==n_degen) then
|
if(list_degen_sorted(m)==n_degen) then
|
||||||
is_ok(i+k) = .False.
|
is_ok(i+k) = .False.
|
||||||
k += 1
|
k += 1
|
||||||
endif
|
endif
|
||||||
enddo
|
enddo
|
||||||
|
|
||||||
print *, ' number of identical degeneracies = ', k
|
print *, ' number of identical degeneracies = ', k
|
||||||
size_mat = k*n_degen
|
size_mat = k*n_degen
|
||||||
print *, ' size_mat = ', size_mat
|
print *, ' size_mat = ', size_mat
|
||||||
@ -75,10 +89,12 @@ subroutine diag_mat_per_fock_degen(fock_diag,mat_ref,n,thr_deg,leigvec,reigvec,e
|
|||||||
list_same_degen(icount) = list_degen(index_degen,m)
|
list_same_degen(icount) = list_degen(index_degen,m)
|
||||||
enddo
|
enddo
|
||||||
enddo
|
enddo
|
||||||
|
|
||||||
print *, ' list of elements '
|
print *, ' list of elements '
|
||||||
do icount = 1, size_mat
|
do icount = 1, size_mat
|
||||||
print *, icount, list_same_degen(icount)
|
print *, icount, list_same_degen(icount)
|
||||||
enddo
|
enddo
|
||||||
|
|
||||||
! you copy subset of matrix elements having all the same degeneracy in mat_tmp
|
! you copy subset of matrix elements having all the same degeneracy in mat_tmp
|
||||||
do ii = 1, size_mat
|
do ii = 1, size_mat
|
||||||
i_good = list_same_degen(ii)
|
i_good = list_same_degen(ii)
|
||||||
@ -87,9 +103,11 @@ subroutine diag_mat_per_fock_degen(fock_diag,mat_ref,n,thr_deg,leigvec,reigvec,e
|
|||||||
mat_tmp(jj,ii) = mat_ref(j_good,i_good)
|
mat_tmp(jj,ii) = mat_ref(j_good,i_good)
|
||||||
enddo
|
enddo
|
||||||
enddo
|
enddo
|
||||||
call non_hrmt_bieig( size_mat, mat_tmp&
|
|
||||||
|
call non_hrmt_bieig( size_mat, mat_tmp, thr_d, thr_nd &
|
||||||
, leigvec_tmp, reigvec_tmp &
|
, leigvec_tmp, reigvec_tmp &
|
||||||
, n_real, eigval_tmp )
|
, n_real, eigval_tmp )
|
||||||
|
|
||||||
do ii = 1, size_mat
|
do ii = 1, size_mat
|
||||||
icount_eigval += 1
|
icount_eigval += 1
|
||||||
eigval_unsrtd(icount_eigval) = eigval_tmp(ii) ! copy eigenvalues
|
eigval_unsrtd(icount_eigval) = eigval_tmp(ii) ! copy eigenvalues
|
||||||
@ -99,9 +117,11 @@ subroutine diag_mat_per_fock_degen(fock_diag,mat_ref,n,thr_deg,leigvec,reigvec,e
|
|||||||
reigvec_unsrtd(j_good,icount_eigval) = reigvec_tmp(jj,ii)
|
reigvec_unsrtd(j_good,icount_eigval) = reigvec_tmp(jj,ii)
|
||||||
enddo
|
enddo
|
||||||
enddo
|
enddo
|
||||||
|
|
||||||
deallocate(mat_tmp, list_same_degen)
|
deallocate(mat_tmp, list_same_degen)
|
||||||
deallocate(eigval_tmp, leigvec_tmp, reigvec_tmp)
|
deallocate(eigval_tmp, leigvec_tmp, reigvec_tmp)
|
||||||
enddo
|
enddo
|
||||||
|
|
||||||
if(icount_eigval .ne. n) then
|
if(icount_eigval .ne. n) then
|
||||||
print *, ' pb !! (icount_eigval.ne.n)'
|
print *, ' pb !! (icount_eigval.ne.n)'
|
||||||
print *, ' icount_eigval,n', icount_eigval, n
|
print *, ' icount_eigval,n', icount_eigval, n
|
||||||
@ -114,6 +134,7 @@ subroutine diag_mat_per_fock_degen(fock_diag,mat_ref,n,thr_deg,leigvec,reigvec,e
|
|||||||
iorder(i) = i
|
iorder(i) = i
|
||||||
enddo
|
enddo
|
||||||
call dsort(eigval_unsrtd, iorder, n)
|
call dsort(eigval_unsrtd, iorder, n)
|
||||||
|
|
||||||
do i = 1, n
|
do i = 1, n
|
||||||
print*,'sorted eigenvalues '
|
print*,'sorted eigenvalues '
|
||||||
i_good = iorder(i)
|
i_good = iorder(i)
|
||||||
@ -124,10 +145,18 @@ subroutine diag_mat_per_fock_degen(fock_diag,mat_ref,n,thr_deg,leigvec,reigvec,e
|
|||||||
reigvec(j,i) = reigvec_unsrtd(j,i_good)
|
reigvec(j,i) = reigvec_unsrtd(j,i_good)
|
||||||
enddo
|
enddo
|
||||||
enddo
|
enddo
|
||||||
|
|
||||||
|
deallocate(leigvec_unsrtd, reigvec_unsrtd, eigval_unsrtd)
|
||||||
|
deallocate(list_degen)
|
||||||
|
deallocate(iorder, list_degen_sorted)
|
||||||
|
deallocate(is_ok)
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
! ---
|
||||||
|
|
||||||
subroutine give_degen_full_list(A,n,thr,list_degen,n_degen_list)
|
subroutine give_degen_full_list(A,n,thr,list_degen,n_degen_list)
|
||||||
implicit none
|
|
||||||
BEGIN_DOC
|
BEGIN_DOC
|
||||||
! you enter with an array A(n) and spits out all the elements degenerated up to thr
|
! you enter with an array A(n) and spits out all the elements degenerated up to thr
|
||||||
!
|
!
|
||||||
@ -141,13 +170,18 @@ subroutine give_degen_full_list(A,n,thr,list_degen,n_degen_list)
|
|||||||
!
|
!
|
||||||
! if list_degen(i,0) == 1 it means that there is no degeneracy for that element
|
! if list_degen(i,0) == 1 it means that there is no degeneracy for that element
|
||||||
END_DOC
|
END_DOC
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
|
||||||
double precision, intent(in) :: A(n)
|
double precision, intent(in) :: A(n)
|
||||||
double precision, intent(in) :: thr
|
double precision, intent(in) :: thr
|
||||||
integer, intent(in) :: n
|
integer, intent(in) :: n
|
||||||
integer, intent(out) :: list_degen(n,0:n), n_degen_list
|
integer, intent(out) :: list_degen(n,0:n), n_degen_list
|
||||||
logical, allocatable :: is_ok(:)
|
|
||||||
allocate(is_ok(n))
|
|
||||||
integer :: i, j, icount, icheck
|
integer :: i, j, icount, icheck
|
||||||
|
logical, allocatable :: is_ok(:)
|
||||||
|
|
||||||
|
|
||||||
|
allocate(is_ok(n))
|
||||||
n_degen_list = 0
|
n_degen_list = 0
|
||||||
is_ok = .True.
|
is_ok = .True.
|
||||||
do i = 1, n
|
do i = 1, n
|
||||||
@ -163,15 +197,22 @@ subroutine give_degen_full_list(A,n,thr,list_degen,n_degen_list)
|
|||||||
list_degen(n_degen_list,icount) = j
|
list_degen(n_degen_list,icount) = j
|
||||||
endif
|
endif
|
||||||
enddo
|
enddo
|
||||||
|
|
||||||
list_degen(n_degen_list,0) = icount
|
list_degen(n_degen_list,0) = icount
|
||||||
enddo
|
enddo
|
||||||
|
|
||||||
icheck = 0
|
icheck = 0
|
||||||
do i = 1, n_degen_list
|
do i = 1, n_degen_list
|
||||||
icheck += list_degen(i,0)
|
icheck += list_degen(i,0)
|
||||||
enddo
|
enddo
|
||||||
|
|
||||||
if(icheck.ne.n)then
|
if(icheck.ne.n)then
|
||||||
print *, ' pb ! :: icheck.ne.n'
|
print *, ' pb ! :: icheck.ne.n'
|
||||||
print *, icheck, n
|
print *, icheck, n
|
||||||
stop
|
stop
|
||||||
endif
|
endif
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
! ---
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user