get_HH_R Subroutine

public subroutine get_HH_R(dis_manifold, kpt_latt, print_output, wigner_seitz, HH_R, u_matrix, v_matrix, eigval, real_lattice, scissors_shift, num_bands, num_kpts, num_wann, num_valence_bands, effective_model, have_disentangled, seedname, ws_distance, ws_region, stdout, timer, error, comm)

Uses

  • proc~~get_hh_r~~UsesGraph proc~get_hh_r get_HH_R module~w90_postw90_types w90_postw90_types proc~get_hh_r->module~w90_postw90_types module~w90_types w90_types proc~get_hh_r->module~w90_types module~w90_comms w90_comms module~w90_postw90_types->module~w90_comms module~w90_constants w90_constants module~w90_postw90_types->module~w90_constants module~w90_types->module~w90_constants module~w90_comms->module~w90_constants module~w90_error_base w90_error_base module~w90_comms->module~w90_error_base

computes <0n|H|Rm>, in eV (pwscf uses Ry, but pw2wannier90 converts to eV)

Arguments

Type IntentOptional Attributes Name
type(dis_manifold_type), intent(in) :: dis_manifold
real(kind=dp), intent(in) :: kpt_latt(:,:)
type(print_output_type), intent(in) :: print_output
type(wigner_seitz_type), intent(inout) :: wigner_seitz
complex(kind=dp), intent(inout), allocatable :: HH_R(:,:,:)
complex(kind=dp), intent(in) :: u_matrix(:,:,:)
complex(kind=dp), intent(in) :: v_matrix(:,:,:)
real(kind=dp), intent(in) :: eigval(:,:)
real(kind=dp), intent(in) :: real_lattice(3,3)
real(kind=dp), intent(in) :: scissors_shift
integer, intent(in) :: num_bands
integer, intent(in) :: num_kpts
integer, intent(in) :: num_wann
integer, intent(in) :: num_valence_bands
logical, intent(in) :: effective_model
logical, intent(in) :: have_disentangled
character(len=50), intent(in) :: seedname
type(ws_distance_type), intent(in) :: ws_distance
type(ws_region_type), intent(in) :: ws_region
integer, intent(in) :: stdout
type(timer_list_type), intent(inout) :: timer
type(w90_error_type), intent(out), allocatable :: error
type(w90_comm_type), intent(in) :: comm

Calls

proc~~get_hh_r~~CallsGraph proc~get_hh_r get_HH_R interface~comms_bcast comms_bcast proc~get_hh_r->interface~comms_bcast proc~fourier_q_to_r fourier_q_to_R proc~get_hh_r->proc~fourier_q_to_r proc~get_win_min get_win_min proc~get_hh_r->proc~get_win_min proc~io_stopwatch_start io_stopwatch_start proc~get_hh_r->proc~io_stopwatch_start proc~io_stopwatch_stop io_stopwatch_stop proc~get_hh_r->proc~io_stopwatch_stop proc~mpirank mpirank proc~get_hh_r->proc~mpirank proc~operator_wigner_setup operator_wigner_setup proc~get_hh_r->proc~operator_wigner_setup proc~set_error_fatal set_error_fatal proc~get_hh_r->proc~set_error_fatal proc~set_error_file set_error_file proc~get_hh_r->proc~set_error_file proc~set_error_input set_error_input proc~get_hh_r->proc~set_error_input proc~comms_bcast_char comms_bcast_char interface~comms_bcast->proc~comms_bcast_char proc~comms_bcast_cmplx comms_bcast_cmplx interface~comms_bcast->proc~comms_bcast_cmplx proc~comms_bcast_int comms_bcast_int interface~comms_bcast->proc~comms_bcast_int proc~comms_bcast_logical comms_bcast_logical interface~comms_bcast->proc~comms_bcast_logical proc~comms_bcast_real comms_bcast_real interface~comms_bcast->proc~comms_bcast_real 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_file->proc~comms_sync_error proc~set_error_file->proc~set_base_error proc~set_error_input->proc~comms_sync_error proc~set_error_input->proc~set_base_error proc~comms_bcast_char->proc~comms_sync_error proc~comms_no_sync_bcast_char comms_no_sync_bcast_char proc~comms_bcast_char->proc~comms_no_sync_bcast_char proc~comms_bcast_cmplx->proc~comms_sync_error proc~comms_no_sync_bcast_cmplx comms_no_sync_bcast_cmplx proc~comms_bcast_cmplx->proc~comms_no_sync_bcast_cmplx proc~comms_bcast_int->proc~comms_sync_error proc~comms_no_sync_bcast_int comms_no_sync_bcast_int proc~comms_bcast_int->proc~comms_no_sync_bcast_int proc~comms_bcast_logical->proc~comms_sync_error proc~comms_no_sync_bcast_logical comms_no_sync_bcast_logical proc~comms_bcast_logical->proc~comms_no_sync_bcast_logical proc~comms_bcast_real->proc~comms_sync_error proc~comms_no_sync_bcast_real comms_no_sync_bcast_real proc~comms_bcast_real->proc~comms_no_sync_bcast_real

Called by

proc~~get_hh_r~~CalledByGraph proc~get_hh_r get_HH_R proc~berry_main berry_main proc~berry_main->proc~get_hh_r proc~berry_get_imfgh_klist berry_get_imfgh_klist proc~berry_main->proc~berry_get_imfgh_klist proc~berry_get_kdotp berry_get_kdotp proc~berry_main->proc~berry_get_kdotp proc~berry_get_kubo_k berry_get_kubo_k proc~berry_main->proc~berry_get_kubo_k proc~berry_get_sc_klist berry_get_sc_klist proc~berry_main->proc~berry_get_sc_klist proc~berry_get_shc_klist berry_get_shc_klist proc~berry_main->proc~berry_get_shc_klist proc~berry_get_imf_klist berry_get_imf_klist proc~berry_main->proc~berry_get_imf_klist proc~calctdfanddos calcTDFandDOS proc~calctdfanddos->proc~get_hh_r proc~wham_get_eig_deleig wham_get_eig_deleig proc~calctdfanddos->proc~wham_get_eig_deleig proc~dos_main dos_main proc~dos_main->proc~get_hh_r proc~dos_main->proc~wham_get_eig_deleig proc~geninterp_main geninterp_main proc~geninterp_main->proc~get_hh_r proc~geninterp_main->proc~wham_get_eig_deleig proc~gyrotropic_main gyrotropic_main proc~gyrotropic_main->proc~get_hh_r proc~gyrotropic_get_k_list gyrotropic_get_k_list proc~gyrotropic_main->proc~gyrotropic_get_k_list proc~k_path k_path proc~k_path->proc~get_hh_r proc~k_path->proc~berry_get_imfgh_klist proc~k_path->proc~berry_get_shc_klist proc~k_path->proc~berry_get_imf_klist proc~k_slice k_slice proc~k_slice->proc~get_hh_r proc~k_slice->proc~wham_get_eig_deleig proc~k_slice->proc~berry_get_imfgh_klist proc~k_slice->proc~berry_get_shc_klist proc~k_slice->proc~berry_get_imf_klist proc~spin_get_moment spin_get_moment proc~spin_get_moment->proc~get_hh_r proc~wham_get_eig_deleig->proc~get_hh_r proc~wham_get_eig_uu_hh_aa_sc wham_get_eig_UU_HH_AA_sc proc~wham_get_eig_uu_hh_aa_sc->proc~get_hh_r proc~wham_get_eig_uu_hh_aa_sc_tb_conv wham_get_eig_UU_HH_AA_sc_TB_conv proc~wham_get_eig_uu_hh_aa_sc_tb_conv->proc~get_hh_r proc~wham_get_eig_uu_hh_jjlist wham_get_eig_UU_HH_JJlist proc~wham_get_eig_uu_hh_jjlist->proc~get_hh_r proc~berry_get_imfgh_klist->proc~wham_get_eig_uu_hh_jjlist proc~berry_get_kdotp->proc~wham_get_eig_deleig proc~berry_get_kdotp->proc~wham_get_eig_uu_hh_aa_sc proc~berry_get_kubo_k->proc~wham_get_eig_deleig proc~berry_get_sc_klist->proc~wham_get_eig_deleig proc~berry_get_sc_klist->proc~wham_get_eig_uu_hh_aa_sc proc~berry_get_sc_klist->proc~wham_get_eig_uu_hh_aa_sc_tb_conv proc~berry_get_shc_klist->proc~wham_get_eig_deleig proc~boltzwann_main boltzwann_main proc~boltzwann_main->proc~calctdfanddos proc~gyrotropic_get_k_list->proc~wham_get_eig_deleig proc~gyrotropic_get_k_list->proc~berry_get_imfgh_klist proc~gyrotropic_get_k_list->proc~berry_get_imf_klist program~postw90 postw90 program~postw90->proc~berry_main program~postw90->proc~dos_main program~postw90->proc~geninterp_main program~postw90->proc~gyrotropic_main program~postw90->proc~k_path program~postw90->proc~k_slice program~postw90->proc~spin_get_moment program~postw90->proc~boltzwann_main proc~berry_get_imf_klist->proc~berry_get_imfgh_klist

Source Code

  subroutine get_HH_R(dis_manifold, kpt_latt, print_output, wigner_seitz, HH_R, u_matrix, &
                      v_matrix, eigval, real_lattice, scissors_shift, num_bands, num_kpts, &
                      num_wann, num_valence_bands, effective_model, have_disentangled, seedname, &
                      ws_distance, ws_region, stdout, timer, error, comm)
    !================================================
    !
    !! computes <0n|H|Rm>, in eV
    !! (pwscf uses Ry, but pw2wannier90 converts to eV)
    !
    !================================================

    use w90_postw90_types, only: wigner_seitz_type
    use w90_types, only: dis_manifold_type, print_output_type, timer_list_type, &
                         ws_distance_type, ws_region_type
    implicit none

    ! arguments
    type(dis_manifold_type), intent(in) :: dis_manifold
    type(print_output_type), intent(in) :: print_output
    type(w90_comm_type), intent(in) :: comm
    type(wigner_seitz_type), intent(inout) :: wigner_seitz
    type(ws_distance_type), intent(in) :: ws_distance
    type(ws_region_type), intent(in) :: ws_region
    type(timer_list_type), intent(inout) :: timer
    type(w90_error_type), allocatable, intent(out) :: error

    integer, intent(in) :: num_bands, num_kpts, num_wann, num_valence_bands, stdout

    real(kind=dp), intent(in) :: eigval(:, :), real_lattice(3, 3)
    real(kind=dp), intent(in) :: scissors_shift
    real(kind=dp), intent(in) :: kpt_latt(:, :)

    complex(kind=dp), intent(in) :: u_matrix(:, :, :), v_matrix(:, :, :)
    complex(kind=dp), allocatable, intent(inout) :: HH_R(:, :, :) !  <0n|r|Rm>
    complex(kind=dp), allocatable :: HH_R_temp(:, :, :)

    character(len=50), intent(in) :: seedname

    logical, intent(in) :: have_disentangled
    logical, intent(in) :: effective_model

    ! local variables
    integer                       :: i, j, n, m, ii, ik, winmin_q, file_unit, &
                                     ir, io, idum, ivdum(3), ivdum_old(3)
    integer, allocatable          :: num_states(:)
    real(kind=dp)                 :: rdum_real, rdum_imag
    complex(kind=dp), allocatable :: HH_q(:, :, :)
    logical                       :: new_ir

    complex(kind=dp), allocatable :: sciss_q(:, :, :)
    complex(kind=dp), allocatable :: sciss_R(:, :, :)

    logical :: on_root = .false.
    if (mpirank(comm) == 0) on_root = .true.

    if (print_output%timing_level > 1 .and. print_output%iprint > 0) &
      call io_stopwatch_start('get_oper: get_HH_R', timer)

    if (wigner_seitz%nrpts < 1) then
      call set_error_fatal(error, 'Error: wigner_setiz%nrpts incorrect at get_HH_R() ', comm)
      return
    end if

    allocate (HH_R_temp(num_wann, num_wann, wigner_seitz%nrpts))

    if (.not. allocated(HH_R)) then
      allocate (HH_R(num_wann, num_wann, wigner_seitz%nrpts_pw90))
    else
      if (print_output%timing_level > 1 .and. print_output%iprint > 0) &
        call io_stopwatch_stop('get_oper: get_HH_R', timer)
      return
    end if

    ! Real-space Hamiltonian H(R) is read from file
    !
    if (effective_model) then
      HH_R = cmplx_0
      if (on_root) then
        write (stdout, '(/a)') ' Reading real-space Hamiltonian from file ' &
          //trim(seedname)//'_HH_R.dat'
        open (newunit=file_unit, file=trim(seedname)//'_HH_R.dat', form='formatted', &
              status='old', err=101)
        read (file_unit, *) ! header
        read (file_unit, *) idum ! num_wann
        read (file_unit, *) idum ! nrpts
        ir = 1
        new_ir = .true.
        ivdum_old(:) = 0
        n = 1
        do
          read (file_unit, '(5I5,2F12.6)', iostat=io) ivdum(1:3), j, i, &
            rdum_real, rdum_imag
          if (io < 0) exit ! reached end of file
          if (i < 1 .or. i > num_wann .or. j < 1 .or. j > num_wann) then
            write (stdout, *) 'num_wann=', num_wann, '  i=', i, '  j=', j
            call set_error_fatal(error, 'Error in get_HH_R: orbital indices out of bounds', comm)
            return
          end if
          if (n > 1) then
            if (ivdum(1) /= ivdum_old(1) .or. ivdum(2) /= ivdum_old(2) .or. &
                ivdum(3) /= ivdum_old(3)) then
              ir = ir + 1
              new_ir = .true.
            else
              new_ir = .false.
            end if
          end if
          ivdum_old = ivdum
          ! Note that the same (j,i,ir) may occur more than once in
          ! the file seedname_HH_R.dat, hence the addition instead
          ! of a simple equality. (This has to do with the way the
          ! Berlijn effective Hamiltonian algorithm is
          ! implemented.)
          HH_R(j, i, ir) = HH_R(j, i, ir) + cmplx(rdum_real, rdum_imag, kind=dp)
          if (new_ir) then
            wigner_seitz%irvec(:, ir) = ivdum(:)
            if (ivdum(1) == 0 .and. ivdum(2) == 0 .and. ivdum(3) == 0) wigner_seitz%rpt_origin = ir
          end if
          n = n + 1
        end do
        close (file_unit)
        if (ir /= wigner_seitz%nrpts) then
          write (stdout, *) 'ir=', ir, '  nrpts=', wigner_seitz%nrpts
          call set_error_fatal(error, 'Error in get_HH_R: inconsistent nrpts values', comm)
          return
        end if
        do ir = 1, wigner_seitz%nrpts
          wigner_seitz%crvec(:, ir) = matmul(transpose(real_lattice), wigner_seitz%irvec(:, ir))
        end do
        wigner_seitz%ndegen(:) = 1 ! This is assumed when reading HH_R from file
        !
        wigner_seitz%nrpts_pw90 = wigner_seitz%nrpts
        wigner_seitz%irvec_pw90 = wigner_seitz%irvec
        wigner_seitz%crvec_pw90 = wigner_seitz%crvec
        !
        ! TODO: Implement scissors in this case? Need to choose a
        ! uniform k-mesh (the scissors correction is applied in
        ! k-space) and then proceed as below, Fourier transforming
        ! back to real space and adding to HH_R_temp, Hopefully the
        ! result converges (rapidly) with the k-mesh density, but
        ! one should check
        !
        if (abs(scissors_shift) > 1.0e-7_dp) then
          call set_error_input(error, 'Error in get_HH_R: scissors shift not implemented for ' &
                               //'effective_model=T', comm)
          return
        end if
      end if
      call comms_bcast(HH_R(1, 1, 1), num_wann*num_wann*wigner_seitz%nrpts, error, comm)
      if (allocated(error)) return
      call comms_bcast(wigner_seitz%ndegen(1), wigner_seitz%nrpts, error, comm)
      if (allocated(error)) return
      call comms_bcast(wigner_seitz%irvec(1, 1), 3*wigner_seitz%nrpts, error, comm)
      if (allocated(error)) return
      call comms_bcast(wigner_seitz%crvec(1, 1), 3*wigner_seitz%nrpts, error, comm)
      if (allocated(error)) return
      if (print_output%timing_level > 1 .and. print_output%iprint > 0) &
        call io_stopwatch_stop('get_oper: get_HH_R', timer)
      return
    end if

    ! Everything below is only executed if effective_model==False (default)

    ! Real-space Hamiltonian H(R) is calculated by Fourier
    ! transforming H(q) defined on the ab-initio reciprocal mesh
    !
    allocate (HH_q(num_wann, num_wann, num_kpts))
    allocate (num_states(num_kpts))

    HH_q = cmplx_0
    do ik = 1, num_kpts
      if (have_disentangled) then
        num_states(ik) = dis_manifold%ndimwin(ik)
      else
        num_states(ik) = num_wann
      end if

      call get_win_min(num_bands, dis_manifold, ik, winmin_q, have_disentangled)
      do m = 1, num_wann
        do n = 1, m
          do i = 1, num_states(ik)
            ii = winmin_q + i - 1
            HH_q(n, m, ik) = HH_q(n, m, ik) &
                             + conjg(v_matrix(i, n, ik))*eigval(ii, ik) &
                             *v_matrix(i, m, ik)
          end do
          HH_q(m, n, ik) = conjg(HH_q(n, m, ik))
        end do
      end do
    end do

    call fourier_q_to_R(num_kpts, wigner_seitz%nrpts, wigner_seitz%irvec, kpt_latt, HH_q, HH_R_temp)

    ! Scissors correction for an insulator: shift conduction bands upwards by
    ! scissors_shift eV
    !
    if (num_valence_bands > 0 .and. abs(scissors_shift) > 1.0e-7_dp) then
      allocate (sciss_R(num_wann, num_wann, wigner_seitz%nrpts))
      allocate (sciss_q(num_wann, num_wann, num_kpts))
      sciss_q = cmplx_0
      do ik = 1, num_kpts
        do j = 1, num_wann
          do i = 1, j
            do m = 1, num_valence_bands
              sciss_q(i, j, ik) = sciss_q(i, j, ik) - &
                                  conjg(u_matrix(m, i, ik))*u_matrix(m, j, ik)
            end do
            sciss_q(j, i, ik) = conjg(sciss_q(i, j, ik))
          end do
        end do
      end do

      call fourier_q_to_R(num_kpts, wigner_seitz%nrpts, wigner_seitz%irvec, kpt_latt, sciss_q, &
                          sciss_R)
      do n = 1, num_wann
        sciss_R(n, n, wigner_seitz%rpt_origin) = sciss_R(n, n, wigner_seitz%rpt_origin) + 1.0_dp
      end do
      sciss_R = sciss_R*scissors_shift
      HH_R_temp = HH_R_temp + sciss_R
    end if

    ! Apply degeneracy factor and reorder according to the wigner-seitz vectors
    call operator_wigner_setup(ws_distance, ws_region, wigner_seitz, num_wann, HH_R_temp, HH_R)

    if (print_output%timing_level > 1 .and. print_output%iprint > 0) &
      call io_stopwatch_stop('get_oper: get_HH_R', timer)
    return

101 call set_error_file(error, 'Error in get_HH_R: problem opening file '// &
                        trim(seedname)//'_HH_R.dat', comm)
    return

  end subroutine get_HH_R