10
0
mirror of https://github.com/LCPQ/quantum_package synced 2024-11-14 10:03:51 +01:00
quantum_package/plugins/Perturbation/epstein_nesbet.irp.f

94 lines
3.2 KiB
Fortran
Raw Normal View History

2014-05-28 23:12:00 +02:00
subroutine pt2_epstein_nesbet(det_pert,c_pert,e_2_pert,H_pert_diag,Nint,ndet,N_st)
2014-05-18 22:46:38 +02:00
use bitmasks
implicit none
2014-05-28 23:12:00 +02:00
integer, intent(in) :: Nint,ndet,N_st
2014-05-18 22:46:38 +02:00
integer(bit_kind), intent(in) :: det_pert(Nint,2)
2014-05-28 23:12:00 +02:00
double precision , intent(out) :: c_pert(N_st),e_2_pert(N_st),H_pert_diag(N_st)
2014-05-18 22:46:38 +02:00
double precision :: i_H_psi_array(N_st)
BEGIN_DOC
! compute the standard Epstein-Nesbet perturbative first order coefficient and second order energetic contribution
!
2014-05-28 23:12:00 +02:00
! for the various N_st states.
2014-05-18 22:46:38 +02:00
!
! c_pert(i) = <psi(i)|H|det_pert>/( E(i) - <det_pert|H|det_pert> )
!
! e_2_pert(i) = <psi(i)|H|det_pert>^2/( E(i) - <det_pert|H|det_pert> )
!
END_DOC
integer :: i,j
2014-05-28 23:12:00 +02:00
double precision :: diag_H_mat_elem, h
2014-10-15 15:19:34 +02:00
PROVIDE selection_criterion
2014-05-18 22:46:38 +02:00
ASSERT (Nint == N_int)
ASSERT (Nint > 0)
2014-05-27 17:30:44 +02:00
call i_H_psi(det_pert,psi_selectors,psi_selectors_coef,Nint,N_det_selectors,psi_selectors_size,N_st,i_H_psi_array)
2014-05-28 23:12:00 +02:00
h = diag_H_mat_elem(det_pert,Nint)
do i =1,N_st
if(CI_electronic_energy(i)>h.and.CI_electronic_energy(i).ne.0.d0)then
c_pert(i) = -1.d0
e_2_pert(i) = selection_criterion*selection_criterion_factor*2.d0
else if (dabs(CI_electronic_energy(i) - h) > 1.d-6) then
2014-05-28 23:12:00 +02:00
c_pert(i) = i_H_psi_array(i) / (CI_electronic_energy(i) - h)
2014-05-30 18:07:04 +02:00
H_pert_diag(i) = h*c_pert(i)*c_pert(i)
2014-05-27 17:30:44 +02:00
e_2_pert(i) = c_pert(i) * i_H_psi_array(i)
else
2014-05-30 18:07:04 +02:00
c_pert(i) = -1.d0
e_2_pert(i) = -dabs(i_H_psi_array(i))
H_pert_diag(i) = h
2014-05-27 17:30:44 +02:00
endif
enddo
2014-05-18 22:46:38 +02:00
end
2014-05-28 23:12:00 +02:00
subroutine pt2_epstein_nesbet_2x2(det_pert,c_pert,e_2_pert,H_pert_diag,Nint,ndet,N_st)
2014-05-18 22:46:38 +02:00
use bitmasks
implicit none
2014-05-28 23:12:00 +02:00
integer, intent(in) :: Nint,ndet,N_st
2014-05-18 22:46:38 +02:00
integer(bit_kind), intent(in) :: det_pert(Nint,2)
2014-05-28 23:12:00 +02:00
double precision , intent(out) :: c_pert(N_st),e_2_pert(N_st),H_pert_diag(N_st)
2014-05-18 22:46:38 +02:00
double precision :: i_H_psi_array(N_st)
BEGIN_DOC
! compute the Epstein-Nesbet 2x2 diagonalization coefficient and energetic contribution
!
2014-05-28 23:12:00 +02:00
! for the various N_st states.
2014-05-18 22:46:38 +02:00
!
! e_2_pert(i) = 0.5 * (( <det_pert|H|det_pert> - E(i) ) - sqrt( ( <det_pert|H|det_pert> - E(i)) ^2 + 4 <psi(i)|H|det_pert>^2 )
!
! c_pert(i) = e_2_pert(i)/ <psi(i)|H|det_pert>
!
END_DOC
integer :: i,j
2014-05-28 23:12:00 +02:00
double precision :: diag_H_mat_elem,delta_e, h
2014-05-18 22:46:38 +02:00
ASSERT (Nint == N_int)
ASSERT (Nint > 0)
2014-10-15 15:19:34 +02:00
PROVIDE CI_electronic_energy
2014-05-28 23:12:00 +02:00
call i_H_psi(det_pert,psi_selectors,psi_selectors_coef,Nint,N_det_selectors,psi_selectors_size,N_st,i_H_psi_array)
h = diag_H_mat_elem(det_pert,Nint)
do i =1,N_st
if (i_H_psi_array(i) /= 0.d0) then
delta_e = h - CI_electronic_energy(i)
if (delta_e > 0.d0) then
e_2_pert(i) = 0.5d0 * (delta_e - dsqrt(delta_e * delta_e + 4.d0 * i_H_psi_array(i) * i_H_psi_array(i)))
else
e_2_pert(i) = 0.5d0 * (delta_e + dsqrt(delta_e * delta_e + 4.d0 * i_H_psi_array(i) * i_H_psi_array(i)))
endif
if (dabs(i_H_psi_array(i)) > 1.d-6) then
c_pert(i) = e_2_pert(i)/i_H_psi_array(i)
else
c_pert(i) = 0.d0
endif
H_pert_diag(i) = h*c_pert(i)*c_pert(i)
2014-05-26 13:09:32 +02:00
else
e_2_pert(i) = 0.d0
c_pert(i) = 0.d0
H_pert_diag(i) = 0.d0
2014-05-26 13:09:32 +02:00
endif
2014-05-18 22:46:38 +02:00
enddo
2014-05-21 16:37:54 +02:00
2014-05-18 22:46:38 +02:00
end