mirror of
https://github.com/QuantumPackage/qp2.git
synced 2024-11-14 18:13:51 +01:00
615 lines
19 KiB
Fortran
615 lines
19 KiB
Fortran
|
subroutine print_mo_energies(key_ref,nint,nmo)
|
||
|
use bitmasks
|
||
|
BEGIN_DOC
|
||
|
! get mo energies for one det
|
||
|
END_DOC
|
||
|
implicit none
|
||
|
integer, intent(in) :: nint, nmo
|
||
|
integer(bit_kind), intent(in) :: key_ref(nint,2)
|
||
|
double precision, allocatable :: e_mo(:,:)
|
||
|
integer, allocatable :: occ(:,:),virt(:,:) !(nint*bit_kind_size,2)
|
||
|
integer :: n_occ(2), n_virt(2)
|
||
|
integer, parameter :: int_spin2(1:2) = (/2,1/)
|
||
|
integer :: i,j,ispin,jspin,i0,j0,k
|
||
|
integer(bit_kind), allocatable :: key_virt(:,:)
|
||
|
integer, allocatable :: is_occ(:,:)
|
||
|
|
||
|
|
||
|
allocate(occ(nint*bit_kind_size,2),virt(nint*bit_kind_size,2),key_virt(nint,2),e_mo(nmo,2),is_occ(nmo,2))
|
||
|
is_occ=0
|
||
|
|
||
|
call bitstring_to_list_ab(key_ref,occ,n_occ,nint)
|
||
|
do i=1,nint
|
||
|
do ispin=1,2
|
||
|
key_virt(i,ispin)=xor(full_ijkl_bitmask(i),key_ref(i,ispin))
|
||
|
enddo
|
||
|
enddo
|
||
|
call bitstring_to_list_ab(key_virt,virt,n_virt,nint)
|
||
|
|
||
|
e_mo(1:nmo,1)=mo_mono_elec_integral_diag(1:nmo)
|
||
|
e_mo(1:nmo,2)=mo_mono_elec_integral_diag(1:nmo)
|
||
|
|
||
|
do ispin=1,2
|
||
|
jspin=int_spin2(ispin)
|
||
|
do i0=1,n_occ(ispin)
|
||
|
i=occ(i0,ispin)
|
||
|
is_occ(i,ispin)=1
|
||
|
do j0=i0+1,n_occ(ispin)
|
||
|
j=occ(j0,ispin)
|
||
|
e_mo(i,ispin) = e_mo(i,ispin) + mo_bielec_integral_jj_anti(i,j)
|
||
|
e_mo(j,ispin) = e_mo(j,ispin) + mo_bielec_integral_jj_anti(i,j)
|
||
|
enddo
|
||
|
do k=2,ispin
|
||
|
do j0=1,n_occ(jspin)
|
||
|
j=occ(j0,jspin)
|
||
|
e_mo(i,ispin) = e_mo(i,ispin) + mo_bielec_integral_jj(i,j)
|
||
|
e_mo(j,jspin) = e_mo(j,jspin) + mo_bielec_integral_jj(i,j) !can delete this and remove k level of loop
|
||
|
enddo
|
||
|
enddo
|
||
|
do j0=1,n_virt(ispin)
|
||
|
j=virt(j0,ispin)
|
||
|
e_mo(j,ispin) = e_mo(j,ispin) + mo_bielec_integral_jj_anti(i,j)
|
||
|
enddo
|
||
|
do j0=1,n_virt(jspin)
|
||
|
j=virt(j0,jspin)
|
||
|
e_mo(j,jspin) = e_mo(j,jspin) + mo_bielec_integral_jj(i,j)
|
||
|
enddo
|
||
|
enddo
|
||
|
enddo
|
||
|
|
||
|
do i=1,nmo
|
||
|
write(6,'(2(I5),2(E25.15))')is_occ(i,1),is_occ(i,2),e_mo(i,1),e_mo(i,2)
|
||
|
enddo
|
||
|
deallocate(occ,virt,key_virt,e_mo,is_occ)
|
||
|
end
|
||
|
|
||
|
subroutine get_mo_energies(key_ref,nint,nmo,e_mo)
|
||
|
use bitmasks
|
||
|
BEGIN_DOC
|
||
|
! get mo energies for one det
|
||
|
END_DOC
|
||
|
implicit none
|
||
|
integer, intent(in) :: nint, nmo
|
||
|
integer(bit_kind), intent(in) :: key_ref(nint,2)
|
||
|
double precision, intent(out) :: e_mo(nmo,2)
|
||
|
integer, allocatable :: occ(:,:),virt(:,:) !(nint*bit_kind_size,2)
|
||
|
integer :: n_occ(2), n_virt(2)
|
||
|
integer, parameter :: int_spin2(1:2) = (/2,1/)
|
||
|
integer :: i,j,ispin,jspin,i0,j0,k
|
||
|
integer(bit_kind), allocatable :: key_virt(:,:)
|
||
|
|
||
|
|
||
|
allocate(occ(nint*bit_kind_size,2),virt(nint*bit_kind_size,2),key_virt(nint,2))
|
||
|
|
||
|
call bitstring_to_list_ab(key_ref,occ,n_occ,nint)
|
||
|
do i=1,nint
|
||
|
do ispin=1,2
|
||
|
key_virt(i,ispin)=xor(full_ijkl_bitmask(i),key_ref(i,ispin))
|
||
|
enddo
|
||
|
enddo
|
||
|
call bitstring_to_list_ab(key_virt,virt,n_virt,nint)
|
||
|
|
||
|
e_mo(1:nmo,1)=mo_mono_elec_integral_diag(1:nmo)
|
||
|
e_mo(1:nmo,2)=mo_mono_elec_integral_diag(1:nmo)
|
||
|
|
||
|
do ispin=1,2
|
||
|
jspin=int_spin2(ispin)
|
||
|
do i0=1,n_occ(ispin)
|
||
|
i=occ(i0,ispin)
|
||
|
do j0=i0+1,n_occ(ispin)
|
||
|
j=occ(j0,ispin)
|
||
|
e_mo(i,ispin) = e_mo(i,ispin) + mo_bielec_integral_jj_anti(i,j)
|
||
|
e_mo(j,ispin) = e_mo(j,ispin) + mo_bielec_integral_jj_anti(i,j)
|
||
|
enddo
|
||
|
do k=2,ispin
|
||
|
do j0=1,n_occ(jspin)
|
||
|
j=occ(j0,jspin)
|
||
|
e_mo(i,ispin) = e_mo(i,ispin) + mo_bielec_integral_jj(i,j)
|
||
|
e_mo(j,jspin) = e_mo(j,jspin) + mo_bielec_integral_jj(i,j) !can delete this and remove k level of loop
|
||
|
enddo
|
||
|
enddo
|
||
|
do j0=1,n_virt(ispin)
|
||
|
j=virt(j0,ispin)
|
||
|
e_mo(j,ispin) = e_mo(j,ispin) + mo_bielec_integral_jj_anti(i,j)
|
||
|
enddo
|
||
|
do j0=1,n_virt(jspin)
|
||
|
j=virt(j0,jspin)
|
||
|
e_mo(j,jspin) = e_mo(j,jspin) + mo_bielec_integral_jj(i,j)
|
||
|
enddo
|
||
|
enddo
|
||
|
enddo
|
||
|
|
||
|
deallocate(occ,virt,key_virt)
|
||
|
end
|
||
|
|
||
|
subroutine get_mask_phase_new(det1, pm, Nint)
|
||
|
use bitmasks
|
||
|
BEGIN_DOC
|
||
|
! phasemask copied from qp2
|
||
|
! return phasemask of det1 in pm
|
||
|
END_DOC
|
||
|
implicit none
|
||
|
integer, intent(in) :: Nint
|
||
|
integer(bit_kind), intent(in) :: det1(Nint,2)
|
||
|
integer(bit_kind), intent(out) :: pm(Nint,2)
|
||
|
integer(bit_kind) :: tmp1, tmp2
|
||
|
integer :: i
|
||
|
pm(1:Nint,1:2) = det1(1:Nint,1:2)
|
||
|
tmp1 = 0_8
|
||
|
tmp2 = 0_8
|
||
|
do i=1,Nint
|
||
|
pm(i,1) = ieor(pm(i,1), shiftl(pm(i,1), 1))
|
||
|
pm(i,2) = ieor(pm(i,2), shiftl(pm(i,2), 1))
|
||
|
pm(i,1) = ieor(pm(i,1), shiftl(pm(i,1), 2))
|
||
|
pm(i,2) = ieor(pm(i,2), shiftl(pm(i,2), 2))
|
||
|
pm(i,1) = ieor(pm(i,1), shiftl(pm(i,1), 4))
|
||
|
pm(i,2) = ieor(pm(i,2), shiftl(pm(i,2), 4))
|
||
|
pm(i,1) = ieor(pm(i,1), shiftl(pm(i,1), 8))
|
||
|
pm(i,2) = ieor(pm(i,2), shiftl(pm(i,2), 8))
|
||
|
pm(i,1) = ieor(pm(i,1), shiftl(pm(i,1), 16))
|
||
|
pm(i,2) = ieor(pm(i,2), shiftl(pm(i,2), 16))
|
||
|
pm(i,1) = ieor(pm(i,1), shiftl(pm(i,1), 32))
|
||
|
pm(i,2) = ieor(pm(i,2), shiftl(pm(i,2), 32))
|
||
|
pm(i,1) = ieor(pm(i,1), tmp1)
|
||
|
pm(i,2) = ieor(pm(i,2), tmp2)
|
||
|
if(iand(popcnt(det1(i,1)), 1) == 1) tmp1 = not(tmp1)
|
||
|
if(iand(popcnt(det1(i,2)), 1) == 1) tmp2 = not(tmp2)
|
||
|
end do
|
||
|
end subroutine
|
||
|
|
||
|
subroutine get_phase_hp(g_idx_int,g_idx_bit,g_spin,g_sign,det_in,g_det_phase,nint,n_g)
|
||
|
use bitmasks
|
||
|
implicit none
|
||
|
integer, intent(in) :: nint,n_g
|
||
|
integer, intent(in) :: g_idx_int(n_g), g_idx_bit(n_g),g_spin(n_g)
|
||
|
double precision, intent(in) :: g_sign(n_g)
|
||
|
integer(bit_kind), intent(in) :: det_in(nint,2)
|
||
|
double precision, intent(out) :: g_det_phase(n_g)
|
||
|
|
||
|
integer(bit_kind) :: tmp_spindet(nint), pm(nint,2)
|
||
|
double precision, parameter :: phase_dble(0:1) = (/1.d0,-1.d0/)
|
||
|
|
||
|
integer :: i
|
||
|
logical :: is_allowed(n_g), all_banned, is_filled
|
||
|
|
||
|
all_banned=.True.
|
||
|
do i=1,n_g
|
||
|
tmp_spindet(1:nint) = det_in(1:nint,g_spin(i))
|
||
|
call spinorb_is_filled_int_bit(tmp_spindet,g_idx_int(i),g_idx_bit(i),nint,is_filled)
|
||
|
is_allowed(i) = (.not.(((g_sign(i)<0).and.(.not.is_filled)).or.((g_sign(i)>0).and.(is_filled))))
|
||
|
all_banned=(all_banned.and.(.not.is_allowed(i)))
|
||
|
enddo
|
||
|
|
||
|
if (all_banned) then
|
||
|
g_det_phase(:)=0.d0
|
||
|
else
|
||
|
call get_mask_phase_new(det_in,pm,nint)
|
||
|
do i=1,n_g
|
||
|
if (is_allowed(i)) then
|
||
|
g_det_phase(i) = phase_dble(popcnt(iand(ibset(0_bit_kind,g_idx_bit(i)),pm(g_idx_int(i),g_spin(i)))))
|
||
|
else
|
||
|
g_det_phase(i)=0.d0
|
||
|
endif
|
||
|
enddo
|
||
|
endif
|
||
|
end
|
||
|
|
||
|
subroutine get_homo_lumo(key_ref,nint,nmo,idx_homo_lumo,spin_homo_lumo)
|
||
|
use bitmasks
|
||
|
implicit none
|
||
|
integer, intent(in) :: nint,nmo
|
||
|
integer(bit_kind), intent(in) :: key_ref(nint,2)
|
||
|
integer, intent(out) :: idx_homo_lumo(2), spin_homo_lumo(2)
|
||
|
|
||
|
double precision, allocatable :: e_mo(:,:)
|
||
|
integer, allocatable :: occ(:,:),virt(:,:) !(nint*bit_kind_size,2)
|
||
|
integer :: n_occ(2), n_virt(2)
|
||
|
integer :: i,i0,ispin
|
||
|
integer(bit_kind), allocatable :: key_virt(:,:)
|
||
|
double precision :: maxocc(2), minvirt(2)
|
||
|
integer :: imaxocc(2), iminvirt(2)
|
||
|
|
||
|
allocate(e_mo(nmo,2),key_virt(nint,2),occ(nint*bit_kind_size,2),virt(nint*bit_kind_size,2))
|
||
|
|
||
|
call get_mo_energies(key_ref,nint,nmo,e_mo)
|
||
|
|
||
|
!allocate(occ(nint*bit_kind_size,2),virt(nint*bit_kind_size,2))
|
||
|
|
||
|
call bitstring_to_list_ab(key_ref,occ,n_occ,nint)
|
||
|
do i=1,nint
|
||
|
do ispin=1,2
|
||
|
key_virt(i,ispin)=xor(full_ijkl_bitmask(i),key_ref(i,ispin))
|
||
|
enddo
|
||
|
enddo
|
||
|
call bitstring_to_list_ab(key_virt,virt,n_virt,nint)
|
||
|
|
||
|
maxocc=-1.d20 !maybe use -1.d0*huge(0.d0)?
|
||
|
minvirt=1.d20
|
||
|
imaxocc=-1
|
||
|
iminvirt=-1
|
||
|
|
||
|
do ispin=1,2
|
||
|
do i0=1,n_occ(ispin)
|
||
|
i=occ(i0,ispin)
|
||
|
if (e_mo(i,ispin).gt.maxocc(ispin)) then
|
||
|
maxocc(ispin)=e_mo(i,ispin)
|
||
|
imaxocc(ispin)=i
|
||
|
endif
|
||
|
enddo
|
||
|
do i0=1,n_virt(ispin)
|
||
|
i=virt(i0,ispin)
|
||
|
if (e_mo(i,ispin).lt.minvirt(ispin)) then
|
||
|
minvirt(ispin)=e_mo(i,ispin)
|
||
|
iminvirt(ispin)=i
|
||
|
endif
|
||
|
enddo
|
||
|
enddo
|
||
|
double precision :: e_mo_thresh
|
||
|
e_mo_thresh = 1.d-8
|
||
|
!these should both just be 2x2 arrays, but performance here doesn't really matter and this is more readable
|
||
|
!if (maxocc(1).ge.maxocc(2)) then
|
||
|
if ((maxocc(2)-maxocc(1)).le.e_mo_thresh) then
|
||
|
spin_homo_lumo(1)=1
|
||
|
else
|
||
|
spin_homo_lumo(1)=2
|
||
|
endif
|
||
|
if ((minvirt(1)-minvirt(2)).le.e_mo_thresh) then
|
||
|
spin_homo_lumo(2)=1
|
||
|
else
|
||
|
spin_homo_lumo(2)=2
|
||
|
endif
|
||
|
|
||
|
idx_homo_lumo(1)=imaxocc(spin_homo_lumo(1))
|
||
|
idx_homo_lumo(2)=iminvirt(spin_homo_lumo(2))
|
||
|
|
||
|
deallocate(e_mo,occ,virt,key_virt)
|
||
|
|
||
|
end
|
||
|
|
||
|
subroutine get_list_hp_banned_ab(tmp_det,N_hp,exc_is_banned,spin_hp,sign_hp,idx_hp,nint,all_banned)
|
||
|
use bitmasks
|
||
|
implicit none
|
||
|
BEGIN_DOC
|
||
|
! input determinant tmp_det and list of single holes/particles
|
||
|
! for each hole/particle, determine whether it is filled/empty in tmp_det
|
||
|
! return which are disallowed in exc_is_banned
|
||
|
! if all are banned, set all_banned to true
|
||
|
END_DOC
|
||
|
integer, intent(in) :: N_hp,nint
|
||
|
integer, intent(in) :: spin_hp(N_hp), idx_hp(N_hp)
|
||
|
double precision, intent(in) :: sign_hp(N_hp)
|
||
|
integer(bit_kind), intent(in) :: tmp_det(nint,2)
|
||
|
logical, intent(out) :: exc_is_banned(N_hp)
|
||
|
logical, intent(out) :: all_banned
|
||
|
|
||
|
integer :: i
|
||
|
logical :: is_filled
|
||
|
|
||
|
all_banned = .True.
|
||
|
do i=1,N_hp
|
||
|
call orb_is_filled(tmp_det,idx_hp(i),spin_hp(i),nint,is_filled)
|
||
|
if (sign_hp(i).gt.0) then ! particle creation, banned if already filled
|
||
|
exc_is_banned(i) = is_filled
|
||
|
else ! hole creation, banned if already empty
|
||
|
exc_is_banned(i) = (.not.is_filled)
|
||
|
endif
|
||
|
all_banned = (all_banned.and.exc_is_banned(i))
|
||
|
enddo
|
||
|
end
|
||
|
|
||
|
subroutine get_list_hp_banned_single_spin(tmp_spindet,N_hp,exc_is_banned,spin_hp,sign_hp,idx_hp,ispin,nint,all_banned)
|
||
|
use bitmasks
|
||
|
implicit none
|
||
|
BEGIN_DOC
|
||
|
! input spindeterminant tmp_spindet and list of single holes/particles
|
||
|
! tmp_spindet is only one spin part of a full det, with spin==ispin
|
||
|
! for each hole/particle, determine whether it is filled/empty in tmp_det
|
||
|
! return which are disallowed in exc_is_banned
|
||
|
! if all are banned, set all_banned to true
|
||
|
END_DOC
|
||
|
integer, intent(in) :: N_hp, ispin, nint
|
||
|
integer, intent(in) :: spin_hp(N_hp), idx_hp(N_hp)
|
||
|
double precision, intent(in) :: sign_hp(N_hp)
|
||
|
integer(bit_kind), intent(in) :: tmp_spindet(nint)
|
||
|
logical, intent(out) :: exc_is_banned(N_hp)
|
||
|
logical, intent(out) :: all_banned
|
||
|
|
||
|
integer :: i
|
||
|
logical :: is_filled
|
||
|
|
||
|
all_banned = .True.
|
||
|
do i=1,N_hp
|
||
|
if (spin_hp(i).eq.ispin) then
|
||
|
call orb_is_filled_single_spin(tmp_spindet,idx_hp(i),nint,is_filled)
|
||
|
if (sign_hp(i).gt.0) then ! particle creation, banned if already filled
|
||
|
exc_is_banned(i) = is_filled
|
||
|
else ! hole creation, banned if already empty
|
||
|
exc_is_banned(i) = (.not.is_filled)
|
||
|
endif
|
||
|
else
|
||
|
exc_is_banned(i) = .False.
|
||
|
endif
|
||
|
all_banned = (all_banned.and.exc_is_banned(i))
|
||
|
enddo
|
||
|
end
|
||
|
|
||
|
subroutine get_list_hp_banned_spin(tmp_det,N_hp,exc_is_banned,spin_hp,sign_hp,idx_hp,ispin,nint,all_banned)
|
||
|
use bitmasks
|
||
|
implicit none
|
||
|
BEGIN_DOC
|
||
|
! input determinant tmp_det and list of single holes/particles
|
||
|
! for each hole/particle, determine whether it is filled/empty in tmp_det
|
||
|
! return which are disallowed in exc_is_banned
|
||
|
! if all are banned, set all_banned to true
|
||
|
! only consider tmp_det(1:N_int, ispin)
|
||
|
END_DOC
|
||
|
integer, intent(in) :: N_hp, ispin, nint
|
||
|
integer, intent(in) :: spin_hp(N_hp), idx_hp(N_hp)
|
||
|
double precision, intent(in) :: sign_hp(N_hp)
|
||
|
integer(bit_kind), intent(in) :: tmp_det(nint,2)
|
||
|
logical, intent(out) :: exc_is_banned(N_hp)
|
||
|
logical, intent(out) :: all_banned
|
||
|
|
||
|
integer(bit_kind) :: spindet(nint)
|
||
|
|
||
|
integer :: i
|
||
|
logical :: is_filled
|
||
|
spindet(1:nint) = tmp_det(1:nint,ispin)
|
||
|
|
||
|
all_banned = .True.
|
||
|
do i=1,N_hp
|
||
|
if (spin_hp(i).eq.ispin) then
|
||
|
call orb_is_filled(tmp_det,idx_hp(i),ispin,nint,is_filled)
|
||
|
if (sign_hp(i).gt.0) then ! particle creation, banned if already filled
|
||
|
exc_is_banned(i) = is_filled
|
||
|
else ! hole creation, banned if already empty
|
||
|
exc_is_banned(i) = (.not.is_filled)
|
||
|
endif
|
||
|
else
|
||
|
exc_is_banned(i) = .False.
|
||
|
endif
|
||
|
all_banned = (all_banned.and.exc_is_banned(i))
|
||
|
enddo
|
||
|
end
|
||
|
|
||
|
|
||
|
subroutine spinorb_is_filled_int_bit(key_ref,iorb_int,iorb_bit,Nint,is_filled)
|
||
|
use bitmasks
|
||
|
implicit none
|
||
|
BEGIN_DOC
|
||
|
! determine whether iorb is filled in key_ref
|
||
|
! iorb is specified by int and bit locations within the determinant
|
||
|
END_DOC
|
||
|
integer, intent(in) :: iorb_int, iorb_bit, Nint
|
||
|
integer(bit_kind), intent(in) :: key_ref(Nint)
|
||
|
logical, intent(out) :: is_filled
|
||
|
|
||
|
ASSERT (iorb_int > 0)
|
||
|
ASSERT (iorb_bit >= 0)
|
||
|
ASSERT (Nint > 0)
|
||
|
is_filled = btest(key_ref(iorb_int),iorb_bit)
|
||
|
end
|
||
|
|
||
|
subroutine orb_is_filled_int_bit(key_ref,iorb_int,iorb_bit,ispin,Nint,is_filled)
|
||
|
use bitmasks
|
||
|
implicit none
|
||
|
BEGIN_DOC
|
||
|
! todo: not finished
|
||
|
! determine whether iorb is filled in key_ref
|
||
|
! iorb is specified by int and bit locations within the determinant
|
||
|
END_DOC
|
||
|
integer, intent(in) :: iorb_int, iorb_bit, ispin, Nint
|
||
|
integer(bit_kind), intent(in) :: key_ref(Nint,2)
|
||
|
logical, intent(out) :: is_filled
|
||
|
|
||
|
ASSERT (iorb_int > 0)
|
||
|
ASSERT (iorb_bit >= 0)
|
||
|
ASSERT (ispin > 0)
|
||
|
ASSERT (ispin < 3)
|
||
|
ASSERT (Nint > 0)
|
||
|
is_filled = btest(key_ref(iorb_int,ispin),iorb_bit)
|
||
|
! call spinorb_is_filled_int_bit(key_ref(1,ispin),iorb_int,iorb_bit,Nint,is_filled)
|
||
|
end
|
||
|
|
||
|
subroutine get_orb_int_bit(iorb,iorb_int,iorb_bit)
|
||
|
BEGIN_DOC
|
||
|
! get int and bit corresponding to orbital index iorb
|
||
|
END_DOC
|
||
|
use bitmasks
|
||
|
implicit none
|
||
|
integer, intent(in) :: iorb
|
||
|
integer, intent(out) :: iorb_int, iorb_bit
|
||
|
ASSERT (iorb > 0)
|
||
|
iorb_int = ishft(iorb-1,-bit_kind_shift)+1
|
||
|
ASSERT (iorb_int > 0)
|
||
|
iorb_bit = iorb - ishft(iorb_int-1,bit_kind_shift)-1
|
||
|
ASSERT (iorb_bit >= 0)
|
||
|
end
|
||
|
|
||
|
subroutine orb_is_filled_single_spin(key_ref,iorb,Nint,is_filled)
|
||
|
use bitmasks
|
||
|
implicit none
|
||
|
BEGIN_DOC
|
||
|
! determine whether iorb is filled in key_ref
|
||
|
! key_ref is single alpha or beta determinant
|
||
|
END_DOC
|
||
|
integer, intent(in) :: iorb, Nint
|
||
|
integer(bit_kind), intent(in) :: key_ref(Nint)
|
||
|
logical, intent(out) :: is_filled
|
||
|
|
||
|
integer :: k,l
|
||
|
|
||
|
ASSERT (iorb > 0)
|
||
|
ASSERT (Nint > 0)
|
||
|
|
||
|
! k is index of the int where iorb is found
|
||
|
! l is index of the bit where iorb is found
|
||
|
k = ishft(iorb-1,-bit_kind_shift)+1
|
||
|
ASSERT (k >0)
|
||
|
l = iorb - ishft(k-1,bit_kind_shift)-1
|
||
|
ASSERT (l >= 0)
|
||
|
is_filled = btest(key_ref(k),l)
|
||
|
end
|
||
|
|
||
|
subroutine orb_is_filled(key_ref,iorb,ispin,Nint,is_filled)
|
||
|
use bitmasks
|
||
|
implicit none
|
||
|
BEGIN_DOC
|
||
|
! determine whether iorb, ispin is filled in key_ref
|
||
|
! key_ref has alpha and beta parts
|
||
|
END_DOC
|
||
|
integer, intent(in) :: iorb, ispin, Nint
|
||
|
integer(bit_kind), intent(in) :: key_ref(Nint,2)
|
||
|
logical, intent(out) :: is_filled
|
||
|
|
||
|
integer :: k,l
|
||
|
|
||
|
ASSERT (iorb > 0)
|
||
|
ASSERT (ispin > 0)
|
||
|
ASSERT (ispin < 3)
|
||
|
ASSERT (Nint > 0)
|
||
|
|
||
|
! k is index of the int where iorb is found
|
||
|
! l is index of the bit where iorb is found
|
||
|
k = ishft(iorb-1,-bit_kind_shift)+1
|
||
|
ASSERT (k >0)
|
||
|
l = iorb - ishft(k-1,bit_kind_shift)-1
|
||
|
ASSERT (l >= 0)
|
||
|
is_filled = btest(key_ref(k,ispin),l)
|
||
|
end
|
||
|
|
||
|
subroutine ac_operator_phase(key_new,key_ref,iorb,ispin,Nint,phase)
|
||
|
use bitmasks
|
||
|
implicit none
|
||
|
BEGIN_DOC
|
||
|
! apply creation operator to key_ref
|
||
|
! add electron with spin ispin to orbital with index iorb
|
||
|
! output resulting det and phase in key_new and phase
|
||
|
END_DOC
|
||
|
integer, intent(in) :: iorb, ispin, Nint
|
||
|
integer(bit_kind), intent(in) :: key_ref(Nint,2)
|
||
|
integer(bit_kind), intent(out) :: key_new(Nint,2)
|
||
|
double precision, intent(out) :: phase
|
||
|
|
||
|
integer :: k,l,i
|
||
|
|
||
|
double precision, parameter :: p(0:1) = (/ 1.d0, -1.d0 /)
|
||
|
|
||
|
ASSERT (iorb > 0)
|
||
|
ASSERT (ispin > 0)
|
||
|
ASSERT (ispin < 3)
|
||
|
ASSERT (Nint > 0)
|
||
|
|
||
|
key_new=key_ref
|
||
|
|
||
|
! alpha det is list of Nint 64-bit ints
|
||
|
! k is index of the int where iorb is found
|
||
|
! l is index of the bit where iorb is found
|
||
|
k = ishft(iorb-1,-bit_kind_shift)+1
|
||
|
ASSERT (k >0)
|
||
|
l = iorb - ishft(k-1,bit_kind_shift)-1
|
||
|
ASSERT (l >= 0)
|
||
|
key_new(k,ispin) = ibset(key_new(k,ispin),l)
|
||
|
|
||
|
integer(bit_kind) :: parity_filled
|
||
|
|
||
|
! I assume here that the ordering is all alpha spinorbs and then all beta spinorbs
|
||
|
! If we add an alpha electron, parity is not affected by beta part of determinant
|
||
|
! (only need number of alpha occupied orbs below iorb)
|
||
|
|
||
|
! If we add a beta electron, the parity is affected by alpha part
|
||
|
! (need total number of occupied alpha orbs (all of which come before beta)
|
||
|
! and total number of beta occupied orbs below iorb)
|
||
|
|
||
|
if (ispin==1) then
|
||
|
parity_filled=0_bit_kind
|
||
|
else
|
||
|
parity_filled=iand(elec_alpha_num,1_bit_kind)
|
||
|
endif
|
||
|
|
||
|
! get parity due to orbs in other ints (with lower indices)
|
||
|
do i=1,k-1
|
||
|
parity_filled = iand(popcnt(key_ref(i,ispin)),parity_filled)
|
||
|
enddo
|
||
|
|
||
|
! get parity due to orbs in same int as iorb
|
||
|
! ishft(1_bit_kind,l)-1 has its l rightmost bits set to 1, other bits set to 0
|
||
|
parity_filled = iand(popcnt(iand(ishft(1_bit_kind,l)-1,key_ref(k,ispin))),parity_filled)
|
||
|
phase = p(iand(1_bit_kind,parity_filled))
|
||
|
|
||
|
end
|
||
|
|
||
|
subroutine a_operator_phase(key_new,key_ref,iorb,ispin,Nint,phase)
|
||
|
use bitmasks
|
||
|
implicit none
|
||
|
BEGIN_DOC
|
||
|
! apply annihilation operator to key_ref
|
||
|
! remove electron with spin ispin to orbital with index iorb
|
||
|
! output resulting det and phase in key_new and phase
|
||
|
END_DOC
|
||
|
integer, intent(in) :: iorb, ispin, Nint
|
||
|
integer(bit_kind), intent(in) :: key_ref(Nint,2)
|
||
|
integer(bit_kind), intent(out) :: key_new(Nint,2)
|
||
|
double precision, intent(out) :: phase
|
||
|
|
||
|
integer :: k,l,i
|
||
|
|
||
|
double precision, parameter :: p(0:1) = (/ 1.d0, -1.d0 /)
|
||
|
|
||
|
ASSERT (iorb > 0)
|
||
|
ASSERT (ispin > 0)
|
||
|
ASSERT (ispin < 3)
|
||
|
ASSERT (Nint > 0)
|
||
|
|
||
|
key_new=key_ref
|
||
|
|
||
|
! alpha det is list of Nint 64-bit ints
|
||
|
! k is index of the int where iorb is found
|
||
|
! l is index of the bit where iorb is found
|
||
|
k = ishft(iorb-1,-bit_kind_shift)+1
|
||
|
ASSERT (k >0)
|
||
|
l = iorb - ishft(k-1,bit_kind_shift)-1
|
||
|
ASSERT (l >= 0)
|
||
|
key_new(k,ispin) = ibclr(key_new(k,ispin),l)
|
||
|
|
||
|
integer(bit_kind) :: parity_filled
|
||
|
|
||
|
! I assume here that the ordering is all alpha spinorbs and then all beta spinorbs
|
||
|
! If we add an alpha electron, parity is not affected by beta part of determinant
|
||
|
! (only need number of alpha occupied orbs below iorb)
|
||
|
|
||
|
! If we add a beta electron, the parity is affected by alpha part
|
||
|
! (need total number of occupied alpha orbs (all of which come before beta)
|
||
|
! and total number of beta occupied orbs below iorb)
|
||
|
|
||
|
if (ispin==1) then
|
||
|
parity_filled=0_bit_kind
|
||
|
else
|
||
|
parity_filled=iand(elec_alpha_num,1_bit_kind)
|
||
|
endif
|
||
|
|
||
|
! get parity due to orbs in other ints (with lower indices)
|
||
|
do i=1,k-1
|
||
|
parity_filled = iand(popcnt(key_ref(i,ispin)),parity_filled)
|
||
|
enddo
|
||
|
|
||
|
! get parity due to orbs in same int as iorb
|
||
|
! ishft(1_bit_kind,l)-1 has its l rightmost bits set to 1, other bits set to 0
|
||
|
parity_filled = iand(popcnt(iand(ishft(1_bit_kind,l)-1,key_ref(k,ispin))),parity_filled)
|
||
|
phase = p(iand(1_bit_kind,parity_filled))
|
||
|
|
||
|
end
|
||
|
BEGIN_PROVIDER [ double precision, mo_mono_elec_integral_diag,(mo_tot_num)]
|
||
|
implicit none
|
||
|
integer :: i
|
||
|
BEGIN_DOC
|
||
|
! diagonal elements of mo_mono_elec_integral array
|
||
|
END_DOC
|
||
|
print*,'Providing the mono electronic integrals (diagonal)'
|
||
|
|
||
|
do i = 1, mo_tot_num
|
||
|
mo_mono_elec_integral_diag(i) = real(mo_mono_elec_integral(i,i))
|
||
|
enddo
|
||
|
|
||
|
END_PROVIDER
|