From 18084047e4c9fccf1019624409ddc2ada80fa581 Mon Sep 17 00:00:00 2001 From: Yann Garniron Date: Mon, 5 Sep 2016 17:16:09 +0200 Subject: [PATCH] compiles - does not work --- plugins/Full_CI_ZMQ/run_selection_slave.irp.f | 2 + plugins/Full_CI_ZMQ/selection.irp.f | 1278 +++-------------- plugins/Full_CI_ZMQ/selection_double.irp.f | 512 +++++++ plugins/Full_CI_ZMQ/selection_single.irp.f | 333 +++++ src/Determinants/determinants.irp.f | 46 +- 5 files changed, 1053 insertions(+), 1118 deletions(-) create mode 100644 plugins/Full_CI_ZMQ/selection_double.irp.f create mode 100644 plugins/Full_CI_ZMQ/selection_single.irp.f diff --git a/plugins/Full_CI_ZMQ/run_selection_slave.irp.f b/plugins/Full_CI_ZMQ/run_selection_slave.irp.f index 7bc1a7ef..36550116 100644 --- a/plugins/Full_CI_ZMQ/run_selection_slave.irp.f +++ b/plugins/Full_CI_ZMQ/run_selection_slave.irp.f @@ -152,3 +152,5 @@ subroutine pull_selection_results(zmq_socket_pull, pt2, val, det, N, task_id, nt ! rc = f77_zmq_send( zmq_socket_pull, task_id(1), ntask*4, 0) end subroutine + + diff --git a/plugins/Full_CI_ZMQ/selection.irp.f b/plugins/Full_CI_ZMQ/selection.irp.f index a34ef1ae..d3d8e30b 100644 --- a/plugins/Full_CI_ZMQ/selection.irp.f +++ b/plugins/Full_CI_ZMQ/selection.irp.f @@ -1,1116 +1,162 @@ - - -BEGIN_PROVIDER [ double precision, integral8, (mo_tot_num, mo_tot_num, mo_tot_num, mo_tot_num) ] - integral8 = 0d0 - integer :: h1, h2 - do h1=1, mo_tot_num - do h2=1, mo_tot_num - call get_mo_bielec_integrals_ij(h1, h2 ,mo_tot_num,integral8(1,1,h1,h2),mo_integrals_map) - end do - end do -END_PROVIDER - - -subroutine select_connected(i_generator,E0,pt2,b) - !use f77_zmq - use bitmasks - use selection_types - implicit none - integer, intent(in) :: i_generator - type(selection_buffer), intent(inout) :: b - double precision, intent(inout) :: pt2(N_states) - integer :: k,l - double precision, intent(in) :: E0(N_states) - - integer(bit_kind) :: hole_mask(N_int,2), particle_mask(N_int,2) - double precision :: fock_diag_tmp(2,mo_tot_num+1) - - call build_fock_tmp(fock_diag_tmp,psi_det_generators(1,1,i_generator),N_int) - - do l=1,N_generators_bitmask - do k=1,N_int - hole_mask(k,1) = iand(generators_bitmask(k,1,s_hole,l), psi_det_generators(k,1,i_generator)) - hole_mask(k,2) = iand(generators_bitmask(k,2,s_hole,l), psi_det_generators(k,2,i_generator)) - particle_mask(k,1) = iand(generators_bitmask(k,1,s_part,l), not(psi_det_generators(k,1,i_generator)) ) - particle_mask(k,2) = iand(generators_bitmask(k,2,s_part,l), not(psi_det_generators(k,2,i_generator)) ) - - hole_mask(k,1) = ior(generators_bitmask(k,1,s_hole,l), generators_bitmask(k,1,s_part,l)) - hole_mask(k,2) = ior(generators_bitmask(k,2,s_hole,l), generators_bitmask(k,2,s_part,l)) - particle_mask(k,:) = hole_mask(k,:) - enddo - - call select_doubles(i_generator,hole_mask,particle_mask,fock_diag_tmp,E0,pt2,b) - call select_singles(i_generator,hole_mask,particle_mask,fock_diag_tmp,E0,pt2,b) - enddo -end - - - -subroutine select_singles(i_generator,hole_mask,particle_mask,fock_diag_tmp,E0,pt2,buf) - !use f77_zmq - use bitmasks - use selection_types - implicit none - BEGIN_DOC -! Select determinants connected to i_det by H - END_DOC - integer, intent(in) :: i_generator - double precision, intent(in) :: fock_diag_tmp(mo_tot_num) - double precision, intent(inout) :: pt2(N_states) - integer(bit_kind), intent(in) :: hole_mask(N_int,2), particle_mask(N_int,2) - double precision, intent(in) :: E0(N_states) - type(selection_buffer), intent(inout) :: buf - - integer :: i,j,k,l - - integer :: msg_size - msg_size = bit_kind*N_int*2 - - ! Apply hole and particle masks - ! ----------------------------- - - integer(bit_kind) :: hole(N_int,2), particle(N_int,2) - do k=1,N_int - hole (k,1) = iand(psi_det_generators(k,1,i_generator), hole_mask(k,1)) - hole (k,2) = iand(psi_det_generators(k,2,i_generator), hole_mask(k,2)) - particle(k,1) = iand(not(psi_det_generators(k,1,i_generator)), particle_mask(k,1)) - particle(k,2) = iand(not(psi_det_generators(k,2,i_generator)), particle_mask(k,2)) - enddo - - ! Create lists of holes and particles - ! ----------------------------------- - - integer :: N_holes(2), N_particles(2) - integer :: hole_list(N_int*bit_kind_size,2) - integer :: particle_list(N_int*bit_kind_size,2) - - call bitstring_to_list_ab(hole , hole_list , N_holes , N_int) - call bitstring_to_list_ab(particle, particle_list, N_particles, N_int) - - ! Create excited determinants - ! --------------------------- - - integer :: ispin, other_spin - integer(bit_kind) :: exc_det(N_int,2), ion_det(N_int,2) - - do k=1,N_int - exc_det(k,1) = psi_det_generators(k,1,i_generator) - exc_det(k,2) = psi_det_generators(k,2,i_generator) - ion_det(k,1) = psi_det_generators(k,1,i_generator) - ion_det(k,2) = psi_det_generators(k,2,i_generator) - enddo - - - - integer :: ptr_microlist(0:mo_tot_num * 2 + 1), N_microlist(0:mo_tot_num * 2) - integer, allocatable :: idx_microlist(:) - integer(bit_kind), allocatable :: microlist(:, :, :) - double precision, allocatable :: psi_coef_microlist(:,:) - - allocate(microlist(N_int, 2, N_det_selectors * 3), psi_coef_microlist(psi_selectors_size * 3, N_states), idx_microlist(N_det_selectors * 3)) - - do ispin=1,2 - - - do i=1, N_holes(ispin) - ion_det(:,:) = psi_det_generators(:,:,i_generator) - integer :: i_hole - i_hole = hole_list(i,ispin) - - ! Apply the hole - integer :: j_hole, k_hole - k_hole = ishft(i_hole-1,-bit_kind_shift)+1 ! N_int - j_hole = i_hole-ishft(k_hole-1,bit_kind_shift)-1 ! bit index - ion_det(k_hole,ispin) = ibclr(ion_det(k_hole,ispin),j_hole) - - - call create_microlist_single(psi_selectors, i_generator, N_det_selectors, ion_det, microlist, idx_microlist, N_microlist, ptr_microlist, N_int) - - do j=1, ptr_microlist(mo_tot_num * 2 + 1) - 1 - psi_coef_microlist(j,:) = psi_selectors_coef_transp(:,idx_microlist(j)) - enddo - - if(ptr_microlist(mo_tot_num * 2 + 1) == 1) then - cycle - endif - - - do j=1,N_particles(ispin) - exc_det(:,:) = ion_det(:,:) - - integer :: i_particle - i_particle = particle_list(j,ispin) - - integer :: j_particle, k_particle - k_particle = ishft(i_particle-1,-bit_kind_shift)+1 ! N_int - j_particle = i_particle-ishft(k_particle-1,bit_kind_shift)-1 ! bit index - exc_det(k_particle,ispin) = ibset(exc_det(k_particle,ispin),j_particle) - - - logical, external :: is_in_wavefunction - logical :: nok - if (.not. is_in_wavefunction(exc_det,N_int)) then - double precision :: i_H_psi_value(N_states), i_H_psi_value2(N_states) - i_H_psi_value = 0d0 - i_H_psi_value2 = 0d0 - integer :: sporb - - - nok = .false. - sporb = i_particle + (ispin - 1) * mo_tot_num - - if(N_microlist(sporb) > 0) call check_past(exc_det, microlist(1,1,ptr_microlist(sporb)), idx_microlist(ptr_microlist(sporb)), N_microlist(sporb), i_generator, nok, N_int) - if(nok) cycle - - if(N_microlist(0) > 0) call i_H_psi(exc_det,microlist,psi_coef_microlist,N_int,N_microlist(0),psi_selectors_size*3,N_states,i_H_psi_value) - if(N_microlist(sporb) > 0) call i_H_psi(exc_det,microlist(1,1,ptr_microlist(sporb)),psi_coef_microlist(ptr_microlist(sporb), 1),N_int,N_microlist(sporb),psi_selectors_size*3,N_states,i_H_psi_value2) - i_H_psi_value(:) = i_H_psi_value(:) + i_H_psi_value2(:) - double precision :: Hii, diag_H_mat_elem_fock - Hii = diag_H_mat_elem_fock(psi_det_generators(1,1,i_generator),exc_det,fock_diag_tmp,N_int) - - double precision :: delta_E, e_pert(N_states), e_pertm - e_pert(:) = 0d0 - e_pertm = 0d0 - - do k=1,N_states - if (i_H_psi_value(k) == 0.d0) cycle - delta_E = E0(k) - Hii - if (delta_E < 0.d0) then - e_pert(k) = 0.5d0 * (-dsqrt(delta_E * delta_E + 4.d0 * i_H_psi_value(k) * i_H_psi_value(k)) - delta_E) - else - e_pert(k) = 0.5d0 * ( dsqrt(delta_E * delta_E + 4.d0 * i_H_psi_value(k) * i_H_psi_value(k)) - delta_E) - endif - if(dabs(e_pert(k)) > dabs(e_pertm)) e_pertm = e_pert(k) - pt2(k) += e_pert(k) - enddo - call add_to_selection_buffer(buf, exc_det, e_pertm) - endif - - ! Reset exc_det - exc_det(k_particle,ispin) = psi_det_generators(k_particle,ispin,i_generator) - enddo ! j - - ! Reset ion_det - ion_det(k_hole,ispin) = psi_det_generators(k_hole,ispin,i_generator) - enddo ! i - enddo ! ispin -end - - - -subroutine select_doubles(i_generator,hole_mask,particle_mask,fock_diag_tmp,E0,pt2,buf) - !use f77_zmq - use bitmasks - use selection_types - implicit none - BEGIN_DOC -! Select determinants connected to i_det by H - END_DOC - integer, intent(in) :: i_generator - double precision, intent(in) :: fock_diag_tmp(mo_tot_num) - double precision, intent(inout) :: pt2(N_states) - integer(bit_kind), intent(in) :: hole_mask(N_int,2), particle_mask(N_int,2) - double precision, intent(in) :: E0(N_states) - type(selection_buffer), intent(inout) :: buf - logical :: isinwf(mo_tot_num*2, mo_tot_num*2) - double precision :: d0s(mo_tot_num, mo_tot_num, N_states) - - integer :: i,j,k,l,j1,j2,i1,i2,ib,jb - - integer :: msg_size - msg_size = bit_kind*N_int*2 - - ! Apply hole and particle masks - ! ----------------------------- - - integer(bit_kind) :: hole(N_int,2), particle(N_int,2) - do k=1,N_int - hole (k,1) = iand(psi_det_generators(k,1,i_generator), hole_mask(k,1)) - hole (k,2) = iand(psi_det_generators(k,2,i_generator), hole_mask(k,2)) - particle(k,1) = iand(not(psi_det_generators(k,1,i_generator)), particle_mask(k,1)) - particle(k,2) = iand(not(psi_det_generators(k,2,i_generator)), particle_mask(k,2)) - enddo - - ! Create lists of holes and particles - ! ----------------------------------- - - integer :: N_holes(2), N_particles(2) - integer :: hole_list(N_int*bit_kind_size,2) - integer :: particle_list(N_int*bit_kind_size,2) - - call bitstring_to_list_ab(hole , hole_list , N_holes , N_int) - call bitstring_to_list_ab(particle, particle_list, N_particles, N_int) - - ! Create excited determinants - ! --------------------------- - - integer :: ispin1, ispin2, other_spin - integer(bit_kind) :: exc_det(N_int,2), ion_det(N_int,2) - - - integer :: ptr_microlist(0:mo_tot_num * 2 + 1), N_microlist(0:mo_tot_num * 2) - double precision, allocatable :: psi_coef_microlist(:,:) - - integer :: ptr_tmicrolist(0:mo_tot_num * 2 + 1), N_tmicrolist(0:mo_tot_num * 2) - double precision, allocatable :: psi_coef_tmicrolist(:,:) - - integer, allocatable :: idx_tmicrolist(:), idx_microlist(:) - integer(bit_kind), allocatable :: microlist(:,:,:), tmicrolist(:,:,:) - - integer :: ptr_futur_microlist(0:mo_tot_num * 2 + 1), ptr_futur_tmicrolist(0:mo_tot_num * 2 + 1) - integer :: N_futur_microlist(0:mo_tot_num * 2), N_futur_tmicrolist(0:mo_tot_num * 2) - logical :: pastlink - - allocate(idx_tmicrolist(N_det_selectors * 3), idx_microlist(N_det_selectors * 4)) - allocate(microlist(N_int, 2, N_det_selectors * 4), tmicrolist(N_int, 2, N_det_selectors * 3)) - allocate(psi_coef_tmicrolist(psi_selectors_size * 3, N_states), psi_coef_microlist(psi_selectors_size * 4, N_states)) - - do k=1,N_int - exc_det(k,1) = psi_det_generators(k,1,i_generator) - exc_det(k,2) = psi_det_generators(k,2,i_generator) - ion_det(k,1) = psi_det_generators(k,1,i_generator) - ion_det(k,2) = psi_det_generators(k,2,i_generator) - enddo - - do ispin1=1,2 - do ispin2=1,ispin1 - integer :: i_hole1, i_hole2, j_hole, k_hole - do i1=N_holes(ispin1),1,-1 ! Generate low excitations first - if(ispin1 == ispin2) then - ib = i1+1 - else - ib = 1 - endif - do i2=N_holes(ispin2),ib,-1 ! Generate low excitations first - ion_det(:,:) = psi_det_generators(:,:,i_generator) - - i_hole1 = hole_list(i1,ispin1) - k_hole = ishft(i_hole1-1,-bit_kind_shift)+1 ! N_int - j_hole = i_hole1-ishft(k_hole-1,bit_kind_shift)-1 ! bit index - ion_det(k_hole,ispin1) = ibclr(ion_det(k_hole,ispin1),j_hole) - - i_hole2 = hole_list(i2,ispin2) - k_hole = ishft(i_hole2-1,-bit_kind_shift)+1 ! N_int - j_hole = i_hole2-ishft(k_hole-1,bit_kind_shift)-1 ! bit index - ion_det(k_hole,ispin2) = ibclr(ion_det(k_hole,ispin2),j_hole) - - call create_microlist_double(psi_selectors, i_generator, N_det_selectors, ion_det, & - microlist, idx_microlist, N_microlist, ptr_microlist, & - tmicrolist, idx_tmicrolist, N_tmicrolist, ptr_tmicrolist, & - isinwf, d0s, N_int) - - if(ptr_microlist(mo_tot_num * 2 + 1) == 1 .and. ptr_tmicrolist(mo_tot_num * 2 + 1) == 1) cycle - - call finish_isinwf(ion_det, psi_det_sorted(1,1,N_det_selectors+1), N_det - N_det_selectors, isinwf) - - - call create_futur_ptr(ptr_microlist, idx_microlist, ptr_futur_microlist, N_futur_microlist, i_generator) - call create_futur_ptr(ptr_tmicrolist, idx_tmicrolist, ptr_futur_tmicrolist, N_futur_tmicrolist, i_generator) - - - do j=1, ptr_microlist(mo_tot_num * 2 + 1) - 1 - psi_coef_microlist(j,:) = psi_selectors_coef_transp(:,idx_microlist(j)) - enddo - do j=1, ptr_tmicrolist(mo_tot_num * 2 + 1) - 1 - psi_coef_tmicrolist(j,:) = psi_selectors_coef_transp(:,idx_tmicrolist(j)) - enddo - - - ! Create particles - ! ---------------- - integer :: i_particle1, i_particle2, k_particle, j_particle - integer :: p1, p2, sporb, lorb - - do j1=1,N_particles(ispin1) - i_particle1 = particle_list(j1, ispin1) - p1 = i_particle1 + (ispin1 - 1) * mo_tot_num - if(N_tmicrolist(p1) > 0 .and. idx_tmicrolist(ptr_tmicrolist(p1)) < i_generator) cycle - jb = 1 - if(ispin1 == ispin2) jb = j1+1 - do j2=jb,N_particles(ispin2) - - i_particle2 = particle_list(j2, ispin2) - - - - p2 = i_particle2 + (ispin2 - 1) * mo_tot_num - if(N_tmicrolist(p2) > 0 .and. idx_tmicrolist(ptr_tmicrolist(p2)) < i_generator) cycle - if(isinwf(p1, p2)) cycle - exc_det = ion_det - - - if(N_microlist(p1) < N_microlist(p2)) then - sporb = p1 - lorb = p2 - else - sporb = p2 - lorb = p1 - endif - - - ! Apply the particle - k_particle = ishft(i_particle2-1,-bit_kind_shift)+1 ! N_int - j_particle = i_particle2-ishft(k_particle-1,bit_kind_shift)-1 ! bit index - exc_det(k_particle,ispin2) = ibset(exc_det(k_particle,ispin2),j_particle) - - ! Apply the particle - k_particle = ishft(i_particle1-1,-bit_kind_shift)+1 ! N_int - j_particle = i_particle1-ishft(k_particle-1,bit_kind_shift)-1 ! bit index - exc_det(k_particle,ispin1) = ibset(exc_det(k_particle,ispin1),j_particle) - - logical, external :: is_in_wavefunction - logical :: nok - ! Compute perturbative contribution and select determinant - double precision :: i_H_psi_value(N_states), i_H_psi_value2(N_states) - i_H_psi_value = 0d0 - i_H_psi_value2 = 0d0 - - nok = .false. - call check_past_s(exc_det, microlist(1,1,ptr_microlist(sporb)), N_microlist(sporb) - N_futur_microlist(sporb), nok, N_int) - if(nok) cycle - !DET DRIVEN - if(N_futur_microlist(0) > 0) then - call i_H_psi(exc_det,microlist(1,1,ptr_futur_microlist(0)),psi_coef_microlist(ptr_futur_microlist(0), 1),N_int,N_futur_microlist(0),psi_selectors_size*4,N_states,i_H_psi_value) - end if - !INTEGRAL DRIVEN -! do j=1, N_states -! i_H_psi_value(j) = d0s(mod(p1-1, mo_tot_num)+1, mod(p2-1, mo_tot_num)+1, j) -! end do - - - if(N_futur_microlist(sporb) > 0) then - !!! COMPUTE INTERSECTION - !!!!!!!!!!!!! -! if(dfloat(N_futur_microlist(lorb)) / dfloat(N_futur_microlist(sporb)) < 2d0) then -! c1 = ptr_futur_microlist(p1) -! c2 = ptr_futur_microlist(p2) -! do while(c1 < ptr_microlist(p1+1) .and. c2 < ptr_microlist(p2+1)) -! if(idx_microlist(c1) < idx_microlist(c2)) then -! c1 += 1 -! else if(idx_microlist(c1) > idx_microlist(c2)) then -! c2 += 1 -! else -! call i_H_j(exc_det,microlist(1,1,c1),N_int,hij) -! do j = 1, N_states -! i_H_psi_value2(j) = i_H_psi_value2(j) + psi_coef_microlist(c1,j)*hij -! end do -! c1 += 1 -! c2 += 1 -! endif -! end do -! else - call i_H_psi(exc_det,microlist(1,1,ptr_futur_microlist(sporb)),psi_coef_microlist(ptr_futur_microlist(sporb), 1),N_int,N_futur_microlist(sporb),psi_selectors_size*4,N_states,i_H_psi_value2) - i_H_psi_value = i_H_psi_value + i_H_psi_value2 - end if - - if(.true.) then ! DET DRIVEN - integer :: c1, c2 - double precision :: hij - c1 = ptr_futur_tmicrolist(p1) - c2 = ptr_futur_tmicrolist(p2) - do while(.true.) - if(c1 >= ptr_tmicrolist(p1+1) .or. c2 >= ptr_tmicrolist(p2+1)) then - if(ptr_tmicrolist(p1+1) /= c1) then - call i_H_psi(exc_det,tmicrolist(1,1,c1),psi_coef_tmicrolist(c1, 1),N_int, ptr_tmicrolist(p1+1)-c1 ,psi_selectors_size*3,N_states,i_H_psi_value2) - i_H_psi_value = i_H_psi_value + i_H_psi_value2 - end if - - if(ptr_tmicrolist(p2+1) /= c2) then - call i_H_psi(exc_det,tmicrolist(1,1,c2),psi_coef_tmicrolist(c2, 1),N_int, ptr_tmicrolist(p2+1)-c2 ,psi_selectors_size*3,N_states,i_H_psi_value2) - i_H_psi_value = i_H_psi_value + i_H_psi_value2 - endif - - exit - endif - - if(idx_tmicrolist(c1) < idx_tmicrolist(c2)) then - call i_H_j(exc_det,tmicrolist(1,1,c1),N_int,hij) - do j = 1, N_states - i_H_psi_value(j) = i_H_psi_value(j) + psi_coef_tmicrolist(c1,j)*hij - enddo - c1 += 1 - else - call i_H_j(exc_det,tmicrolist(1,1,c2),N_int,hij) - do j = 1, N_states - i_H_psi_value(j) = i_H_psi_value(j) + psi_coef_tmicrolist(c2,j)*hij - enddo - if(idx_tmicrolist(c1) == idx_tmicrolist(c2)) c1 = c1 + 1 - c2 += 1 - end if - enddo - end if - - double precision :: Hii, diag_H_mat_elem_fock - Hii = diag_H_mat_elem_fock(psi_det_generators(1,1,i_generator),exc_det,fock_diag_tmp,N_int) - double precision :: delta_E, e_pert(N_states), e_pertm - e_pert(:) = 0d0 - e_pertm = 0d0 - - do k=1,N_states - if (i_H_psi_value(k) == 0.d0) cycle - delta_E = E0(k) - Hii - if (delta_E < 0.d0) then - e_pert(k) = 0.5d0 * (-dsqrt(delta_E * delta_E + 4.d0 * i_H_psi_value(k) * i_H_psi_value(k)) - delta_E) - else - e_pert(k) = 0.5d0 * ( dsqrt(delta_E * delta_E + 4.d0 * i_H_psi_value(k) * i_H_psi_value(k)) - delta_E) - endif - e_pertm += dabs(e_pert(k)) -! if(dabs(e_pert(k)) > dabs(e_pertm)) e_pertm = e_pert(k) - pt2(k) += e_pert(k) - enddo - if(dabs(e_pertm) > dabs(buf%mini)) then - call add_to_selection_buffer(buf, exc_det, e_pertm) - end if - enddo - enddo - enddo - enddo - enddo - enddo -end - - - -subroutine create_futur_ptr(ptr_microlist, idx_microlist, ptr_futur_microlist, N_futur_microlist, i_generator) - integer, intent(in) :: ptr_microlist(0:mo_tot_num * 2 + 1), idx_microlist(*), i_generator - integer, intent(out) :: ptr_futur_microlist(0:mo_tot_num * 2 + 1), N_futur_microlist(0:mo_tot_num * 2) - integer :: i, j - - N_futur_microlist = 0 - do i=0,mo_tot_num*2 - ptr_futur_microlist(i) = ptr_microlist(i+1) - do j=ptr_microlist(i), ptr_microlist(i+1) - 1 - if(idx_microlist(j) >= i_generator) then - ptr_futur_microlist(i) = j - N_futur_microlist(i) = ptr_microlist(i+1) - j - exit - end if - end do - end do -end subroutine - - -subroutine create_microlist_single(minilist, i_cur, N_minilist, key_mask, microlist, idx_microlist, N_microlist, ptr_microlist, Nint) - use bitmasks - integer, intent(in) :: Nint, i_cur, N_minilist - integer(bit_kind), intent(in) :: minilist(Nint,2,N_minilist), key_mask(Nint,2) - - integer, intent(out) :: N_microlist(0:mo_tot_num*2), ptr_microlist(0:mo_tot_num*2+1), idx_microlist(N_minilist*4) - integer(bit_kind), intent(out) :: microlist(Nint,2,N_minilist*4) - - integer :: i,j,k,s,nt,n_element(2) - integer :: list(Nint*bit_kind_size,2), cur_microlist(0:mo_tot_num*2+1) - integer(bit_kind) :: key_mask_neg(Nint,2), mobileMask(Nint,2) - integer :: mo_tot_num_2 - mo_tot_num_2 = mo_tot_num+mo_tot_num - - - do i=1,Nint - key_mask_neg(i,1) = not(key_mask(i,1)) - key_mask_neg(i,2) = not(key_mask(i,2)) - end do - - do i=0,mo_tot_num_2 - N_microlist(i) = 0 - enddo - - do i=1, N_minilist - nt = 0 - do j=1,Nint - mobileMask(j,1) = iand(key_mask_neg(j,1), minilist(j,1,i)) - mobileMask(j,2) = iand(key_mask_neg(j,2), minilist(j,2,i)) - nt += popcnt(mobileMask(j, 1)) + popcnt(mobileMask(j, 2)) - end do - - if(nt > 3) then !! TOO MANY DIFFERENCES - continue - else if(nt < 3) then - if(i < i_cur) then !!!!!!!!!!!!!!!!!!!!! DESACTIVADO - N_microlist(:) = 0 !!!! PAST LINKED TO EVERYBODY! - ptr_microlist(:) = 1 - return - else !! FUTUR LINKED TO EVERYBODY - N_microlist(0) = N_microlist(0) + 1 - endif - else - call bitstring_to_list(mobileMask(1,1), list(1,1), n_element(1), Nint) - call bitstring_to_list(mobileMask(1,2), list(1,2), n_element(2), Nint) - - do s=1,2 - do j=1,n_element(s) - nt = list(j,s) + mo_tot_num * (s-1) - N_microlist(nt) = N_microlist(nt) + 1 - end do - end do - endif - end do - - ptr_microlist(0) = 1 - do i=1,mo_tot_num_2+1 - ptr_microlist(i) = ptr_microlist(i-1) + N_microlist(i-1) - end do - - do i=0,mo_tot_num_2+1 - cur_microlist(i) = ptr_microlist(i) - end do - - - do i=1, N_minilist - do j=1,Nint - mobileMask(j,1) = iand(key_mask_neg(j,1), minilist(j,1,i)) - mobileMask(j,2) = iand(key_mask_neg(j,2), minilist(j,2,i)) - end do - - call bitstring_to_list(mobileMask(1,1), list(1,1), n_element(1), Nint) - call bitstring_to_list(mobileMask(1,2), list(1,2), n_element(2), Nint) - - - if(n_element(1) + n_element(2) < 3) then - idx_microlist(cur_microlist(0)) = i - do k=1,Nint - microlist(k,1,cur_microlist(0)) = minilist(k,1,i) - microlist(k,2,cur_microlist(0)) = minilist(k,2,i) - enddo - cur_microlist(0) = cur_microlist(0) + 1 - else if(n_element(1) + n_element(2) == 3) then - do s = 1, 2 - do j=1,n_element(s) - nt = list(j,s) + mo_tot_num * (s-1) - idx_microlist(cur_microlist(nt)) = i - do k=1,Nint - microlist(k,1,cur_microlist(nt)) = minilist(k,1,i) - microlist(k,2,cur_microlist(nt)) = minilist(k,2,i) - enddo - cur_microlist(nt) = cur_microlist(nt) + 1 - end do - end do - end if - end do -end subroutine - - -subroutine finish_isinwf(key_mask, keys, N_keys, isinwf) - use bitmasks - implicit none - - integer(bit_kind), intent(in) :: key_mask(N_int, 2), keys(N_int, 2, N_keys) - integer(bit_kind) :: key_mask_neg(N_int, 2) - integer(bit_kind) :: mobileMask(N_int, 2) - logical,intent(inout) :: isinwf(mo_tot_num*2, mo_tot_num*2) - integer, intent(in) :: N_keys - integer :: i,j,nt,nt2,list(2,2), n_element(2) - logical, external :: detEq - - do i=1,N_int - key_mask_neg(i,1) = not(key_mask(i,1)) - key_mask_neg(i,2) = not(key_mask(i,2)) - end do - - do i=1, N_keys - nt = 0 - - do j=1,N_int - mobileMask(j,1) = iand(key_mask_neg(j,1), keys(j,1,i)) - mobileMask(j,2) = iand(key_mask_neg(j,2), keys(j,2,i)) - nt += popcnt(mobileMask(j, 1)) + popcnt(mobileMask(j, 2)) - end do - - if(nt /= 2) cycle - - call bitstring_to_list(mobileMask(1,1), list(1,1), n_element(1), N_int) - call bitstring_to_list(mobileMask(1,2), list(1,2), n_element(2), N_int) - - if(n_element(1) >= 1) nt = list(1,1) - if(n_element(1) == 2) nt2 = list(2,1) - if(n_element(2) == 2) nt = list(2,2) + mo_tot_num - if(n_element(2) >= 1) nt2 = list(1,2) + mo_tot_num - - isinwf(nt, nt2) = .true. - isinwf(nt2, nt) = .true. - end do -end subroutine - - -subroutine create_microlist_double(minilist, i_cur, N_minilist, key_mask, microlist, idx_microlist, N_microlist, ptr_microlist, & - tmicrolist, idx_tmicrolist, N_tmicrolist, ptr_tmicrolist, & - isinwf, d0s, Nint) - use bitmasks - implicit none - integer, intent(in) :: Nint, i_cur, N_minilist - integer(bit_kind), intent(in) :: minilist(Nint,2,N_minilist), key_mask(Nint,2) - - integer, intent(out) :: N_microlist(0:mo_tot_num*2), ptr_microlist(0:mo_tot_num*2+1), idx_microlist(N_minilist*4) - integer(bit_kind), intent(out) :: microlist(Nint,2,N_minilist*4) - - integer, intent(out) :: N_tmicrolist(0:mo_tot_num*2), ptr_tmicrolist(0:mo_tot_num*2+1), idx_tmicrolist(N_minilist*4) - integer(bit_kind), intent(out) :: tmicrolist(Nint,2,N_minilist*4) - - - integer :: i,j,k,s,nt,nt2 - integer, allocatable :: n_element(:,:), idx(:), list(:,:,:) - integer :: cur_microlist(0:mo_tot_num*2+1), cur_tmicrolist(0:mo_tot_num*2+1) - integer(bit_kind) :: key_mask_neg(Nint,2), mobileMask(Nint,2), tmp_det(Nint, 2) - integer :: mo_tot_num_2, pwen(4), pweni - logical,intent(out) :: isinwf(mo_tot_num*2, mo_tot_num*2) - double precision, intent(out) :: d0s(mo_tot_num, mo_tot_num, N_states) - double precision :: integ(mo_tot_num, mo_tot_num) - logical :: localbanned(mo_tot_num*2), banned(mo_tot_num*2), banned_pair(mo_tot_num*2, mo_tot_num*2), ok - banned = .false. - banned_pair = .false. - - allocate(list(4,2,N_minilist), n_element(2,N_minilist), idx(0:N_minilist)) - - isinwf = .false. - integ = 0d0 - d0s = 0d0 - mo_tot_num_2 = mo_tot_num+mo_tot_num - - idx(0) = 0 - do i=1,Nint - key_mask_neg(i,1) = not(key_mask(i,1)) - key_mask_neg(i,2) = not(key_mask(i,2)) - end do - - do i=0,mo_tot_num_2 - N_microlist(i) = 0 - N_tmicrolist(i) = 0 - enddo - - do i=1, N_minilist - nt = 0 - do j=1,Nint - mobileMask(j,1) = iand(key_mask_neg(j,1), minilist(j,1,i)) - mobileMask(j,2) = iand(key_mask_neg(j,2), minilist(j,2,i)) - nt += popcnt(mobileMask(j, 1)) + popcnt(mobileMask(j, 2)) - end do - - if(nt > 4) cycle !! TOO MANY DIFFERENCES - idx(0) += 1 - idx(idx(0)) = i - - call bitstring_to_list(mobileMask(1,1), list(1,1,idx(0)), n_element(1, idx(0)), Nint) - call bitstring_to_list(mobileMask(1,2), list(1,2,idx(0)), n_element(2, idx(0)), Nint) - - - if(nt == 2) then - if(i < i_cur) then - N_microlist(:) = 0 - ptr_microlist = 1 - N_tmicrolist = 0 - ptr_tmicrolist = 1 - return - else - N_microlist(0) = N_microlist(0) + 1 - endif - else - do s=1,2 - do j=1,n_element(s,idx(0)) - k = list(j,s,idx(0)) + mo_tot_num * (s-1) - if(nt == 4) N_microlist(k) = N_microlist(k) + 1 - if(nt == 3) then - N_tmicrolist(k) = N_tmicrolist(k) + 1 - if(idx(i) < i_cur) banned(nt) = .true. - end if - end do - end do - endif - end do - - ptr_microlist(0) = 1 - ptr_tmicrolist(0) = 1 - do i=1,mo_tot_num_2+1 - ptr_microlist(i) = ptr_microlist(i-1) + N_microlist(i-1) - ptr_tmicrolist(i) = ptr_tmicrolist(i-1) + N_tmicrolist(i-1) - end do - - do i=0,mo_tot_num_2+1 - cur_microlist(i) = ptr_microlist(i) - cur_tmicrolist(i) = ptr_tmicrolist(i) - end do - - - do i=1, idx(0) - if(n_element(1, i) + n_element(2, i) == 2) cycle - pweni = 0 - do s = 1, 2 - do j=1,n_element(s,i) - nt = list(j,s,i) + mo_tot_num * (s-1) - pweni += 1 - pwen(pweni) = nt - if(n_element(1,i) + n_element(2,i) == 4) then - idx_microlist(cur_microlist(nt)) = idx(i) - do k=1,Nint - microlist(k,1,cur_microlist(nt)) = minilist(k,1,idx(i)) - microlist(k,2,cur_microlist(nt)) = minilist(k,2,idx(i)) - enddo - cur_microlist(nt) = cur_microlist(nt) + 1 - else - idx_tmicrolist(cur_tmicrolist(nt)) = idx(i) - do k=1,Nint - tmicrolist(k,1,cur_tmicrolist(nt)) = minilist(k,1,idx(i)) - tmicrolist(k,2,cur_tmicrolist(nt)) = minilist(k,2,idx(i)) - enddo - cur_tmicrolist(nt) = cur_tmicrolist(nt) + 1 - endif - end do - end do - if(idx(i) < i_cur .and. pweni == 4) then - do j=1,4 - do k=j+1,4 - banned_pair(pwen(j), pwen(k)) = .true. - banned_pair(pwen(k), pwen(j)) = .true. - end do - end do - end if - end do - - - do i=1, idx(0) - if(n_element(1, i) + n_element(2, i) <= 2) then - idx_microlist(cur_microlist(0)) = idx(i) - do k=1,Nint - microlist(k,1,cur_microlist(0)) = minilist(k,1,idx(i)) - microlist(k,2,cur_microlist(0)) = minilist(k,2,idx(i)) - enddo - cur_microlist(0) = cur_microlist(0) + 1 - - if(n_element(1,i) >= 1) nt = list(1,1,i) - if(n_element(1,i) == 2) nt2 = list(2,1,i) - if(n_element(2,i) == 2) nt = list(2,2,i) + mo_tot_num - if(n_element(2,i) >= 1) nt2 = list(1,2,i) + mo_tot_num - - isinwf(nt, nt2) = .true. - isinwf(nt2, nt) = .true. - !!!! INTEGRAL DRIVEN -! !!!!!!!!!!!!!!!!!!!! - call get_d0(minilist(1,1,idx(i)), banned, banned_pair, d0s, key_mask, 1+(nt2-1)/mo_tot_num, 1+(nt-1)/mo_tot_num, & - mod(nt2-1, mo_tot_num)+1, mod(nt-1, mo_tot_num)+1, psi_selectors_coef_transp(1,idx(i))) - -! do j=1, N_states -! do nt2=1, mo_tot_num -! do nt=1, mo_tot_num -! d0s(nt,nt2,j) = d0s(nt,nt2,j) + (integ(nt,nt2) * psi_selectors_coef(idx(i), j)) !!! SUPPOSE MINILIST = SELECTORS !!!! -! end do -! end do -! end do - else if(.false. .and. n_element(1, i) + n_element(2, i) == 3) then ! INTEGRAL DRIVEN - ! -459.6399263191298 - pweni = 0 - do s = 1, 2 - do j=1,n_element(s,i) - nt = list(j,s,i) + mo_tot_num * (s-1) - pweni += 1 - pwen(pweni) = nt - end do - end do - - call get_d1(minilist(1,1,idx(i)), banned, banned_pair, d0s, key_mask, pwen, psi_selectors_coef_transp(1,idx(i))) - -! do k=1, N_states -! do nt2=1, mo_tot_num -! do nt=1, mo_tot_num -! d0s(nt,nt2,k) = d0s(nt,nt2,k) + (integ(nt,nt2) * psi_selectors_coef(idx(i), k)) !!! SUPPOSE MINILIST = SELECTORS !!!! -! end do -! end do -! end do - end if - end do - - -end subroutine - - -subroutine get_d1(gen, banned, banned_pair, mat, mask, pwen, coefs) - use bitmasks - implicit none - - integer(bit_kind), intent(in) :: mask(N_int, 2), gen(N_int, 2) - logical, intent(in) :: banned(mo_tot_num*2), banned_pair(mo_tot_num*2, mo_tot_num*2) - integer(bit_kind) :: deth(N_int, 2), det(N_int, 2), i8 - double precision, intent(in) :: coefs(N_states) - double precision, intent(inout) :: mat(mo_tot_num, mo_tot_num, N_states) - double precision :: hij, phase, inv, inv2 - integer, intent(in) :: pwen(3) - integer :: s(3), p(3), i, j, k, h1, h2, ns(2), sm, mwen, a1, a2, pwens(2), sp, st - integer :: sfix, pfix - integer :: exc(0:2, 2, 2) - logical :: lbanned(mo_tot_num*2) - logical :: ok, mono, ab - integer :: tmp_array(4) - - lbanned = banned - !mat = 0d0 - pwens = 0 - - ns = 0 - do sp=1,2 - do i=1, N_int - ns(sp) += popcnt(gen(i, sp)) - popcnt(mask(i, sp)) - i8 = iand(not(gen(i, sp)), mask(i, sp)) - if(i8 /= 0_8) then - sfix = sp - pfix = 1+trailz(i8) + bit_kind*8*(i-1) - end if - end do - end do - - - do i=1,3 - s(i) = 1+(pwen(i)-1)/mo_tot_num - p(i) = 1+mod(pwen(i)-1, mo_tot_num) - pwens(s(i)) += 1 - end do - - do i=1,3 - if(s(i) == 1 .and. ns(1) == 0) cycle - if(s(i) == 2 .and. ns(2) == 0) cycle - if(lbanned(pwen(i))) cycle - ab = pwens(s(i)) == 2 - - if(ns(1) == 1) sm = mod(s(i), 2) + 1 - if(ns(1) == 2) sm = 1 - if(ns(2) == 2) sm = 2 - - lbanned(pwen(i)) = .true. - - if(ab) then - if(s(mod(i,3)+1) == 2) then - a1 = mod(i, 3) + 1 - a2 = mod(i+1, 3) + 1 - else - a2 = mod(i,3)+1 - a1 = mod(i+1,3)+1 - end if - - exc(0, :, 1) = 1 - exc(0, :, 2) = 1 - exc(1, 1, 1) = p(a2) - exc(1, 1, 2) = p(a1) - exc(1, 2, sfix) = pfix - - call apply_particle(mask, 0, 0 ,s(i), p(i), deth, ok, N_int) - - do j=1,mo_tot_num - mwen = j + (sm-1)*mo_tot_num - if(lbanned(mwen)) cycle - tmp_array = (/0,0,sm,j/) - call apply_particle(deth, 0, 0 ,s(i), p(i), det, ok, N_int) - if(.not. ok) cycle - - mono = mwen == pwen(a1) .or. mwen == pwen(a2) - if(mono) then - call i_h_j(gen, det, N_int, hij) - else - exc(1, 2, sm) = j - call get_double_excitation_phase(gen, det, exc, phase, N_int) - if(sfix == 1) hij = integral8(j, pfix, p(a1), p(a2)) * phase - if(sfix == 2) hij = integral8(pfix, j, p(a1), p(a2)) * phase - end if - - if(ns(1) == 1) then - do st=1, N_states - if(sm == 2) mat(j, p(i), st) = mat(j, p(i), st) + hij * coefs(st) - if(sm == 1) mat(p(i), j, st) = mat(p(i), j, st) + hij * coefs(st) - end do - else - do st=1, N_states - mat(j, p(i), st) += hij * coefs(st) - mat(p(i), j, st) += hij * coefs(st) - end do - end if - end do - - else !! AA / BB - a1 = mod(i,3)+1 - a2 = mod(i+1,3)+1 - - h1 = p(a1) - h2 = p(a2) - inv = 1d0 - if(h1 > h2) inv = -1d0 - - if(pwens(s(i)) == 1) sp = mod(s(i), 2)+1 - if(pwens(s(i)) == 3) sp = s(i) - - exc(0, :, sp) = 2 - exc(0, :, mod(sp, 2)+1) = 0 - exc(1, 1, sp) = min(h1, h2) - exc(2, 1, sp) = max(h1, h2) - - call apply_particle(mask, 0, 0 ,s(i), p(i) , deth, ok, N_int) - - do j=1,mo_tot_num - if(j == pfix) inv = -inv - mwen = j + (sm-1)*mo_tot_num - if(lbanned(mwen)) cycle - call apply_particle(deth, 0, 0 ,s(i), p(i) , det, ok, N_int) - if(.not. ok) cycle - - mono = mwen == pwen(a1) .or. mwen == pwen(a2) - if(mono) then - call i_h_j(gen, det, N_int, hij) - else - exc(1, 2, sfix) = min(j,pfix) - exc(2, 2, sp) = max(j,pfix) - call get_double_excitation_phase(gen, det, exc, phase, N_int) - hij = (integral8(j, pfix, h1, h2) - integral8(pfix,j, h1, h2))*phase*inv - end if - if(ns(1) == 1) then - do st=1, N_states - if(sm == 2) mat(j, p(i), st) = mat(j, p(i), st) + hij * coefs(st) - if(sm == 1) mat(p(i), j, st) = mat(p(i), j, st) + hij * coefs(st) - end do - else - do st=1, N_states - mat(j, p(i), st) += hij * coefs(st) - mat(p(i), j, st) += hij * coefs(st) - end do - end if - end do - end if - end do - -end subroutine - - -subroutine get_d0(gen, banned, banned_pair, mat, mask, s1, s2, h1, h2, coefs) - use bitmasks - implicit none - - double precision, intent(inout) :: mat(mo_tot_num, mo_tot_num, N_states) - logical, intent(in) :: banned(mo_tot_num*2), banned_pair(mo_tot_num*2, mo_tot_num*2) - double precision :: mat_mwen(mo_tot_num, mo_tot_num) - double precision, intent(in) :: coefs(N_states) - integer, intent(in) :: h1, h2, s1, s2 - integer(bit_kind), intent(in) :: mask(N_int, 2), gen(N_int, 2) - integer(bit_kind) :: det1(N_int, 2), det2(N_int, 2) - logical :: ok, mono - double precision :: phase, phase2, inv, hij - integer :: p1, p2, hmi, hma, ns1, ns2, st - logical, external :: detEq - integer :: exc(0:2, 2, 2), exc2(0:2,2,2) - integer :: tmp_array(4) - - exc = 0 -! mat_mwen = integral8(:,:,h1,h2) - !call get_mo_bielec_integrals_ij(h1, h2 ,mo_tot_num,mat_mwen,mo_integrals_map) - - ns1 = mo_tot_num*(s1-1) - ns2 = mo_tot_num*(s2-1) - - !mat = 0d0 - if(s1 == s2) then - hmi = min(h1, h2) - hma = max(h1, h2) - inv = 1d0 - if(h1 > h2) inv = -1d0 - exc(0, :, s1) = 2 - exc(1, 1, s1) = hmi - exc(2, 1, s1) = hma - do p2=1,mo_tot_num - if(banned(p2 + ns2)) cycle - do p1=1,mo_tot_num - if(banned(p1 + ns1)) cycle - if(p1 == p2) cycle - if(banned_pair(p1 + ns1, p2 + ns2)) cycle - !tmp_array = (/s1,p1,s2,p2/) - call apply_particle(mask, s1,p1,s2,p2, det2, ok, N_int) - if(.not. ok) cycle - mono = (hmi == p1 .or. hma == p2 .or. hmi == p2 .or. hma == p1) - if(mono) then - - call i_h_j(gen, det2, N_int, hij) - do st=1, N_states - mat(p1, p2, st) += hij * coefs(st) - end do - else - exc(1, 2, s1) = min(p1, p2) - exc(2, 2, s2) = max(p2, p1) - call get_double_excitation_phase(gen, det2, exc, phase, N_int) - do st=1, N_states - mat(p1, p2, st) += coefs(st) * inv * (integral8(p1, p2, h1, h2) - integral8(p2, p1, h1, h2)) * phase - end do - end if - end do - end do - else - exc(0, :, 1) = 1 - exc(0, :, 2) = 1 - if(s1 /= 2) stop "alpha beta inversified" - exc(1, 1, 1) = h2 - exc(1, 1, 2) = h1 - - do p2=1, mo_tot_num - if(banned(p2 + ns2)) cycle - do p1=1, mo_tot_num - if(banned(p1 + ns1)) cycle - if(banned_pair(p1 + ns1, p2 + ns2)) cycle - !tmp_array = (/s1,p1,s2,p2/) - call apply_particle(mask, s1,p1,s2,p2, det2, ok, N_int) - if(.not. ok) cycle - mono = (h1 == p1 .or. h2 == p2) - if(mono) then - call i_h_j(gen, det2, N_int, hij) - do st=1, N_states - mat(p1, p2, st) += hij * coefs(st) - end do - else - exc(1, 2, s1) = p1 - exc(1, 2, s2) = p2 - call get_double_excitation_phase(gen, det2, exc, phase, N_int) - do st=1, N_states - mat(p1, p2, st) += coefs(st) * integral8(p1, p2, h1, h2) * phase - end do - !mat(p1, p2) = integral8(p1, p2, h1, h2) * phase - end if - end do - end do - end if -end subroutine - - -subroutine check_past(det, list, idx, N, cur, ok, Nint) - implicit none - use bitmasks - - integer(bit_kind), intent(in) :: det(Nint, 2), list(Nint, 2, N) - integer, intent(in) :: Nint, idx(N), N, cur - logical, intent(out) :: ok - integer :: i,s,ni - - ok = .false. - do i=1,N - if(idx(i) >= cur) exit - s = 0 - do ni=1,Nint - s += popcnt(xor(det(ni,1), list(ni,1,i))) + popcnt(xor(det(ni,2), list(ni,2,i))) - end do - if(s <= 4) then - ok = .true. - return - end if - end do -end subroutine - - -subroutine check_past_s(det, list, N, ok, Nint) - implicit none - use bitmasks - - integer(bit_kind), intent(in) :: det(Nint, 2), list(Nint, 2, N) - integer, intent(in) :: Nint, N - logical, intent(out) :: ok - integer :: i,s,ni - - ok = .false. - do i=1,N - s = 0 - do ni=1,Nint - s += popcnt(xor(det(ni,1), list(ni,1,i))) + popcnt(xor(det(ni,2), list(ni,2,i))) - end do - if(s <= 4) then - ok = .true. - return - end if - end do -end subroutine +use bitmasks + +BEGIN_PROVIDER [ double precision, integral8, (mo_tot_num, mo_tot_num, mo_tot_num, mo_tot_num) ] + use bitmasks + implicit none + + integer :: h1, h2 + + integral8 = 0d0 + do h1=1, mo_tot_num + do h2=1, mo_tot_num + call get_mo_bielec_integrals_ij(h1, h2 ,mo_tot_num,integral8(1,1,h1,h2),mo_integrals_map) + end do + end do +END_PROVIDER + + +BEGIN_PROVIDER [ integer(bit_kind), psi_phasemask, (N_int, 2, N_det)] + use bitmasks + implicit none + + integer :: i + print *, "pro" + print *, "pross" + do i=1, N_det + call get_mask_phase(psi_det_sorted(1,1,i), psi_phasemask(1,1,i)) + end do +END_PROVIDER + + +subroutine assert(cond, msg) + character(*), intent(in) :: msg + logical, intent(in) :: cond + + if(.not. cond) then + print *, "assert fail: "//msg + stop + end if +end subroutine + + +subroutine get_mask_phase(det, phasemask) + use bitmasks + implicit none + + integer(bit_kind), intent(in) :: det(N_int, 2) + integer(bit_kind), intent(out) :: phasemask(N_int, 2) + integer :: s, ni, i + logical :: change + + do s=1,2 + change = .false. + do ni=1,N_int + do i=0,bit_kind_size-1 + if(BTEST(det(ni, s), i)) change = .not. change + if(change) phasemask(ni, s) = ibset(phasemask(ni, s), i) + end do + end do + end do +end subroutine + + +subroutine select_connected(i_generator,E0,pt2,b) + use bitmasks + use selection_types + implicit none + integer, intent(in) :: i_generator + type(selection_buffer), intent(inout) :: b + double precision, intent(inout) :: pt2(N_states) + integer :: k,l + double precision, intent(in) :: E0(N_states) + + integer(bit_kind) :: hole_mask(N_int,2), particle_mask(N_int,2) + double precision :: fock_diag_tmp(2,mo_tot_num+1) + + print *, "BEG" + + + call build_fock_tmp(fock_diag_tmp,psi_det_generators(1,1,i_generator),N_int) + + do l=1,N_generators_bitmask + do k=1,N_int + hole_mask(k,1) = iand(generators_bitmask(k,1,s_hole,l), psi_det_generators(k,1,i_generator)) + hole_mask(k,2) = iand(generators_bitmask(k,2,s_hole,l), psi_det_generators(k,2,i_generator)) + particle_mask(k,1) = iand(generators_bitmask(k,1,s_part,l), not(psi_det_generators(k,1,i_generator)) ) + particle_mask(k,2) = iand(generators_bitmask(k,2,s_part,l), not(psi_det_generators(k,2,i_generator)) ) + + hole_mask(k,1) = ior(generators_bitmask(k,1,s_hole,l), generators_bitmask(k,1,s_part,l)) + hole_mask(k,2) = ior(generators_bitmask(k,2,s_hole,l), generators_bitmask(k,2,s_part,l)) + particle_mask(k,:) = hole_mask(k,:) + enddo + + print *, "sel" +! call select_doubles(i_generator,hole_mask,particle_mask,fock_diag_tmp,E0,pt2,b) + print *, "poivre" + print *, b%cur, b%N + call select_singles(i_generator,hole_mask,particle_mask,fock_diag_tmp,E0,pt2,b) + print *, b%cur, b%N + print *, "paprika" + enddo + print *, "safran" +end subroutine + + +subroutine spot_occupied(mask, bannedOrb) + use bitmasks + implicit none + + integer(bit_kind),intent(in) :: mask(N_int, 2) + logical, intent(inout) :: bannedOrb(mo_tot_num, 2) + integer :: s, i, ne, list(mo_tot_num) + + do s=1,2 + call bitstring_to_list(mask(1,s), list, ne, N_int) + do i=1, ne + bannedOrb(list(i), s) = .true. + end do + end do +end subroutine + + +double precision function get_phase_bi(phasemask, s1, s2, h1, p1, h2, p2) + use bitmasks + implicit none + + integer(bit_kind), intent(in) :: phasemask(N_int, 2) + integer, intent(in) :: s1, s2, h1, h2, p1, p2 + logical :: change + + !ASSERT(h1 <= h2 .and. p1 <= p2) + change = btest(phasemask(ishft(h1, bit_kind_shift), s1), iand(h1, 63_8)) + change = xor(change, btest(phasemask(ishft(p1, bit_kind_shift), s1), iand(p1, 63_8))) + + change = xor(change, btest(phasemask(ishft(h2, bit_kind_shift), s2), iand(h2, 63_8))) + change = xor(change, btest(phasemask(ishft(p2, bit_kind_shift), s2), iand(p2, 63_8))) + + get_phase_bi = 1d0 + if(s1 == s2) then + if(xor(change, max(h1, p1) > min(h2, p2))) get_phase_bi = -1d0 + else + if(change) get_phase_bi = -1d0 + end if +end subroutine + + +double precision function get_phase_mono(phasemask, s1, h1, p1) + use bitmasks + implicit none + + integer(bit_kind), intent(in) :: phasemask(N_int, 2) + integer, intent(in) :: s1, h1, p1 + logical :: change + + change = btest(phasemask(ishft(h1, bit_kind_shift), s1), iand(h1, 63_8)) + change = xor(change, btest(phasemask(ishft(p1, bit_kind_shift), s1), iand(p1, 63_8))) + + get_phase_mono = 1d0 + if(change) get_phase_mono = -1d0 +end subroutine + + + diff --git a/plugins/Full_CI_ZMQ/selection_double.irp.f b/plugins/Full_CI_ZMQ/selection_double.irp.f new file mode 100644 index 00000000..f6a76141 --- /dev/null +++ b/plugins/Full_CI_ZMQ/selection_double.irp.f @@ -0,0 +1,512 @@ + +subroutine select_doubles(i_generator,hole_mask,particle_mask,fock_diag_tmp,E0,pt2,buf) + use bitmasks + use selection_types + implicit none + + integer, intent(in) :: i_generator + integer(bit_kind), intent(in) :: hole_mask(N_int,2), particle_mask(N_int,2) + double precision, intent(in) :: fock_diag_tmp(mo_tot_num) + double precision, intent(in) :: E0(N_states) + double precision, intent(inout) :: pt2(N_states) + type(selection_buffer), intent(inout) :: buf + + double precision :: mat(N_states, mo_tot_num, mo_tot_num) + integer :: h1,h2,s1,s2,i1,i2,ib,sp,k + integer(bit_kind) :: hole(N_int,2), particle(N_int,2), mask(N_int, 2) + logical :: fullMatch, ok + + do k=1,N_int + hole (k,1) = iand(psi_det_generators(k,1,i_generator), hole_mask(k,1)) + hole (k,2) = iand(psi_det_generators(k,2,i_generator), hole_mask(k,2)) + particle(k,1) = iand(not(psi_det_generators(k,1,i_generator)), particle_mask(k,1)) + particle(k,2) = iand(not(psi_det_generators(k,2,i_generator)), particle_mask(k,2)) + enddo + + integer :: N_holes(2), N_particles(2) + integer :: hole_list(N_int*bit_kind_size,2) + integer :: particle_list(N_int*bit_kind_size,2) + + call bitstring_to_list_ab(hole , hole_list , N_holes , N_int) + call bitstring_to_list_ab(particle, particle_list, N_particles, N_int) + + + do s1=1,2 + do s2=s1,2 + sp = s1 + if(s1 /= s2) sp = 3 + do i1=N_holes(s1),1,-1 ! Generate low excitations first + ib = 1 + if(s1 == s2) ib = i1+1 + do i2=N_holes(s2),ib,-1 ! Generate low excitations first + h1 = hole_list(i1,s1) + h2 = hole_list(i2,s2) + call apply_holes(psi_det_generators(1,1,i_generator), s1,h1,s2,h2, mask, ok, N_int) + + logical :: banned(mo_tot_num, mo_tot_num) + logical :: bannedOrb(mo_tot_num, 2) + + banned = .false. + bannedOrb = .false. + + call spot_isinwf(mask, psi_det_sorted, i_generator, N_det, banned, fullMatch) + if(fullMatch) cycle + call spot_occupied(mask, bannedOrb) + mat = 0d0 + call splash_pq(mask, sp, psi_det_sorted, i_generator, N_det_selectors, bannedOrb, banned, mat) + + call fill_buffer_double(i_generator, sp, h1, h2, banned, bannedOrb, fock_diag_tmp, E0, mat, buf) + end do + end do + end do + end do +end subroutine + + +subroutine fill_buffer_double(i_generator, sp, h1, h2, bannedOrb, banned, fock_diag_tmp, E0, mat, buf) + use bitmasks + use selection_types + implicit none + + integer, intent(in) :: i_generator, sp, h1, h2 + double precision, intent(in) :: mat(N_states, mo_tot_num, mo_tot_num) + logical, intent(in) :: bannedOrb(mo_tot_num, 2), banned(mo_tot_num, mo_tot_num) + double precision, intent(in) :: fock_diag_tmp(mo_tot_num) + double precision, intent(in) :: E0(N_states) + type(selection_buffer), intent(inout) :: buf + logical :: ok + integer :: s1, s2, p1, p2, ib + integer(bit_kind) :: mask(N_int, 2), det(N_int, 2) + double precision :: e_pert, delta_E, val, Hii + double precision, external :: diag_H_mat_elem_fock + + if(N_states > 1) stop "fill_buffer_double N_states > 1" + + if(sp == 3) then + s1 = 1 + s2 = 2 + else + s1 = sp + s2 = sp + end if + + call apply_holes(psi_det_generators(1,1,i_generator), s1, h1, s2, h2, mask, ok, N_int) + + do p1=1,mo_tot_num + if(bannedOrb(p1, s1)) cycle + ib = 1 + if(sp /= 3) ib = p1+1 + do p2=ib,mo_tot_num + if(bannedOrb(p2, s2)) cycle + if(banned(p1,p2)) cycle + if(mat(1, p1, p2) == 0d0) cycle + call apply_particles(mask, s1, p1, s2, p2, det, ok, N_int) + val = mat(1, p1, p2) + + Hii = diag_H_mat_elem_fock(psi_det_generators(1,1,i_generator),det,fock_diag_tmp,N_int) + + delta_E = E0(1) - Hii + if (delta_E < 0.d0) then + e_pert = 0.5d0 * (-dsqrt(delta_E * delta_E + 4.d0 * val * val) - delta_E) + else + e_pert = 0.5d0 * ( dsqrt(delta_E * delta_E + 4.d0 * val * val) - delta_E) + endif + if(dabs(e_pert) > buf%mini) call add_to_selection_buffer(buf, det, e_pert) + end do + end do +end subroutine + + +subroutine splash_pq(mask, sp, det, i_gen, N_sel, bannedOrb, banned, mat) + use bitmasks + implicit none + + integer(bit_kind),intent(in) :: mask(N_int, 2), det(N_int, 2, N_sel) + integer, intent(in) :: sp, i_gen, N_sel + logical, intent(inout) :: bannedOrb(mo_tot_num, 2), banned(mo_tot_num, mo_tot_num) + double precision, intent(inout) :: mat(N_states, mo_tot_num, mo_tot_num) ! intent out + + integer :: i, j, h(0:2,2), p(0:4,2), nt + integer(bit_kind) :: perMask(N_int, 2), mobMask(N_int, 2), negMask(N_int, 2) + + + do i=1,N_int + negMask(i,1) = not(mask(i,1)) + negMask(i,2) = not(mask(i,2)) + end do + + do i=1, N_sel + nt = 0 + do j=1,N_int + mobMask(j,1) = iand(negMask(j,1), det(j,1,i)) + mobMask(j,2) = iand(negMask(j,2), det(j,2,i)) + nt += popcnt(mobMask(j, 1)) + popcnt(mobMask(j, 2)) + end do + + if(nt > 4) cycle + + do j=1,N_int + perMask(j,1) = iand(mask(j,1), not(det(j,1,i))) + perMask(j,2) = iand(mask(j,2), not(det(j,2,i))) + end do + + call bitstring_to_list(perMask(1,1), h(1,1), h(0,1), N_int) + call bitstring_to_list(perMask(1,2), h(1,2), h(0,2), N_int) + + call bitstring_to_list(mobMask(1,1), p(1,1), p(0,1), N_int) + call bitstring_to_list(mobMask(1,2), p(1,2), p(0,2), N_int) + + if(i < i_gen) then + if(nt == 4) call past_d2(banned, p, sp) + if(nt == 3) call past_d1(bannedOrb, p) + else + if(i == i_gen) mat = 0d0 + if(nt == 4) then + call get_d2(det(1,1,i), psi_phasemask(1,1,i), bannedOrb, banned, mat, mask, h, p, sp, psi_selectors_coef_transp(1, i)) + else if(nt == 3) then + call get_d1(det(1,1,i), psi_phasemask(1,1,i), bannedOrb, banned, mat, mask, h, p, sp, psi_selectors_coef_transp(1, i)) + else + call get_d0(det(1,1,i), psi_phasemask(1,1,i), bannedOrb, banned, mat, mask, h, p, sp, psi_selectors_coef_transp(1, i)) + end if + end if + end do +end subroutine + + +subroutine get_d2(gen, phasemask, bannedOrb, banned, mat, mask, h, p, sp, coefs) + use bitmasks + implicit none + + integer(bit_kind), intent(in) :: mask(N_int, 2), gen(N_int, 2), phasemask(N_int, 2) + logical, intent(in) :: bannedOrb(mo_tot_num, 2), banned(mo_tot_num, mo_tot_num) + double precision, intent(in) :: coefs(N_states) + double precision, intent(inout) :: mat(mo_tot_num, mo_tot_num, N_states) + integer, intent(in) :: h(0:2,2), p(0:4,2), sp + + double precision, external :: get_phase_bi + + integer :: i, j, tip, ma, mi, puti, putj + integer :: h1, h2, p1, p2 + double precision :: hij, phase + + tip = p(0,1) * p(0,2) + ma = sp + if(p(0,1) > p(0,2)) ma = 1 + if(p(0,1) < p(0,2)) ma = 2 + mi = mod(ma, 2) + 1 + + if(sp == 3) then + if(tip == 3) then + putj = p(1, 2) + do i = 1, 3 + puti = p(i, ma) + + p1 = p(mod(i, 3) + 1, ma) + p2 = p(mod(i+1, 3) + 1, ma) + + hij = (integral8(p1, p2, h1, h2) - integral8(p2,p1, h1, h2)) * get_phase_bi(phasemask, ma, ma, h1, p1, h2, p2) + + if(ma == 1) then + mat(:, puti, putj) += coefs * hij + else + mat(:, putj, puti) += coefs * hij + end if + end do + else ! tip == 4 + do i = 1,2 + do j = 1,2 + puti = p(i, 1) + putj = p(j, 2) + p1 = p(mod(i, 2) + 1, 1) + p2 = p(mod(j, 2) + 1, 2) + + hij = integral8(p1, p2, h1, h2) * get_phase_bi(phasemask, 1, 2, h1, p1, h2, p2) + + mat(:, puti, putj) += coefs * hij + end do + end do + end if + + else !! AA/BB + + if(tip == 0) then + do i=1,3 + puti = p(i, ma) + do j=i+1,4 + putj = p(j, ma) + if(j == i+1) then + p1 = p(mod(j, 4) + 1, ma) + p2 = p(mod(j+1, 4) + 1, ma) + else if(j == i+2) then + p1 = p(mod(i, 4) + 1, ma) + p2 = p(mod(j, 4) + 1, ma) + else + p1 = 2 + p2 = 3 + end if + + hij = (integral8(p1, p2, h1, h2) - integral8(p2,p1, h1, h2)) * get_phase_bi(phasemask, ma, ma, h1, p1, h2, p2) + mat(:, puti, putj) += coefs * hij + end do + end do + else if(tip == 3) then + p2 = p(1, mi) + do i=1,3 + p1 = p(i, ma) + puti = p(mod(i, 3) + 1, ma) + putj = p(mod(i+1, 3) + 1, ma) + hij = integral8(p1, p2, h1, h2) * get_phase_bi(phasemask, ma, mi, h1, p1, h2, p2) + mat(:, min(puti, putj), max(puti, putj)) += coefs * hij + end do + else ! tip == 4 + puti = p(1, sp) + putj = p(2, sp) + p1 = p(1, mi) + p2 = p(2, mi) + hij = (integral8(p1, p2, h1, h2) - integral8(p2,p1, h1, h2)) * get_phase_bi(phasemask, mi, mi, h1, p1, h2, p2) + mat(:, puti, putj) += coefs * hij + end if + end if +end subroutine + + + +subroutine get_d1(gen, phasemask, bannedOrb, banned, mat, mask, ho, pa, sp, coefs) + use bitmasks + implicit none + + integer(bit_kind), intent(in) :: mask(N_int, 2), gen(N_int, 2), phasemask(N_int, 2) + logical, intent(in) :: bannedOrb(mo_tot_num, 2), banned(mo_tot_num, mo_tot_num) + integer(bit_kind) :: det(N_int, 2) + double precision, intent(in) :: coefs(N_states) + double precision, intent(inout) :: mat(N_states, mo_tot_num, mo_tot_num) + double precision :: hij, tmp_row(N_states, mo_tot_num) + double precision, external :: get_phase_bi + + logical :: lbanned(mo_tot_num, 2), ok + integer :: ms, i, i1, i2, j, hole, tmp, s(3), p(3) + + integer, intent(in) :: ho(0:2,2), pa(0:4,2), sp + + do i = 1, pa(0,1) + s(i) = 1 + p(i) = pa(i, 1) + end do + + j = i + + do i = 1, pa(0,2) + s(j) = 2 + p(j) = pa(i, 2) + j += 1 + end do + + if(ho(0,1) == 1) then + hole = ho(1,1) + else + hole = ho(1,2) + end if + + lbanned = bannedOrb + + do i=1, 3 + lbanned(p(i), s(i)) = .true. + end do + + do i=1, 3 + if(lbanned(p(i), s(i))) cycle + if(sp /= 3 .and. sp /= s(i)) cycle + ms = sp + if(sp == 3) ms = mod(s(i), 2) + 1 + i1 = mod(i,3)+1 + i2 = mod(i+1,3)+1 + + if(s(i1) /= s(i2)) then + if(s(i1) /= ms) then + tmp = i1 + i1 = i2 + i2 = tmp + end if + tmp_row = 0d0 + do j=1,mo_tot_num + if(lbanned(j, s(i))) cycle + tmp_row(:, j) += coefs * integral8(p(i1), p(i2), j, hole) * get_phase_bi(phasemask, 1, 2, j, p(i1), hole, p(i2)) + end do + if(ms == 1) then + mat(:, :, p(i)) += tmp_row + else + mat(:, p(i), :) += tmp_row + end if + else + do j=1,mo_tot_num + if(lbanned(j, s(i))) cycle + tmp_row(:, j) += coefs * (integral8(p(i1), p(i2), j, hole) - integral8(p(i2), p(i1), j, hole)) * get_phase_bi(phasemask, 1, 2, j, p(i1), hole, p(i2)) + end do + mat(:, :p(i), p(i)) += tmp_row(:, :p(i)) + mat(:, p(i), p(i):) += tmp_row(:, p(i):) + end if + end do + !! MONO + do i=1, 2 + do j=i+1,3 + if(bannedOrb(p(i), s(i)) .or. bannedOrb(p(j), s(j))) cycle + if((s(i) /= s(j) .or. sp /= s(i)) .and. (s(i) == s(j) .or. sp /= 3)) cycle + call apply_particles(mask, s(i), p(i), s(j), p(j), det, ok, N_int) + call i_h_j(gen, det, N_int, hij) + + if(s(i) == s(j)) then + mat(:, p(i), p(j)) += coefs * hij + else if(s(i) == 1) then + mat(:, p(i), p(j)) += coefs * hij + else + mat(:, p(j), p(i)) += coefs * hij + end if + end do + end do +end subroutine + + + + +subroutine get_d0(gen, phasemask, bannedOrb, banned, mat, mask, h, p, sp, coefs) + use bitmasks + implicit none + + integer(bit_kind), intent(in) :: gen(N_int, 2), mask(N_int, 2), phasemask(N_int, 2) + logical, intent(in) :: bannedOrb(mo_tot_num), banned(mo_tot_num, mo_tot_num) + integer(bit_kind) :: det(N_int, 2) + double precision, intent(in) :: coefs(N_states) + double precision, intent(inout) :: mat(N_states, mo_tot_num, mo_tot_num) + integer, intent(in) :: h(0:2,2), p(0:4,2), sp + + integer :: i, j, s, h1, h2, p1, p2 + double precision :: hij + double precision, external :: get_phase_bi + logical :: ok + + if(sp == 3) then ! AB + h1 = p(1,1) + h2 = p(1,2) + do p1=1, mo_tot_num + if(bannedOrb(i)) cycle + do p2=1, mo_tot_num + if(bannedOrb(j)) cycle + if(banned(i, j)) cycle ! rentable? + if(p1 == h1 .or. p2 == h2) then + call apply_particles(mask, 1,p1,2,p2, det, ok, N_int) + call i_h_j(gen, det, N_int, hij) + mat(:, p1, p2) += coefs * hij + else + mat(:, p1, p2) += coefs * integral8(p1, p2, h1, h2) * get_phase_bi(phasemask, 1, 2, h1, p1, h2, p2) + end if + end do + end do + else ! AA BB + s = 1 + if(p(0,2) == 2) s =2 + h1 = p(1,s) + h2 = p(2,s) + do p1=1, mo_tot_num + if(bannedOrb(i)) cycle + do p2=p1+1, mo_tot_num + if(bannedOrb(j)) cycle + if(banned(i, j)) cycle ! rentable? + if(p1 == h1 .or. p2 == h2 .or. p1 == h2 .or. p2 == h1) then + call apply_particles(mask, s,p1,s,p2, det, ok, N_int) + ASSERT(ok) + call i_h_j(gen, det, N_int, hij) + mat(:, p1, p2) += coefs * hij + else + mat(:, p1, p2) += coefs * (integral8(p1, p2, h1, h2) - integral8(p2, p1, h1, h2))* get_phase_bi(phasemask, s, s, h1, p1, h2, p2) + end if + end do + end do + end if +end subroutine + + +subroutine past_d1(bannedOrb, p) + use bitmasks + implicit none + + logical, intent(inout) :: bannedOrb(mo_tot_num, 2) + integer, intent(in) :: p(0:4, 2) + integer :: i,s + + do s = 1, 2 + do i = 1, p(0, s) + bannedOrb(p(i, s), s) = .true. + end do + end do +end subroutine + + +subroutine past_d2(banned, p, sp) + use bitmasks + implicit none + + logical, intent(inout) :: banned(mo_tot_num, mo_tot_num) + integer, intent(in) :: p(0:4, 2), sp + integer :: i,j + + if(sp == 3) then + do i=1,p(0,1) + do j=1,p(0,2) + banned(p(i,1), p(j,2)) = .true. + end do + end do + else + do i=1,p(0, sp) + do j=1,i-1 + banned(p(j,sp), p(i,sp)) = .true. + banned(p(i,sp), p(j,sp)) = .true. + end do + end do + end if +end subroutine + + + +subroutine spot_isinwf(mask, det, i_gen, N, banned, fullMatch) + use bitmasks + implicit none + + integer(bit_kind),intent(in) :: mask(N_int, 2), det(N_int, 2, N) + integer, intent(in) :: i_gen, N + logical, intent(inout) :: banned(mo_tot_num, mo_tot_num) + logical, intent(out) :: fullMatch + + + integer :: i, j, na, nb, list(3) + integer(bit_kind) :: myMask(N_int, 2), negMask(N_int, 2) + + fullMatch = .false. + + do i=1,N_int + negMask(i,1) = not(mask(i,1)) + negMask(i,2) = not(mask(i,2)) + end do + + genl : do i=1, N + do j=1, N_int + if(iand(det(j,1,i), mask(j,1)) /= mask(j, 1)) cycle genl + if(iand(det(j,2,i), mask(j,2)) /= mask(j, 1)) cycle genl + end do + + if(i < i_gen) then + fullMatch = .true. + return + end if + + do j=1, N_int + myMask(j, 1) = iand(det(j, 1, i), negMask(j, 1)) + myMask(j, 2) = iand(det(j, 2, i), negMask(j, 2)) + end do + + call bitstring_to_list(myMask(1,1), list(1), na, N_int) + call bitstring_to_list(myMask(1,2), list(na+1), nb, N_int) + + banned(list(1), list(2)) = .true. + end do genl +end subroutine + diff --git a/plugins/Full_CI_ZMQ/selection_single.irp.f b/plugins/Full_CI_ZMQ/selection_single.irp.f new file mode 100644 index 00000000..a2409135 --- /dev/null +++ b/plugins/Full_CI_ZMQ/selection_single.irp.f @@ -0,0 +1,333 @@ + + +subroutine select_singles(i_generator,hole_mask,particle_mask,fock_diag_tmp,E0,pt2,buf) + use bitmasks + use selection_types + implicit none + BEGIN_DOC +! Select determinants connected to i_det by H + END_DOC + integer, intent(in) :: i_generator + integer(bit_kind), intent(in) :: hole_mask(N_int,2), particle_mask(N_int,2) + double precision, intent(in) :: fock_diag_tmp(mo_tot_num) + double precision, intent(in) :: E0(N_states) + double precision, intent(inout) :: pt2(N_states) + type(selection_buffer), intent(inout) :: buf + + double precision :: vect(N_states, mo_tot_num) + logical :: bannedOrb(mo_tot_num) + integer :: i, k + integer :: h1,h2,s1,s2,i1,i2,ib,sp + integer(bit_kind) :: hole(N_int,2), particle(N_int,2), mask(N_int, 2) + logical :: fullMatch, ok + + + do k=1,N_int + hole (k,1) = iand(psi_det_generators(k,1,i_generator), hole_mask(k,1)) + hole (k,2) = iand(psi_det_generators(k,2,i_generator), hole_mask(k,2)) + particle(k,1) = iand(not(psi_det_generators(k,1,i_generator)), particle_mask(k,1)) + particle(k,2) = iand(not(psi_det_generators(k,2,i_generator)), particle_mask(k,2)) + enddo + + ! Create lists of holes and particles + ! ----------------------------------- + + integer :: N_holes(2), N_particles(2) + integer :: hole_list(N_int*bit_kind_size,2) + integer :: particle_list(N_int*bit_kind_size,2) + + call bitstring_to_list_ab(hole , hole_list , N_holes , N_int) + call bitstring_to_list_ab(particle, particle_list, N_particles, N_int) + + + do sp=1,2 + do i=1, N_holes(sp) + h1 = hole_list(i,sp) + call apply_hole(psi_det_generators(1,1,i_generator), sp, h1, mask, ok, N_int) + + bannedOrb = .false. + + call spot_hasBeen(mask, sp, psi_det_sorted, i_generator, N_det, bannedOrb, fullMatch) + + if(fullMatch) cycle + call spot_occupied(mask, bannedOrb) + vect = 0d0 + call splash_p(mask, sp, psi_det_sorted(1,1,i_generator), N_det_selectors - i_generator + 1, bannedOrb, vect) + call fill_buffer_single(i_generator, sp, h1, bannedOrb, fock_diag_tmp, E0, vect, buf) + end do + enddo +end subroutine + + +subroutine fill_buffer_single(i_generator, sp, h1, bannedOrb, fock_diag_tmp, E0, vect, buf) + use bitmasks + use selection_types + implicit none + + integer, intent(in) :: i_generator, sp, h1 + double precision, intent(in) :: vect(N_states, mo_tot_num) + logical, intent(in) :: bannedOrb(mo_tot_num) + double precision, intent(in) :: fock_diag_tmp(mo_tot_num) + double precision, intent(in) :: E0(N_states) + type(selection_buffer), intent(inout) :: buf + logical :: ok + integer :: s1, s2, p1, p2, ib + integer(bit_kind) :: mask(N_int, 2), det(N_int, 2) + double precision :: e_pert, delta_E, val, Hii + double precision, external :: diag_H_mat_elem_fock + + if(N_states > 1) stop "fill_buffer_single N_states > 1" + + call apply_hole(psi_det_generators(1,1,i_generator), sp, h1, mask, ok, N_int) + + do p1=1,mo_tot_num + if(bannedOrb(p1)) cycle + if(vect(1, p1) == 0d0) cycle + call apply_particle(mask, s1, p1, det, ok, N_int) + val = vect(1, p1) + + Hii = diag_H_mat_elem_fock(psi_det_generators(1,1,i_generator),det,fock_diag_tmp,N_int) + + delta_E = E0(1) - Hii + if (delta_E < 0.d0) then + e_pert = 0.5d0 * (-dsqrt(delta_E * delta_E + 4.d0 * val * val) - delta_E) + else + e_pert = 0.5d0 * ( dsqrt(delta_E * delta_E + 4.d0 * val * val) - delta_E) + endif + if(dabs(e_pert) > buf%mini) call add_to_selection_buffer(buf, det, e_pert) + end do +end subroutine + + +subroutine splash_p(mask, sp, det, N_sel, bannedOrb, vect) + use bitmasks + implicit none + + integer(bit_kind),intent(in) :: mask(N_int, 2), det(N_int, 2, N_sel) + integer, intent(in) :: sp, N_sel + logical, intent(inout) :: bannedOrb(mo_tot_num) + double precision, intent(inout) :: vect(N_states, mo_tot_num) + + integer :: i, j, h(0:2,2), p(0:3,2), nt + integer(bit_kind) :: perMask(N_int, 2), mobMask(N_int, 2), negMask(N_int, 2) + + do i=1,N_int + negMask(i,1) = not(mask(i,1)) + negMask(i,2) = not(mask(i,2)) + end do + + do i=1, N_sel + nt = 0 + do j=1,N_int + mobMask(j,1) = iand(negMask(j,1), det(j,1,i)) + mobMask(j,2) = iand(negMask(j,2), det(j,2,i)) + nt += popcnt(mobMask(j, 1)) + popcnt(mobMask(j, 2)) + end do + + if(nt > 3) cycle + + do j=1,N_int + perMask(j,1) = iand(mask(j,1), not(det(j,1,i))) + perMask(j,2) = iand(mask(j,2), not(det(j,2,i))) + end do + + call bitstring_to_list(perMask(1,1), h(1,1), h(0,1), N_int) + call bitstring_to_list(perMask(1,2), h(1,2), h(0,2), N_int) + + call bitstring_to_list(mobMask(1,1), p(1,1), p(0,1), N_int) + call bitstring_to_list(mobMask(1,2), p(1,2), p(0,2), N_int) + + if(nt == 3) then + call get_m2(det(1,1,i), psi_phasemask(1,1,i), bannedOrb, vect, mask, h, p, sp, psi_selectors_coef_transp(1, i)) + else if(nt == 2) then + call get_m1(det(1,1,i), psi_phasemask(1,1,i), bannedOrb, vect, mask, h, p, sp, psi_selectors_coef_transp(1, i)) + else + call get_m0(det(1,1,i), psi_phasemask(1,1,i), bannedOrb, vect, mask, h, p, sp, psi_selectors_coef_transp(1, i)) + end if + end do +end subroutine + + +subroutine get_m2(gen, phasemask, bannedOrb, vect, mask, h, p, sp, coefs) + use bitmasks + implicit none + + integer(bit_kind), intent(in) :: gen(N_int, 2), phasemask(N_int, 2), mask(N_int, 2) + logical, intent(in) :: bannedOrb(mo_tot_num) + double precision, intent(in) :: coefs(N_states) + double precision, intent(inout) :: vect(N_states, mo_tot_num) + integer, intent(in) :: sp, h(0:2, 2), p(0:3, 2) + integer :: i, j, h1, h2, p1, p2, sfix, hfix, pfix, hmob, pmob, puti + double precision :: hij + double precision, external :: get_phase_bi + + + if(h(0,sp) == 2) then + h1 = h(1, sp) + h2 = h(2, sp) + do i=1,3 + p1 = p(mod(i,3) + 1, sp) + p2 = p(mod(i+1,3) + 1, sp) + hij = integral8(p1, p2, h1, h2) - integral8(p2, p1, h1, h2) + hij *= get_phase_bi(phasemask, sp, sp, h1, p1, h2, p2) + vect(:, p(i,sp)) += hij * coefs + end do + else if(h(0,sp) == 1) then + sfix = mod(sp,2)+1 + hfix = h(1,sfix) + pfix = p(1,sfix) + hmob = h(1,sp) + do j=1,2 + puti = p(j, sp) + pmob = p(mod(j,2)+1, sp) + hij = integral8(hfix, hmob, pfix, pmob) + hij *= get_phase_bi(phasemask, sp, sfix, hmob, pmob, hfix, pfix) + vect(:, puti) += hij * coefs + end do + else + puti = p(1,sp) + sfix = mod(sp,2)+1 + hij = integral8(p(1,sfix), p(2,sfix), h(1,sfix), h(2,sfix)) + hij *= get_phase_bi(phasemask, sfix, sfix, h(1,sfix), p(1,sfix), h(2,sfix), p(2,sfix)) + vect(:, puti) += hij * coefs + end if +end subroutine + + + +subroutine get_m1(gen, phasemask, bannedOrb, vect, mask, h, p, sp, coefs) + use bitmasks + implicit none + + integer(bit_kind), intent(in) :: gen(N_int, 2), phasemask(N_int, 2), mask(N_int, 2) + logical, intent(in) :: bannedOrb(mo_tot_num) + double precision, intent(in) :: coefs(N_states) + double precision, intent(inout) :: vect(N_states, mo_tot_num) + integer, intent(in) :: sp, h(0:2, 2), p(0:3, 2) + integer :: i, hole, p1, p2, sh + logical :: ok, lbanned(mo_tot_num) + integer(bit_kind) :: det(N_int, 2) + double precision :: hij + double precision, external :: get_phase_bi + + lbanned = bannedOrb + sh = 1 + if(h(0,2) == 1) sh = 2 + hole = h(1, sh) + p1 = p(1, sp) + lbanned(p1) = .true. + + if(sp == sh) then + p2 = p(2, sp) + lbanned(p2) = .true. + + do i=1,hole-1 + if(lbanned(i)) cycle + hij = (integral8(hole, i, p1, p2) - integral8(i, hole, p1, p2)) + hij *= get_phase_bi(phasemask, sp, sp, i, p1, hole, p2) + vect(:,i) += hij * coefs + end do + do i=hole+1,mo_tot_num + if(lbanned(i)) cycle + hij = (integral8(hole, i, p1, p2) - integral8(i, hole, p1, p2)) + hij *= get_phase_bi(phasemask, sp, sp, hole, p1, i, p2) + vect(:,i) += hij * coefs + end do + else + p2 = p(1, sh) + do i=1,mo_tot_num + if(lbanned(i)) cycle + hij = integral8(i,hole,p1,p2) + hij *= get_phase_bi(phasemask, sp, sh, i, p1, hole, p2) + vect(:,i) += hij * coefs + end do + end if + + !MONO + + call apply_particle(mask, sp, p1, det, ok, N_int) + call i_h_j(gen, det, N_int, hij) + vect(:, p1) += hij * coefs + + if(sp == sh) then + call apply_particle(mask, sp, p2, det, ok, N_int) + call i_h_j(gen, det, N_int, hij) + vect(:, p2) += hij * coefs + end if +end subroutine + + +subroutine get_m0(gen, phasemask, bannedOrb, vect, mask, h, p, sp, coefs) + use bitmasks + implicit none + + integer(bit_kind), intent(in) :: gen(N_int, 2), phasemask(N_int, 2), mask(N_int, 2) + logical, intent(in) :: bannedOrb(mo_tot_num) + double precision, intent(in) :: coefs(N_states) + double precision, intent(inout) :: vect(N_states, mo_tot_num) + integer, intent(in) :: sp, h(0:2, 2), p(0:3, 2) + integer :: i + logical :: ok, lbanned(mo_tot_num) + integer(bit_kind) :: det(N_int, 2) + double precision :: hij + + lbanned = bannedOrb + lbanned(p(1,sp)) = .true. + do i=1,mo_tot_num + if(lbanned(i)) cycle + call apply_particle(mask, sp, i, det, ok, N_int) + call i_h_j(gen, det, N_int, hij) + vect(1, i) = vect(1, i) + hij * coefs(1) + end do +end subroutine + + +subroutine spot_hasBeen(mask, sp, det, i_gen, N, banned, fullMatch) + use bitmasks + implicit none + + integer(bit_kind),intent(in) :: mask(N_int, 2), det(N_int, 2, N) + integer, intent(in) :: i_gen, N, sp + logical, intent(inout) :: banned(mo_tot_num) + logical, intent(out) :: fullMatch + + + integer :: i, j, na, nb, list(3), nt + integer(bit_kind) :: myMask(N_int, 2), negMask(N_int, 2) + + fullMatch = .false. + + do i=1,N_int + negMask(i,1) = not(mask(i,1)) + negMask(i,2) = not(mask(i,2)) + end do + + genl : do i=1, N + nt = 0 + + do j=1, N_int + myMask(j, 1) = iand(det(j, 1, i), negMask(j, 1)) + myMask(j, 2) = iand(det(j, 2, i), negMask(j, 2)) + nt += popcnt(myMask(j, 1)) + popcnt(myMask(j, 2)) + end do + + if(nt > 3) cycle + + if(nt <= 2 .and. i < i_gen) then + fullMatch = .true. + return + end if + + call bitstring_to_list(myMask(1,sp), list(1), na, N_int) + + if(nt == 3 .and. i < i_gen) then + do j=1,na + banned(list(j)) = .true. + end do + else if(nt == 1 .and. na == 1) then + banned(list(1)) = .true. + end if + end do genl +end subroutine + + diff --git a/src/Determinants/determinants.irp.f b/src/Determinants/determinants.irp.f index 258f5391..d0827f3b 100644 --- a/src/Determinants/determinants.irp.f +++ b/src/Determinants/determinants.irp.f @@ -774,7 +774,7 @@ subroutine apply_excitation(det, exc, res, ok, Nint) end subroutine -subroutine apply_particle(det, s1, p1, s2, p2, res, ok, Nint) +subroutine apply_particles(det, s1, p1, s2, p2, res, ok, Nint) use bitmasks implicit none integer, intent(in) :: Nint @@ -803,7 +803,7 @@ subroutine apply_particle(det, s1, p1, s2, p2, res, ok, Nint) end subroutine -subroutine apply_hole(det, s1, h1, s2, h2, res, ok, Nint) +subroutine apply_holes(det, s1, h1, s2, h2, res, ok, Nint) use bitmasks implicit none integer, intent(in) :: Nint @@ -831,3 +831,45 @@ subroutine apply_hole(det, s1, h1, s2, h2, res, ok, Nint) ok = .true. end subroutine +subroutine apply_particle(det, s1, p1, res, ok, Nint) + use bitmasks + implicit none + integer, intent(in) :: Nint + integer, intent(in) :: s1, p1 + integer(bit_kind),intent(in) :: det(Nint, 2) + integer(bit_kind),intent(out) :: res(Nint, 2) + logical, intent(out) :: ok + integer :: ii, pos + + ok = .false. + res = det + + ii = (p1-1)/bit_kind_size + 1 + pos = mod(p1-1, 64)!iand(p1-1,bit_kind_size-1) + if(iand(det(ii, s1), ishft(1_bit_kind, pos)) /= 0_8) return + res(ii, s1) = ibset(res(ii, s1), pos) + + ok = .true. +end subroutine + + +subroutine apply_hole(det, s1, h1, res, ok, Nint) + use bitmasks + implicit none + integer, intent(in) :: Nint + integer, intent(in) :: s1, h1 + integer(bit_kind),intent(in) :: det(Nint, 2) + integer(bit_kind),intent(out) :: res(Nint, 2) + logical, intent(out) :: ok + integer :: ii, pos + + ok = .false. + res = det + + ii = (h1-1)/bit_kind_size + 1 + pos = mod(h1-1, 64)!iand(h1-1,bit_kind_size-1) + if(iand(det(ii, s1), ishft(1_bit_kind, pos)) == 0_8) return + res(ii, s1) = ibclr(res(ii, s1), pos) + + ok = .true. +end subroutine \ No newline at end of file