pw90common_fourier_R_to_k_vec_dadb_TB_conv Subroutine

public 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)

Uses

  • proc~~pw90common_fourier_r_to_k_vec_dadb_tb_conv~~UsesGraph proc~pw90common_fourier_r_to_k_vec_dadb_tb_conv pw90common_fourier_R_to_k_vec_dadb_TB_conv module~w90_comms w90_comms proc~pw90common_fourier_r_to_k_vec_dadb_tb_conv->module~w90_comms module~w90_constants w90_constants proc~pw90common_fourier_r_to_k_vec_dadb_tb_conv->module~w90_constants module~w90_postw90_types w90_postw90_types proc~pw90common_fourier_r_to_k_vec_dadb_tb_conv->module~w90_postw90_types module~w90_types w90_types proc~pw90common_fourier_r_to_k_vec_dadb_tb_conv->module~w90_types module~w90_utility w90_utility proc~pw90common_fourier_r_to_k_vec_dadb_tb_conv->module~w90_utility module~w90_ws_distance w90_ws_distance proc~pw90common_fourier_r_to_k_vec_dadb_tb_conv->module~w90_ws_distance module~w90_comms->module~w90_constants module~w90_error_base w90_error_base module~w90_comms->module~w90_error_base module~w90_postw90_types->module~w90_comms module~w90_postw90_types->module~w90_constants module~w90_types->module~w90_constants module~w90_utility->module~w90_comms module~w90_utility->module~w90_constants module~w90_ws_distance->module~w90_constants module~w90_error w90_error module~w90_ws_distance->module~w90_error module~w90_error->module~w90_comms module~w90_error->module~w90_error_base

For : For :

Arguments

Type IntentOptional 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(:,:,:,:)

Calls

proc~~pw90common_fourier_r_to_k_vec_dadb_tb_conv~~CallsGraph proc~pw90common_fourier_r_to_k_vec_dadb_tb_conv pw90common_fourier_R_to_k_vec_dadb_TB_conv proc~utility_cart_to_frac utility_cart_to_frac proc~pw90common_fourier_r_to_k_vec_dadb_tb_conv->proc~utility_cart_to_frac proc~utility_inverse_mat utility_inverse_mat proc~pw90common_fourier_r_to_k_vec_dadb_tb_conv->proc~utility_inverse_mat proc~utility_inv3 utility_inv3 proc~utility_inverse_mat->proc~utility_inv3

Called by

proc~~pw90common_fourier_r_to_k_vec_dadb_tb_conv~~CalledByGraph proc~pw90common_fourier_r_to_k_vec_dadb_tb_conv pw90common_fourier_R_to_k_vec_dadb_TB_conv proc~berry_get_sc_klist berry_get_sc_klist proc~berry_get_sc_klist->proc~pw90common_fourier_r_to_k_vec_dadb_tb_conv proc~berry_main berry_main proc~berry_main->proc~berry_get_sc_klist program~postw90 postw90 program~postw90->proc~berry_main

Source Code

  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