subroutine FullShake()
! This method calculates the lambdas by solving the full matrix
! equation.
integer :: l, n, m, info, ipiv(TotNoConstraints)
character(len=*), parameter :: this_routine = 'FullShake'
call set_timer(FullShake_Time, 30)
! FULL MATRIX INVERSION METHOD
! Calculate matrix from the derivatives of the constraints w.r.t the the coefficients at t1 and t2. I.e. the initial
! coefficients and those that have been moved by the corrected force.
DerivConstrT1T2(:, :) = 0.0_dp
do l = 1, TotNoConstraints
do n = 1, TotNoConstraints
do m = 1, NoOrbs
! Product of constraint i, j at time t1, mult by constraint l, n.
! Add these over all m for a specific constraints to get matrix elements
DerivConstrT1T2(n, l) = DerivConstrT1T2(n, l) + (Dot_Product(DerivConstrT2(:, m, l), DerivConstrT1(:, m, n)))
end do
end do
end do ! have filled up whole matrix
! Invert the matrix to calculate the lambda values.
! LU decomposition.
call dgetrf(TotNoConstraints, TotNoConstraints, DerivConstrT1T2, TotNoConstraints, ipiv, info)
if (info /= 0) then
write(stdout, *) 'info ', info
call Stop_All(this_routine, "The LU decomposition of matrix inversion failed...")
end if
do n = 1, TotNoConstraints
ShakeLambdaNew(n) = Constraint(n) / (TimeStep * (-1))
end do
! These are actually still the constraint values, but now Lambda(n)
! can go into dgetrs as the constraints (B in AX = B), and come out
! as the computed lambdas (X).
call dgetrs('N', TotNoConstraints, 1, DerivConstrT1T2, TotNoConstraints, ipiv, ShakeLambdaNew, TotNoConstraints, info)
if (info /= 0) call Stop_All(this_routine, "Error in dgetrs, solving for the lambdas...")
call halt_timer(FullShake_Time)
end subroutine FullShake