surfgf.f90 Source File


Source Code

!-----------------------------------------------------------------------------------------!
! Copyright (c) 2018 Peter Grünberg Institut, Forschungszentrum Jülich, Germany           !
! This file is part of Jülich KKR code and available as free software under the conditions!
! of the MIT license as expressed in the LICENSE.md file in more detail.                  !
!-----------------------------------------------------------------------------------------!

!-------------------------------------------------------------------------------
!> Summary: Solve surface green's function: \(f(x)=ml\left(m0-x\right)^{\left(-1\right)*mr}\)
!> Author: 
!> Solve surface green's function: \(f(x)=ml\left(m0-x\right)^{\left(-1\right)*mr}\)
!> method: decimation technique
!> input:  ml,m0,mr - complex rectangular matrices
!> output: x        - result, matrix of same type as before
!------------------------------------------------------------------------------------
!> @note NEW VERSION (speeded up) by V.Bellini (march,1999)
!> @endnote
!------------------------------------------------------------------------------------
module mod_surfgf

contains

  !-------------------------------------------------------------------------------
  !> Summary: Solve surface green's function: \(f(x)=ml(m0-x)^{(-1)*mr}\)
  !> Author: 
  !> Category: KKRhost, structural-greensfunction
  !> Deprecated: False 
  !> Solve surface green's function: \(f(x)=ml(m0-x)^{(-1)*mr}\)
  !> method: decimation technique
  !> input:  ml,m0,mr - complex rectangular matrices
  !> output: x        - result, matrix of same type as before
  !-------------------------------------------------------------------------------
  !> @note NEW VERSION (speeded up) by V.Bellini (march,1999)
  !> @endnote
  !-------------------------------------------------------------------------------
  subroutine surfgf(ndim, ml, m0, mr, x, itermax, errmax, ichck)

    use :: mod_constants
    use :: mod_profiling
    use :: global_variables
    use :: mod_datatypes, only: dp
    use :: mod_cinit

    implicit none

    ! .. Input variables
    integer, intent (in) :: ndim
    integer, intent (in) :: ichck
    integer, intent (in) :: itermax
    real (kind=dp), intent (in) :: errmax
    ! .. Input arrays
    complex (kind=dp), dimension (ndim, ndim), intent (in) :: m0
    complex (kind=dp), dimension (ndim, ndim), intent (in) :: ml
    complex (kind=dp), dimension (ndim, ndim), intent (in) :: mr
    ! .. Output variables
    complex (kind=dp), dimension (ndim, ndim), intent (out) :: x
    ! .. Local Scalars
    integer :: i, info, iter, j, n
    real (kind=dp) :: err, sum, xim, xre
    ! .. Local Arrays
    integer, dimension (ndim) :: ipvt
    complex (kind=dp), dimension (ndim, ndim) :: aa, alfa, bb, beta, cc, cunit, eps, tempin
    complex (kind=dp), dimension (ndim, ndim) :: tempout, y1, y2
    ! ..

    call cinit(ndim*ndim, cunit)
    do n = 1, ndim
      cunit(n, n) = cone
    end do

    call zcopy(ndim*ndim, m0, 1, eps, 1)
    call zcopy(ndim*ndim, ml, 1, alfa, 1)
    call zcopy(ndim*ndim, mr, 1, beta, 1)
    call zcopy(ndim*ndim, m0, 1, x, 1)

    iter = 1
100 continue

    call zcopy(ndim*ndim, eps, 1, y1, 1)
    call zcopy(ndim*ndim, y1, 1, tempin, 1)
    call zgetrf(ndim, ndim, tempin, ndim, ipvt, info)

    ! aa = eps^-1 * alfa
    call zcopy(ndim*ndim, alfa, 1, tempout, 1)
    call zgetrs('N', ndim, ndim, tempin, ndim, ipvt, tempout, ndim, info)
    call zcopy(ndim*ndim, tempout, 1, aa, 1)

    ! bb = eps^-1 * beta

    call zcopy(ndim*ndim, beta, 1, tempout, 1)
    call zgetrs('N', ndim, ndim, tempin, ndim, ipvt, tempout, ndim, info)
    call zcopy(ndim*ndim, tempout, 1, bb, 1)

    ! alfa_new = alfa * aa

    call zgemm('N', 'N', ndim, ndim, ndim, cone, alfa, ndim, aa, ndim, czero, y1, ndim)

    ! beta_new = beta * bb

    call zgemm('N', 'N', ndim, ndim, ndim, cone, beta, ndim, bb, ndim, czero, y2, ndim)

    ! cc = - alfa * bb

    call zgemm('N', 'N', ndim, ndim, ndim, -cone, alfa, ndim, bb, ndim, czero, cc, ndim)

    ! x_new = x + cc

    call zaxpy(ndim*ndim, cone, cc, 1, x, 1)

    ! cc = eps + cc

    call zaxpy(ndim*ndim, cone, cc, 1, eps, 1)

    ! eps_new = cc - beta * aa

    call zgemm('N', 'N', ndim, ndim, ndim, -cone, beta, ndim, aa, ndim, cone, eps, ndim)

    call zcopy(ndim*ndim, y1, 1, alfa, 1)
    call zcopy(ndim*ndim, y2, 1, beta, 1)

    sum = 0.e0_dp
    do i = 1, ndim
      do j = 1, ndim
        xre = real(alfa(i,j))
        xim = aimag(alfa(i,j))
        sum = sum + xre*xre + xim*xim
      end do
    end do

    err = sqrt(sum)
    if (err<errmax .or. iter>itermax) go to 110
    iter = iter + 1
    go to 100

110 continue

    call zcopy(ndim*ndim, x, 1, tempin, 1)
    call zcopy(ndim*ndim, cunit, 1, tempout, 1)
    call zgetrf(ndim, ndim, tempin, ndim, ipvt, info)
    call zgetrs('N', ndim, ndim, tempin, ndim, ipvt, tempout, ndim, info)
    call zcopy(ndim*ndim, tempout, 1, x, 1)

    call zgemm('N', 'N', ndim, ndim, ndim, cone, x, ndim, mr, ndim, czero, tempin, ndim)
    call zgemm('N', 'N', ndim, ndim, ndim, cone, ml, ndim, tempin, ndim, czero, x, ndim)

    if (iter>itermax) then
      write (6, fmt='('' itermax too small.  iter='',i3)') iter
      write (6, '('' Surfgf:  iter='',i4,''  error='',d14.7)') iter, err
    end if
    if (ichck==0) return
    ! write(6,'('' Surfgf:  iter='',i4,''  error='',d12.7)') iter,err
    ! write(6,'(/'' X matrix'')')
    ! write(6,*)

    return
  end subroutine surfgf

end module mod_surfgf