SetUpSymLabels_RDM Subroutine

public subroutine SetUpSymLabels_RDM()

Arguments

None

Contents

Source Code


Source Code

    subroutine SetUpSymLabels_RDM()

        ! This routine just sets up the symmetry labels so that the orbitals
        ! are ordered according to symmetry (all beta then all alpha if spin orbs).

        use rdm_data, only: tOpenShell
        use RotateOrbsData, only: SymLabelList2_rot, SymLabelCounts2_rot, SymLabelListInv_rot
        use RotateOrbsData, only: NoOrbs, SpatOrbs, NoSymLabelCounts
        use sort_mod, only: sort
        use SystemData, only: G1, BRR, lNoSymmetry, tFixLz, iMaxLz
        use UMatCache, only: gtID
        use MemoryManager, only: LogMemAlloc, LogMemDealloc

        integer, allocatable :: SymOrbs_rot(:)
        integer :: SymOrbs_rotTag, ierr, i, j, SpatSym, LzSym
        integer :: lo, hi, Symi, SymCurr, Symi2, SymCurr2
        character(len=*), parameter :: t_r = 'SetUpSymLabels_RDM'

        ! This is only allocated temporarily to be used to order the orbitals by.
        allocate(SymOrbs_rot(NoOrbs), stat=ierr)
        call LogMemAlloc('SymOrbs_rot', NoOrbs, 4, t_r, SymOrbs_rotTag, ierr)
        if (ierr /= 0) call stop_all(t_r, "Mem allocation for SymOrbs_rot failed.")

        ! Now we want to put the spatial orbital index, followed by the symmetry.
        SymLabelList2_rot(:) = 0
        SymOrbs_rot(:) = 0

        ! *** STEP 1 *** Fill SymLabelList2_rot.
        ! Find the orbitals and order them in terms of symmetry.
        do i = 1, SpatOrbs
            if (tOpenShell) then
                ! For open shell systems, all alpha are followed by all beta.
                SymLabelList2_rot(i) = BRR(2 * i)
                SymLabelList2_rot(i + SpatOrbs) = BRR((2 * i) - 1)

                if (tFixLz) then
                    SpatSym = int(G1(BRR(2 * i))%sym%S)
                    LzSym = int(G1(BRR(2 * i))%Ml)
                    SymOrbs_rot(i) = (SpatSym * ((2 * iMaxLz) + 1)) + (LzSym + iMaxLz)

                    SpatSym = int(G1(BRR((2 * i) - 1))%sym%S)
                    LzSym = int(G1(BRR((2 * i) - 1))%Ml)
                    SymOrbs_rot(i + SpatOrbs) = (SpatSym * ((2 * iMaxLz) + 1)) + (LzSym + iMaxLz)
                else
                    SymOrbs_rot(i) = int(G1(BRR(2 * i))%sym%S)
                    SymOrbs_rot(i + SpatOrbs) = int(G1(BRR((2 * i) - 1))%sym%S)
                end if
            else
                SymLabelList2_rot(i) = gtID(BRR(2 * i))
                if (tFixLz) then
                    SpatSym = int(G1(BRR(2 * i))%sym%S)
                    LzSym = int(G1(BRR(2 * i))%Ml)
                    SymOrbs_rot(i) = (SpatSym * ((2 * iMaxLz) + 1)) + (LzSym + iMaxLz)
                else
                    SymOrbs_rot(i) = int(G1(BRR(2 * i))%sym%S)
                end if
                ! Orbital BRR(2*i) for i = 1 will be the beta orbital with the
                ! second lowest energy - want the spatial orbital index to go with this.
                ! G1 also in spin orbitals - get symmetry of this beta orbital, will
                ! be the same as the spatial orbital.
            end if
        end do

        call sort(SymOrbs_rot(1:SpatOrbs), SymLabelList2_rot(1:SpatOrbs))
        ! Sorts SymLabelList2_rot according to the order of SymOrbs_rot
        ! (i.e. in terms of symmetry).
        if (tOpenShell) &
            call sort(SymOrbs_rot(SpatOrbs + 1:nBasis), SymLabelList2_rot(SpatOrbs + 1:nBasis))
        ! Also do this for the beta set if spin orbitals.

        ! *** STEP 2 *** Fill SymLabelCounts2_rot_rot. This is like
        ! SymLabelCounts2_rot, but has a different ordering - BEWARE.
        ! SymLabelCounts(1,:) contains the position in SymLabelList2_rot
        ! where the symmetry index starts, SymLabelCounts(2,:) contains the
        ! number of orbitals in that symmetry index. Again if spin orbs, all
        ! alpha are followed by all beta - i.e. first 8 refer to alpha, second
        ! 8 to beta.

        if (lNoSymmetry) then
            ! If we are ignoring symmetry, all orbitals essentially have
            ! symmetry 0.
            SymLabelCounts2_rot(1, 1) = 1
            SymLabelCounts2_rot(2, 1) = SpatOrbs
            if (tOpenShell) then
                SymLabelCounts2_rot(1, 9) = SpatOrbs + 1
                SymLabelCounts2_rot(2, 9) = SpatOrbs
            end if
        else
            ! Otherwise we run through the occupied orbitals, counting the
            ! number with each symmetry (spatial and Lz) and noting where in
            ! SymLabelList2_rot each symmetry block starts.
            SymCurr = 0
            SymLabelCounts2_rot(1, 1) = 1
            if (tOpenShell) then
                SymCurr2 = 0
                SymLabelCounts2_rot(1, 9) = SpatOrbs + 1
            end if
            do i = 1, SpatOrbs
                if (tOpenShell) then
                    Symi = SymOrbs_rot(i)
                    Symi2 = SymOrbs_rot(i + SpatOrbs)
                else
                    Symi = SymOrbs_rot(i)
                end if
                SymLabelCounts2_rot(2, (Symi + 1)) = SymLabelCounts2_rot(2, (Symi + 1)) + 1
                if (Symi /= SymCurr) then
                    do j = SymCurr + 1, Symi
                        SymLabelCounts2_rot(1, (j + 1)) = i
                    end do
                    SymCurr = Symi
                end if
                if (tOpenShell) then
                    SymLabelCounts2_rot(2, (Symi2 + 9)) = SymLabelCounts2_rot(2, (Symi2 + 9)) + 1
                    if (Symi2 /= SymCurr2) then
                        do j = SymCurr2 + 1, Symi2
                            SymLabelCounts2_rot(1, (j + 9)) = i + SpatOrbs
                        end do
                        SymCurr2 = Symi2
                    end if
                end if
            end do
        end if

        ! Go through each symmetry group, making sure the orbitals are
        ! ordered lowest to highest within each symmetry.
        do i = 1, NoSymLabelCounts
            if (SymLabelCounts2_rot(2, i) /= 0) then
                lo = SymLabelCounts2_rot(1, i)
                hi = lo + SymLabelCounts2_rot(2, i) - 1
                call sort(SymLabelList2_rot(lo:hi))
            end if
        end do

        ! Construct the inverse matrix. While SymLabelList2_rot takes a
        ! position and tells us what orbital is in it, we also might need to
        ! take an orbital and find out what position to put its contribution in.
        do i = 1, NoOrbs
            SymLabelListInv_rot(SymLabelList2_rot(i)) = i
        end do

        ! Deallocate the arrays just used in this routine.
        deallocate(SymOrbs_rot)
        call LogMemDealloc(t_r, SymOrbs_rotTag)

    end subroutine SetUpSymLabels_RDM