The Elk Code
sbessel.f90
Go to the documentation of this file.
1 
2 ! Copyright (C) 2002-2006 J. K. Dewhurst, S. Sharma and C. Ambrosch-Draxl.
3 ! This file is distributed under the terms of the GNU Lesser General Public
4 ! License. See the file COPYING for license details.
5 
6 !BOP
7 ! !ROUTINE: sbessel
8 ! !INTERFACE:
9 subroutine sbessel(lmax,x,jl)
10 ! !INPUT/OUTPUT PARAMETERS:
11 ! lmax : maximum order of Bessel function (in,integer)
12 ! x : real argument (in,real)
13 ! jl : array of returned values (out,real(0:lmax))
14 ! !DESCRIPTION:
15 ! Computes the spherical Bessel functions of the first kind, $j_l(x)$, for
16 ! real argument $x$ and $l=0\ldots l_{\rm max}$. The recurrence relation
17 ! $$ j_{l+1}(x)=\frac{2l+1}{x}j_l(x)-j_{l-1}(x) $$
18 ! is used downwards for $x<l_{\rm max}$ or upwards for $x\ge l_{\rm max}$.
19 ! The asymptotic form
20 ! $$ j_l(x)\approx\frac{x^l}{(2l+1)!!} $$
21 ! is used for $x\ll 1$. This procedure is numerically stable and accurate to
22 ! near machine precision for $l\le 50$.
23 !
24 ! !REVISION HISTORY:
25 ! Created January 2003 (JKD)
26 ! Modified to return an array of values, October 2004 (JKD)
27 ! Improved stability, August 2006 (JKD)
28 !EOP
29 !BOC
30 implicit none
31 ! arguments
32 integer, intent(in) :: lmax
33 real(8), intent(in) :: x
34 real(8), intent(out) :: jl(0:lmax)
35 ! local variables
36 integer l,lst
37 ! rescale limit
38 real(8), parameter :: rsc=1.d150,rsci=1.d0/rsc
39 real(8) xi,j0,j1,t1
40 if ((lmax < 0).or.(lmax > 50)) then
41  write(*,*)
42  write(*,'("Error(sbessel): lmax out of range : ",I8)') lmax
43  write(*,*)
44  stop
45 end if
46 if ((x < 0.d0).or.(x > 1.d5)) then
47  write(*,*)
48  write(*,'("Error(sbessel): x out of range : ",G18.10)') x
49  write(*,*)
50  stop
51 end if
52 ! treat x << 1
53 if (x < 1.d-8) then
54  jl(0)=1.d0
55  t1=1.d0
56  do l=1,lmax
57  t1=t1*x/dble(2*l+1)
58  jl(l)=t1
59  end do
60  return
61 end if
62 if (lmax == 0) then
63  jl(0)=sin(x)/x
64  return
65 end if
66 xi=1.d0/x
67 if (x < lmax) then
68 ! for x < lmax recurse down
69  j1=1.d0
70  j0=0.d0
71 ! starting value for l above lmax
72  lst=lmax+lmax/8+14
73  do l=lst,lmax+1,-1
74  t1=(2*l+1)*j1*xi-j0
75  j0=j1
76  j1=t1
77 ! check for overflow
78  if (abs(j1) > rsc) then
79 ! rescale
80  t1=t1*rsci
81  j0=j0*rsci
82  j1=j1*rsci
83  end if
84  end do
85  do l=lmax,0,-1
86  t1=(2*l+1)*j1*xi-j0
87  j0=j1
88  j1=t1
89 ! check for overflow
90  if (abs(j1) > rsc) then
91 ! rescale
92  t1=t1*rsci
93  j0=j0*rsci
94  j1=j1*rsci
95  jl(l+1:lmax)=jl(l+1:lmax)*rsci
96  end if
97  jl(l)=j0
98  end do
99 ! rescaling constant
100  t1=sin(x)/(x*j0)
101  jl(0:lmax)=t1*jl(0:lmax)
102 else
103 ! for x >= lmax recurse up
104  jl(0)=sin(x)*xi
105  jl(1)=(jl(0)-cos(x))*xi
106  if (lmax == 1) return
107  j0=jl(0)
108  j1=jl(1)
109  do l=2,lmax
110  t1=(2*l-1)*j1*xi-j0
111  j0=j1
112  j1=t1
113  jl(l)=j1
114  end do
115 end if
116 end subroutine
117 !EOC
118 
subroutine sbessel(lmax, x, jl)
Definition: sbessel.f90:10