calc_explicit_2_rdm_guga Subroutine

public subroutine calc_explicit_2_rdm_guga(ilut, csf_i, n_tot, excitations)

Arguments

Type IntentOptional Attributes Name
integer(kind=n_int), intent(in) :: ilut(0:GugaBits%len_tot)
type(CSF_Info_t), intent(in) :: csf_i
integer, intent(out) :: n_tot
integer(kind=n_int), intent(out), allocatable :: excitations(:,:)

Contents


Source Code

    subroutine calc_explicit_2_rdm_guga(ilut, csf_i, n_tot, excitations)
        integer(n_int), intent(in) :: ilut(0:GugaBits%len_tot)
        type(CSF_Info_t), intent(in) :: csf_i
        integer, intent(out) :: n_tot
        integer(n_int), intent(out), allocatable :: excitations(:, :)
        character(*), parameter :: this_routine = "calc_explicit_2_rdm_guga"

        integer :: i, j, k, l, nMax, ierr, n, n_excits
        integer(n_int), allocatable :: temp_excits(:, :), tmp_all_excits(:, :)

        nMax = 6 + 4 * (nSpatOrbs)**3 * (count_open_orbs(ilut) + 1)
        allocate(tmp_all_excits(0:GugaBits%len_tot, nMax), stat=ierr)
        call LogMemAlloc('tmp_all_excits', (GugaBits%len_tot + 1) * nMax, 8, this_routine, tag_tmp_excits)

        n_tot = 0
        do i = 1, nSpatOrbs
            do j = 1, nSpatOrbs
                do k = 1, nSpatOrbs
                    do l = 1, nSpatOrbs

                        ! pure diagonal contribution:
                        if (i == j .and. k == l) cycle

                        call calc_all_excits_guga_rdm_doubles(ilut, csf_i, i, j, k, l, &
                                                              temp_excits, n_excits)

#ifdef DEBUG_
                        do n = 1, n_excits
                            if (.not. isProperCSF_ilut(temp_excits(:, n), .true.)) then
                                print *, "===="
                                call write_det_guga(stdout, ilut, .true.)
                                call write_det_guga(stdout, temp_excits(:, n), .true.)
                                print *, i, j, k, l
                            end if
                            ASSERT(isProperCSF_ilut(temp_excits(:, n), .true.))
                        end do
#endif
                        if (i == l .and. j == k) then
                            ! exclude the diagonal exchange here,
                            ! as it is already accounted for in the
                            ! diagonal contribution routine
#ifdef DEBUG_
                            if (n_excits > 0) then
                                if (.not. DetBitEQ(ilut, temp_excits(:, 1), nifd)) then
                                    print *, "not equal!"
                                end if
                            end if
#endif

                            if (n_excits > 1) then
                                call add_guga_lists_rdm(n_tot, n_excits - 1, &
                                                        tmp_all_excits, temp_excits(:, 2:))
                            end if
                        else
                            if (n_excits > 0) then
                                call add_guga_lists_rdm(n_tot, n_excits, tmp_all_excits, temp_excits)
                            end if
                        end if

                        deallocate(temp_excits)

                    end do
                end do
            end do
        end do

        j = 1
        do i = 1, n_tot
            if (near_zero(extract_matrix_element(tmp_all_excits(:, i), 1))) cycle

            tmp_all_excits(:, j) = tmp_all_excits(:, i)

            j = j + 1

        end do

        n_tot = j - 1

        allocate(excitations(0:GugaBits%len_tot, n_tot), &
                  source=tmp_all_excits(0:GugaBits%len_tot, 1:n_tot), stat=ierr)

        ! hm to log that does not make so much sense.. since it gets called
        ! more than once and is only a temporary array..
        call LogMemAlloc('excitations', n_tot, 8, this_routine, tag_excitations)

        deallocate(tmp_all_excits)
        call LogMemDealloc(this_routine, tag_tmp_excits)

    end subroutine calc_explicit_2_rdm_guga