!-----------------------------------------------------------------------------------------! ! 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: Calculates the charge density inside r(irmin) in case of a non spherical input potential. !> Author: B. Drittler !> Calculates the charge density inside r(irmin) in case of a non spherical input potential. !> Fills the array `cden` for the complex density of states the non spher. !> wavefunctions are approximated in that region in the following way: !> !> * The regular one (ir < irmin = irws-irns) : !> \begin{equation} !> pns(ir,lm1,lm2) = pz(ir,l1) ar(lm1,lm2) !> \end{equation} !> where \(pz\) is the regular wavefct of the spherically symmetric part of the !> potential and ar the alpha matrix (see subroutine `regns`) !> * The irregular one (ir < irmin) : !> \begin{equation} !> qns(ir,lm1,lm2) = pz(ir,l1) cr(lm1,lm2)+ qz(ir,l1) dr(lm1,lm2) !> \end{equation} !> where \(pz\) is the regular and \(qz\) is the irregular wavefct of the !> spherically symmetric part of the potential and \(cr\) , \(dr\) the matrices calculated !> at the point `irmin` (see subroutine `irwns()`). !> The structured part of the greens-function (`gmat`) is symmetric in its lm-indices, !> therefore only one half of the matrix is calculated in the subroutine for the !> back-symmetrisation . !> Rhe gaunt coeffients are symmetric too (since the are calculated using the real spherical harmonics). !> Rhat is why the `lm2-` and the `lm02-` loops are only only going up to `lm1` or `lm01` !> and the summands are multiplied by a factor of 2 in the case of `lm1 .ne. lm2` or `lm01 .ne. lm02`. !> (see notes by B. Drittler) !------------------------------------------------------------------------------------ !> @note !> !> * Remember that the matrices `ar`,`cr`,`dr` are rescaled (see subroutines `irwns()` and `regns()`) !> * Arrays `rho2ns` and `cden` are initialized in subroutine `rhoout`. !> @endnote !> @warning The gaunt coeffients which are used here are ordered in a special way !> (see subroutine `gaunt()`) !> @endwarning !------------------------------------------------------------------------------------ module mod_rhoin contains !------------------------------------------------------------------------------- !> Summary: Calculates the charge density inside r(irmin) in case of a non spherical input potential. !> Author: B. Drittler !> Category: physical-observables, KKRhost !> Deprecated: False !> Calculates the charge density inside r(irmin) in case of a non spherical input potential. !> Fills the array `cden` for the complex density of states the non spher. !> wavefunctions are approximated in that region in the following way: !> !> * The regular one (ir < irmin = irws-irns) : !> \begin{equation} !> pns(ir,lm1,lm2) = pz(ir,l1) ar(lm1,lm2) !> \end{equation} !> where \(pz\) is the regular wavefct of the spherically symmetric part of the !> potential and ar the alpha matrix (see subroutine `regns`) !> * The irregular one (ir < irmin) : !> \begin{equation} !> qns(ir,lm1,lm2) = pz(ir,l1) cr(lm1,lm2)+ qz(ir,l1) dr(lm1,lm2) !> \end{equation} !> where \(pz\) is the regular and \(qz\) is the irregular wavefct of the !> spherically symmetric part of the potential and \(cr\) , \(dr\) the matrices calculated !> at the point `irmin` (see subroutine `irwns()`). !> The structured part of the greens-function (`gmat`) is symmetric in its lm-indices, !> therefore only one half of the matrix is calculated in the subroutine for the !> back-symmetrisation . !> Rhe gaunt coeffients are symmetric too (since the are calculated using the real spherical harmonics). !> Rhat is why the `lm2-` and the `lm02-` loops are only only going up to `lm1` or `lm01` !> and the summands are multiplied by a factor of 2 in the case of `lm1 .ne. lm2` or `lm01 .ne. lm02`. !> (see notes by B. Drittler) !------------------------------------------------------------------------------- !> @note !> * Remember that the matrices `ar`,`cr`,`dr` are rescaled (see subroutines `irwns()` and `regns()`) !> * Arrays `rho2ns` and `cden` are initialized in subroutine `rhoout`. !> @endnote !> @warning The gaunt coeffients which are used here are ordered in a special way !> (see subroutine `gaunt()`) !> @endwarning !------------------------------------------------------------------------------- subroutine rhoin(ar,cden,cr,df,gmat,ek,rho2ns,irc1,nsra,efac,pz,fz,qz,sz,cleb, & icleb,jend,iend,ekl,cdenlm) use :: mod_datatypes, only: dp use :: global_variables, only: lmmaxd, lmaxd, irmd, ncleb, lmpotd use :: mod_constants, only: pi, czero implicit none ! interface complex (kind=dp) :: df, ek integer :: iend, irc1, nsra complex (kind=dp) :: ar(lmmaxd, lmmaxd), cden(irmd, 0:lmaxd), cr(lmmaxd, lmmaxd), efac(lmmaxd), ekl(0:lmaxd), fz(irmd, 0:lmaxd), gmat(lmmaxd, lmmaxd), pz(irmd, 0:lmaxd), qz(irmd, 0:lmaxd), & sz(irmd, 0:lmaxd), cdenlm(irmd, lmmaxd) real (kind=dp) :: cleb(ncleb), rho2ns(irmd, lmpotd) integer :: icleb(ncleb, 4), jend(lmpotd, 0:lmaxd, 0:lmaxd) ! local complex (kind=dp) :: efac1, efac2, ffz, gmatl, ppz, v1, v2 real (kind=dp) :: c0ll integer :: i, ir, j, j0, j1, l, l1, l2, lm1, lm2, lm3, lm3max, ln2, ln3, m complex (kind=dp) :: vr(lmmaxd, lmmaxd), wf(irmd, 0:lmaxd, 0:lmaxd), wr(lmmaxd, lmmaxd) #ifdef __GFORTRAN__ ! for the gfortran compiler zdotu leads to a segfault, then using ! dot_product gives the correct result without segfault, this needs these ! auxiliary arrays complex (kind=dp) :: ar2(lmmaxd**2), vr2(lmmaxd**2) #endif complex (kind=dp), external :: zdotu ! C0LL = 1/sqrt(4*pi) c0ll = 1.0e0_dp/sqrt(4.0e0_dp*pi) lm3max = icleb(iend, 3) ! ---> set up array wr(lm1,lm2) ! use first vr wr = czero vr = czero do lm2 = 1, lmmaxd ln2 = lm2 v2 = efac(lm2)*efac(lm2)*gmat(ln2, ln2) do lm1 = 1, lmmaxd vr(lm1, lm2) = ek*cr(lm1, lm2) + v2*ar(lm1, lm2) end do end do ! ---> using symmetry of structural green function do lm2 = 2, lmmaxd ln2 = lm2 efac2 = 2.0e0_dp*efac(lm2) do lm3 = 1, lm2 - 1 ln3 = lm3 v1 = efac2*gmat(ln3, ln2)*efac(lm3) do lm1 = 1, lmmaxd vr(lm1, lm2) = vr(lm1, lm2) + v1*ar(lm1, lm3) end do end do end do #ifdef __GFORTRAN__ ar2 = reshape(ar, [lmmaxd**2]) vr2 = reshape(vr, [lmmaxd**2]) #endif do lm1 = 1, lmmaxd efac1 = efac(lm1) #ifdef __GFORTRAN__ wr(lm1, lm1) = dot_product(conjg(ar2(lm1::lmmaxd)), vr2(lm1::lmmaxd))/(efac1*efac1) ! this works only with conjugation due to definition of dot_product #else wr(lm1, lm1) = zdotu(lmmaxd, ar(lm1,1), lmmaxd, vr(lm1,1), lmmaxd)/(efac1*efac1) ! this works with the intel compiler #endif do lm2 = 1, lm1 - 1 ! ---> using symmetry of gaunt coeffients efac2 = efac(lm2) #ifdef __GFORTRAN__ wr(lm1, lm2) = ( dot_product(conjg(ar2(lm1::lmmaxd)),vr2(lm2::lmmaxd)) + dot_product(conjg(ar2(lm2::lmmaxd)),vr2(lm1::lmmaxd)) )/(efac1*efac2) ! this works with gfortran #else wr(lm1, lm2) = ( zdotu(lmmaxd,ar(lm1,1),lmmaxd,vr(lm2,1),lmmaxd) + zdotu(lmmaxd,ar(lm2,1),lmmaxd,vr(lm1,1),lmmaxd) )/(efac1*efac2) ! this works with the intel compiler #endif end do end do ! ---> set up array wf(l1,l2) = pz(l1)*pz(l2) if (nsra==2) then do l1 = 0, lmaxd do l2 = 0, l1 do ir = 2, irc1 wf(ir, l1, l2) = pz(ir, l1)*pz(ir, l2) + fz(ir, l1)*fz(ir, l2) end do end do end do else do l1 = 0, lmaxd do l2 = 0, l1 do ir = 2, irc1 wf(ir, l1, l2) = pz(ir, l1)*pz(ir, l2) end do end do end do end if ! ---> first calculate only the spherically symmetric contribution ! remember that the gaunt coeffients for that case are 1/sqrt(4 pi) do l = 0, lmaxd gmatl = czero do m = -l, l lm1 = l*(l+1) + m + 1 gmatl = gmatl + wr(lm1, lm1) end do if (nsra==2) then do i = 2, irc1 ppz = pz(i, l) ffz = fz(i, l) cden(i, l) = ppz*(gmatl*ppz+ekl(l)*qz(i,l)) + ffz*(gmatl*ffz+ekl(l)*sz(i,l)) rho2ns(i, 1) = rho2ns(i, 1) + c0ll*aimag(df*cden(i,l)) ! Implicit integration over energies do m = -l, l lm1 = l*(l+1) + m + 1 cdenlm(i, lm1) = ppz*(wr(lm1,lm1)*ppz+ek*qz(i,l)) + ffz*(wr(lm1,lm1)*ffz+ek*sz(i,l)) end do end do else do i = 2, irc1 ppz = pz(i, l) cden(i, l) = ppz*(gmatl*ppz+ekl(l)*qz(i,l)) rho2ns(i, 1) = rho2ns(i, 1) + c0ll*aimag(df*cden(i,l)) ! Implicit integration over energies do m = -l, l lm1 = l*(l+1) + m + 1 cdenlm(i, lm1) = ppz*(wr(lm1,lm1)*ppz+ek*qz(i,l)) end do end do end if end do ! ---> calculate the non spherically symmetric contribution ! to speed up the pointer jend generated in gaunt is used ! remember that the wavefunctions are l and not lm dependent j0 = 1 do lm3 = 2, lm3max do l1 = 0, lmaxd do l2 = 0, l1 j1 = jend(lm3, l1, l2) if (j1/=0) then gmatl = czero ! ---> sum over m1,m2 for fixed lm3,l1,l2 do j = j0, j1 lm1 = icleb(j, 1) lm2 = icleb(j, 2) gmatl = gmatl + cleb(j)*wr(lm1, lm2) end do j0 = j1 + 1 gmatl = df*gmatl do i = 2, irc1 rho2ns(i, lm3) = rho2ns(i, lm3) + aimag(gmatl*wf(i,l1,l2)) end do end if ! (j1/=0) end do ! l2 end do ! l1 end do ! lm3 end subroutine rhoin end module mod_rhoin