tran_green Subroutine

private subroutine tran_green(tot, tott, h_00, h_01, e_scan, g, igreen, invert, nxx, stdout, error, comm)

Uses

  • proc~~tran_green~~UsesGraph proc~tran_green tran_green module~w90_constants w90_constants proc~tran_green->module~w90_constants module~w90_error w90_error proc~tran_green->module~w90_error module~w90_comms w90_comms module~w90_error->module~w90_comms module~w90_error_base w90_error_base module~w90_error->module~w90_error_base module~w90_comms->module~w90_constants module~w90_comms->module~w90_error_base

Arguments

Type IntentOptional Attributes Name
complex(kind=dp), intent(in) :: tot(nxx,nxx)
complex(kind=dp), intent(in) :: tott(nxx,nxx)
real(kind=dp), intent(in) :: h_00(nxx,nxx)
real(kind=dp), intent(in) :: h_01(nxx,nxx)
real(kind=dp), intent(in) :: e_scan
complex(kind=dp), intent(out) :: g(nxx,nxx)
integer, intent(in) :: igreen
integer, intent(in) :: invert
integer, intent(in) :: nxx
integer, intent(in) :: stdout
type(w90_error_type), intent(out), allocatable :: error
type(w90_comm_type), intent(in) :: comm

Calls

proc~~tran_green~~CallsGraph proc~tran_green tran_green proc~set_error_alloc set_error_alloc proc~tran_green->proc~set_error_alloc proc~set_error_dealloc set_error_dealloc proc~tran_green->proc~set_error_dealloc proc~set_error_fatal set_error_fatal proc~tran_green->proc~set_error_fatal zgemm zgemm proc~tran_green->zgemm zgesv zgesv proc~tran_green->zgesv proc~comms_sync_error comms_sync_error proc~set_error_alloc->proc~comms_sync_error proc~set_base_error set_base_error proc~set_error_alloc->proc~set_base_error proc~set_error_dealloc->proc~comms_sync_error proc~set_error_dealloc->proc~set_base_error proc~set_error_fatal->proc~comms_sync_error proc~set_error_fatal->proc~set_base_error

Called by

proc~~tran_green~~CalledByGraph proc~tran_green tran_green proc~tran_bulk tran_bulk proc~tran_bulk->proc~tran_green proc~tran_lcr tran_lcr proc~tran_lcr->proc~tran_green proc~tran_main tran_main proc~tran_main->proc~tran_bulk proc~tran_main->proc~tran_lcr proc~w90_transport w90_transport proc~w90_transport->proc~tran_main program~wannier wannier program~wannier->proc~w90_transport

Source Code

  subroutine tran_green(tot, tott, h_00, h_01, e_scan, g, igreen, invert, nxx, stdout, error, comm)
    !================================================!
    !   construct green's functions
    !
    !   igreen = -1  left surface
    !   igreen =  1  right surface
    !   igreen =  0  bulk
    !
    !   invert = 0 computes g^-1
    !   invert = 1 computes g^-1 and g
    !================================================!

    use w90_constants, only: dp, cmplx_0, cmplx_1
    use w90_error, only: w90_error_type, set_error_alloc, set_error_fatal, set_error_dealloc

    implicit none

    type(w90_error_type), allocatable, intent(out) :: error
    type(w90_comm_type), intent(in) :: comm
    integer, intent(in) :: nxx
    integer, intent(in) :: stdout
    integer, intent(in) :: igreen
    integer, intent(in) :: invert
    real(kind=dp), intent(in) :: e_scan
    real(kind=dp), intent(in) :: h_00(nxx, nxx), h_01(nxx, nxx)
    complex(kind=dp), intent(in) :: tot(nxx, nxx), tott(nxx, nxx)
    complex(kind=dp), intent(out) :: g(nxx, nxx)

    integer :: ierr, info
    integer :: i
    integer, allocatable :: ipiv(:)
    complex(kind=dp), allocatable, dimension(:, :) :: g_inv, eh_00
    complex(kind=dp), allocatable, dimension(:, :) :: s1, s2, c1

    allocate (ipiv(nxx), stat=ierr)
    if (ierr /= 0) then
      call set_error_alloc(error, 'Error in allocating ipiv in tran_green', comm)
      return
    end if
    allocate (g_inv(nxx, nxx), stat=ierr)
    if (ierr /= 0) then
      call set_error_alloc(error, 'Error in allocating g_inv in tran_green', comm)
      return
    end if
    allocate (eh_00(nxx, nxx), stat=ierr)
    if (ierr /= 0) then
      call set_error_alloc(error, 'Error in allocating eh_00 in tran_green', comm)
      return
    end if
    allocate (c1(nxx, nxx), stat=ierr)
    if (ierr /= 0) then
      call set_error_alloc(error, 'Error in allocating c1 in tran_green', comm)
      return
    end if
    allocate (s1(nxx, nxx), stat=ierr)
    if (ierr /= 0) then
      call set_error_alloc(error, 'Error in allocating s1 in tran_green', comm)
      return
    end if
    allocate (s2(nxx, nxx), stat=ierr)
    if (ierr /= 0) then
      call set_error_alloc(error, 'Error in allocating s2 in tran_green', comm)
      return
    end if

    c1(:, :) = cmplx(h_01(:, :), kind=dp)

    select case (igreen)

    case (1)

      ! construct the surface green's function g00

      s1 = cmplx_0
      ! s1 = H_01 * T
      call ZGEMM('N', 'N', nxx, nxx, nxx, cmplx_1, c1, nxx, tot, nxx, cmplx_0, s1, nxx)

      ! eh_00 =  -H_00 - H_01*T
      eh_00(:, :) = cmplx(-h_00(:, :), kind=dp) - s1(:, :)
      ! eh_00 = e_scan -H_00 - H_01*T
      do i = 1, nxx
        eh_00(i, i) = cmplx(e_scan, kind=dp) + eh_00(i, i)
      end do

      g_inv(:, :) = eh_00(:, :)

      ! identity
      g = cmplx_0
      do i = 1, nxx
        g(i, i) = cmplx_1
      end do

      if (invert .eq. 1) then
        call ZGESV(nxx, nxx, eh_00, nxx, ipiv, g, nxx, info)
        if (info .ne. 0) then
          write (stdout, *) 'ERROR:  IN ZGESV IN tran_green, INFO=', info
          call set_error_fatal(error, 'tran_green: problem in ZGESV 1', comm)
          return
        end if
      end if

    case (-1)

      !  construct the dual surface green's function gbar00

      s1 = cmplx_0
      ! s1 = H_01^+ * T^bar
      call ZGEMM('C', 'N', nxx, nxx, nxx, cmplx_1, c1, nxx, tott, nxx, cmplx_0, s1, nxx)

      ! s1 = -H_00 - H_01^+ * T^bar
      eh_00(:, :) = cmplx(-h_00(:, :), kind=dp) - s1(:, :)
      ! s1 = e_scan - H_00 - H_01^+ * T^bar
      do i = 1, nxx
        eh_00(i, i) = cmplx(e_scan, kind=dp) + eh_00(i, i)
      end do

      g_inv(:, :) = eh_00(:, :)

      ! identity
      g = cmplx_0
      do i = 1, nxx
        g(i, i) = cmplx_1
      end do

      if (invert .eq. 1) then
        call ZGESV(nxx, nxx, eh_00, nxx, ipiv, g, nxx, info)
        if (info .ne. 0) then
          write (stdout, *) 'ERROR:  IN ZGESV IN tran_green, INFO=', info
          call set_error_fatal(error, 'tran_green: problem in ZGESV 2', comm)
          return
        end if
      end if

    case (0)

      !  construct the bulk green's function gnn or (if surface=.true.) the
      !  sub-surface green's function

      s1 = cmplx_0
      s2 = cmplx_0
      ! s1 = H_01 * T
      call ZGEMM('N', 'N', nxx, nxx, nxx, cmplx_1, c1, nxx, tot, nxx, cmplx_0, s1, nxx)
      ! s2 = H_01^+ * T^bar
      call ZGEMM('C', 'N', nxx, nxx, nxx, cmplx_1, c1, nxx, tott, nxx, cmplx_0, s2, nxx)

      eh_00(:, :) = cmplx(-h_00(:, :), kind=dp) - s1(:, :) - s2(:, :)
      do i = 1, nxx
        eh_00(i, i) = cmplx(e_scan, kind=dp) + eh_00(i, i)
      end do

      g_inv(:, :) = eh_00(:, :)

      ! identity
      g = cmplx_0
      do i = 1, nxx
        g(i, i) = cmplx_1
      end do

      if (invert .eq. 1) then
        call ZGESV(nxx, nxx, eh_00, nxx, ipiv, g, nxx, info)
        if (info .ne. 0) then
          write (stdout, *) 'ERROR:  IN ZGESV IN tran_green, INFO=', info
          call set_error_fatal(error, 'tran_green: problem in ZGESV 3', comm)
          return
        end if
      end if

    end select

    deallocate (s2, stat=ierr)
    if (ierr /= 0) then
      call set_error_dealloc(error, 'Error in deallocating s2 in tran_green', comm)
      return
    end if
    deallocate (s1, stat=ierr)
    if (ierr /= 0) then
      call set_error_dealloc(error, 'Error in deallocating s1 in tran_green', comm)
      return
    end if
    deallocate (c1, stat=ierr)
    if (ierr /= 0) then
      call set_error_alloc(error, 'Error in deallocating c1 in tran_green', comm)
      return
    end if
    deallocate (eh_00, stat=ierr)
    if (ierr /= 0) then
      call set_error_dealloc(error, 'Error in deallocating eh_00 in tran_green', comm)
      return
    end if
    deallocate (g_inv, stat=ierr)
    if (ierr /= 0) then
      call set_error_dealloc(error, 'Error in deallocating g_inv in tran_green', comm)
      return
    end if
    deallocate (ipiv, stat=ierr)
    if (ierr /= 0) then
      call set_error_dealloc(error, 'Error in deallocating ipiv in tran_green', comm)
      return
    end if

    return

  end subroutine tran_green