LCOV - code coverage report
Current view: top level - hybrid/util - util.f90 (source / functions) Hit Total Coverage
Test: FLEUR test coverage Lines: 89 239 37.2 %
Date: 2024-05-15 04:28:08 Functions: 4 13 30.8 %

          Line data    Source code
       1             : MODULE m_util
       2             :    USE m_juDFT
       3             : !     error and warning codes for intgrf function
       4             :    INTEGER, PARAMETER :: NO_ERROR = 0
       5             :    INTEGER, PARAMETER :: NEGATIVE_EXPONENT_ERROR = 2
       6             : !     return type of the pure intgrf function
       7             : 
       8             :    INTERFACE derivative
       9             :       MODULE PROCEDURE derivative_t, derivative_nt
      10             :    END INTERFACE
      11             : 
      12             : CONTAINS
      13             : 
      14             :     ! Calculates Gaunt coefficients, i.e. the integrals of three spherical harmonics
      15             :     ! integral ( conjg(Y(l1,m1)) * Y(l2,m2) * conjg(Y(l3,m3)) )
      16             :     ! They are also the coefficients C(l1,l2,l3,m1,m2,m3) in
      17             :     ! conjg(Y(l1,m1)) * Y(l2,m2) = sum(l3,m3) C(l1,l2,l3,m1,m2,m3) Y(l3,m3)
      18             :     ! fac contains factorial up to maxfac, i.e. fac(i)= i!
      19             :     ! sfac contains square root of fac, i.e. sfac(i)= sqrt(i!)
      20             : 
      21     1392704 :    FUNCTION gaunt(l1, l2, l3, m1, m2, m3, maxfac, fac, sfac)
      22             : 
      23             :       USE m_constants, ONLY: pimach
      24             : 
      25             :       IMPLICIT NONE
      26             : 
      27             :       REAL                  :: gaunt
      28             :       INTEGER, INTENT(IN) :: l1, l2, l3, m1, m2, m3, maxfac
      29             :       REAL  , INTENT(IN) :: fac(0:maxfac)
      30             :       REAL  , INTENT(IN) :: sfac(0:maxfac)
      31             : 
      32     1392704 :       gaunt = 0
      33     1392704 :       IF (m3 /= m2 - m1) RETURN
      34     1392704 :       IF (abs(m1) > l1) RETURN
      35     1392704 :       IF (abs(m2) > l2) RETURN
      36     1392704 :       IF (abs(m3) > l3) RETURN
      37     1392704 :       IF (l3 < abs(l1 - l2) .OR. l3 > l1 + l2) RETURN
      38             :       gaunt = (-1)**(m1 + m3)* &
      39             :               sqrt((2*l1 + 1)*(2*l2 + 1)*(2*l3 + 1)/pimach()/4)* &
      40             :               wigner3j(l1, l2, l3, -m1, m2, -m3, maxfac, fac, sfac)* &
      41     1392704 :               wigner3j(l1, l2, l3, 0, 0, 0, maxfac, fac, sfac)
      42     1392704 :    END FUNCTION gaunt
      43             : 
      44             : ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      45             : 
      46             : !     Calculates the Wigner 3j symbols using Racah's formula
      47             : 
      48     2785408 :    FUNCTION wigner3j(l1, l2, l3, m1, m2, m3, maxfac, fac, sfac)
      49             : 
      50             :       IMPLICIT NONE
      51             : 
      52             :       REAL                  :: wigner3j
      53             :       INTEGER, INTENT(IN) :: l1, l2, l3, m1, m2, m3, maxfac
      54             :       REAL  , INTENT(IN) :: fac(0:maxfac)
      55             :       REAL  , INTENT(IN) :: sfac(0:maxfac)
      56             : !     - local -
      57             :       INTEGER               :: tmin, tmax, t, f1, f2, f3, f4, f5
      58             : 
      59     2785408 :       wigner3j = 0
      60             : 
      61             : !     The following IF clauses should be in the calling routine and commented here.
      62             : !      if(-m3.ne.m1+m2)  return
      63             : !      if(abs(m1).gt.l1) return
      64             : !      if(abs(m2).gt.l2) return
      65             : !      if(abs(m3).gt.l3) return
      66             : !      if(l3.lt.abs(l1-l2).or.l3.gt.l1+l2) return
      67             : 
      68     2785408 :       f1 = l3 - l2 + m1
      69     2785408 :       f2 = l3 - l1 - m2
      70     2785408 :       f3 = l1 + l2 - l3
      71     2785408 :       f4 = l1 - m1
      72     2785408 :       f5 = l2 + m2
      73     2785408 :       tmin = max(0, -f1, -f2) ! The arguments to fac (see below)
      74     2785408 :       tmax = min(f3, f4, f5)  ! must not be negative.
      75             : 
      76             : ! The following line is only for testing and should be removed at a later time.
      77     2785408 :       IF (tmax - tmin /= min(l1 + m1, l1 - m1, l2 + m2, l2 - m2, l3 + m3, l3 - m3, &
      78             :                              l1 + l2 - l3, l1 - l2 + l3, -l1 + l2 + l3)) &
      79           0 :          call judft_error("wigner3j: Number of terms incorrect.")
      80             : 
      81     2785408 :       IF (tmin <= tmax) THEN
      82     6464112 :          DO t = tmin, tmax
      83             :             wigner3j = wigner3j + (-1)**t/ &
      84             :                        (fac(t)*fac(f1 + t)*fac(f2 + t) &
      85     6464112 :                         *fac(f3 - t)*fac(f4 - t)*fac(f5 - t))
      86             :          END DO
      87             :          wigner3j = wigner3j*(-1)**(l1 - l2 - m3)*sfac(l1 + l2 - l3) &
      88             :                     *sfac(l1 - l2 + l3)*sfac(-l1 + l2 + l3) &
      89             :                     /sfac(l1 + l2 + l3 + 1)* &
      90             :                     sfac(l1 + m1)*sfac(l1 - m1)* &
      91             :                     sfac(l2 + m2)*sfac(l2 - m2)* &
      92     2785408 :                     sfac(l3 + m3)*sfac(l3 - m3)
      93             :       END IF
      94     2785408 :    END FUNCTION wigner3j
      95             : 
      96             : 
      97             : 
      98             : ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      99             : 
     100             : !     Calculates the primitive of f, on grid(itypein):
     101             : 
     102             : !                   r
     103             : !     primf(r) = integral f(r') dr'   ( r = grid point )
     104             : !                   0
     105             : 
     106             : !     If itypein is negative, the primitive
     107             : 
     108             : !                   R
     109             : !     primf(r) = integral f(r') dr'   ( R = MT sphere radius )
     110             : !                   r
     111             : 
     112             : !     is calculated instead.
     113             : 
     114             : !     -----------------------------
     115             : 
     116             : !     Fast calculation of primitive.
     117             : !     Only Lagrange integration is used
     118             : 
     119        9776 :    SUBROUTINE primitivef(primf, fin, rmsh, dx, jri, jmtd, itypein, ntype)
     120             : 
     121             :       USE m_constants
     122             : 
     123             :       IMPLICIT NONE
     124             : 
     125             : !     - scalars -
     126             :       INTEGER, INTENT(IN)   :: itypein, jmtd, ntype
     127             : 
     128             : !     - arrays -
     129             :       INTEGER, INTENT(IN)   :: jri(ntype)
     130             :       REAL, INTENT(OUT)  :: primf(jri(abs(itypein)))
     131             :       REAL, INTENT(IN)   :: fin(jri(abs(itypein)))
     132             :       REAL, INTENT(IN)   :: rmsh(jmtd, ntype), dx(ntype)
     133             : 
     134             : !     - local scalars -
     135             :       INTEGER                 :: itype, n, i, n0
     136             :       REAL                    :: h, x, h1
     137             :       REAL                    :: intgr, r1, a, dr
     138             : 
     139             : !     - local arrays -
     140             :       REAL                    :: fr(7)
     141        9776 :       REAL                    :: f(jri(abs(itypein)))
     142        9776 :       REAL                    :: r(jri(abs(itypein)))
     143             :       REAL, PARAMETER       :: lagrange(7, 6) = reshape( &
     144             :       (/19087., 65112., -46461., 37504., -20211., 6312., -863., &
     145             :       -863., 25128., 46989., -16256., 7299., -2088., 271., &
     146             :       &               271., -2760., 30819., 37504., -6771., 1608., -191., &
     147             :       -191., 1608., -6771., 37504., 30819., -2760., 271., &
     148             :       &               271., -2088., 7299., -16256., 46989., 25128., -863., &
     149             :       -863., 6312., -20211., 37504., -46461., 65112., 19087./), &
     150             :       (/7, 6/))
     151             : 
     152        9776 :       itype = abs(itypein)
     153             : 
     154     7619760 :       primf = 0
     155             : 
     156        9776 :       n = jri(itype)
     157        9776 :       h = dx(itype)
     158             : 
     159        9776 :       IF (itypein > 0) THEN
     160        4888 :          r1 = rmsh(1, itype)      ! perform outward integration
     161     3809880 :          f = fin                ! (from 0 to r)
     162             :       ELSE
     163        4888 :          r1 = rmsh(jri(itype), itype)         ! perform inward integration
     164        4888 :          h = -h                             ! (from MT sphere radius to r)
     165     3809880 :          f = fin(n:1:-1)                    !
     166             :       END IF
     167             : 
     168             : ! integral from 0 to r1 approximated by leading term in power series expansion (only if h>0)
     169        9776 :       IF (h > 0 .AND. f(1)*f(2) > 1e-10) THEN
     170          24 :          IF (f(2) == f(1)) THEN
     171           0 :             intgr = r1*f(1)
     172             :          ELSE
     173          24 :             x = (f(3) - f(2))/(f(2) - f(1))
     174          24 :             a = (f(2) - x*f(1))/(1 - x)
     175          24 :             x = log(x)/h
     176          24 :             IF (x < 0) THEN
     177           0 :                IF (x > -1) WRITE (oUnit, '(A,ES9.1)') &
     178             :                   '+intgr: Warning! Negative &exponent x in'// &
     179           0 :                   'extrapolation a+c*r**x:', x
     180           0 :                IF (x <= -1) WRITE (oUnit, '(A,ES9.1)') 'intgr: Negative exponent,'// &
     181           0 :                   'x in extrapolation a+c*r**x:', x
     182           0 :                IF (x <= -1) call judft_error("intgr:Negative exponent x in extrapolation")
     183             :             END IF
     184          24 :             intgr = r1*(f(1) + x*a)/(x + 1)
     185             :          END IF
     186             :       ELSE
     187             :          intgr = 0
     188             :       END IF
     189             : 
     190        9776 :       primf(1) = intgr
     191        9776 :       dr = exp(h)
     192        9776 :       r(1) = r1
     193        9776 :       n0 = 1
     194        9776 :       h1 = h/60480
     195             : 
     196             : ! Lagrange integration from r(n0) to r(n0+5)
     197     8901144 : 1     DO i = 2, 7
     198     8901144 :          r(i) = r(i - 1)*dr
     199             :       END DO
     200    10172736 :       fr = f(n0:n0 + 6)*r(:7)
     201     8901144 :       DO i = 1, 6
     202    61036416 :          intgr = intgr + h1*dot_product(lagrange(:, i), fr)
     203     8901144 :          IF (primf(n0 + i) == 0) primf(n0 + i) = intgr ! avoid double-definition
     204             :       END DO
     205     1271592 :       IF (n0 + 12 <= n) THEN
     206     1254480 :          r(1) = r(7)
     207     1254480 :          n0 = n0 + 6
     208     1254480 :          GOTO 1
     209       17112 :       ELSE IF (n0 + 6 < n) THEN
     210        7336 :          r(1) = r(n - 5 - n0)
     211        7336 :          n0 = n - 6
     212        7336 :          intgr = primf(n - 6)
     213        7336 :          GOTO 1
     214             :       END IF
     215             : 
     216        9776 :       IF (itypein < 0) THEN    !
     217     7619760 :          primf = -primf(n:1:-1) ! Inward integration
     218             :       END IF                    !
     219             : 
     220        9776 :    END SUBROUTINE primitivef
     221             : 
     222             : ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     223             : 
     224             : ! unction modulo1 maps kpoint into first BZ
     225           0 :    FUNCTION modulo1(kpoint, nkpt3)
     226             : 
     227             :       USE m_constants
     228             : 
     229             :       IMPLICIT NONE
     230             : 
     231             :       INTEGER, INTENT(IN)  :: nkpt3(3)
     232             :       REAL  , INTENT(IN)  :: kpoint(3)
     233             :       REAL                  :: modulo1(3)
     234             :       INTEGER               :: help(3)
     235             : 
     236           0 :       modulo1 = kpoint*nkpt3
     237           0 :       help = nint(modulo1)
     238           0 :       IF (any(abs(help - modulo1) > 1e-10)) THEN
     239           0 :          WRITE (oUnit, '(A,F5.3,2('','',F5.3),A)') 'modulo1: argument (', kpoint, &
     240           0 :             ') is not an element of the k-point set.'
     241             :          CALL juDFT_error( &
     242             :             'modulo1: argument not an element of k-point set.', &
     243           0 :             calledby='util:modulo1')
     244             :       END IF
     245           0 :       modulo1 = modulo(help, nkpt3)*1.0/nkpt3
     246             : 
     247             :    END FUNCTION modulo1
     248             : 
     249             : ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     250             : 
     251             : !     Returns derivative of f in df.
     252             : 
     253           0 :    SUBROUTINE derivative_t(df, f, atoms, itype)
     254             :       USE m_types_atoms
     255             :       IMPLICIT NONE
     256             :       REAL, INTENT(IN)   ::   f(:)
     257             :       REAL, INTENT(OUT)  ::   df(:)
     258             :       TYPE(t_atoms), INTENT(IN)::atoms
     259             :       INTEGER, INTENT(IN)   ::   itype
     260             : 
     261             :       call derivative_nt(df, f, atoms%jmtd, atoms%jri, atoms%dx, atoms%rmsh, &
     262           0 :                          atoms%ntype, itype)
     263           0 :    END SUBROUTINE
     264             : 
     265           0 :    SUBROUTINE derivative_nt(df, f, jmtd, jri, dx, rmsh, ntype, itype)
     266             : 
     267             :       IMPLICIT NONE
     268             : 
     269             :       INTEGER, INTENT(IN)   :: ntype, itype, jmtd
     270             :       INTEGER, INTENT(IN)   :: jri(ntype)
     271             :       REAL, INTENT(IN)   :: dx(ntype), rmsh(jmtd, ntype)
     272             :       REAL, INTENT(IN)   :: f(jri(itype))
     273             :       REAL, INTENT(OUT)  :: df(jri(itype))
     274             :       REAL                   :: x, h, r, d21, d32, d43, d31, d42, d41, df1, df2
     275             :       INTEGER                :: i, n
     276             : 
     277           0 :       n = jri(itype)
     278           0 :       h = dx(itype)
     279           0 :       r = rmsh(1, itype)
     280             : ! use power series expansion a+c**x for first point
     281           0 :       IF (f(2) == f(1)) THEN
     282           0 :          df(1) = 0.0
     283             :       ELSE
     284           0 :          x = (f(3) - f(2))/(f(2) - f(1))
     285           0 :          df(1) = (f(2) - f(1))/(x - 1)*log(x)/h/r
     286             :       END IF
     287             : ! use Lagrange interpolation of 3rd order for all other points (and averaging)
     288           0 :       d21 = r*(exp(h) - 1); d32 = d21*exp(h); d43 = d32*exp(h)
     289           0 :       d31 = d21 + d32; d42 = d32 + d43
     290           0 :       d41 = d31 + d43
     291             :       df(2) = -d32*d42/(d21*d31*d41)*f(1) &
     292             :               + (1.0/d21 - 1.0/d32 - 1.0/d42)*f(2) &
     293             :               + d21*d42/(d31*d32*d43)*f(3) &
     294           0 :               - d21*d32/(d41*d42*d43)*f(4)
     295             :       df1 = d32*d43/(d21*d31*d41)*f(1) &
     296             :             - d31*d43/(d21*d32*d42)*f(2) &
     297             :             + (1.0/d31 + 1.0/d32 - 1.0/d43)*f(3) &
     298           0 :             + d31*d32/(d41*d42*d43)*f(4)
     299           0 :       DO i = 3, n - 2
     300           0 :          d21 = d32; d32 = d43; d43 = d43*exp(h)
     301           0 :          d31 = d42; d42 = d42*exp(h)
     302           0 :          d41 = d41*exp(h)
     303             :          df2 = -d32*d42/(d21*d31*d41)*f(i - 1) &
     304             :                + (1.0/d21 - 1.0/d32 - 1.0/d42)*f(i) &
     305             :                + d21*d42/(d31*d32*d43)*f(i + 1) &
     306           0 :                - d21*d32/(d41*d42*d43)*f(i + 2)
     307           0 :          df(i) = (df1 + df2)/2
     308             :          df1 = d32*d43/(d21*d31*d41)*f(i - 1) &
     309             :                - d31*d43/(d21*d32*d42)*f(i) &
     310             :                + (1.0/d31 + 1.0/d32 - 1.0/d43)*f(i + 1) &
     311           0 :                + d31*d32/(d41*d42*d43)*f(i + 2)
     312             :       END DO
     313           0 :       df(n - 1) = df1
     314             :       df(n) = -d42*d43/(d21*d31*d41)*f(n - 3) &
     315             :               + d41*d43/(d21*d32*d42)*f(n - 2) &
     316             :               - d41*d42/(d31*d32*d43)*f(n - 1) &
     317           0 :               + (1.0/d41 + 1.0/d42 + 1.0/d43)*f(n)
     318             : 
     319           0 :    END SUBROUTINE derivative_nt
     320             : 
     321             : 
     322             : !     Calculates the spherical Bessel functions of orders 0 to l at x
     323             : !     by backward recurrence using j_l(x) = (2l+3)/x j_l+1(x) - j_l+2(x) .
     324             : !     (Starting points are calculated according to Zhang, Min,
     325             : !      "Computation of Special Functions".)
     326           0 :    pure SUBROUTINE sphbessel(sphbes, x, l)
     327             : 
     328             :       IMPLICIT NONE
     329             : 
     330             :       INTEGER, INTENT(IN)    :: l
     331             :       REAL  , INTENT(IN)    :: x
     332             :       REAL  , INTENT(INOUT) :: sphbes(0:l)
     333             :       REAL                     :: s0, s1, f, f0, f1, cs
     334             :       INTEGER                  :: ll, lsta, lmax, msta2
     335             : 
     336             : !      IF( x.lt.0 ) THEN
     337             : !        call judft_error("sphbes: negative argument (bug?).")
     338             : !      ELSE
     339           0 :       IF (x == 0) THEN
     340           0 :          sphbes(0) = 1.0
     341           0 :          DO ll = 1, l
     342           0 :             sphbes(ll) = 0.0
     343             :          END DO
     344             :          RETURN
     345             :       ENDIF
     346           0 :       sphbes(0) = sin(x)/x
     347           0 :       IF (l == 0) RETURN
     348           0 :       sphbes(1) = (sphbes(0) - cos(x))/x
     349             : !       IF(l.le.1) RETURN
     350           0 :       s0 = sphbes(0)
     351           0 :       s1 = sphbes(1)
     352           0 :       lsta = lsta1(x, 200)      !
     353           0 :       lmax = l                 !
     354           0 :       IF (lsta < l) THEN       !
     355           0 :          lmax = lsta ! determine starting point lsta
     356           0 :          sphbes(lmax + 1:) = 0.0  ! for backward recurrence
     357             :       ELSE                     !
     358           0 :          lsta = lsta2(x, l, 15)   !
     359             :       END IF                    !
     360           0 :       f0 = 0.0                                                      !
     361           0 :       f1 = 1e-100                                                   !
     362           0 :       DO ll = lsta, 0, -1                                             ! backward recurrence
     363           0 :          f = f1/x*(2*ll + 3) - f0; IF (ll <= lmax) sphbes(ll) = f ! with arbitrary start values
     364           0 :          f0 = f1                                                     !
     365           0 :          f1 = f                                                      !
     366             :       END DO                                                        !
     367           0 :       IF (abs(s0) > abs(s1)) THEN; cs = s0/f   !
     368           0 :       ELSE; cs = s1/f0  ! scale to correct values
     369             :       END IF                                      !
     370           0 :       sphbes = cs*sphbes                        !
     371             : 
     372             :    CONTAINS
     373             : 
     374             : !     Test starting point
     375             :       PURE FUNCTION lsta0(x, mp)
     376             : 
     377             :          IMPLICIT NONE
     378             : 
     379             :          INTEGER               :: lsta0
     380             :          INTEGER, INTENT(IN) :: mp
     381             :          REAL  , INTENT(IN) :: x
     382             :          REAL                  :: f, lgx
     383             : 
     384             :          lgx = log10(x)
     385             :          lsta0 = 0
     386             :          f = lgx
     387             :          DO WHILE (f > -mp)
     388             :             lsta0 = lsta0 + 1
     389             :             f = f + lgx - log10(2.0*lsta0 + 1)
     390             :          END DO
     391             :       END FUNCTION lsta0
     392             : 
     393             : !     Returns starting point lsta1 for backward recurrence such that sphbes(lsta1) approx. 10^(-mp).
     394           0 :       PURE FUNCTION lsta1(x, mp)
     395             : 
     396             :          IMPLICIT NONE
     397             : 
     398             :          INTEGER               :: lsta1
     399             :          INTEGER, INTENT(IN) :: mp
     400             :          REAL  , INTENT(IN) :: x
     401             :          REAL                  :: f0, f1, f
     402             :          INTEGER               :: n0, n1, nn, it
     403             : 
     404           0 :          n0 = int(1.1*x) + 1
     405           0 :          f0 = envj(n0, x) - mp
     406           0 :          n1 = n0 + 5
     407           0 :          f1 = envj(n1, x) - mp
     408           0 :          DO it = 1, 20
     409           0 :             nn = n1 - (n1 - n0)/(1.0 - f0/f1)
     410           0 :             f = envj(nn, x) - mp
     411           0 :             IF (abs(nn - n1) < 1) EXIT
     412           0 :             n0 = n1
     413           0 :             f0 = f1
     414           0 :             n1 = nn
     415           0 :             f1 = f
     416             :          END DO
     417           0 :          lsta1 = nn
     418           0 :       END FUNCTION lsta1
     419             : 
     420             : !     Returns the starting point lsta2 for backward recurrence such that all sphbes(l) have mp significant digits.
     421           0 :       PURE FUNCTION lsta2(x, l, mp)
     422             : 
     423             :          IMPLICIT NONE
     424             : 
     425             :          INTEGER               :: lsta2
     426             :          INTEGER, INTENT(IN) :: l, mp
     427             :          REAL  , INTENT(IN) :: x
     428             :          REAL                  :: f0, f1, f, hmp, ejn, obj
     429             :          INTEGER               :: n0, n1, nn, it
     430             : 
     431           0 :          hmp = 0.5*mp
     432           0 :          ejn = envj(l, x)
     433           0 :          IF (ejn <= hmp) THEN
     434           0 :             obj = mp
     435           0 :             n0 = int(1.1*x) + 1
     436             :          ELSE
     437           0 :             obj = hmp + ejn
     438           0 :             n0 = l
     439             :          END IF
     440           0 :          f0 = envj(n0, x) - obj
     441           0 :          n1 = n0 + 5
     442           0 :          f1 = envj(n1, x) - obj
     443           0 :          DO it = 1, 20
     444           0 :             nn = n1 - (n1 - n0)/(1.0 - f0/f1)
     445           0 :             f = envj(nn, x) - obj
     446           0 :             IF (abs(nn - n1) < 1) EXIT
     447           0 :             n0 = n1
     448           0 :             f0 = f1
     449           0 :             n1 = nn
     450           0 :             f1 = f
     451             :          END DO
     452           0 :          lsta2 = nn + 10
     453           0 :       END FUNCTION lsta2
     454             : 
     455           0 :       PURE FUNCTION envj(l, x)
     456             : 
     457             :          IMPLICIT NONE
     458             : 
     459             :          REAL                  :: envj
     460             :          REAL  , INTENT(IN) :: x
     461             :          INTEGER, INTENT(IN) :: l
     462             : 
     463           0 :          envj = 0.5*log10(6.28*l) - l*log10(1.36*x/l)
     464             : 
     465           0 :       END FUNCTION envj
     466             : 
     467             :    END SUBROUTINE sphbessel
     468             : 
     469             : !     Returns the spherical harmonics Y_lm(^rvec)
     470             : !     for l = 0,...,ll in Y(1,...,(ll+1)**2).
     471             : 
     472           0 :    PURE SUBROUTINE harmonicsr(Y, rvec, ll)
     473             : 
     474             :       IMPLICIT NONE
     475             : 
     476             :       integer  , intent(in)  :: ll
     477             :       real  , intent(in)  :: rvec(3)
     478             :       complex, intent(out) :: Y((ll + 1)**2)
     479             :       complex               :: c
     480             :       real                    :: stheta, ctheta, sphi, cphi, r, rvec1(3)
     481             :       integer                 :: l, m, lm
     482             :       complex, parameter   :: img = (0.0, 1.0)
     483             : 
     484           0 :       Y(1) = 0.282094791773878
     485           0 :       IF (ll == 0) RETURN
     486             : 
     487           0 :       stheta = 0
     488           0 :       ctheta = 0
     489           0 :       sphi = 0
     490           0 :       cphi = 0
     491           0 :       r = norm2(rvec)
     492           0 :       IF (r > 1e-16) THEN
     493           0 :          rvec1 = rvec/r
     494           0 :          ctheta = rvec1(3)
     495           0 :          stheta = sqrt(rvec1(1)**2 + rvec1(2)**2)
     496           0 :          IF (stheta > 1e-16) THEN
     497           0 :             cphi = rvec1(1)/stheta
     498           0 :             sphi = rvec1(2)/stheta
     499             :          END IF
     500             :       ELSE
     501           0 :          Y(2:) = 0.0
     502             :          RETURN
     503             :       END IF
     504             : 
     505             : !     define Y,l,-l and Y,l,l
     506           0 :       r = Y(1)
     507           0 :       c = 1
     508           0 :       DO l = 1, ll
     509           0 :          r = r*stheta*sqrt(1.0 + 1.0/(2*l))
     510           0 :          c = c*(cphi + img*sphi)
     511           0 :          Y(l**2 + 1) = r*conjg(c)  ! l,-l
     512           0 :          Y((l + 1)**2) = r*c*(-1)**l ! l,l
     513             :       END DO
     514             : 
     515             : !     define Y,l,-l+1 and Y,l,l-1
     516           0 :       Y(3) = 0.48860251190292*ctheta
     517           0 :       DO l = 2, ll
     518           0 :          r = sqrt(2.0*l + 1)*ctheta
     519           0 :          Y(l**2 + 2) = r*Y((l - 1)**2 + 1) ! l,-l+1
     520           0 :          Y(l*(l + 2)) = r*Y(l**2)       ! l,l-1
     521             :       END DO
     522             : 
     523             : !     define Y,l,m, |m|<l-1
     524           0 :       DO l = 2, ll
     525           0 :          lm = l**2 + 2
     526           0 :          DO m = -l + 2, l - 2
     527           0 :             lm = lm + 1
     528             :             Y(lm) = sqrt((2.0*l + 1)/(l + m)/(l - m))*( &
     529             :                     sqrt(2.0*l - 1)*ctheta*Y(lm - 2*l) - &
     530           0 :                     sqrt((l + m - 1.0)*(l - m - 1)/(2*l - 3))*Y(lm - 4*l + 2))
     531             :          END DO
     532             :       END DO
     533             : 
     534             :    END SUBROUTINE harmonicsr
     535             : 
     536             : !     Returns the complex error function.
     537           6 :    FUNCTION cerf(z)
     538             : 
     539             :       USE m_constants, ONLY: pimach
     540             : 
     541             :       IMPLICIT NONE
     542             :       COMPLEX, INTENT(IN) ::  z
     543             :       COMPLEX             ::  cerf
     544             :       COMPLEX             ::  z1, z2, c, d, delta
     545             :       REAL                  ::  pi
     546             :       INTEGER               ::  i
     547             : 
     548           6 :       pi = pimach()
     549           6 :       z1 = z
     550           6 :       IF (real(z) < 0) z1 = -z1
     551           6 :       IF (real(z1) < 2.0) THEN ! McLaurin series
     552           0 :          z2 = z1**2
     553           0 :          i = 0
     554           0 :          c = z1
     555           0 :          cerf = z1
     556             :          DO
     557           0 :             i = i + 1
     558           0 :             c = -c*z2/i
     559           0 :             cerf = cerf + c/(2*i + 1)
     560           0 :             IF (abs(c/(2*i + 1)) < 1e-20) EXIT
     561             :          END DO
     562           0 :          cerf = cerf*2/sqrt(pi)
     563             :       ELSE ! continued fraction using Lentz's method
     564             :          d = 0.0
     565             :          c = z1
     566             :          cerf = z1
     567             :          i = 0
     568             :          DO
     569         126 :             i = i + 1
     570         126 :             c = 2*z1 + i/c
     571         126 :             d = (2*z1 + i*d)**(-1)
     572         126 :             delta = c*d
     573         126 :             cerf = cerf*delta
     574         126 :             IF (abs(1 - delta) < 1e-15) EXIT
     575         126 :             i = i + 1
     576         126 :             c = z1 + i/c
     577         126 :             d = (z1 + i*d)**(-1)
     578         126 :             delta = c*d
     579         126 :             cerf = cerf*delta
     580         126 :             IF (abs(1 - delta) < 1e-15) EXIT
     581         120 :             IF (i == 10000) &
     582           6 :                call judft_error("cerf: Lentz method not converged after 10000 steps.")
     583             :          END DO
     584           6 :          cerf = 1 - exp(-z1**2)/cerf/sqrt(pi)
     585             :       END IF
     586           6 :       IF (real(z) < 0) cerf = -cerf
     587           6 :    END FUNCTION cerf
     588             : 
     589           0 :    FUNCTION chr(int)
     590             : 
     591             :       IMPLICIT NONE
     592             : 
     593             :       CHARACTER(5) :: chr
     594             :       INTEGER        :: int
     595             : 
     596           0 :       WRITE (chr, '(I5)') int
     597           0 :    END FUNCTION chr
     598             : 
     599             : END MODULE m_util

Generated by: LCOV version 1.14