get_ex Function

private function get_ex(this, ind) result(ex)

Type Bound

cc_amplitude

Arguments

Type IntentOptional Attributes Name
class(cc_amplitude), intent(in) :: this
integer, intent(in) :: ind

Return Value integer, (2,this%order)


Contents

Source Code


Source Code

    function get_ex(this, ind) result(ex)
        ! this function gives the specific excitation, if present in the
        ! cc_amplitudes, which are encoded in a linear fashion
        ! with the convention that all the electron and orbital indices are
        ! always provided in an ordered(from lowest to highest) fashion
        class(cc_amplitude), intent(in) :: this
        integer, intent(in) :: ind
        integer :: ex(2, this%order)
        character(*), parameter :: this_routine = "get_ex"

        integer :: ij, ab, cum, i, j, a, b, nij

        ASSERT(ind > 0)
        select case (this%order)
        case (1)

            if (allocated(this%operators)) then
                ex = this%operators(ind, :, :)
                return
            end if

            ! fix this below if i want to actually encode that directly and
            ! not store the operators..
            ASSERT(ind <= nel * (nbasis - nel))

            ! it is a single excition so this is easy to decompose
            ! this decomposition depends on the encoding below!
            ex(2, 1) = mod(ind - 1, (nbasis - nel))
            ! lets hope the integer division is done correctly.. on all compilers
            ex(1, 1) = int((ind - ex(2, 1)) / (nbasis - nel)) + 1
            ! and modify by nel the orbital index again to get the real
            ! orbital index!
            ex(2, 1) = ex(2, 1) + nel + 1

        case (2)

            if (allocated(this%operators)) then
                ex = this%operators(ind, :, :)
                return
            end if

            ! fix this below if i want to actually encode that directly and
            ! not store the operators..
            call stop_all(this_routine, "still buggy for double excitations!")
            ! first we have to get ij, ab back:

            nij = nel * (nel - 1) / 2

            ab = mod(ind - 1, nij)
            ij = (ind - ab) / (nij) + 1

            ab = ab + 1

            ! then we have to get ij and ab from those indices in the same
            ! way
            ! but here it gets more tricky because we can just do the mod..
            ! maybe i have to store the indices in the end..
            i = 1
            cum = (nel - i)

            ! do a stupid sum..
            do while (cum < ij .and. i <= nel)
                i = i + 1
                cum = cum + (nel - i)
            end do

            j = ij + i - (cum - nel + i)

            ! and the same for ab
            a = 1
            cum = (nbasis - nel - a)
            do while (cum < ab .and. a <= (nbasis - nel))
                a = a + 1
                cum = cum + (nbasis - nel - a)
            end do

            b = ab + a - (cum - (nbasis - nel) + a)

            ex(1, :) = [i, j]
            ex(2, :) = [a, b] + nel

        case (3)
            ex = this%operators(ind, :, :)

        case default
            call stop_all(this_routine, "higher than cc_order 2 not yet implemented!")

        end select

    end function get_ex