internal_check_orthonorm Subroutine

public subroutine internal_check_orthonorm(u_matrix_opt, ndimwin, num_kpts, num_wann, timing_level, on_root, timer, error, stdout, comm)

Uses

  • proc~~internal_check_orthonorm~~UsesGraph proc~internal_check_orthonorm internal_check_orthonorm module~w90_comms w90_comms proc~internal_check_orthonorm->module~w90_comms module~w90_constants w90_constants proc~internal_check_orthonorm->module~w90_constants module~w90_error w90_error proc~internal_check_orthonorm->module~w90_error module~w90_io w90_io proc~internal_check_orthonorm->module~w90_io module~w90_types w90_types proc~internal_check_orthonorm->module~w90_types module~w90_comms->module~w90_constants module~w90_error_base w90_error_base module~w90_comms->module~w90_error_base module~w90_error->module~w90_comms module~w90_error->module~w90_error_base module~w90_io->module~w90_constants module~w90_types->module~w90_constants

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.

Arguments

Type IntentOptional 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

Calls

proc~~internal_check_orthonorm~~CallsGraph proc~internal_check_orthonorm internal_check_orthonorm proc~io_stopwatch_start io_stopwatch_start proc~internal_check_orthonorm->proc~io_stopwatch_start proc~io_stopwatch_stop io_stopwatch_stop proc~internal_check_orthonorm->proc~io_stopwatch_stop proc~set_error_fatal set_error_fatal proc~internal_check_orthonorm->proc~set_error_fatal proc~comms_sync_error comms_sync_error proc~set_error_fatal->proc~comms_sync_error proc~set_base_error set_base_error proc~set_error_fatal->proc~set_base_error

Called by

proc~~internal_check_orthonorm~~CalledByGraph proc~internal_check_orthonorm internal_check_orthonorm proc~dis_main dis_main proc~dis_main->proc~internal_check_orthonorm proc~w90_disentangle~2 w90_disentangle proc~w90_disentangle~2->proc~dis_main proc~w90_disentangle w90_disentangle proc~w90_disentangle->proc~w90_disentangle~2 program~wannier wannier program~wannier->proc~w90_disentangle~2

Source Code

  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