For : For :
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(ws_region_type), | intent(in) | :: | ws_region | |||
| type(wannier_data_type), | intent(in) | :: | wannier_data | |||
| type(ws_distance_type), | intent(inout) | :: | ws_distance | |||
| type(wigner_seitz_type), | intent(in) | :: | wigner_seitz | |||
| complex(kind=dp), | intent(in) | :: | OO_R(:,:,:,:) | |||
| real(kind=dp), | intent(in) | :: | kpt(3) | |||
| real(kind=dp), | intent(in) | :: | real_lattice(3,3) | |||
| integer, | intent(in) | :: | mp_grid(3) | |||
| integer, | intent(in) | :: | num_wann | |||
| type(w90_error_type), | intent(out), | allocatable | :: | error | ||
| type(w90_comm_type), | intent(in) | :: | comm | |||
| complex(kind=dp), | intent(out), | optional | :: | OO_da(:,:,:) | ||
| complex(kind=dp), | intent(out), | optional | :: | OO_dadb(:,:,:,:) |
subroutine pw90common_fourier_R_to_k_vec_dadb_TB_conv(ws_region, wannier_data, ws_distance, & wigner_seitz, OO_R, kpt, real_lattice, & mp_grid, num_wann, error, comm, OO_da, & OO_dadb) !================================================! ! ! modified version of pw90common_fourier_R_to_k_vec_dadb, includes wannier centres in ! the exponential inside the sum (so called TB convention) ! !! For $$OO_{ij;dx,dy,dz}$$: !! $$O_{ij;dx,dy,dz}(k) = \sum_R e^{+ik.(R+tau_ij)} O_{ij;dx,dy,dz}(R)$$ !! For $$OO_{ij;dx1,dy1,dz1;dx2,dy2,dz2}$$: !! $$O_{ij;dx1,dy1,dz1;dx2,dy2,dz2}(k) = \sum_R e^{+ik.(R+tau_ij)} i.(R+tau_ij)_{dx2,dy2,dz2} !! .O_{ij;dx1,dy1,dz1}(R)$$ ! with tau_ij = tau_j - tau_i, being tau_i=<0i|r|0i> the individual wannier centres ! !================================================! use w90_constants, only: dp, cmplx_0, cmplx_i, twopi use w90_types, only: ws_region_type, wannier_data_type, ws_distance_type use w90_ws_distance, only: ws_translate_dist use w90_utility, only: utility_cart_to_frac, utility_inverse_mat use w90_postw90_types, only: wigner_seitz_type use w90_comms, only: w90_comm_type implicit none ! arguments type(ws_region_type), intent(in) :: ws_region type(wannier_data_type), intent(in) :: wannier_data type(ws_distance_type), intent(inout) :: ws_distance type(wigner_seitz_type), intent(in) :: wigner_seitz type(w90_error_type), allocatable, intent(out) :: error type(w90_comm_type), intent(in) :: comm integer, intent(in) :: num_wann integer, intent(in) :: mp_grid(3) real(kind=dp), intent(in) :: kpt(3), real_lattice(3, 3) complex(kind=dp), intent(in) :: OO_R(:, :, :, :) complex(kind=dp), optional, intent(out) :: OO_da(:, :, :) complex(kind=dp), optional, intent(out) :: OO_dadb(:, :, :, :) ! local variables real(kind=dp) :: inv_lattice(3, 3) integer :: ir, i, j, ideg, a, b real(kind=dp) :: rdotk complex(kind=dp) :: phase_fac real(kind=dp) :: wannier_centres_frac(3, num_wann) real(kind=dp) :: r_sum(3) r_sum = 0.d0 if (present(OO_da)) OO_da = cmplx_0 if (present(OO_dadb)) OO_dadb = cmplx_0 ! rotate wannier centres from cartesian to fractional coordinates wannier_centres_frac(:, :) = 0.d0 call utility_inverse_mat(real_lattice, inv_lattice) do ir = 1, num_wann call utility_cart_to_frac(wigner_seitz%wannier_centres_from_AA_R(:, ir), & wannier_centres_frac(:, ir), inv_lattice) end do ! print *, 'wannier_centres_frac' ! do ir = 1,num_wann ! print *, wannier_centres_frac(:,ir) ! enddo ! stop ! ! print *, 'crvec' ! do ir = 1,nrpts ! print *, crvec(:,ir) ! enddo ! stop ! print *, 'wannier_centres' ! do ir = 1,num_wann ! print *, wannier_centres(:,ir) ! enddo ! stop do ir = 1, wigner_seitz%nrpts_pw90 ! [lp] Original code, without IJ-dependent shift: do j = 1, num_wann do i = 1, num_wann r_sum(:) = real(wigner_seitz%irvec_pw90(:, ir)) & + wannier_centres_frac(:, j) - wannier_centres_frac(:, i) rdotk = twopi*dot_product(kpt(:), r_sum(:)) phase_fac = cmplx(cos(rdotk), sin(rdotk), dp) if (present(OO_da)) then ! if we are at the origin and at the same band, then the ! matrix element is zero in this convention if ((wigner_seitz%irvec_pw90(1, ir) .eq. 0) .and. (wigner_seitz%irvec_pw90(2, ir) .eq. 0) .and. & (wigner_seitz%irvec_pw90(3, ir) .eq. 0) .and. (i .eq. j)) then OO_da(i, j, 1) = OO_da(i, j, 1) + phase_fac*(OO_R(i, j, ir, 1) & - wigner_seitz%wannier_centres_from_AA_R(1, j)) OO_da(i, j, 2) = OO_da(i, j, 2) + phase_fac*(OO_R(i, j, ir, 2) & - wigner_seitz%wannier_centres_from_AA_R(2, j)) OO_da(i, j, 3) = OO_da(i, j, 3) + phase_fac*(OO_R(i, j, ir, 3) & - wigner_seitz%wannier_centres_from_AA_R(3, j)) ! print *, 'OO_R(i,j,ir,1)', OO_R(i,j,ir,1) ! print *, 'local_wannier_centres(1,j)', local_wannier_centres(1,j) ! print *, 'OO_R(i,j,ir,2)', OO_R(i,j,ir,2) ! print *, 'local_wannier_centres(2,j)', local_wannier_centres(2,j) ! cycle else OO_da(i, j, 1) = OO_da(i, j, 1) + phase_fac*OO_R(i, j, ir, 1) OO_da(i, j, 2) = OO_da(i, j, 2) + phase_fac*OO_R(i, j, ir, 2) OO_da(i, j, 3) = OO_da(i, j, 3) + phase_fac*OO_R(i, j, ir, 3) end if end if if (present(OO_dadb)) then ! same skip as before if ((wigner_seitz%irvec_pw90(1, ir) .eq. 0) .and. (wigner_seitz%irvec_pw90(2, ir) .eq. 0) .and. & (wigner_seitz%irvec_pw90(3, ir) .eq. 0) .and. (i .eq. j)) then do a = 1, 3 do b = 1, 3 OO_dadb(i, j, a, b) = OO_dadb(i, j, a, b) + & cmplx_i*(wigner_seitz%crvec_pw90(b, ir) + & wigner_seitz%wannier_centres_from_AA_R(b, j) & - wigner_seitz%wannier_centres_from_AA_R(b, i))*phase_fac* & (OO_R(i, j, ir, a) - wigner_seitz%wannier_centres_from_AA_R(a, j)) end do end do ! cycle else do a = 1, 3 do b = 1, 3 OO_dadb(i, j, a, b) = OO_dadb(i, j, a, b) + & cmplx_i*(wigner_seitz%crvec_pw90(b, ir) + & wigner_seitz%wannier_centres_from_AA_R(b, j) & - wigner_seitz%wannier_centres_from_AA_R(b, i))* & phase_fac*OO_R(i, j, ir, a) end do end do end if end if end do end do end do end subroutine pw90common_fourier_R_to_k_vec_dadb_TB_conv