The Elk Code
 
Loading...
Searching...
No Matches
sbesseli.f90
Go to the documentation of this file.
1
2! Copyright (C) 2008 F. Bultmark, F. Cricchio, L. Nordstrom and J. K. Dewhurst.
3! This file is distributed under the terms of the GNU General Public License.
4! See the file COPYING for license details.
5
6!BOP
7! !ROUTINE: sbesseli
8! !INTERFACE:
9subroutine sbesseli(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 spherical Bessel functions with imaginary argument,
16! $\tilde{j}_l(x)\equiv i^lj_l(ix)$, for real $x$ and
17! $l=0\ldots l_{\rm max}$. The recurrence relation
18! $$ \tilde{j}_{l+1}(x)=\frac{2l+1}{x}\tilde{j}_l(x)+\tilde{j}_{l-1}(x) $$
19! is used either downwards for $x<2\,l_{\rm max}$ or upwards for
20! $x\ge 2\,l_{\rm max}$. The starting values are $\tilde{j}_0(x)=\sinh(x)/x$
21! and $\tilde{j}_1(x)=(\tilde{j}_0(x)-\cosh(x))/x$. The asymptotic form
22! $$ \tilde{j}_l(x)\approx\frac{(-x)^l}{(2l+1)!!} $$
23! is used for $x\ll 1$.
24!
25! !REVISION HISTORY:
26! Created April 2008 from sbessel routine (Lars Nordstrom)
27! Fixed accuracy issue and changed name, September 2021 (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
37real(8), parameter :: rsc=1.d150,rsci=1.d0/rsc
38real(8) xi,j0,j1,t1
39if ((lmax < 0).or.(lmax > 20)) then
40 write(*,*)
41 write(*,'("Error(sbesseli): lmax out of range : ",I8)') lmax
42 write(*,*)
43 stop
44end if
45if ((x < 0.d0).or.(x > 1.d8)) then
46 write(*,*)
47 write(*,'("Error(sbesseli): x out of range : ",G18.10)') x
48 write(*,*)
49 stop
50end if
51! treat x << 1
52if (x < 1.d-8) then
53 jl(0)=1.d0
54 t1=1.d0
55 do l=1,lmax
56 t1=-t1*x/dble(2*l+1)
57 jl(l)=t1
58 end do
59 return
60end if
61if (lmax == 0) then
62 jl(0)=sinh(x)/x
63 return
64end if
65xi=1.d0/x
66if (x < 2*lmax) then
67! for x < 2*lmax recurse down
68 j1=1.d0
69 j0=0.d0
70! starting value for l above lmax
71 lst=lmax+lmax/2+12
72 do l=lst,lmax+1,-1
73 t1=j0-(2*l+1)*j1*xi
74 j0=j1
75 j1=t1
76! check for overflow
77 if (abs(j1) > rsc) then
78! rescale
79 t1=t1*rsci
80 j0=j0*rsci
81 j1=j1*rsci
82 end if
83 end do
84 do l=lmax,0,-1
85 t1=j0-(2*l+1)*j1*xi
86 j0=j1
87 j1=t1
88! check for overflow
89 if (abs(j1) > rsc) then
90! rescale
91 t1=t1*rsci
92 j0=j0*rsci
93 j1=j1*rsci
94 jl(l+1:lmax)=jl(l+1:lmax)*rsci
95 end if
96 jl(l)=j0
97 end do
98! rescaling constant
99 t1=sinh(x)/(x*j0)
100 jl(0:lmax)=t1*jl(0:lmax)
101else
102! for x >= 2*lmax recurse up
103 jl(0)=sinh(x)*xi
104 jl(1)=(jl(0)-cosh(x))*xi
105 if (lmax == 1) return
106 j0=jl(0)
107 j1=jl(1)
108 do l=2,lmax
109 t1=(2*l-1)*j1*xi+j0
110 j0=j1
111 j1=t1
112 jl(l)=j1
113 end do
114end if
115end subroutine
116!EOC
117
subroutine sbesseli(lmax, x, jl)
Definition sbesseli.f90:10