TestShakeConvergence Subroutine

public subroutine TestShakeConvergence(ConvergeCount, TotCorConstraints, ShakeIteration, tShakeNotConverged)

Arguments

Type IntentOptional Attributes Name
integer :: ConvergeCount
real(kind=dp) :: TotCorConstraints
integer :: ShakeIteration
logical :: tShakeNotConverged

Contents

Source Code


Source Code

    subroutine TestShakeConvergence(ConvergeCount, TotCorConstraints, ShakeIteration, tShakeNotConverged)

        ! This calculates the value of each orthonomalisation constraint using the corrected coefficients.
        ! Each of these should tend to 0 when the coefficients become orthonomal.
        ! CovergeCount counts the number of constraints that individually have values below the specified
        ! convergence criteria.  If this  =  0, the shake is converged, else keep iterating.

        integer :: l, i, j, m, a, ConvergeCount
        real(dp) :: TotCorConstraints
        integer :: ShakeIteration
        logical :: tShakeNotConverged

        TotCorConstraints = 0.0_dp
        ConvergeCount = 0
        ConstraintCor(:) = 0.0_dp
        do l = 1, TotNoConstraints
            i = lab(1, l)
            j = lab(2, l)
            if (i == j) then
                ConstraintCor(l) = Dot_Product(CoeffCorT2(:, i), CoeffCorT2(:, j)) - 1.0_dp
            else
                ! Each of these components should tend towards 0 when the
                ! coefficients become orthonormal.
                ConstraintCor(l) = Dot_Product(CoeffCorT2(:, i), CoeffCorT2(:, j))
            end if

            TotCorConstraints = TotCorConstraints + ABS(ConstraintCor(l))
            ! Sum of all Contraint components - indication of overall
            ! orthonormality.

            if (ABS(ConstraintCor(l)) > ShakeConverged) ConvergeCount = ConvergeCount + 1
            ! Count the number of constraints which are still well above 0.

        end do

        if (tShakeIter) then
            if (ShakeIteration == ShakeIterMax) then
                do m = 1, NoOrbs
                    do a = 1, NoOrbs
                        CoeffT1(a, m) = CoeffCorT2(a, m)
                    end do
                end do
                tShakeNotConverged = .false.
            end if
        else if (ConvergeCount == 0) then
            tShakeNotConverged = .false.

            ! If convergence is reached, make the new coefficients coeff, to
            ! start the rotation iteration again.

            do m = 1, NoOrbs
                do a = 1, NoOrbs
                    CoeffT1(a, m) = CoeffCorT2(a, m)
                end do
            end do
        end if

    end subroutine TestShakeConvergence