mirror of
https://github.com/LCPQ/quantum_package
synced 2024-11-09 07:33:53 +01:00
368 lines
11 KiB
Fortran
368 lines
11 KiB
Fortran
|
|
BEGIN_PROVIDER [ double precision, delta_ij, (N_det,N_det,N_states) ]
|
|
&BEGIN_PROVIDER [ double precision, second_order_pt_new, (N_states) ]
|
|
&BEGIN_PROVIDER [ double precision, second_order_pt_new_1h, (N_states) ]
|
|
&BEGIN_PROVIDER [ double precision, second_order_pt_new_1p, (N_states) ]
|
|
&BEGIN_PROVIDER [ double precision, second_order_pt_new_1h1p, (N_states) ]
|
|
&BEGIN_PROVIDER [ double precision, second_order_pt_new_2h, (N_states) ]
|
|
&BEGIN_PROVIDER [ double precision, second_order_pt_new_2p, (N_states) ]
|
|
&BEGIN_PROVIDER [ double precision, second_order_pt_new_1h2p, (N_states) ]
|
|
&BEGIN_PROVIDER [ double precision, second_order_pt_new_2h1p, (N_states) ]
|
|
&BEGIN_PROVIDER [ double precision, second_order_pt_new_2h2p, (N_states) ]
|
|
implicit none
|
|
BEGIN_DOC
|
|
! Dressing matrix in N_det basis
|
|
END_DOC
|
|
integer :: i,j,m
|
|
integer :: i_state
|
|
double precision :: accu(N_states)
|
|
double precision, allocatable :: delta_ij_tmp(:,:,:)
|
|
|
|
|
|
delta_ij = 0.d0
|
|
|
|
allocate (delta_ij_tmp(N_det,N_det,N_states))
|
|
|
|
|
|
! 1h
|
|
delta_ij_tmp = 0.d0
|
|
call H_apply_mrpt_1h(delta_ij_tmp,N_det)
|
|
accu = 0.d0
|
|
do i_state = 1, N_states
|
|
do i = 1, N_det
|
|
do j = 1, N_det
|
|
accu(i_state) += delta_ij_tmp(j,i,i_state) * psi_coef(i,i_state) * psi_coef(j,i_state)
|
|
delta_ij(j,i,i_state) += delta_ij_tmp(j,i,i_state)
|
|
enddo
|
|
enddo
|
|
second_order_pt_new_1h(i_state) = accu(i_state)
|
|
enddo
|
|
print*, '1h = ',accu
|
|
|
|
! 1p
|
|
delta_ij_tmp = 0.d0
|
|
call H_apply_mrpt_1p(delta_ij_tmp,N_det)
|
|
accu = 0.d0
|
|
do i_state = 1, N_states
|
|
do i = 1, N_det
|
|
do j = 1, N_det
|
|
accu(i_state) += delta_ij_tmp(j,i,i_state) * psi_coef(i,i_state) * psi_coef(j,i_state)
|
|
delta_ij(j,i,i_state) += delta_ij_tmp(j,i,i_state)
|
|
enddo
|
|
enddo
|
|
second_order_pt_new_1p(i_state) = accu(i_state)
|
|
enddo
|
|
print*, '1p = ',accu
|
|
|
|
! 1h1p
|
|
delta_ij_tmp = 0.d0
|
|
call H_apply_mrpt_1h1p(delta_ij_tmp,N_det)
|
|
double precision :: e_corr_from_1h1p_singles(N_states)
|
|
!call give_singles_and_partial_doubles_1h1p_contrib(delta_ij_tmp,e_corr_from_1h1p_singles)
|
|
!call give_1h1p_only_doubles_spin_cross(delta_ij_tmp)
|
|
accu = 0.d0
|
|
do i_state = 1, N_states
|
|
do i = 1, N_det
|
|
do j = 1, N_det
|
|
accu(i_state) += delta_ij_tmp(j,i,i_state) * psi_coef(i,i_state) * psi_coef(j,i_state)
|
|
delta_ij(j,i,i_state) += delta_ij_tmp(j,i,i_state)
|
|
enddo
|
|
enddo
|
|
second_order_pt_new_1h1p(i_state) = accu(i_state)
|
|
enddo
|
|
print*, '1h1p = ',accu
|
|
|
|
! 1h1p third order
|
|
if(do_third_order_1h1p)then
|
|
delta_ij_tmp = 0.d0
|
|
call give_1h1p_sec_order_singles_contrib(delta_ij_tmp)
|
|
accu = 0.d0
|
|
do i_state = 1, N_states
|
|
do i = 1, N_det
|
|
do j = 1, N_det
|
|
accu(i_state) += delta_ij_tmp(j,i,i_state) * psi_coef(i,i_state) * psi_coef(j,i_state)
|
|
delta_ij(j,i,i_state) += delta_ij_tmp(j,i,i_state)
|
|
enddo
|
|
enddo
|
|
second_order_pt_new_1h1p(i_state) = accu(i_state)
|
|
enddo
|
|
print*, '1h1p(3)',accu
|
|
endif
|
|
|
|
! 2h
|
|
delta_ij_tmp = 0.d0
|
|
call H_apply_mrpt_2h(delta_ij_tmp,N_det)
|
|
accu = 0.d0
|
|
do i_state = 1, N_states
|
|
do i = 1, N_det
|
|
do j = 1, N_det
|
|
accu(i_state) += delta_ij_tmp(j,i,i_state) * psi_coef(i,i_state) * psi_coef(j,i_state)
|
|
delta_ij(j,i,i_state) += delta_ij_tmp(j,i,i_state)
|
|
enddo
|
|
enddo
|
|
second_order_pt_new_2h(i_state) = accu(i_state)
|
|
enddo
|
|
print*, '2h = ',accu
|
|
|
|
! 2p
|
|
delta_ij_tmp = 0.d0
|
|
call H_apply_mrpt_2p(delta_ij_tmp,N_det)
|
|
accu = 0.d0
|
|
do i_state = 1, N_states
|
|
do i = 1, N_det
|
|
do j = 1, N_det
|
|
accu(i_state) += delta_ij_tmp(j,i,i_state) * psi_coef(i,i_state) * psi_coef(j,i_state)
|
|
delta_ij(j,i,i_state) += delta_ij_tmp(j,i,i_state)
|
|
enddo
|
|
enddo
|
|
second_order_pt_new_2p(i_state) = accu(i_state)
|
|
enddo
|
|
print*, '2p = ',accu
|
|
|
|
! 1h2p
|
|
delta_ij_tmp = 0.d0
|
|
!call give_1h2p_contrib(delta_ij_tmp)
|
|
call H_apply_mrpt_1h2p(delta_ij_tmp,N_det)
|
|
accu = 0.d0
|
|
do i_state = 1, N_states
|
|
do i = 1, N_det
|
|
do j = 1, N_det
|
|
accu(i_state) += delta_ij_tmp(j,i,i_state) * psi_coef(i,i_state) * psi_coef(j,i_state)
|
|
delta_ij(j,i,i_state) += delta_ij_tmp(j,i,i_state)
|
|
enddo
|
|
enddo
|
|
second_order_pt_new_1h2p(i_state) = accu(i_state)
|
|
enddo
|
|
print*, '1h2p = ',accu
|
|
|
|
! 2h1p
|
|
delta_ij_tmp = 0.d0
|
|
!call give_2h1p_contrib(delta_ij_tmp)
|
|
call H_apply_mrpt_2h1p(delta_ij_tmp,N_det)
|
|
accu = 0.d0
|
|
do i_state = 1, N_states
|
|
do i = 1, N_det
|
|
do j = 1, N_det
|
|
accu(i_state) += delta_ij_tmp(j,i,i_state) * psi_coef(i,i_state) * psi_coef(j,i_state)
|
|
delta_ij(j,i,i_state) += delta_ij_tmp(j,i,i_state)
|
|
enddo
|
|
enddo
|
|
second_order_pt_new_2h1p(i_state) = accu(i_state)
|
|
enddo
|
|
print*, '2h1p = ',accu
|
|
|
|
! 2h2p
|
|
!delta_ij_tmp = 0.d0
|
|
!call H_apply_mrpt_2h2p(delta_ij_tmp,N_det)
|
|
!accu = 0.d0
|
|
!do i_state = 1, N_states
|
|
!do i = 1, N_det
|
|
! do j = 1, N_det
|
|
! accu(i_state) += delta_ij_tmp(j,i,i_state) * psi_coef(i,i_state) * psi_coef(j,i_state)
|
|
! delta_ij(j,i,i_state) += delta_ij_tmp(j,i,i_state)
|
|
! enddo
|
|
!enddo
|
|
!second_order_pt_new_2h2p(i_state) = accu(i_state)
|
|
!enddo
|
|
!print*, '2h2p = ',accu
|
|
|
|
double precision :: contrib_2h2p(N_states)
|
|
call give_2h2p(contrib_2h2p)
|
|
do i_state = 1, N_states
|
|
do i = 1, N_det
|
|
delta_ij(i,i,i_state) += contrib_2h2p(i_state)
|
|
enddo
|
|
second_order_pt_new_2h2p(i_state) = contrib_2h2p(i_state)
|
|
enddo
|
|
print*, '2h2p = ',contrib_2h2p(1)
|
|
|
|
|
|
! total
|
|
accu = 0.d0
|
|
do i_state = 1, N_states
|
|
do i = 1, N_det
|
|
! write(*,'(1000(F16.10,x))')delta_ij(i,:,:)
|
|
do j = i_state, N_det
|
|
accu(i_state) += delta_ij(j,i,i_state) * psi_coef(i,i_state) * psi_coef(j,i_state)
|
|
enddo
|
|
enddo
|
|
second_order_pt_new(i_state) = accu(i_state)
|
|
print*, 'total= ',accu(i_state)
|
|
enddo
|
|
|
|
|
|
|
|
|
|
END_PROVIDER
|
|
|
|
BEGIN_PROVIDER [double precision, Hmatrix_dressed_pt2_new, (N_det,N_det,N_states)]
|
|
implicit none
|
|
integer :: i,j,i_state
|
|
do i_state = 1, N_states
|
|
do i = 1,N_det
|
|
do j = 1,N_det
|
|
Hmatrix_dressed_pt2_new(j,i,i_state) = H_matrix_all_dets(j,i) + delta_ij(j,i,i_state)
|
|
enddo
|
|
enddo
|
|
enddo
|
|
END_PROVIDER
|
|
|
|
|
|
|
|
BEGIN_PROVIDER [double precision, Hmatrix_dressed_pt2_new_symmetrized, (N_det,N_det,N_states)]
|
|
implicit none
|
|
integer :: i,j,i_state
|
|
do i_state = 1, N_states
|
|
do i = 1,N_det
|
|
do j = i,N_det
|
|
Hmatrix_dressed_pt2_new_symmetrized(j,i,i_state) = H_matrix_all_dets(j,i) &
|
|
+ 0.5d0 * ( delta_ij(j,i,i_state) + delta_ij(i,j,i_state) )
|
|
Hmatrix_dressed_pt2_new_symmetrized(i,j,i_state) = Hmatrix_dressed_pt2_new_symmetrized(j,i,i_state)
|
|
enddo
|
|
enddo
|
|
enddo
|
|
END_PROVIDER
|
|
|
|
BEGIN_PROVIDER [ double precision, CI_electronic_dressed_pt2_new_energy, (N_states_diag) ]
|
|
&BEGIN_PROVIDER [ double precision, CI_dressed_pt2_new_eigenvectors, (N_det,N_states_diag) ]
|
|
&BEGIN_PROVIDER [ double precision, CI_dressed_pt2_new_eigenvectors_s2, (N_states_diag) ]
|
|
BEGIN_DOC
|
|
! Eigenvectors/values of the CI matrix
|
|
END_DOC
|
|
implicit none
|
|
double precision :: ovrlp,u_dot_v
|
|
integer :: i_good_state
|
|
integer, allocatable :: index_good_state_array(:)
|
|
logical, allocatable :: good_state_array(:)
|
|
double precision, allocatable :: s2_values_tmp(:)
|
|
integer :: i_other_state
|
|
double precision, allocatable :: eigenvectors(:,:), eigenvalues(:)
|
|
integer :: i_state
|
|
double precision :: s2,e_0
|
|
integer :: i,j,k
|
|
double precision, allocatable :: s2_eigvalues(:)
|
|
double precision, allocatable :: e_array(:)
|
|
integer, allocatable :: iorder(:)
|
|
|
|
! Guess values for the "N_states_diag" states of the CI_dressed_pt2_new_eigenvectors
|
|
do j=1,min(N_states_diag,N_det)
|
|
do i=1,N_det
|
|
CI_dressed_pt2_new_eigenvectors(i,j) = psi_coef(i,j)
|
|
enddo
|
|
enddo
|
|
|
|
do j=N_det+1,N_states_diag
|
|
do i=1,N_det
|
|
CI_dressed_pt2_new_eigenvectors(i,j) = 0.d0
|
|
enddo
|
|
enddo
|
|
|
|
if (diag_algorithm == "Davidson") then
|
|
|
|
print*, 'Davidson not yet implemented for the dressing ... '
|
|
stop
|
|
|
|
else if (diag_algorithm == "Lapack") then
|
|
|
|
allocate (eigenvectors(size(H_matrix_all_dets,1),N_det))
|
|
allocate (eigenvalues(N_det))
|
|
call lapack_diag(eigenvalues,eigenvectors, &
|
|
H_matrix_all_dets,size(H_matrix_all_dets,1),N_det)
|
|
CI_electronic_energy(:) = 0.d0
|
|
if (s2_eig) then
|
|
i_state = 0
|
|
allocate (s2_eigvalues(N_det))
|
|
allocate(index_good_state_array(N_det),good_state_array(N_det))
|
|
good_state_array = .False.
|
|
call u_0_S2_u_0(s2_eigvalues,eigenvectors,N_det,psi_det,N_int,&
|
|
N_det,size(eigenvectors,1))
|
|
do j=1,N_det
|
|
! Select at least n_states states with S^2 values closed to "expected_s2"
|
|
if(dabs(s2_eigvalues(j)-expected_s2).le.0.5d0)then
|
|
i_state +=1
|
|
index_good_state_array(i_state) = j
|
|
good_state_array(j) = .True.
|
|
endif
|
|
if(i_state.eq.N_states) then
|
|
exit
|
|
endif
|
|
enddo
|
|
if(i_state .ne.0)then
|
|
! Fill the first "i_state" states that have a correct S^2 value
|
|
do j = 1, i_state
|
|
do i=1,N_det
|
|
CI_eigenvectors(i,j) = eigenvectors(i,index_good_state_array(j))
|
|
enddo
|
|
CI_electronic_energy(j) = eigenvalues(index_good_state_array(j))
|
|
CI_eigenvectors_s2(j) = s2_eigvalues(index_good_state_array(j))
|
|
enddo
|
|
i_other_state = 0
|
|
do j = 1, N_det
|
|
if(good_state_array(j))cycle
|
|
i_other_state +=1
|
|
if(i_state+i_other_state.gt.n_states_diag)then
|
|
exit
|
|
endif
|
|
do i=1,N_det
|
|
CI_eigenvectors(i,i_state+i_other_state) = eigenvectors(i,j)
|
|
enddo
|
|
CI_electronic_energy(i_state+i_other_state) = eigenvalues(j)
|
|
CI_eigenvectors_s2(i_state+i_other_state) = s2_eigvalues(i_state+i_other_state)
|
|
enddo
|
|
|
|
else
|
|
print*,''
|
|
print*,'!!!!!!!! WARNING !!!!!!!!!'
|
|
print*,' Within the ',N_det,'determinants selected'
|
|
print*,' and the ',N_states_diag,'states requested'
|
|
print*,' We did not find any state with S^2 values close to ',expected_s2
|
|
print*,' We will then set the first N_states eigenvectors of the H matrix'
|
|
print*,' as the CI_eigenvectors'
|
|
print*,' You should consider more states and maybe ask for s2_eig to be .True. or just enlarge the CI space'
|
|
print*,''
|
|
do j=1,min(N_states_diag,N_det)
|
|
do i=1,N_det
|
|
CI_eigenvectors(i,j) = eigenvectors(i,j)
|
|
enddo
|
|
CI_electronic_energy(j) = eigenvalues(j)
|
|
CI_eigenvectors_s2(j) = s2_eigvalues(j)
|
|
enddo
|
|
endif
|
|
deallocate(index_good_state_array,good_state_array)
|
|
deallocate(s2_eigvalues)
|
|
else
|
|
call u_0_S2_u_0(CI_eigenvectors_s2,eigenvectors,N_det,psi_det,N_int,&
|
|
min(N_det,N_states_diag),size(eigenvectors,1))
|
|
! Select the "N_states_diag" states of lowest energy
|
|
do j=1,min(N_det,N_states_diag)
|
|
do i=1,N_det
|
|
CI_eigenvectors(i,j) = eigenvectors(i,j)
|
|
enddo
|
|
CI_electronic_energy(j) = eigenvalues(j)
|
|
enddo
|
|
endif
|
|
deallocate(eigenvectors,eigenvalues)
|
|
endif
|
|
|
|
|
|
END_PROVIDER
|
|
|
|
|
|
BEGIN_PROVIDER [ double precision, CI_dressed_pt2_new_energy, (N_states_diag) ]
|
|
implicit none
|
|
BEGIN_DOC
|
|
! N_states lowest eigenvalues of the CI matrix
|
|
END_DOC
|
|
|
|
integer :: j
|
|
character*(8) :: st
|
|
call write_time(output_determinants)
|
|
do j=1,N_states_diag
|
|
CI_dressed_pt2_new_energy(j) = CI_electronic_dressed_pt2_new_energy(j) + nuclear_repulsion
|
|
write(st,'(I4)') j
|
|
call write_double(output_determinants,CI_dressed_pt2_new_energy(j),'Energy of state '//trim(st))
|
|
call write_double(output_determinants,CI_eigenvectors_s2(j),'S^2 of state '//trim(st))
|
|
enddo
|
|
|
|
END_PROVIDER
|