Compute several matrices for spin Hall conductivity SH_R = <0n|sigma_{x,y,z}.H|Rm>
| Type | Intent | Optional | 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 |
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