!-----------------------------------------------------------------------------------------! ! 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: Spherical harmonics except the factor \(\exp{i m \phi}\) !> Author: !> Spherical harmonics except the factor \(\exp{i m \phi}\) !> \(m=-l\) to \(l\) , for given \(l\). !> \(x=cos(\theta)\) !------------------------------------------------------------------------------------ module mod_spher use :: mod_datatypes, only: dp private :: dp contains !------------------------------------------------------------------------------- !> Summary: Spherical harmonics except the factor \(\exp{i m \phi}\) !> Author: !> Category: special-functions, numerical-tools, KKRhost !> Deprecated: False !> Spherical harmonics except the factor \(\exp{i m \phi}\) !> \(m=-l\) to \(l\) , for given \(l\). !> \(x=cos(\theta)\) !------------------------------------------------------------------------------- subroutine spher(ylm, l, x) use :: mod_constants, only : pi ! .. Scalar Arguments .. integer, intent(in) :: l !! Angular momentum real (kind=dp), intent(in) :: x !! \(x=cos(\theta)\) ! .. Output variables real (kind=dp), dimension(*), intent(out) :: ylm !! real spherical harmonic to a given l,m ! .. Local Scalars .. real (kind=dp) :: fac, ovr1, qq integer :: i, ii, l2, lm, ln, m, nn ! .. ! .. Intrinsic Functions .. intrinsic :: abs, real, sqrt ovr1 = abs(x) - 1.e0_dp if (ovr1>0.1e-12_dp) then write (6, fmt=100) x stop else if (abs(ovr1)<1.e-10_dp) then if (x>0.0e0_dp) then fac = 1.0e0_dp else fac = (-1)**l end if l2 = 2*l + 1 do i = 1, l2 ylm(i) = 0.0e0_dp end do ylm(l+1) = sqrt(real(l2,kind=dp)/(4.0e0_dp*pi))*fac return end if ! l<0 if (l<0) then write (6, fmt=*) ' === l=', l, ' < 0 : in sub.spher. ===' stop '=== stop in sub.spher. (l<0) ===' ! l=0 else if (l==0) then ylm(1) = sqrt(1.0e0_dp/(4.0e0_dp*pi)) ! l=1 else if (l==1) then fac = sqrt(3.0e0_dp/(4.0e0_dp*pi)) ylm(1) = fac*sqrt((1.0e0_dp-x*x)/2.0e0_dp) ylm(2) = fac*x ylm(3) = -ylm(1) ! l>1 else ylm(1) = 1.0e0_dp ylm(2) = x do i = 2, l ylm(i+1) = ((2*i-1)*x*ylm(i)-(i-1)*ylm(i-1))/i end do fac = 1.0e0_dp/sqrt(1.0e0_dp-x*x) do m = 1, l lm = l + m ylm(lm+1) = fac*(-(l-m+1)*x*ylm(lm)+(lm-1)*ylm(l)) if (m<l) then nn = m + 1 do i = nn, l ii = l - i + nn ylm(ii) = fac*(-(ii-m)*x*ylm(ii)+(ii+m-2)*ylm(ii-1)) end do end if end do fac = sqrt((2*l+1)/(4.0e0_dp*pi)) ylm(l+1) = fac*ylm(l+1) do m = 1, l fac = -fac/sqrt(real((l+m)*(l-m+1),kind=dp)) lm = l + 1 + m ln = l + 1 - m qq = ylm(lm) ylm(lm) = fac*qq ylm(ln) = abs(fac)*qq end do end if return 100 format (/, /, 3x, '==invalid argument for spher; x=', d24.16, ' ==') end subroutine spher end module mod_spher