This subroutine checks that the states in the columns of the final matrix U_opt are orthonormal at every k-point, i.e., that the matrix is unitary in the sense that conjg(U_opt).U_opt = 1 (but not U_opt.conjg(U_opt) = 1).
In particular, this checks whether the projected gaussians are indeed orthogonal to the frozen states, at those k-points where both are present in the trial subspace.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| complex(kind=dp), | intent(inout) | :: | u_matrix_opt(:,:,:) | |||
| integer, | intent(in) | :: | ndimwin(:) | |||
| integer, | intent(in) | :: | num_kpts | |||
| integer, | intent(in) | :: | num_wann | |||
| integer, | intent(in) | :: | timing_level | |||
| logical, | intent(in) | :: | on_root | |||
| type(timer_list_type), | intent(inout) | :: | timer | |||
| type(w90_error_type), | intent(out), | allocatable | :: | error | ||
| integer, | intent(in) | :: | stdout | |||
| type(w90_comm_type), | intent(in) | :: | comm |
subroutine internal_check_orthonorm(u_matrix_opt, ndimwin, num_kpts, num_wann, timing_level, & on_root, timer, error, stdout, comm) !================================================! ! !! This subroutine checks that the states in the columns of the !! final matrix U_opt are orthonormal at every k-point, i.e., !! that the matrix is unitary in the sense that !! conjg(U_opt).U_opt = 1 (but not U_opt.conjg(U_opt) = 1). !! !! In particular, this checks whether the projected gaussians !! are indeed orthogonal to the frozen states, at those k-points !! where both are present in the trial subspace. ! !================================================! use w90_comms, only: w90_comm_type use w90_constants, only: dp, cmplx_0, cmplx_1 use w90_constants, only: eps8 use w90_error use w90_io, only: io_stopwatch_start, io_stopwatch_stop use w90_types, only: timer_list_type implicit none ! arguments type(timer_list_type), intent(inout) :: timer type(w90_error_type), allocatable, intent(out) :: error type(w90_comm_type), intent(in) :: comm integer, intent(in) :: timing_level integer, intent(in) :: stdout integer, intent(in) :: num_kpts, num_wann integer, intent(in) :: ndimwin(:) ! (num_kpts) complex(kind=dp), intent(inout) :: u_matrix_opt(:, :, :) logical, intent(in) :: on_root ! local variables integer :: nkp, l, m, j complex(kind=dp) :: ctmp if (timing_level > 1) call io_stopwatch_start('dis: main: check_orthonorm', timer) do nkp = 1, num_kpts do l = 1, num_wann do m = 1, l ctmp = cmplx_0 do j = 1, ndimwin(nkp) ctmp = ctmp + conjg(u_matrix_opt(j, m, nkp))*u_matrix_opt(j, l, nkp) end do if (l .eq. m) then if (abs(ctmp - cmplx_1) .gt. eps8) then if (on_root) then write (stdout, '(3i6,2f16.12)') nkp, l, m, ctmp write (stdout, '(1x,a)') & 'The trial orbitals for disentanglement are not orthonormal' end if call set_error_fatal(error, 'Error in dis_main: check_orthonorm: orthonormal error 1', comm) return end if else if (abs(ctmp) .gt. eps8) then if (on_root) then write (stdout, '(3i6,2f16.12)') nkp, l, m, ctmp write (stdout, '(1x,a)') & 'The trial orbitals for disentanglement are not orthonormal' end if call set_error_fatal(error, 'Error in dis_main: check_orthonorm: orthonormal error 2', comm) return end if end if end do end do end do if (timing_level > 1) call io_stopwatch_stop('dis: main: check_orthonorm', timer) return !================================================! end subroutine internal_check_orthonorm