setup_ind_matrix_doubles Subroutine

private subroutine setup_ind_matrix_doubles()

Arguments

None

Contents


Source Code

    subroutine setup_ind_matrix_doubles()
        character(*), parameter :: this_routine = "setup_ind_matrix_doubles"

        integer :: n_elec_pairs, i, j, a, b, elec_i, elec_j
        integer :: ij, ab, orb_a, orb_b, k
        logical :: t_par
        integer(n_int) :: temp_ilut(0:nifd)

        ASSERT(allocated(projedet))
        ASSERT(allocated(iLutRef))

        nvirt = nbasis - nel
        n_virt_pairs = nvirt * (nvirt - 1) / 2
        n_elec_pairs = nel * (nel - 1) / 2

        call setup_virtual_mask()

        call setup_elec_ind_mat()
        call setup_orb_ind_mat()

        ! encode only the possible excitations from the closed shell
        ! reference!
        ! i < j; a < b and (i,j) /= (a,b)

        ASSERT(n_elec_pairs == ElecPairs)

        allocate(ind_matrix_doubles(n_elec_pairs, n_virt_pairs))
        ind_matrix_doubles = 0

        temp_ilut = iLutRef(0:nifd, 1)
        k = 1

        ! i could also just loop over the reference determinant..
        do i = 1, nel
            elec_i = projedet(i, 1)
            do j = i + 1, nel
                elec_j = projedet(j, 1)

                t_par = same_spin(elec_i, elec_j)

                ! i have to convert (i,j) -> to a linear index
                ! and i definetly have to use the actual spin orbitals,
                ! since this is the quantity we have access to in the rest of
                ! the calculation
                ij = linear_elec_ind(elec_i, elec_j)
                ! maybe here i could to a check if ij = 0 ?

                ASSERT(ij > 0)
                ASSERT(ij <= ElecPairs)

                ! now i have to check if the orbitals fit and if the spin
                ! fits!
                ! use the virtual mask from back-spawn!
                if (t_par) then
                    do a = 1, Nvirt
                        orb_a = mask_virt_ni(a, 1)
                        do b = a + 1, Nvirt
                            orb_b = mask_virt_ni(b, 1)

                            if (same_spin(orb_a, orb_b) .and. same_spin(orb_a, elec_i)) then
                                ab = linear_orb_ind(orb_a, orb_b)
                                ASSERT(ab > 0)
                                ASSERT(ab <= n_virt_pairs)

                                ind_matrix_doubles(ij, ab) = k
                                k = k + 1

                            end if
                        end do
                    end do
                else
                    do a = 1, nvirt
                        orb_a = mask_virt_ni(a, 1)
                        do b = a + 1, nvirt
                            orb_b = mask_virt_ni(b, 1)
                            if (.not. same_spin(orb_a, orb_b)) then
                                ab = linear_orb_ind(orb_a, orb_b)

                                ASSERT(ab > 0)
                                ASSERT(ab <= n_virt_pairs)

                                ind_matrix_doubles(ij, ab) = k
                                k = k + 1
                            end if
                        end do
                    end do
                end if
            end do
        end do

    end subroutine setup_ind_matrix_doubles