get_SH_R Subroutine

public subroutine get_SH_R(dis_manifold, kmesh_info, kpt_latt, print_output, pw90_oper_read, pw90_spin_hall, SH_R, v_matrix, eigval, scissors_shift, wigner_seitz, ws_distance, ws_region, num_bands, num_kpts, num_wann, num_valence_bands, have_disentangled, seedname, stdout, timer, error, comm)

Uses

  • proc~~get_sh_r~~UsesGraph proc~get_sh_r get_SH_R module~w90_postw90_types w90_postw90_types proc~get_sh_r->module~w90_postw90_types module~w90_types w90_types proc~get_sh_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

Compute several matrices for spin Hall conductivity SH_R = <0n|sigma_{x,y,z}.H|Rm>

Arguments

Type IntentOptional Attributes Name
type(dis_manifold_type), intent(in) :: dis_manifold
type(kmesh_info_type), intent(in) :: kmesh_info
real(kind=dp), intent(in) :: kpt_latt(:,:)
type(print_output_type), intent(in) :: print_output
type(pw90_oper_read_type), intent(in) :: pw90_oper_read
type(pw90_spin_hall_type), intent(in) :: pw90_spin_hall
complex(kind=dp), intent(inout), allocatable :: SH_R(:,:,:,:)
complex(kind=dp), intent(in) :: v_matrix(:,:,:)
real(kind=dp), intent(in) :: eigval(:,:)
real(kind=dp), intent(in) :: scissors_shift
type(wigner_seitz_type), intent(in) :: wigner_seitz
type(ws_distance_type), intent(in) :: ws_distance
type(ws_region_type), intent(in) :: ws_region
integer, intent(in) :: num_bands
integer, intent(in) :: num_kpts
integer, intent(in) :: num_wann
integer, intent(in) :: num_valence_bands
logical, intent(in) :: have_disentangled
character(len=50), intent(in) :: seedname
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_sh_r~~CallsGraph proc~get_sh_r get_SH_R interface~comms_bcast comms_bcast proc~get_sh_r->interface~comms_bcast proc~fourier_q_to_r fourier_q_to_R proc~get_sh_r->proc~fourier_q_to_r proc~get_gauge_overlap_matrix get_gauge_overlap_matrix proc~get_sh_r->proc~get_gauge_overlap_matrix proc~io_stopwatch_start io_stopwatch_start proc~get_sh_r->proc~io_stopwatch_start proc~io_stopwatch_stop io_stopwatch_stop proc~get_sh_r->proc~io_stopwatch_stop proc~mpirank mpirank proc~get_sh_r->proc~mpirank proc~operator_wigner_setup operator_wigner_setup proc~get_sh_r->proc~operator_wigner_setup proc~set_error_alloc set_error_alloc proc~get_sh_r->proc~set_error_alloc proc~set_error_dealloc set_error_dealloc proc~get_sh_r->proc~set_error_dealloc proc~set_error_fatal set_error_fatal proc~get_sh_r->proc~set_error_fatal proc~set_error_file set_error_file proc~get_sh_r->proc~set_error_file 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~get_win_min get_win_min proc~get_gauge_overlap_matrix->proc~get_win_min proc~utility_zgemmm utility_zgemmm proc~get_gauge_overlap_matrix->proc~utility_zgemmm proc~comms_sync_error comms_sync_error proc~set_error_alloc->proc~comms_sync_error proc~set_base_error set_base_error proc~set_error_alloc->proc~set_base_error proc~set_error_dealloc->proc~comms_sync_error proc~set_error_dealloc->proc~set_base_error proc~set_error_fatal->proc~comms_sync_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~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 proc~utility_zgemm_new utility_zgemm_new proc~utility_zgemmm->proc~utility_zgemm_new zgemm zgemm proc~utility_zgemm_new->zgemm

Called by

proc~~get_sh_r~~CalledByGraph proc~get_sh_r get_SH_R proc~berry_main berry_main proc~berry_main->proc~get_sh_r program~postw90 postw90 program~postw90->proc~berry_main

Source Code

  subroutine get_SH_R(dis_manifold, kmesh_info, kpt_latt, print_output, pw90_oper_read, &
                      pw90_spin_hall, SH_R, v_matrix, eigval, scissors_shift, &
                      wigner_seitz, ws_distance, ws_region, num_bands, num_kpts, num_wann, &
                      num_valence_bands, have_disentangled, seedname, stdout, timer, error, comm)
    !================================================
    !
    !! Compute several matrices for spin Hall conductivity
    !! SH_R  = <0n|sigma_{x,y,z}.H|Rm>
    !
    !================================================

    use w90_postw90_types, only: pw90_oper_read_type, pw90_spin_hall_type, wigner_seitz_type
    use w90_types, only: dis_manifold_type, kmesh_info_type, ws_distance_type, ws_region_type, &
                         print_output_type, timer_list_type

    implicit none

    ! arguments
    type(dis_manifold_type), intent(in) :: dis_manifold
    type(kmesh_info_type), intent(in) :: kmesh_info
    type(pw90_oper_read_type), intent(in) :: pw90_oper_read
    type(print_output_type), intent(in) :: print_output
    type(pw90_spin_hall_type), intent(in) :: pw90_spin_hall
    type(wigner_seitz_type), intent(in) :: 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_comm_type), intent(in) :: comm
    type(w90_error_type), allocatable, intent(out) :: error

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

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

    complex(kind=dp), intent(in) :: v_matrix(:, :, :)
    complex(kind=dp), allocatable, intent(inout) :: SH_R(:, :, :, :) ! <0n|sigma_x,y,z.H|Rm>

    complex(kind=dp), allocatable :: SH_R_temp(:, :, :, :)

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

    ! local variables
    complex(kind=dp), allocatable :: SH_q(:, :, :, :)

    complex(kind=dp), allocatable :: S_o(:, :)
    complex(kind=dp), allocatable :: spn_o(:, :, :, :), spn_temp(:, :)
    complex(kind=dp), allocatable :: H_o(:, :, :)
    complex(kind=dp), allocatable :: SH_o(:, :, :, :)

    real(kind=dp)                 :: s_real, s_img
    integer                       :: spn_in, counter, ierr, s, is

    integer                       :: n, m, ik, idir, nb_tmp, nkp_tmp
    integer, allocatable          :: num_states(:)
    character(len=60)             :: header
    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_SH_R', timer)

    allocate (SH_R_temp(num_wann, num_wann, wigner_seitz%nrpts, 3))

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

    ! start copying from get_SS_R, Junfeng Qiao
    ! read spn file
    if (on_root) then

      allocate (spn_o(num_bands, num_bands, num_kpts, 3))

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

      ! Read from .spn file the original spin matrices <psi_nk|sigma_i|psi_mk>
      ! (sigma_i = Pauli matrix) between ab initio eigenstates
      !
      if (pw90_oper_read%spn_formatted) then
        open (newunit=spn_in, file=trim(seedname)//'.spn', form='formatted', &
              status='old', err=109)
        write (stdout, '(/a)', advance='no') &
          ' Reading spin matrices from '//trim(seedname)//'.spn in get_SH_R : '
        read (spn_in, *, err=110, end=110) header
        write (stdout, '(a)') trim(header)
        read (spn_in, *, err=110, end=110) nb_tmp, nkp_tmp
      else
        open (newunit=spn_in, file=trim(seedname)//'.spn', form='unformatted', &
              status='old', err=109)
        write (stdout, '(/a)', advance='no') &
          ' Reading spin matrices from '//trim(seedname)//'.spn in get_SH_R : '
        read (spn_in, err=110, end=110) header
        write (stdout, '(a)') trim(header)
        read (spn_in, err=110, end=110) nb_tmp, nkp_tmp
      end if
      if (nb_tmp .ne. num_bands) then
        call set_error_fatal(error, trim(seedname)//'.spn has wrong number of bands', comm)
        return
      end if
      if (nkp_tmp .ne. num_kpts) then
        call set_error_fatal(error, trim(seedname)//'.spn has wrong number of k-points', comm)
        return
      end if
      if (pw90_oper_read%spn_formatted) then
        do ik = 1, num_kpts
          do m = 1, num_bands
            do n = 1, m
              read (spn_in, *, err=110, end=110) s_real, s_img
              spn_o(n, m, ik, 1) = cmplx(s_real, s_img, dp)
              read (spn_in, *, err=110, end=110) s_real, s_img
              spn_o(n, m, ik, 2) = cmplx(s_real, s_img, dp)
              read (spn_in, *, err=110, end=110) s_real, s_img
              spn_o(n, m, ik, 3) = cmplx(s_real, s_img, dp)
              ! Read upper-triangular part, now build the rest
              spn_o(m, n, ik, 1) = conjg(spn_o(n, m, ik, 1))
              spn_o(m, n, ik, 2) = conjg(spn_o(n, m, ik, 2))
              spn_o(m, n, ik, 3) = conjg(spn_o(n, m, ik, 3))
            end do
          end do
        end do
      else
        allocate (spn_temp(3, (num_bands*(num_bands + 1))/2), stat=ierr)
        if (ierr /= 0) then
          call set_error_alloc(error, 'Error in allocating spm_temp in get_SH_R', comm)
          return
        end if
        do ik = 1, num_kpts
          read (spn_in) ((spn_temp(s, m), s=1, 3), m=1, (num_bands*(num_bands + 1))/2)
          counter = 0
          do m = 1, num_bands
            do n = 1, m
              counter = counter + 1
              spn_o(n, m, ik, 1) = spn_temp(1, counter)
              spn_o(m, n, ik, 1) = conjg(spn_temp(1, counter))
              spn_o(n, m, ik, 2) = spn_temp(2, counter)
              spn_o(m, n, ik, 2) = conjg(spn_temp(2, counter))
              spn_o(n, m, ik, 3) = spn_temp(3, counter)
              spn_o(m, n, ik, 3) = conjg(spn_temp(3, counter))
            end do
          end do
        end do
        deallocate (spn_temp, stat=ierr)
        if (ierr /= 0) then
          call set_error_dealloc(error, 'Error in deallocating spm_temp in get_SH_R', comm)
          return
        end if
      end if

      close (spn_in)

    end if !on_root
    ! end copying from get_SS_R, Junfeng Qiao

    ! start copying from get_HH_R, Junfeng Qiao
    ! Note this is different from get_HH_R, at here we need the
    ! original Hamiltonian to construct SHR_R, SH_R.
    if (on_root) then
      allocate (H_o(num_bands, num_bands, num_kpts))
      H_o = cmplx_0
      do ik = 1, num_kpts
        do m = 1, num_bands
          H_o(m, m, ik) = eigval(m, ik)
        end do
        ! scissors shift applied to the original Hamiltonian
        if (num_valence_bands > 0 .and. abs(scissors_shift) > 1.0e-7_dp) then
          do m = num_valence_bands + 1, num_bands
            H_o(m, m, ik) = H_o(m, m, ik) + scissors_shift
          end do
        else if (pw90_spin_hall%bandshift) then
          do m = pw90_spin_hall%bandshift_firstband, num_bands
            H_o(m, m, ik) = H_o(m, m, ik) + pw90_spin_hall%bandshift_energyshift
          end do
        end if
      end do
    end if !on_root
    ! end copying from get_HH_R, Junfeng Qiao

    ! start copying from get_AA_R, Junfeng Qiao
    ! read mmn file
    !
    if (on_root) then

      allocate (SH_q(num_wann, num_wann, num_kpts, 3))

      SH_q = cmplx_0

      ! QZYZ18 Eq.(48)
      allocate (SH_o(num_bands, num_bands, num_kpts, 3))
      SH_o = cmplx_0
      do ik = 1, num_kpts
        do is = 1, 3
          SH_o(:, :, ik, is) = matmul(spn_o(:, :, ik, is), H_o(:, :, ik))

          call get_gauge_overlap_matrix(num_bands, num_wann, eigval, v_matrix, dis_manifold, &
                                        ik, num_states(ik), ik, num_states(ik), &
                                        SH_o(:, :, ik, is), have_disentangled, SH_q(:, :, ik, is))
        end do
      end do

      do is = 1, 3
        ! QZYZ18 Eq.(46)
        call fourier_q_to_R(num_kpts, wigner_seitz%nrpts, wigner_seitz%irvec, kpt_latt, &
                            SH_q(:, :, :, is), SH_R_temp(:, :, :, is))
      end do

      do is = 1, 3
        ! QZYZ18 Eq.(46)
        call operator_wigner_setup(ws_distance, ws_region, wigner_seitz, num_wann, &
                                   SH_R_temp(:, :, :, is), SH_R(:, :, :, is))
      end do

    end if !on_root

    call comms_bcast(SH_R(1, 1, 1, 1), num_wann*num_wann*wigner_seitz%nrpts_pw90*3, error, comm)
    if (allocated(error)) return

    ! end copying from get_AA_R, Junfeng Qiao

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

    deallocate (SH_R_temp)

101 call set_error_file(error, 'Error: Problem opening input file '//trim(seedname)//'.mmn', comm)
    return
102 call set_error_file(error, 'Error: Problem reading input file '//trim(seedname)//'.mmn', comm)
    return
109 call set_error_file(error, 'Error: Problem opening input file '//trim(seedname)//'.spn', comm)
    return
110 call set_error_file(error, 'Error: Problem reading input file '//trim(seedname)//'.spn', comm)
    return

  end subroutine get_SH_R