10
0
mirror of https://github.com/LCPQ/quantum_package synced 2024-07-07 11:55:56 +02:00
quantum_package/src/Determinants/connected_to_ref.irp.f

449 lines
12 KiB
Fortran
Raw Normal View History

2015-04-20 16:45:06 +02:00
integer*8 function det_search_key(det,Nint)
use bitmasks
implicit none
BEGIN_DOC
! Return an integer*8 corresponding to a determinant index for searching
END_DOC
integer, intent(in) :: Nint
integer(bit_kind), intent(in) :: det(Nint,2)
integer :: i
det_search_key = iand(det(1,1),det(1,2))
do i=2,Nint
det_search_key = ieor(det_search_key,iand(det(i,1),det(i,2)))
enddo
2015-07-13 18:00:38 +02:00
det_search_key = iand(huge(det(1,1)),det_search_key)
2015-04-20 16:45:06 +02:00
end
integer*8 function occ_pattern_search_key(det,Nint)
use bitmasks
implicit none
BEGIN_DOC
! Return an integer*8 corresponding to a determinant index for searching
END_DOC
integer, intent(in) :: Nint
integer(bit_kind), intent(in) :: det(Nint,2)
integer :: i
occ_pattern_search_key = ieor(det(1,1),det(1,2))
do i=2,Nint
occ_pattern_search_key = ieor(occ_pattern_search_key,iand(det(i,1),det(i,2)))
enddo
2015-07-13 18:00:38 +02:00
occ_pattern_search_key = iand(huge(det(1,1)),occ_pattern_search_key)
2015-04-20 16:45:06 +02:00
end
2015-07-29 18:27:07 +02:00
logical function is_in_wavefunction(key,Nint)
2015-04-20 16:45:06 +02:00
use bitmasks
implicit none
BEGIN_DOC
! True if the determinant ``det`` is in the wave function
END_DOC
2015-07-29 18:27:07 +02:00
integer, intent(in) :: Nint
2015-04-20 16:45:06 +02:00
integer(bit_kind), intent(in) :: key(Nint,2)
integer, external :: get_index_in_psi_det_sorted_bit
!DIR$ FORCEINLINE
is_in_wavefunction = get_index_in_psi_det_sorted_bit(key,Nint) > 0
end
integer function get_index_in_psi_det_sorted_bit(key,Nint)
use bitmasks
BEGIN_DOC
! Returns the index of the determinant in the ``psi_det_sorted_bit`` array
END_DOC
implicit none
integer, intent(in) :: Nint
integer(bit_kind), intent(in) :: key(Nint,2)
integer :: i, ibegin, iend, istep, l
integer*8 :: det_ref, det_search
integer*8, external :: det_search_key
2015-07-29 18:27:07 +02:00
logical :: in_wavefunction
2015-04-20 16:45:06 +02:00
2015-07-29 18:27:07 +02:00
in_wavefunction = .False.
2015-04-20 16:45:06 +02:00
get_index_in_psi_det_sorted_bit = 0
ibegin = 1
iend = N_det+1
!DIR$ FORCEINLINE
det_ref = det_search_key(key,Nint)
!DIR$ FORCEINLINE
det_search = det_search_key(psi_det_sorted_bit(1,1,1),Nint)
istep = ishft(iend-ibegin,-1)
i=ibegin+istep
do while (istep > 0)
!DIR$ FORCEINLINE
det_search = det_search_key(psi_det_sorted_bit(1,1,i),Nint)
if ( det_search > det_ref ) then
iend = i
else if ( det_search == det_ref ) then
exit
else
ibegin = i
endif
istep = ishft(iend-ibegin,-1)
i = ibegin + istep
end do
!DIR$ FORCEINLINE
do while (det_search_key(psi_det_sorted_bit(1,1,i),Nint) == det_ref)
i = i-1
if (i == 0) then
exit
endif
enddo
2016-02-04 10:56:39 +01:00
if (i >= N_det) then
2015-04-20 16:45:06 +02:00
return
endif
2016-02-04 10:56:39 +01:00
i += 1
2015-04-20 16:45:06 +02:00
!DIR$ FORCEINLINE
do while (det_search_key(psi_det_sorted_bit(1,1,i),Nint) == det_ref)
if ( (key(1,1) /= psi_det_sorted_bit(1,1,i)).or. &
(key(1,2) /= psi_det_sorted_bit(1,2,i)) ) then
continue
else
2015-07-29 18:27:07 +02:00
in_wavefunction = .True.
2015-04-20 16:45:06 +02:00
do l=2,Nint
if ( (key(l,1) /= psi_det_sorted_bit(l,1,i)).or. &
(key(l,2) /= psi_det_sorted_bit(l,2,i)) ) then
2015-07-29 18:27:07 +02:00
in_wavefunction = .False.
2015-04-20 16:45:06 +02:00
endif
enddo
2015-07-29 18:27:07 +02:00
if (in_wavefunction) then
2015-04-20 16:45:06 +02:00
get_index_in_psi_det_sorted_bit = i
! exit
return
endif
endif
i += 1
if (i > N_det) then
! exit
return
endif
enddo
! DEBUG is_in_wf
2015-07-29 18:27:07 +02:00
! if (in_wavefunction) then
2015-04-20 16:45:06 +02:00
! degree = 1
! do i=1,N_det
! integer :: degree
! call get_excitation_degree(key,psi_det(1,1,i),degree,N_int)
! if (degree == 0) then
! exit
! endif
! enddo
! if (degree /=0) then
! stop 'pouet 1'
! endif
! else
! do i=1,N_det
! call get_excitation_degree(key,psi_det(1,1,i),degree,N_int)
! if (degree == 0) then
! stop 'pouet 2'
! endif
! enddo
! endif
! END DEBUG is_in_wf
end
2015-11-19 21:20:43 +01:00
logical function is_connected_to(key,keys,Nint,Ndet)
use bitmasks
implicit none
integer, intent(in) :: Nint, Ndet
integer(bit_kind), intent(in) :: keys(Nint,2,Ndet)
integer(bit_kind), intent(in) :: key(Nint,2)
integer :: i, l
integer :: degree_x2
2016-05-20 09:44:22 +02:00
logical, external :: is_generable_cassd
2015-11-19 21:20:43 +01:00
ASSERT (Nint > 0)
ASSERT (Nint == N_int)
is_connected_to = .false.
do i=1,Ndet
degree_x2 = popcnt(xor( key(1,1), keys(1,1,i))) + &
popcnt(xor( key(1,2), keys(1,2,i)))
do l=2,Nint
degree_x2 = degree_x2 + popcnt(xor( key(l,1), keys(l,1,i))) +&
popcnt(xor( key(l,2), keys(l,2,i)))
enddo
if (degree_x2 > 4) then
cycle
else
2016-05-20 09:44:22 +02:00
! if(.not. is_generable_cassd(keys(1,1,i), key(1,1), Nint)) cycle !!!Nint==1 !!!!!
2015-11-19 21:20:43 +01:00
is_connected_to = .true.
return
endif
enddo
end
2016-05-20 09:44:22 +02:00
logical function is_generable_cassd(det1, det2, Nint) !!! TEST Cl HARD !!!!!
use bitmasks
implicit none
integer, intent(in) :: Nint
integer(bit_kind) :: det1(Nint, 2), det2(Nint, 2)
integer :: degree, f, exc(0:2, 2, 2), h1, h2, p1, p2, s1, s2, t
double precision :: phase
is_generable_cassd = .false.
call get_excitation(det1, det2, exc, degree, phase, Nint)
if(degree == -1) return
if(degree == 0) then
is_generable_cassd = .true.
return
end if
call decode_exc(exc,degree,h1,p1,h2,p2,s1,s2)
if(degree == 1 .and. h1 <= 11) is_generable_cassd = .true.
if(degree == 2 .and. h1 <= 11 .and. h2 <= 11) is_generable_cassd = .true.
end function
2016-02-18 11:33:26 +01:00
logical function is_connected_to_by_mono(key,keys,Nint,Ndet)
use bitmasks
implicit none
integer, intent(in) :: Nint, Ndet
integer(bit_kind), intent(in) :: keys(Nint,2,Ndet)
integer(bit_kind), intent(in) :: key(Nint,2)
integer :: i, l
integer :: degree_x2
ASSERT (Nint > 0)
ASSERT (Nint == N_int)
is_connected_to_by_mono = .false.
do i=1,Ndet
degree_x2 = popcnt(xor( key(1,1), keys(1,1,i))) + &
popcnt(xor( key(1,2), keys(1,2,i)))
do l=2,Nint
degree_x2 = degree_x2 + popcnt(xor( key(l,1), keys(l,1,i))) +&
popcnt(xor( key(l,2), keys(l,2,i)))
enddo
if (degree_x2 > 2) then
cycle
else
is_connected_to_by_mono = .true.
return
endif
enddo
end
2015-11-19 21:20:43 +01:00
2015-04-20 16:45:06 +02:00
integer function connected_to_ref(key,keys,Nint,N_past_in,Ndet)
use bitmasks
implicit none
integer, intent(in) :: Nint, N_past_in, Ndet
integer(bit_kind), intent(in) :: keys(Nint,2,Ndet)
integer(bit_kind), intent(in) :: key(Nint,2)
integer :: N_past
integer :: i, l
integer :: degree_x2
logical :: t
double precision :: hij_elec
! output : 0 : not connected
! i : connected to determinant i of the past
! -i : is the ith determinant of the reference wf keys
2015-04-20 16:45:06 +02:00
ASSERT (Nint > 0)
ASSERT (Nint == N_int)
connected_to_ref = 0
N_past = max(1,N_past_in)
if (Nint == 1) then
do i=N_past-1,1,-1
degree_x2 = popcnt(xor( key(1,1), keys(1,1,i))) + &
popcnt(xor( key(1,2), keys(1,2,i)))
if (degree_x2 > 4) then
cycle
else
connected_to_ref = i
return
endif
enddo
return
else if (Nint==2) then
do i=N_past-1,1,-1
degree_x2 = popcnt(xor( key(1,1), keys(1,1,i))) + &
popcnt(xor( key(1,2), keys(1,2,i))) + &
popcnt(xor( key(2,1), keys(2,1,i))) + &
popcnt(xor( key(2,2), keys(2,2,i)))
if (degree_x2 > 4) then
cycle
else
connected_to_ref = i
return
endif
enddo
return
else if (Nint==3) then
do i=N_past-1,1,-1
degree_x2 = popcnt(xor( key(1,1), keys(1,1,i))) + &
popcnt(xor( key(1,2), keys(1,2,i))) + &
popcnt(xor( key(2,1), keys(2,1,i))) + &
popcnt(xor( key(2,2), keys(2,2,i))) + &
popcnt(xor( key(3,1), keys(3,1,i))) + &
popcnt(xor( key(3,2), keys(3,2,i)))
if (degree_x2 > 4) then
cycle
else
connected_to_ref = i
return
endif
enddo
return
else
do i=N_past-1,1,-1
degree_x2 = popcnt(xor( key(1,1), keys(1,1,i))) + &
popcnt(xor( key(1,2), keys(1,2,i)))
do l=2,Nint
degree_x2 = degree_x2 + popcnt(xor( key(l,1), keys(l,1,i))) +&
popcnt(xor( key(l,2), keys(l,2,i)))
2016-07-15 15:31:16 +02:00
if (degree_x2 > 4) then
exit
endif
2015-04-20 16:45:06 +02:00
enddo
if (degree_x2 > 4) then
cycle
else
connected_to_ref = i
return
endif
enddo
endif
end
integer function connected_to_ref_by_mono(key,keys,Nint,N_past_in,Ndet)
use bitmasks
implicit none
integer, intent(in) :: Nint, N_past_in, Ndet
integer(bit_kind), intent(in) :: keys(Nint,2,Ndet)
integer(bit_kind), intent(in) :: key(Nint,2)
integer :: N_past
integer :: i, l
integer :: degree_x2
logical :: t
double precision :: hij_elec
! output : 0 : not connected
! i : connected to determinant i of the past
! -i : is the ith determinant of the refernce wf keys
ASSERT (Nint > 0)
ASSERT (Nint == N_int)
connected_to_ref_by_mono = 0
N_past = max(1,N_past_in)
if (Nint == 1) then
do i=N_past-1,1,-1
degree_x2 = popcnt(xor( key(1,1), keys(1,1,i))) + &
popcnt(xor( key(1,2), keys(1,2,i)))
if (degree_x2 > 3.and. degree_x2 <5) then
cycle
else if (degree_x2 == 4)then
cycle
else if(degree_x2 == 2)then
connected_to_ref_by_mono = i
return
endif
enddo
return
else if (Nint==2) then
do i=N_past-1,1,-1
degree_x2 = popcnt(xor( key(1,1), keys(1,1,i))) + &
popcnt(xor( key(1,2), keys(1,2,i))) + &
popcnt(xor( key(2,1), keys(2,1,i))) + &
popcnt(xor( key(2,2), keys(2,2,i)))
if (degree_x2 > 3.and. degree_x2 <5) then
cycle
else if (degree_x2 == 4)then
cycle
else if(degree_x2 == 2)then
connected_to_ref_by_mono = i
return
endif
enddo
return
else if (Nint==3) then
do i=N_past-1,1,-1
degree_x2 = popcnt(xor( key(1,1), keys(1,1,i))) + &
popcnt(xor( key(1,2), keys(1,2,i))) + &
popcnt(xor( key(2,1), keys(2,1,i))) + &
popcnt(xor( key(2,2), keys(2,2,i))) + &
popcnt(xor( key(3,1), keys(3,1,i))) + &
popcnt(xor( key(3,2), keys(3,2,i)))
if (degree_x2 > 3.and. degree_x2 <5) then
cycle
else if (degree_x2 == 4)then
cycle
else if(degree_x2 == 2)then
connected_to_ref_by_mono = i
return
endif
enddo
return
else
do i=N_past-1,1,-1
degree_x2 = popcnt(xor( key(1,1), keys(1,1,i))) + &
popcnt(xor( key(1,2), keys(1,2,i)))
do l=2,Nint
degree_x2 = degree_x2 + popcnt(xor( key(l,1), keys(l,1,i))) +&
popcnt(xor( key(l,2), keys(l,2,i)))
enddo
if (degree_x2 > 3.and. degree_x2 <5) then
cycle
else if (degree_x2 == 4)then
cycle
else if(degree_x2 == 2)then
connected_to_ref_by_mono = i
return
endif
enddo
endif
end