The Elk Code
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:
9 subroutine 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
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 real(8), parameter :: rsc=1.d150,rsci=1.d0/rsc
38 real(8) xi,j0,j1,t1
39 if ((lmax < 0).or.(lmax > 20)) then
40  write(*,*)
41  write(*,'("Error(sbesseli): lmax out of range : ",I8)') lmax
42  write(*,*)
43  stop
44 end if
45 if ((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
50 end if
51 ! treat x << 1
52 if (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
60 end if
61 if (lmax == 0) then
62  jl(0)=sinh(x)/x
63  return
64 end if
65 xi=1.d0/x
66 if (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)
101 else
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
114 end if
115 end subroutine
116 !EOC
117 
subroutine sbesseli(lmax, x, jl)
Definition: sbesseli.f90:10