symmetrize_ukirr Subroutine

private subroutine symmetrize_ukirr(num_wann, num_bands, ir, ndim, umat, sitesym, stdout, error, comm, n)

Uses

  • proc~~symmetrize_ukirr~~UsesGraph proc~symmetrize_ukirr symmetrize_ukirr module~w90_error w90_error proc~symmetrize_ukirr->module~w90_error module~w90_wannier90_types w90_wannier90_types proc~symmetrize_ukirr->module~w90_wannier90_types module~w90_comms w90_comms module~w90_error->module~w90_comms module~w90_error_base w90_error_base module~w90_error->module~w90_error_base module~w90_constants w90_constants module~w90_wannier90_types->module~w90_constants module~w90_comms->module~w90_constants module~w90_comms->module~w90_error_base

Arguments

Type IntentOptional Attributes Name
integer, intent(in) :: num_wann
integer, intent(in) :: num_bands
integer, intent(in) :: ir
integer, intent(in) :: ndim
complex(kind=dp), intent(inout) :: umat(ndim,num_wann)
type(sitesym_type), intent(in) :: sitesym
integer, intent(in) :: stdout
type(w90_error_type), intent(out), allocatable :: error
type(w90_comm_type), intent(in) :: comm
integer, intent(in), optional :: n

Calls

proc~~symmetrize_ukirr~~CallsGraph proc~symmetrize_ukirr symmetrize_ukirr proc~orthogonalize_u orthogonalize_u proc~symmetrize_ukirr->proc~orthogonalize_u proc~set_error_fatal set_error_fatal proc~symmetrize_ukirr->proc~set_error_fatal proc~set_error_unconv set_error_unconv proc~symmetrize_ukirr->proc~set_error_unconv zgemm zgemm proc~symmetrize_ukirr->zgemm proc~orthogonalize_u->proc~set_error_fatal proc~set_error_dealloc set_error_dealloc proc~orthogonalize_u->proc~set_error_dealloc zgesvd zgesvd proc~orthogonalize_u->zgesvd 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 proc~set_error_unconv->proc~comms_sync_error proc~set_error_unconv->proc~set_base_error proc~set_error_dealloc->proc~comms_sync_error proc~set_error_dealloc->proc~set_base_error

Called by

proc~~symmetrize_ukirr~~CalledByGraph proc~symmetrize_ukirr symmetrize_ukirr proc~sitesym_dis_extract_symmetry sitesym_dis_extract_symmetry proc~sitesym_dis_extract_symmetry->proc~symmetrize_ukirr proc~sitesym_symmetrize_u_matrix sitesym_symmetrize_u_matrix proc~sitesym_symmetrize_u_matrix->proc~symmetrize_ukirr proc~dis_extract dis_extract proc~dis_extract->proc~sitesym_dis_extract_symmetry proc~dis_extract->proc~sitesym_symmetrize_u_matrix proc~dis_main dis_main proc~dis_main->proc~sitesym_symmetrize_u_matrix proc~dis_main->proc~dis_extract proc~internal_find_u internal_find_u proc~dis_main->proc~internal_find_u proc~internal_find_u->proc~sitesym_symmetrize_u_matrix proc~overlap_project overlap_project proc~overlap_project->proc~sitesym_symmetrize_u_matrix proc~w90_disentangle~2 w90_disentangle proc~w90_disentangle~2->proc~dis_main proc~w90_project_overlap~2 w90_project_overlap proc~w90_project_overlap~2->proc~overlap_project proc~w90_disentangle w90_disentangle proc~w90_disentangle->proc~w90_disentangle~2 proc~w90_project_overlap w90_project_overlap proc~w90_project_overlap->proc~w90_project_overlap~2 program~wannier wannier program~wannier->proc~w90_disentangle~2 program~wannier->proc~w90_project_overlap~2

Source Code

  subroutine symmetrize_ukirr(num_wann, num_bands, ir, ndim, umat, &
                              sitesym, stdout, error, comm, n)
    !================================================!
    !
    !  calculate u~(k)=1/N_{R'} \sum_{R'} d^{+}(R',k) u(k) D(R',k)
    !  where R'k = k
    !  and orthonormalize it
    !
    !================================================!

    use w90_wannier90_types, only: sitesym_type
    use w90_error, only: w90_error_type, set_error_fatal, set_error_unconv
    implicit none

    ! arguments
    type(sitesym_type), intent(in) :: sitesym
    type(w90_comm_type), intent(in) :: comm
    type(w90_error_type), allocatable, intent(out) :: error

    integer, intent(in) :: ir, ndim
    integer, intent(in) :: num_bands
    integer, intent(in) :: num_wann
    integer, intent(in) :: stdout
    integer, optional, intent(in) :: n

    complex(kind=dp), intent(inout) :: umat(ndim, num_wann)

    ! local variables
    integer :: isym, ngk, i, iter, ntmp
    integer, parameter :: niter = 100
    real(kind=dp)    :: diff
    complex(kind=dp) :: usum(ndim, num_wann)
    complex(kind=dp) :: cmat_sub(ndim, num_wann)
    complex(kind=dp) :: cmat(ndim, num_wann)
    complex(kind=dp) :: cmat2(num_wann, num_wann)

    !write(stdout,"(a)") '-- symmetrize_ukirr --'
    if (present(n)) then
      if (ndim .ne. num_bands) then
        call set_error_fatal(error, 'ndim!=num_bands', comm)
        return
      end if
      ntmp = n
    else
      if (ndim .ne. num_wann) then
        call set_error_fatal(error, 'ndim!=num_wann', comm)
        return
      end if
      ntmp = ndim
    end if

    ngk = count(sitesym%kptsym(:, ir) .eq. sitesym%ir2ik(ir))
    if (ngk .eq. 1) then
      call orthogonalize_u(ndim, num_wann, umat, ntmp, error, comm)
      return
    end if

    do iter = 1, niter
      usum(:, :) = 0
      cmat2(:, :) = 0
      do i = 1, num_wann
        cmat2(i, i) = cmat2(i, i) + ngk
      end do
      do isym = 1, sitesym%nsymmetry
        if (sitesym%kptsym(isym, ir) .ne. sitesym%ir2ik(ir)) cycle
        !
        ! cmat = d^{+}(R,k) U(k) D(R,k)
        ! size of umat: umat(ndim,num_wann)
        !
        ! cmat_sub = U(k) D(R,k)
        call zgemm('N', 'N', ntmp, num_wann, num_wann, cmplx_1, umat, ndim, &
                   sitesym%d_matrix_wann(:, :, isym, ir), num_wann, cmplx_0, cmat_sub, ndim)
        ! cmat = d^{+}(R,k) * cmat_sub
        call zgemm('C', 'N', ntmp, num_wann, ntmp, cmplx_1, sitesym%d_matrix_band(:, :, isym, ir), &
                   ndim, cmat_sub, ndim, cmplx_0, cmat, ndim)

        usum(:, :) = usum(:, :) + cmat(:, :)
        ! check
        cmat2(:, :) = cmat2(:, :) - &
                      matmul(conjg(transpose(umat(:ntmp, :))), cmat(:ntmp, :))
      end do ! isym
      diff = sum(abs(cmat2))
      if (diff .lt. sitesym%symmetrize_eps) exit
      if (iter .eq. niter) then
        write (stdout, "(a)") 'Error in symmetrize_u: not converged'
        write (stdout, "(a)") 'Either eps is too small or specified irreps is not'
        write (stdout, "(a)") '  compatible with the bands'
        write (stdout, "(a,2e20.10)") 'diff,eps=', diff, sitesym%symmetrize_eps
        call set_error_unconv(error, 'symmetrize_ukirr: not converged', comm)
        return
      end if
      usum = usum/ngk
      call orthogonalize_u(ndim, num_wann, usum, ntmp, error, comm)
      if (allocated(error)) return

      umat(:, :) = usum
    end do ! iter

    return
  end subroutine symmetrize_ukirr