sort_states_by_energy Subroutine

public subroutine sort_states_by_energy(ilut_list, num_states, tSortDoubles)

Arguments

Type IntentOptional Attributes Name
integer(kind=n_int), intent(inout) :: ilut_list(0:NIfTot,1:num_states)
integer, intent(in) :: num_states
logical, intent(in) :: tSortDoubles

Contents

Source Code


Source Code

    subroutine sort_states_by_energy(ilut_list, num_states, tSortDoubles)

        ! Note: If requested, keep all doubles at the top, then sort by energy.

        use DetBitOps, only: FindBitExcitLevel
        use FciMCData, only: ilutHF
        use sort_mod, only: sort

        integer, intent(in) :: num_states
        integer(n_int), intent(inout) :: ilut_list(0:NIfTot, 1:num_states)
        logical, intent(in) :: tSortDoubles
        integer(n_int) :: temp_ilut(0:NIfTot)
        integer :: nI(nel)
        integer :: i, excit_level, num_sing_doub, block_size
        real(dp) :: energies(num_states)

        do i = 1, num_states
            call decode_bit_det(nI, ilut_list(:, i))
            if (tHPHF) then
                energies(i) = hphf_diag_helement(nI, ilut_list(:, i))
            else
                energies(i) = get_helement(nI, nI, 0)
            end if
        end do

        ! Sort the states in order of energy, from smallest to largest.
        call sort(energies, ilut_list(0:NIfTot, 1:num_states))

        ! If requested, sort singles and doubles to the top, keeping the rest of
        ! the ordering the same.
        if (tSortDoubles) then
            num_sing_doub = 0
            block_size = 0
            do i = 1, num_states
                ! for GUGA this would have to be changed, but apparently this
                ! function is never called in the rest of the code so
                ! ignore it for now..
                excit_level = FindBitExcitLevel(ilut_list(:, i), ilutHF)
                if (excit_level <= 2) then
                    num_sing_doub = num_sing_doub + 1
                    temp_ilut = ilut_list(:, i)

                    ! Move block of non-singles or doubles down one in ilut_list.
                    ilut_list(:, num_sing_doub + 1:num_sing_doub + block_size) = &
                        ilut_list(:, num_sing_doub:num_sing_doub + block_size - 1)

                    ! Then move the single or double just found into the space
                    ! created above this block.
                    ilut_list(:, num_sing_doub) = temp_ilut
                else
                    block_size = block_size + 1
                end if
            end do
        end if

    end subroutine sort_states_by_energy