remove_high_energy_orbs Subroutine

public subroutine remove_high_energy_orbs(ilut_list, num_states, target_num_states, tParallel)

Arguments

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

Contents


Source Code

    subroutine remove_high_energy_orbs(ilut_list, num_states, target_num_states, tParallel)

        use Parallel_neci, only: MPISumAll
        use sort_mod, only: sort
        use SystemData, only: nBasis, BRR, Arr

        integer, intent(inout) :: num_states
        integer(n_int), intent(inout) :: ilut_list(0:NIfTot, 1:num_states)
        integer, intent(in) :: target_num_states
        logical, intent(in) :: tParallel
        integer, allocatable, dimension(:) :: orbitals_rmvd
        integer :: i, j, orb, num_orbs_rmvd
        integer :: bit, elem
        integer :: states_rmvd_this_proc, counter
        integer(MPIArg) :: tot_num_states, states_rmvd_all_procs
        logical :: occupied

        states_rmvd_this_proc = 0
        num_orbs_rmvd = 0

        if (tParallel) then
            call MPISumAll(int(num_states, MPIArg), tot_num_states)
        else
            tot_num_states = int(num_states, MPIArg)
        end if

        if (tot_num_states <= target_num_states) return

        write(stdout, '(a32)') "Removing high energy orbitals..."

        ! Loop through all orbitals, from highest energy to lowest.
        do i = nBasis, 1, -1

            num_orbs_rmvd = nBasis - i + 1

            orb = BRR(i)

            bit = mod(orb - 1, bits_n_int)
            elem = (orb - 1 - bit) / bits_n_int

            ! Loop through all states and remove those states with orbital orb
            ! occupied.
            do j = 1, num_states
                occupied = btest(ilut_list(elem, j), bit)
                if (occupied) then
                    ilut_list(:, j) = 0_n_int
                    states_rmvd_this_proc = states_rmvd_this_proc + 1
                end if
            end do

            if (tParallel) then
                call MPISumAll(int(states_rmvd_this_proc, MPIArg), states_rmvd_all_procs)
            else
                states_rmvd_all_procs = int(states_rmvd_this_proc, MPIArg)
            end if

            ! If there are degenerate orbitals, then cycle to remove the
            ! degenerate orbitals too, before giving the program chance to quit.
            if (i > 1) then
                ! If the orbitals energies are the same:
                if (abs(Arr(i, 1) - Arr((i - 1), 1)) < 1.0e-12_dp) cycle
            end if

            if (tot_num_states - states_rmvd_all_procs <= target_num_states) exit

        end do

        ! Loop through the list and shuffle states down to fill in the gaps
        ! created above.
        counter = 0
        do i = 1, num_states
            ! If the state wasn't set to 0:
            if (.not. all(ilut_list(:, i) == 0_n_int)) then
                counter = counter + 1
                ilut_list(:, counter) = ilut_list(:, i)
            end if
        end do
        if (counter /= num_states - states_rmvd_this_proc) &
            call stop_all("remove_high_energy_orbs", &
                          "Wrong number of states found.")
        num_states = counter

        ! Finally, output information:
        write(stdout, '(a36)', advance='no') "The following orbitals were removed:"
        allocate(orbitals_rmvd(num_orbs_rmvd))
        orbitals_rmvd = BRR(nBasis - num_orbs_rmvd + 1:nBasis)
        call sort(orbitals_rmvd)
        do i = 1, num_orbs_rmvd
            write(stdout, '(i5)', advance='no') orbitals_rmvd(i)
            if (i == num_orbs_rmvd) write(stdout, '()', advance='yes')
        end do
        deallocate(orbitals_rmvd)
        write(stdout, '(i6,1x,a29)') states_rmvd_all_procs, "states were removed in total."
        write(stdout, '(i6,1x,a17)') tot_num_states - states_rmvd_all_procs, "states were kept."
        call neci_flush(stdout)

    end subroutine remove_high_energy_orbs