use bitmasks BEGIN_PROVIDER [ integer, N_det ] implicit none BEGIN_DOC ! Number of determinants in the wave function END_DOC logical :: exists character*64 :: label PROVIDE ezfio_filename if (read_wf) then call ezfio_has_determinants_n_det(exists) if (exists) then call ezfio_has_determinants_mo_label(exists) if (exists) then call ezfio_get_determinants_mo_label(label) exists = (label == mo_label) endif endif if (exists) then call ezfio_get_determinants_n_det(N_det) else N_det = 1 endif else N_det = 1 endif call write_int(output_dets,N_det,'Number of determinants') ASSERT (N_det > 0) END_PROVIDER BEGIN_PROVIDER [ integer, psi_det_size ] implicit none BEGIN_DOC ! Size of the psi_det/psi_coef arrays END_DOC PROVIDE ezfio_filename logical :: exists call ezfio_has_determinants_n_det(exists) if (exists) then call ezfio_get_determinants_n_det(psi_det_size) else psi_det_size = 1 endif psi_det_size = max(psi_det_size,10000) call write_int(output_dets,psi_det_size,'Dimension of the psi arrays') END_PROVIDER BEGIN_PROVIDER [ integer(bit_kind), psi_det, (N_int,2,psi_det_size) ] implicit none BEGIN_DOC ! The wave function determinants. Initialized with Hartree-Fock if the EZFIO file ! is empty END_DOC integer :: i logical :: exists character*64 :: label if (read_wf) then call ezfio_has_determinants_N_int(exists) if (exists) then call ezfio_has_determinants_bit_kind(exists) if (exists) then call ezfio_has_determinants_N_det(exists) if (exists) then call ezfio_has_determinants_N_states(exists) if (exists) then call ezfio_has_determinants_psi_det(exists) if (exists) then call ezfio_has_determinants_mo_label(exists) if (exists) then call ezfio_get_determinants_mo_label(label) exists = (label == mo_label) endif endif endif endif endif endif if (exists) then call read_dets(psi_det,N_int,N_det) else psi_det = 0_bit_kind do i=1,N_int psi_det(i,1,1) = HF_bitmask(i,1) psi_det(i,2,1) = HF_bitmask(i,2) enddo endif else psi_det = 0_bit_kind do i=1,N_int psi_det(i,1,1) = HF_bitmask(i,1) psi_det(i,2,1) = HF_bitmask(i,2) enddo endif END_PROVIDER BEGIN_PROVIDER [ double precision, psi_coef, (psi_det_size,N_states_diag) ] implicit none BEGIN_DOC ! The wave function coefficients. Initialized with Hartree-Fock if the EZFIO file ! is empty END_DOC integer :: i,k, N_int2 logical :: exists double precision, allocatable :: psi_coef_read(:,:) character*(64) :: label psi_coef = 0.d0 do i=1,N_states_diag psi_coef(i,i) = 1.d0 enddo if (read_wf) then call ezfio_has_determinants_psi_coef(exists) if (exists) then call ezfio_has_determinants_mo_label(exists) if (exists) then call ezfio_get_determinants_mo_label(label) exists = (label == mo_label) endif endif if (exists) then allocate (psi_coef_read(N_det,N_states)) call ezfio_get_determinants_psi_coef(psi_coef_read) do k=1,N_states do i=1,N_det psi_coef(i,k) = psi_coef_read(i,k) enddo enddo deallocate(psi_coef_read) endif endif END_PROVIDER BEGIN_PROVIDER [ double precision, psi_average_norm_contrib, (N_det) ] implicit none BEGIN_DOC ! Contribution of determinants to the state-averaged density END_DOC integer :: i,j,k double precision :: f f = 1.d0/dble(N_states) do i=1,N_det psi_average_norm_contrib(i) = psi_coef(i,1)*psi_coef(i,1)*f enddo do k=2,N_states do i=1,N_det psi_average_norm_contrib(i) = psi_average_norm_contrib(i) + & psi_coef(i,k)*psi_coef(i,k)*f enddo enddo END_PROVIDER !==============================================================================! ! ! ! Independent alpha/beta parts ! ! ! !==============================================================================! integer*8 function spin_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) integer :: i spin_det_search_key = det(1) do i=2,Nint spin_det_search_key = ieor(spin_det_search_key,det(i)) enddo end BEGIN_PROVIDER [ integer(bit_kind), psi_det_alpha, (N_int,psi_det_size) ] implicit none BEGIN_DOC ! List of alpha determinants of psi_det END_DOC integer :: i,k do i=1,N_det do k=1,N_int psi_det_alpha(k,i) = psi_det(k,1,i) enddo enddo END_PROVIDER BEGIN_PROVIDER [ integer(bit_kind), psi_det_beta, (N_int,psi_det_size) ] implicit none BEGIN_DOC ! List of beta determinants of psi_det END_DOC integer :: i,k do i=1,N_det do k=1,N_int psi_det_beta(k,i) = psi_det(k,2,i) enddo enddo END_PROVIDER BEGIN_PROVIDER [ integer(bit_kind), psi_det_alpha_unique, (N_int,N_det) ] &BEGIN_PROVIDER [ integer, N_det_alpha_unique ] implicit none BEGIN_DOC ! Unique alpha determinants END_DOC integer :: i,k integer, allocatable :: iorder(:) integer*8, allocatable :: bit_tmp(:) integer*8 :: last_key integer*8, external :: spin_det_search_key allocate ( iorder(N_det), bit_tmp(N_det)) do i=1,N_det iorder(i) = i bit_tmp(i) = spin_det_search_key(psi_det_alpha(1,i),N_int) enddo call i8sort(bit_tmp,iorder,N_det) N_det_alpha_unique = 0 last_key = 0_8 do i=1,N_det if (bit_tmp(i) /= last_key) then last_key = bit_tmp(i) N_det_alpha_unique += 1 do k=1,N_int psi_det_alpha_unique(k,N_det_alpha_unique) = psi_det_alpha(k,iorder(i)) enddo endif enddo deallocate (iorder, bit_tmp) END_PROVIDER BEGIN_PROVIDER [ integer(bit_kind), psi_det_beta_unique, (N_int,N_det) ] &BEGIN_PROVIDER [ integer, N_det_beta_unique ] implicit none BEGIN_DOC ! Unique beta determinants END_DOC integer :: i,k integer, allocatable :: iorder(:) integer*8, allocatable :: bit_tmp(:) integer*8 :: last_key integer*8, external :: spin_det_search_key allocate ( iorder(N_det), bit_tmp(N_det)) do i=1,N_det iorder(i) = i bit_tmp(i) = spin_det_search_key(psi_det_beta(1,i),N_int) enddo call i8sort(bit_tmp,iorder,N_det) N_det_beta_unique = 0 last_key = 0_8 do i=1,N_det if (bit_tmp(i) /= last_key) then last_key = bit_tmp(i) N_det_beta_unique += 1 do k=1,N_int psi_det_beta_unique(k,N_det_beta_unique) = psi_det_beta(k,iorder(i)) enddo endif enddo deallocate (iorder, bit_tmp) END_PROVIDER !==============================================================================! ! ! ! Sorting providers ! ! ! !==============================================================================! BEGIN_PROVIDER [ integer(bit_kind), psi_det_sorted, (N_int,2,N_det) ] &BEGIN_PROVIDER [ double precision, psi_coef_sorted, (N_det,N_states) ] &BEGIN_PROVIDER [ double precision, psi_average_norm_contrib_sorted, (N_det) ] implicit none BEGIN_DOC ! Wave function sorted by determinants contribution to the norm (state-averaged) END_DOC integer :: i,j,k integer, allocatable :: iorder(:) allocate ( iorder(N_det) ) do i=1,N_det psi_average_norm_contrib_sorted(i) = -psi_average_norm_contrib(i) iorder(i) = i enddo call dsort(psi_average_norm_contrib_sorted,iorder,N_det) !DIR$ IVDEP do i=1,N_det do j=1,N_int psi_det_sorted(j,1,i) = psi_det(j,1,iorder(i)) psi_det_sorted(j,2,i) = psi_det(j,2,iorder(i)) enddo do k=1,N_states psi_coef_sorted(i,k) = psi_coef(iorder(i),k) enddo psi_average_norm_contrib_sorted(i) = -psi_average_norm_contrib_sorted(i) enddo deallocate(iorder) END_PROVIDER BEGIN_PROVIDER [ integer(bit_kind), psi_det_sorted_bit, (N_int,2,N_det) ] &BEGIN_PROVIDER [ double precision, psi_coef_sorted_bit, (N_det,N_states) ] implicit none BEGIN_DOC ! Determinants on which we apply for perturbation. ! They are sorted by determinants interpreted as integers. Useful ! to accelerate the search of a random determinant in the wave ! function. END_DOC integer :: i,j,k integer, allocatable :: iorder(:) integer*8, allocatable :: bit_tmp(:) integer*8, external :: det_search_key allocate ( iorder(N_det), bit_tmp(N_det) ) do i=1,N_det iorder(i) = i !$DIR FORCEINLINE bit_tmp(i) = det_search_key(psi_det(1,1,i),N_int) enddo call i8sort(bit_tmp,iorder,N_det) !DIR$ IVDEP do i=1,N_det do j=1,N_int psi_det_sorted_bit(j,1,i) = psi_det(j,1,iorder(i)) psi_det_sorted_bit(j,2,i) = psi_det(j,2,iorder(i)) enddo do k=1,N_states psi_coef_sorted_bit(i,k) = psi_coef(iorder(i),k) enddo enddo deallocate(iorder, bit_tmp) END_PROVIDER subroutine int_of_3_highest_electrons( det_in, res, Nint ) implicit none use bitmasks integer,intent(in) :: Nint integer(bit_kind) :: det_in(Nint) integer*8 :: res BEGIN_DOC ! Returns an integer*8 as : ! ! |_<--- 21 bits ---><--- 21 bits ---><--- 21 bits --->| ! ! |0<--- i1 ---><--- i2 ---><--- i3 --->| ! ! It encodes the value of the indices of the 3 highest MOs ! in descending order ! END_DOC integer :: i, k, icount integer(bit_kind) :: ix res = 0_8 icount = 3 do k=Nint,1,-1 ix = det_in(k) do while (ix /= 0_bit_kind) i = bit_kind_size-1-leadz(ix) ix = ibclr(ix,i) res = ior(ishft(res, 21), i+ishft(k-1,bit_kind_shift)) icount -= 1 if (icount == 0) then return endif enddo enddo end subroutine filter_3_highest_electrons( det_in, det_out, Nint ) implicit none use bitmasks integer,intent(in) :: Nint integer(bit_kind) :: det_in(Nint), det_out(Nint) BEGIN_DOC ! Returns a determinant with only the 3 highest electrons END_DOC integer :: i, k, icount integer(bit_kind) :: ix det_out = 0_8 icount = 3 do k=Nint,1,-1 ix = det_in(k) do while (ix /= 0_bit_kind) i = bit_kind_size-1-leadz(ix) ix = ibclr(ix,i) det_out(k) = ibset(det_out(k),i) icount -= 1 if (icount == 0) then return endif enddo enddo end BEGIN_PROVIDER [ integer(bit_kind), psi_det_sorted_ab, (N_int,2,N_det) ] &BEGIN_PROVIDER [ double precision, psi_coef_sorted_ab, (N_det,N_states) ] &BEGIN_PROVIDER [ integer, psi_det_sorted_next_ab, (2,N_det) ] implicit none BEGIN_DOC ! Determinants on which we apply . ! They are sorted by the 3 highest electrons in the alpha part, ! then by the 3 highest electrons in the beta part to accelerate ! the research of connected determinants. END_DOC integer :: i,j,k integer, allocatable :: iorder(:) integer*8, allocatable :: bit_tmp(:) integer*8, external :: det_search_key allocate ( iorder(N_det), bit_tmp(N_det) ) ! Sort alpha dets ! --------------- integer(bit_kind) :: det_tmp(N_int) do i=1,N_det iorder(i) = i call int_of_3_highest_electrons(psi_det(1,1,i),bit_tmp(i),N_int) enddo call i8sort(bit_tmp,iorder,N_det) !DIR$ IVDEP do i=1,N_det do j=1,N_int psi_det_sorted_ab(j,1,i) = psi_det(j,1,iorder(i)) psi_det_sorted_ab(j,2,i) = psi_det(j,2,iorder(i)) enddo do k=1,N_states psi_coef_sorted_ab(i,k) = psi_coef(iorder(i),k) enddo enddo ! Find next alpha ! --------------- integer :: next next = N_det+1 psi_det_sorted_next_ab(1,N_det) = next do i=N_det-1,1,-1 if (bit_tmp(i) /= bit_tmp(i+1)) then next = i+1 endif psi_det_sorted_next_ab(1,i) = next enddo ! Sort beta dets ! -------------- integer :: istart, iend integer(bit_kind), allocatable :: psi_det_sorted_ab_temp (:,:) allocate ( psi_det_sorted_ab_temp (N_int,N_det) ) do i=1,N_det do j=1,N_int psi_det_sorted_ab_temp(j,i) = psi_det_sorted_ab(j,2,i) enddo iorder(i) = i call int_of_3_highest_electrons(psi_det_sorted_ab_temp(1,i),bit_tmp(i),N_int) enddo istart=1 do while ( istart