The Elk Code
 
Loading...
Searching...
No Matches
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:
9subroutine 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
30implicit none
31! arguments
32integer, intent(in) :: lmax
33real(8), intent(in) :: x
34real(8), intent(out) :: jl(0:lmax)
35! local variables
36integer l,lst
37! rescale limit
38real(8), parameter :: rsc=1.d150,rsci=1.d0/rsc
39real(8) xi,j0,j1,t1
40if ((lmax < 0).or.(lmax > 50)) then
41 write(*,*)
42 write(*,'("Error(sbessel): lmax out of range : ",I8)') lmax
43 write(*,*)
44 stop
45end if
46if ((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
51end if
52! treat x << 1
53if (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
61end if
62if (lmax == 0) then
63 jl(0)=sin(x)/x
64 return
65end if
66xi=1.d0/x
67if (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)
102else
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
115end if
116end subroutine
117!EOC
118
subroutine sbessel(lmax, x, jl)
Definition sbessel.f90:10