increase_ex_levl Function

private function increase_ex_levl(csf_i, excitInfo) result(flag)

Arguments

Type IntentOptional Attributes Name
type(CSF_Info_t), intent(in) :: csf_i
type(ExcitationInformation_t), intent(in) :: excitInfo

Return Value logical


Contents

Source Code


Source Code

    function increase_ex_levl(csf_i, excitInfo) result(flag)
        type(CSF_Info_t), intent(in) :: csf_i
        type(ExcitationInformation_t), intent(in) :: excitInfo
        logical :: flag
        character(*), parameter :: this_routine = "increase_ex_levl"

        integer :: elec_1, elec_2, orb_1, orb_2, orbs(2), elecs(2)
        integer :: d_elec, s_elec, d_orb, s_orb
        integer :: loc_elec, loc_orb

        flag = .true.

        ! first i need to check the location of the picked electrons.
        ! which also has to be adapted for chosen spatial orbitals
        if (excitInfo%typ == excit_type%single) then
            ! single excitation
            elec_1 = excitInfo%j
            orb_1 = excitInfo%i

            ! be general here and maybe a bit too cautious and check if
            ! any spin-orbtial in the reference is occupied
            loc_elec = check_electron_location_spatial([elec_1, 0], 1, 1)

            ! now we also want to check if the orbitals are in the
            ! virtual space of the reference det.
            loc_orb = check_orbital_location_spatial([orb_1, 0], 1, 1)

            flag = test_increase_on_loc(loc_elec, loc_orb, 1)

        else
            ! double excitations
            elec_1 = excitInfo%j
            elec_2 = excitInfo%l

            orb_1 = excitInfo%i
            orb_2 = excitInfo%k

            ! there is now a difference depending on some type of
            ! excitations
            select case (excitInfo%typ)
            case (excit_type%single_overlap_L_to_R, &
                  excit_type%fullstop_lowering, &
                  excit_type%fullstart_raising)

                ! here i know the spatial orbital indices are the same
                ASSERT(orb_1 == orb_2)
                ASSERT(csf_i%stepvector(orb_1) == 0)

                ! here check for spin-orbital as we know the occupation
                orbs = [2 * orb_1, 2 * orb_1 - 1]
                loc_orb = check_orbital_location(orbs, 2, 1)

                ! the electrons need to be specified generally
                ! but are there any spin-restrictions in this case?
                ! due to the possible spin-recouplings in CSFs maybe not..
                ! use a testing function for spatial orbitals
                loc_elec = check_electron_location_spatial([elec_1, elec_2], 2, 1)

                flag = test_increase_on_loc(loc_elec, loc_orb, 2)

            case (excit_type%single_overlap_R_to_L, &
                  excit_type%fullstop_raising, &
                  excit_type%fullstart_lowering)

                ! here i know both spatial electon indices are the same
                ASSERT(elec_1 == elec_2)
                ASSERT(csf_i%stepvector(elec_1) == 3)

                elecs = [2 * elec_1, 2 * elec_1 - 1]

                loc_elec = check_electron_location(elecs, 2, 1)

                loc_orb = check_orbital_location_spatial([orb_1, orb_2], 2, 1)

                flag = test_increase_on_loc(loc_elec, loc_orb, 2)

            case (excit_type%fullstop_L_to_R, &
                  excit_type%fullstop_R_to_L, &
                  excit_type%fullStart_L_to_R, &
                  excit_type%fullstart_R_to_L)

                ! here i know one electron and one hole index are the same
                ASSERT(elec_1 /= elec_2)
                ASSERT(orb_1 /= orb_2)

                ! the occupation in the overlap index does not change..
                ! so we could treat the differing indices as a single
                ! excitation or?
                if (elec_1 == orb_1) then

                    s_elec = elec_1
                    s_orb = orb_1

                    d_elec = elec_2
                    d_orb = orb_2

                else if (elec_1 == orb_2) then

                    s_elec = elec_1
                    s_orb = orb_1

                    d_elec = elec_2
                    d_orb = orb_1

                else if (elec_2 == orb_1) then

                    s_elec = elec_2
                    s_orb = orb_1

                    d_elec = elec_1
                    d_orb = orb_2

                else if (elec_2 == orb_2) then

                    s_elec = elec_2
                    s_orb = orb_2

                    d_elec = elec_1
                    d_orb = orb_1

                end if

                loc_elec = check_electron_location_spatial([d_elec, 0], 1, 1)
                loc_orb = check_orbital_location_spatial([d_orb, 0], 1, 1)

                flag = test_increase_on_loc(loc_elec, loc_orb, 1)

            case (excit_type%fullstart_stop_mixed)
                ! here i do not change the 'orbital excitation level'
                if (n_guga_back_spawn_lvl < 0) then
                    flag = .true.

                else
                    flag = .false.
                end if

            case default
                ! the general 4-index excitations..
                loc_elec = check_electron_location_spatial([elec_1, elec_2], 2, 1)
                loc_orb = check_orbital_location_spatial([orb_1, orb_2], 2, 1)

                flag = test_increase_on_loc(loc_elec, loc_orb, 2)

            end select
        end if

    end function increase_ex_levl