combine_spin_basis Function

public function combine_spin_basis(n_orbs, n_first, n_second, n_total, first_basis, t_sort, n_doubles) result(spin_basis)

Arguments

Type IntentOptional Attributes Name
integer, intent(in) :: n_orbs
integer, intent(in) :: n_first
integer, intent(in) :: n_second
integer, intent(in) :: n_total
integer(kind=n_int), intent(in) :: first_basis(:)
logical, intent(in) :: t_sort
integer, intent(in), optional :: n_doubles

Return Value integer(kind=n_int), (0:0,n_total)


Contents

Source Code


Source Code

    function combine_spin_basis(n_orbs, n_first, n_second, n_total, first_basis, &
                                t_sort, n_doubles) result(spin_basis)
        ! function to combine a already given spin-basis with the second one
        ! with the additional option to specify the number of doubly occupied
        ! determinants..
        ! n_orbs   ...  is the number of spatial orbitals
        ! n_first  ...  number of spins, with which first_basis was created
        ! n_second ...  number of spins with which basis is combined now
        ! n_total  ...  total size of basis for given number of doubly occ. sites!
        ! first_basis . already contructed one-spin basis
        ! t_sort   ...  should the basis be sorted. (after combination i am not  sure it will be sorted..
        ! n_doubles ..  (optional:) number of doubly occupied sites(has to fit with n_total!)
        integer, intent(in) :: n_orbs, n_first, n_second, n_total
        integer(n_int), intent(in) :: first_basis(:)
        logical, intent(in) :: t_sort
        integer, intent(in), optional :: n_doubles
        integer(n_int) :: spin_basis(0:0, n_total)
        character(*), parameter :: this_routine = "combine_spin_basis"
#ifdef DEBUG_
        integer, allocatable :: n_dets(:)
#endif
        integer :: n_doub, i, j, n_remain, n
        integer(n_int), allocatable :: second_basis(:)

        ! the half-filled case is the most easy one.. should we treat it
        ! special? maybe..

        ! ASSERT(n_first >= n_second)
#ifdef DEBUG_
        ! be sure that the provided n_total fits with the n_doubles if
        ! provided
        n_dets = calc_n_double(n_orbs, n_first, n_second)
        if (present(n_doubles)) then
            ASSERT(n_dets(n_doubles + 1) == n_total)
        else
            ! n_doubles = 0 is the default
            ASSERT(n_dets(1) == n_total)
        end if
#endif

        ! default value of n_doubles = 0
        if (present(n_doubles)) then
            n_doub = n_doubles
        else
            n_doub = 0
        end if

        ! do the n_double = 0 and half-filled case first, thats the
        ! easiest and only necessary for now..
        select case (n_doub)
        case (0)

            if (n_first + n_second == n_orbs) then
                ! if (n_first == n_orbs) then
                !
                ! else
                    ! half-filled case: easiest
                    ! since ms is not important, just convert the already
                    ! calculated spin-basis to a spin-orbital basis:
                    ! 0011 -> 00 00 01 01 eg.
                    do i = 1, n_total
                        ! do have it ordered -> first set the beta spins on the left
                        spin_basis(:,i) = set_alpha_beta_spins(first_basis(i), n_orbs, .false.)
                        ! and combine it with the alpha spins..
                        spin_basis(:,i) = ieor(spin_basis(:,i), set_alpha_beta_spins(not(first_basis(i)), n_orbs, .true.))
                    end do
                ! end if
            else
                ! we have to distribute the n_second remaining spins
                ! across the n_orbs - n_first orbitals, so there are:
                n_remain = int(choose_i64(n_orbs - n_first, n_second))
                ! states per first_basis states
                ASSERT(n_remain * size(first_basis) == n_total)

                second_basis = create_one_spin_basis(n_orbs - n_first, n_second)

                ! i want to do some sort of tensor product here:
                ! |0011> x |01> = |00 10 01 01>
                ! |0011> x |10> = |10 00 01 01>
                n = 1
                do i = 1, size(first_basis)
                    do j = 1, size(second_basis)
                        spin_basis(:,n) = open_shell_product(first_basis(i), second_basis(j), n_orbs)
                        n = n + 1
                    end do
                end do

            end if

        case default

            ! i should not need a select case here.. this gets to
            ! complicated..
            ! it is similar to non-half filled actually..
            if (n_first + n_second == n_orbs) then
                ! then we have the half-filled case..
            else

            end if

            ! not yet implemented
            call stop_all(this_routine, "not yet implemented!")

        end select

        ! do i want to sort it??
        if (t_sort) then
            call sort(spin_basis)
        end if

    end function combine_spin_basis