Wannier representation of the Pauli matrices: <0n|sigma_a|Rm> (a=x,y,z)
| Type | Intent | Optional | 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(pw90_oper_read_type), | intent(in) | :: | pw90_oper_read | |||
| complex(kind=dp), | intent(inout), | allocatable | :: | SS_R(:,:,:,:) | ||
| complex(kind=dp), | intent(in) | :: | v_matrix(:,:,:) | |||
| real(kind=dp), | intent(in) | :: | eigval(:,:) | |||
| 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 | |||
| 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_SS_R(dis_manifold, kpt_latt, print_output, pw90_oper_read, SS_R, v_matrix, & eigval, wigner_seitz, ws_distance, ws_region, num_bands, num_kpts, num_wann, & have_disentangled, seedname, stdout, timer, error, comm) !================================================ ! !! Wannier representation of the Pauli matrices: <0n|sigma_a|Rm> !! (a=x,y,z) ! !================================================ use w90_postw90_types, only: pw90_oper_read_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(pw90_oper_read_type), intent(in) :: pw90_oper_read 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(print_output_type), intent(in) :: print_output 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 real(kind=dp), intent(in) :: eigval(:, :) real(kind=dp), intent(in) :: kpt_latt(:, :) complex(kind=dp), intent(in) :: v_matrix(:, :, :) complex(kind=dp), allocatable, intent(inout) :: SS_R(:, :, :, :) ! <0n|sigma_x,y,z|Rm> complex(kind=dp), allocatable :: SS_R_temp(:, :, :, :) character(len=50), intent(in) :: seedname logical, intent(in) :: have_disentangled ! local variables complex(kind=dp), allocatable :: spn_o(:, :, :, :), SS_q(:, :, :, :), spn_temp(:, :) real(kind=dp) :: s_real, s_img integer, allocatable :: num_states(:) integer :: m, n, spn_in, ik, is, & nb_tmp, nkp_tmp, ierr, s, counter 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_SS_R', timer) allocate (SS_R_temp(num_wann, num_wann, wigner_seitz%nrpts, 3)) if (.not. allocated(SS_R)) then allocate (SS_R(num_wann, num_wann, wigner_seitz%nrpts_pw90, 3)) else return ! been here before end if if (on_root) then allocate (spn_o(num_bands, num_bands, num_kpts, 3)) allocate (SS_q(num_wann, num_wann, 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_SS_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_SS_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_SS_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_SS_R', comm) return end if end if close (spn_in) ! Transform to projected subspace, Wannier gauge ! SS_q(:, :, :, :) = cmplx_0 do ik = 1, num_kpts do is = 1, 3 call get_gauge_overlap_matrix(num_bands, num_wann, eigval, v_matrix, dis_manifold, & ik, num_states(ik), ik, num_states(ik), & spn_o(:, :, ik, is), have_disentangled, SS_q(:, :, ik, is)) end do !is end do !ik call fourier_q_to_R(num_kpts, wigner_seitz%nrpts, wigner_seitz%irvec, kpt_latt, SS_q(:, :, :, 1), SS_R_temp(:, :, :, 1)) call fourier_q_to_R(num_kpts, wigner_seitz%nrpts, wigner_seitz%irvec, kpt_latt, SS_q(:, :, :, 2), SS_R_temp(:, :, :, 2)) call fourier_q_to_R(num_kpts, wigner_seitz%nrpts, wigner_seitz%irvec, kpt_latt, SS_q(:, :, :, 3), SS_R_temp(:, :, :, 3)) call operator_wigner_setup(ws_distance, ws_region, wigner_seitz, num_wann, SS_R_temp(:, :, :, 1), SS_R(:, :, :, 1)) call operator_wigner_setup(ws_distance, ws_region, wigner_seitz, num_wann, SS_R_temp(:, :, :, 2), SS_R(:, :, :, 2)) call operator_wigner_setup(ws_distance, ws_region, wigner_seitz, num_wann, SS_R_temp(:, :, :, 3), SS_R(:, :, :, 3)) end if !on_root call comms_bcast(SS_R(1, 1, 1, 1), num_wann*num_wann*wigner_seitz%nrpts_pw90*3, error, comm) if (allocated(error)) return if (print_output%timing_level > 1 .and. print_output%iprint > 0) call io_stopwatch_stop('get_oper: get_SS_R', timer) return deallocate (SS_R_temp) 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_SS_R