rll_global_solutions.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: Wrapper for the calculation of the regular solutions
!> Author: 
!> Wrapper for the calculation of the regular solutions
!------------------------------------------------------------------------------------
module mod_rll_global_solutions

contains

  !-------------------------------------------------------------------------------
  !> Summary: Wrapper for the calculation of the regular solutions
  !> Author: 
  !> Category: single-site, KKRhost
  !> Deprecated: False 
  !> Wrapper for the calculation of the regular solutions for the impurity code `KKRimp`
  !-------------------------------------------------------------------------------
  subroutine rll_global_solutions(rpanbound,rmesh,vll,ull,rll,tllp,ncheb,npan,lmsize,   &
    lmsize2,lbessel,nrmax,nvec,jlk_index,hlk,jlk,hlk2,jlk2,gmatprefactor,cmoderll,  &
    use_sratrick1,alphaget)     ! LLY
    ! ************************************************************************
    ! for description see rllsll routine
    ! ************************************************************************
    use :: mod_timing, only: timing_start, timing_stop  ! timing routine
#ifdef CPP_HYBRID
    use :: omp_lib               ! omp functions
#endif

    use :: mod_constants, only: cone, czero
    use :: mod_datatypes, only: dp
    use :: mod_chebint, only: chebint
    use :: mod_rll_local_solutions, only: rll_local_solutions

    implicit none
    integer :: ncheb             ! number of chebyshev nodes
    integer :: npan              ! number of panels
    integer :: lmsize            ! lm-components * nspin
    integer :: lmsize2           ! lmsize * nvec
    integer :: nvec              ! spinor integer
    ! nvec=1 non-rel, nvec=2 for sra and dirac
    integer :: nrmax             ! total number of rad. mesh points
    integer :: lbessel, use_sratrick1 ! dimensions etc.

    ! running indices
    integer :: lm1, lm2
    integer :: info, icheb, ipan, mn, nm

    ! source terms
    complex (kind=dp) :: gmatprefactor ! prefactor of green function
    ! non-rel: = kappa = sqrt e
    complex (kind=dp) :: hlk(lbessel, nrmax), jlk(lbessel, nrmax), hlk2(lbessel, nrmax), jlk2(lbessel, nrmax)

    integer :: jlk_index(2*lmsize)

    character (len=1) :: cmoderll                           ! These define the op(V(r))

    ! cmoderll ="1" : op( )=identity
    ! cmoderll ="T" : op( )=transpose in L
 
    complex (kind=dp) :: ull(lmsize2, lmsize, nrmax)
    complex (kind=dp) :: rll(lmsize2, lmsize, nrmax), & ! reg. fredholm sol.
      tllp(lmsize, lmsize), &    ! t-matrix
      vll(lmsize*nvec, lmsize*nvec, nrmax) ! potential term in 5.7
    ! bauer, phd

    complex (kind=dp), allocatable :: work(:, :), allp(:, :, :), bllp(:, :, :), & ! eq. 5.9, 5.10 for reg. sol
      mrnvy(:, :, :), mrnvz(:, :, :), & ! ***************
      mrjvy(:, :, :), mrjvz(:, :, :) ! eq. 5.19-5.22
    complex (kind=dp), allocatable :: yrf(:, :, :, :), & ! source terms (different array
      zrf(:, :, :, :)            ! ordering)
    ! chebyshev arrays
    real (kind=dp) :: c1(0:ncheb, 0:ncheb), rpanbound(0:npan), drpan2
    real (kind=dp) :: cslc1(0:ncheb, 0:ncheb), & ! Integration matrix from left ( C*S_L*C^-1 in eq. 5.53)
      csrc1(0:ncheb, 0:ncheb), & ! Same from right ( C*S_R*C^-1 in eq. 5.54)
      tau(0:ncheb, 0:npan), &    ! Radial mesh point
      slc1sum(0:ncheb), rmesh(nrmax)

    integer :: ipiv(0:ncheb, lmsize2)
    integer :: ierror
    integer :: idotime
    integer, parameter :: directsolv = 1
    complex (kind=dp) :: alphaget(lmsize, lmsize) ! LLY

#ifdef CPP_HYBRID
    ! openMP variable --sacin 23/04/2015
    integer :: thread_id
#endif

    ! ***********************************************************************
    ! SRA trick
    ! ***********************************************************************
    ! on page 68 of Bauer, PhD, a method is described how to speed up the
    ! calculations in case of the SRA. A similar approach is implemented
    ! here by using Eq. 4.132 and substituting DV from 4.133, and discretising
    ! the radial mesh of the Lippmann-Schwinger eq. according to 5.68.
    ! The Lippmann-Schwinger equation leads to a matrix inversion
    ! problem. The matrix M which needs to be inverted has a special form
    ! if the SRA approximation is used:

    ! matrix A ( C 0)     (same as in eq. 5.68)
    ! ( B 1)
    ! (C, B are matricies here)

    ! inverse of A is   (C^-1    0 )
    ! (-B C^-1 1 )
    ! Thus, it is sufficient to only inverse the matrix C which saves computational
    ! time. This is refered to as the SRA trick.
    ! ***********************************************************************
    ! in future implementation equation 4.134 is supposed to be
    ! implemented which should lead to an additional speed-up.
    ! ***********************************************************************

    ! turn timing output off if in the host code
    idotime = 0
#ifdef test_run
    idotime = 1
#endif
    if (idotime==1) call timing_start('rll-glob')


    do ipan = 1, npan
      do icheb = 0, ncheb
        mn = ipan*ncheb + ipan - icheb
        tau(icheb, ipan) = rmesh(mn)
      end do
    end do

    call chebint(cslc1, csrc1, slc1sum, c1, ncheb)

    allocate (mrnvy(lmsize,lmsize,npan), mrnvz(lmsize,lmsize,npan))
    allocate (mrjvy(lmsize,lmsize,npan), mrjvz(lmsize,lmsize,npan))
    allocate (yrf(lmsize2,lmsize,0:ncheb,npan))
    allocate (zrf(lmsize2,lmsize,0:ncheb,npan))

    allocate (work(lmsize,lmsize))
    allocate (allp(lmsize,lmsize,0:npan), bllp(lmsize,lmsize,0:npan))

    if (idotime==1) call timing_start('local')

#ifdef CPP_HYBRID
    ! $OMP PARALLEL DEFAULT (PRIVATE) &
    ! $OMP& SHARED(tau,npan,drpan2,rpanbound,mrnvy,mrnvz,mrjvy,mrjvz,yrf) &
    ! $OMP& SHARED(zrf,nvec,lmsize,lmsize2,ncheb,jlk,jlk2,jlk_index,vll) &
    ! $OMP& SHARED(gmatprefactor,hlk,hlk2,cslc1,csrc1,slc1sum) &
    ! $OMP& SHARED(cmoderll,use_sratrick, rmesh)

    thread_id = omp_get_thread_num()
#endif

    ! loop over subintervals
#ifdef CPP_HYBRID
    ! openMP pragmas added sachin, parallel region starts earlier to get allocations of arrays right

    ! $OMP DO
#endif
    do ipan = 1, npan

      drpan2 = (rpanbound(ipan)-rpanbound(ipan-1))/2.0_dp ! *(b-a)/2 in eq. 5.53, 5.54
      call rll_local_solutions(vll,tau(0,ipan),drpan2,cslc1,slc1sum,mrnvy(1,1,ipan),& 
        mrnvz(1,1,ipan),mrjvy(1,1,ipan),mrjvz(1,1,ipan),yrf(1,1,0,ipan),            &
        zrf(1,1,0,ipan),ncheb,ipan,lmsize,lmsize2,nrmax,nvec,jlk_index,hlk,jlk,hlk2,& 
        jlk2,gmatprefactor,cmoderll,lbessel,use_sratrick1)

    end do                       ! ipan
#ifdef CPP_HYBRID
    ! $OMP END DO
    ! $OMP END PARALLEL
#endif
    ! end the big loop over the subintervals

    if (idotime==1) call timing_stop('local')
    if (idotime==1) call timing_start('afterlocal')

    ! ***********************************************************************
    ! calculate A(M), B(M), C(M), D(M)
    ! according to 5.17-5.18 (regular solution) of Bauer PhD
    ! C,D are calculated accordingly for the irregular solution
    ! (starting condition: A(0) = 1, B(0) = 0, C(MMAX) = 0 and D(MMAX) = 1)
    ! ***********************************************************************

    ! regular
    do lm2 = 1, lmsize
      do lm1 = 1, lmsize
        bllp(lm1, lm2, 0) = czero
        allp(lm1, lm2, 0) = czero
      end do
    end do

    do lm1 = 1, lmsize
      allp(lm1, lm1, 0) = cone
    end do

    do ipan = 1, npan
      call zcopy(lmsize*lmsize, allp(1,1,ipan-1), 1, allp(1,1,ipan), 1)
      call zcopy(lmsize*lmsize, bllp(1,1,ipan-1), 1, bllp(1,1,ipan), 1)
      call zgemm('n','n',lmsize,lmsize,lmsize,-cone,mrnvy(1,1,ipan),lmsize,         &
        allp(1,1,ipan-1),lmsize,cone,allp(1,1,ipan),lmsize)
      call zgemm('n','n',lmsize,lmsize,lmsize,-cone,mrnvz(1,1,ipan),lmsize,         &
        bllp(1,1,ipan-1),lmsize,cone,allp(1,1,ipan),lmsize)
      call zgemm('n','n',lmsize,lmsize,lmsize,cone,mrjvy(1,1,ipan),lmsize,          &
        allp(1,1,ipan-1),lmsize,cone,bllp(1,1,ipan),lmsize)
      call zgemm('n','n',lmsize,lmsize,lmsize,cone,mrjvz(1,1,ipan),lmsize,          &
        bllp(1,1,ipan-1),lmsize,cone,bllp(1,1,ipan),lmsize)
    end do

    ! ***********************************************************************
    ! determine the regular solution ull by using 5.14
    ! ***********************************************************************
    do ipan = 1, npan
      do icheb = 0, ncheb
        mn = ipan*ncheb + ipan - icheb
        call zgemm('n','n',lmsize2,lmsize,lmsize,cone,yrf(1,1,icheb,ipan),lmsize2,  &
          allp(1,1,ipan-1),lmsize,czero,ull(1,1,mn),lmsize2)
        call zgemm('n','n',lmsize2,lmsize,lmsize,cone,zrf(1,1,icheb,ipan),lmsize2,  &
          bllp(1,1,ipan-1),lmsize,cone,ull(1,1,mn),lmsize2)
      end do
    end do

    if (idotime==1) call timing_stop('afterlocal')
    if (idotime==1) call timing_start('endstuff')

    ! ***********************************************************************
    ! next part converts the volterra solution u of equation (5.7) to
    ! the fredholm solution r by employing eq. 4.122 and 4.120 of bauer, phd
    ! and the t-matrix is calculated
    ! ***********************************************************************

    call zgetrf(lmsize, lmsize, allp(1,1,npan), lmsize, ipiv, info) ! invert alpha
    call zgetri(lmsize, allp(1,1,npan), lmsize, ipiv, work, lmsize*lmsize, info) ! invert alpha -> transformation matrix rll=alpha^-1*rll
    ! get alpha matrix
    do lm1 = 1, lmsize           ! LLY
      do lm2 = 1, lmsize         ! LLY
        alphaget(lm1, lm2) = allp(lm1, lm2, npan) ! LLY
      end do                     ! LLY
    end do                       ! LLY

    ! calculation of the t-matrix ! calc t-matrix tll = bll*alpha^-1
    call zgemm('n','n',lmsize,lmsize,lmsize,cone/gmatprefactor,bllp(1,1,npan),      & 
      lmsize,allp(1,1,npan),lmsize,czero,tllp,lmsize)

    do nm = 1, nrmax
      call zgemm('n','n',lmsize2,lmsize,lmsize,cone,ull(1,1,nm),lmsize2,            &
        allp(1,1,npan),lmsize,czero,rll(1,1,nm),lmsize2)
    end do

    if (idotime==1) call timing_stop('endstuff')
    if (idotime==1) call timing_start('checknan')
    if (idotime==1) call timing_stop('checknan')
    if (idotime==1) call timing_stop('rll-glob')

    deallocate (work, allp, bllp, mrnvy, mrnvz, mrjvy, mrjvz, yrf, zrf, stat=ierror)
    if (ierror/=0) stop '[rll-glob] ERROR in deallocating arrays'

  end subroutine rll_global_solutions

end module mod_rll_global_solutions