get_FF_R Subroutine

public subroutine get_FF_R(num_bands, num_kpts, num_wann, wigner_seitz, ws_distance, ws_region, v_matrix, FF_R, dis_manifold, kmesh_info, kpt_latt, print_output, have_disentangled, stdout, seedname, timer, error, comm)

Uses

  • proc~~get_ff_r~~UsesGraph proc~get_ff_r get_FF_R module~w90_postw90_types w90_postw90_types proc~get_ff_r->module~w90_postw90_types module~w90_types w90_types proc~get_ff_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

FF_ab(R) = <0|r_a.(r-R)_b|R> is the Fourier transform of FF_ab(k) = (a=alpha,b=beta)

Arguments

Type IntentOptional Attributes Name
integer, intent(in) :: num_bands
integer, intent(in) :: num_kpts
integer, intent(in) :: num_wann
type(wigner_seitz_type), intent(in) :: wigner_seitz
type(ws_distance_type), intent(in) :: ws_distance
type(ws_region_type), intent(in) :: ws_region
complex(kind=dp), intent(in) :: v_matrix(:,:,:)
complex(kind=dp), intent(inout), allocatable :: FF_R(:,:,:,:,:)
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
logical, intent(in) :: have_disentangled
integer, intent(in) :: stdout
character(len=50), intent(in) :: seedname
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_ff_r~~CallsGraph proc~get_ff_r get_FF_R interface~comms_bcast comms_bcast proc~get_ff_r->interface~comms_bcast proc~fourier_q_to_r fourier_q_to_R proc~get_ff_r->proc~fourier_q_to_r proc~get_win_min get_win_min proc~get_ff_r->proc~get_win_min proc~io_stopwatch_start io_stopwatch_start proc~get_ff_r->proc~io_stopwatch_start proc~io_stopwatch_stop io_stopwatch_stop proc~get_ff_r->proc~io_stopwatch_stop proc~mpirank mpirank proc~get_ff_r->proc~mpirank proc~operator_wigner_setup operator_wigner_setup proc~get_ff_r->proc~operator_wigner_setup proc~set_error_fatal set_error_fatal proc~get_ff_r->proc~set_error_fatal proc~set_error_file set_error_file proc~get_ff_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~comms_sync_error comms_sync_error proc~set_error_fatal->proc~comms_sync_error proc~set_base_error set_base_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

Source Code

  subroutine get_FF_R(num_bands, num_kpts, num_wann, wigner_seitz, ws_distance, ws_region, v_matrix, &
                      FF_R, dis_manifold, kmesh_info, kpt_latt, print_output, have_disentangled, stdout, &
                      seedname, timer, error, comm)
    !================================================
    !
    !! FF_ab(R) = <0|r_a.(r-R)_b|R> is the Fourier transform of
    !! FF_ab(k) = <del_a u|del_b u> (a=alpha,b=beta)
    !
    !================================================
    use w90_postw90_types, only: 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(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) :: num_bands, num_kpts, num_wann, stdout

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

    complex(kind=dp), intent(in) :: v_matrix(:, :, :)
    complex(kind=dp), allocatable, intent(inout) :: FF_R(:, :, :, :, :) ! <0|r_alpha.(r-R)_beta|R>
    complex(kind=dp), allocatable :: FF_R_temp(:, :, :, :, :)

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

    logical, intent(in) :: have_disentangled

    ! local variables
    integer          :: i, j, ii, jj, m, n, a, b, nn1, nn2, ik, nb_tmp, nkp_tmp, nntot_tmp, &
                        uIu_in, qb1, qb2, winmin_qb1, winmin_qb2

    integer, allocatable          :: num_states(:)
    complex(kind=dp), allocatable :: FF_q(:, :, :, :, :)
    complex(kind=dp), allocatable :: Lo_qb1_q_qb2(:, :)
    complex(kind=dp), allocatable :: L_qb1_q_qb2(:, :)
    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_FF_R', timer)

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

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

    if (on_root) then

      allocate (Lo_qb1_q_qb2(num_bands, num_bands))
      allocate (L_qb1_q_qb2(num_wann, num_wann))
      allocate (FF_q(num_wann, num_wann, num_kpts, 3, 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

      open (newunit=uIu_in, file=TRIM(seedname)//".uIu", form='unformatted', &
            status='old', action='read', err=107)
      write (stdout, '(/a)', advance='no') &
        ' Reading uIu overlaps from '//trim(seedname)//'.uIu in get_FF_R: '
      read (uIu_in, err=108, end=108) header
      write (stdout, '(a)') trim(header)
      read (uIu_in, err=108, end=108) nb_tmp, nkp_tmp, nntot_tmp
      if (nb_tmp .ne. num_bands) then
        call set_error_fatal(error, trim(seedname)//'.uIu has not the right number of bands', comm)
        return
      end if
      if (nkp_tmp .ne. num_kpts) then
        call set_error_fatal(error, trim(seedname)//'.uIu has not the right number of k-points', comm)
        return
      end if
      if (nntot_tmp .ne. kmesh_info%nntot) then
        call set_error_fatal(error, trim(seedname)//'.uIu has not the right number of nearest neighbours', comm)
        return
      end if

      FF_q = cmplx_0
      do ik = 1, num_kpts
        do nn2 = 1, kmesh_info%nntot
          qb2 = kmesh_info%nnlist(ik, nn2)

          call get_win_min(num_bands, dis_manifold, qb2, winmin_qb2, have_disentangled)
          do nn1 = 1, kmesh_info%nntot
            qb1 = kmesh_info%nnlist(ik, nn1)
            call get_win_min(num_bands, dis_manifold, qb1, winmin_qb1, have_disentangled)
            !
            ! Read from .uIu file the matrices <u_{q+b1}|u_{q+b2}>
            ! between the original ab initio eigenstates
            !
            !               do m=1,num_bands
            !                  do n=1,num_bands
            !                     read(uIu_in,err=108,end=108) Lo_qb1_q_qb2(m,n)
            !                  end do
            !               end do
            read (uIu_in, err=108, end=108) &
              ((Lo_qb1_q_qb2(n, m), n=1, num_bands), m=1, num_bands)
            !
            ! **************************************************************
            ! 2013-08-09: Do we need to take a transpose here?! SEE get_CC_R
            Lo_qb1_q_qb2 = transpose(Lo_qb1_q_qb2) ! added 2013-08-09 (?)
            ! **************************************************************
            !
            ! Transform to projected subspace, Wannier gauge
            !
            L_qb1_q_qb2(:, :) = cmplx_0
            do m = 1, num_wann
              do n = 1, num_wann
                do i = 1, num_states(qb1)
                  ii = winmin_qb1 + i - 1
                  do j = 1, num_states(qb2)
                    jj = winmin_qb2 + j - 1
                    L_qb1_q_qb2(n, m) = L_qb1_q_qb2(n, m) &
                                        + conjg(v_matrix(i, n, qb1)) &
                                        *Lo_qb1_q_qb2(ii, jj) &
                                        *v_matrix(j, m, qb2)
                  end do
                end do
              end do
            end do
            do b = 1, 3
              do a = 1, b
                FF_q(:, :, ik, a, b) = FF_q(:, :, ik, a, b) &
                                       + kmesh_info%wb(nn1)*kmesh_info%bk(a, nn1, ik) &
                                       *kmesh_info%wb(nn2)*kmesh_info%bk(b, nn2, ik)*L_qb1_q_qb2(:, :)
              end do
            end do
          end do !nn1
        end do !nn2
        do b = 1, 3
          do a = 1, b
            FF_q(:, :, ik, b, a) = conjg(transpose(FF_q(:, :, ik, a, b)))
          end do
        end do
      end do !ik

      close (uIu_in)

      do b = 1, 3
        do a = 1, 3
          call fourier_q_to_R(num_kpts, wigner_seitz%nrpts, wigner_seitz%irvec, kpt_latt, &
                              FF_q(:, :, :, a, b), FF_R_temp(:, :, :, a, b))
        end do
      end do

      do b = 1, 3
        do a = 1, 3
          call operator_wigner_setup(ws_distance, ws_region, wigner_seitz, num_wann, &
                                     FF_R_temp(:, :, :, a, b), FF_R(:, :, :, a, b))
        end do
      end do

    end if !on_root

    call comms_bcast(FF_R(1, 1, 1, 1, 1), num_wann*num_wann*wigner_seitz%nrpts_pw90*3*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_FF_R', timer)
    return

    deallocate (FF_R_temp)

107 call set_error_file(error, 'Error: Problem opening input file '//trim(seedname)//'.uIu', comm)
    return
108 call set_error_file(error, 'Error: Problem reading input file '//trim(seedname)//'.uIu', comm)
    return

  end subroutine get_FF_R