00001 subroutine bessjy(x,xnu,rj,ry,rjp,ryp)
00002 use phys_constant, only : pi
00003 implicit none
00004 integer :: i, isign, l, nl
00005 integer, parameter :: maxit = 10000
00006 real(8) :: rj, rjp, ry, ryp, x, xnu
00007 real(8), parameter :: eps = 1.0d-16, fpmin = 1.0d-30, xmin = 2.0d0
00008 real(8) :: a, b, br, bi, c, cr, ci, d, del, del1, den, di, dlr, dli, dr, e,
00009 f, fact, fact2, fact3, ff, gam, gam1, gam2, gammi, gampl, h, p, pimu, pimu2, q, &
00010 r, rjl, rjl1, rjmu, rjp1, rjpl, rjtemp, ry1, rymu, rymup, rytemp, sum, sum1, &
00011 temp, w, x2, xi, xi2, xmu, xmu2
00012
00013 if (x.le.0.0d0.or.xnu.lt.0.0d0) stop 'bad arguments in bessjy'
00014 if (x.lt.xmin) then
00015 nl = int(xnu + 0.5d0)
00016 else
00017 nl = max(0,int(xnu-x+1.5d0))
00018 endif
00019 xmu = xnu-nl
00020 xmu2 = xmu*xmu
00021 xi = 1.0d0/x
00022 xi2 = 2.0d0*xi
00023 w = xi2/pi
00024 isign = 1
00025 h = xnu*xi
00026 if (h.lt.fpmin) h = fpmin
00027 b = xi2*xnu
00028 d = 0.0d0
00029 c = h
00030 do i = 1,maxit
00031 b = b+xi2
00032 d = b-d
00033 if (abs(d).lt.fpmin) d = fpmin
00034 c = b-1.0d0/c
00035 if (abs(c).lt.fpmin) c = fpmin
00036 d = 1.0d0/d
00037 del = c*d
00038 h = del*h
00039 if (d.lt.0.0d0) isign = -isign
00040 if (abs(del-1.0d0).lt.eps) exit
00041 if (i.eq.maxit) stop 'x too large in bessjy; try asymptotic expansion'
00042 end do
00043 rjl = isign*fpmin
00044 rjpl = h*rjl
00045 rjl1 = rjl
00046 rjp1 = rjpl
00047 fact = xnu*xi
00048 do l = nl,1,-1
00049 rjtemp = fact*rjl+rjpl
00050 fact = fact-xi
00051 rjpl = fact*rjtemp-rjl
00052 rjl = rjtemp
00053 end do
00054 if (rjl.eq.0.d0) rjl = eps
00055 f = rjpl/rjl
00056 if (x.lt.xmin) then
00057 x2 = .5d0*x
00058 pimu = pi*xmu
00059 if (abs(pimu).lt.eps) then
00060 fact = 1.0d0
00061 else
00062 fact = pimu/sin(pimu)
00063 endif
00064 d = -log(x2)
00065 e = xmu*d
00066 if (abs(e).lt.eps) then
00067 fact2 = 1.0d0
00068 else
00069 fact2 = sinh(e)/e
00070 endif
00071 call beschb(xmu, gam1, gam2, gampl, gammi)
00072 ff = 2.0d0/pi*fact*(gam1*cosh(e)+gam2*fact2*d)
00073 e = exp(e)
00074 p = e/(gampl*pi)
00075 q = 1.0d0/(e*pi*gammi)
00076 pimu2 = 0.50d0*pimu
00077 if (abs(pimu2).lt.eps) then
00078 fact3 = 1.0d0
00079 else
00080 fact3 = sin(pimu2)/pimu2
00081 endif
00082 r = pi*pimu2*fact3*fact3
00083 c = 1.0d0
00084 d = -x2*x2
00085 sum = ff+r*q
00086 sum1 = p
00087 do i = 1,maxit
00088 ff = (i*ff+p+q)/(i*i-xmu2)
00089 c = c*d/i
00090 p = p/(i-xmu)
00091 q = q/(i+xmu)
00092 del = c*(ff+r*q)
00093 sum = sum+del
00094 del1 = c*p-i*del
00095 sum1 = sum1+del1
00096 if (abs(del).lt.(1.0d0+abs(sum))*eps) exit
00097 if (i.eq.maxit) stop 'bessy series failed to converge'
00098 end do
00099 rymu = -sum
00100 ry1 = -sum1*xi2
00101 rymup = xmu*xi*rymu-ry1
00102 rjmu = w/(rymup-f*rymu)
00103 else
00104 a = .25d0-xmu2
00105 p = -.5d0*xi
00106 q = 1.0d0
00107 br = 2.0d0*x
00108 bi = 2.0d0
00109 fact = a*xi/(p*p+q*q)
00110 cr = br+q*fact
00111 ci = bi+p*fact
00112 den = br*br+bi*bi
00113 dr = br/den
00114 di = -bi/den
00115 dlr = cr*dr-ci*di
00116 dli = cr*di+ci*dr
00117 temp = p*dlr-q*dli
00118 q = p*dli+q*dlr
00119 p = temp
00120 do i = 2,maxit
00121 a = a+2*(i-1)
00122 bi = bi+2.d0
00123 dr = a*dr+br
00124 di = a*di+bi
00125 if (abs(dr)+abs(di).lt.fpmin) dr = fpmin
00126 fact = a/(cr*cr+ci*ci)
00127 cr = br+cr*fact
00128 ci = bi-ci*fact
00129 if (abs(cr)+abs(ci).lt.fpmin) cr = fpmin
00130 den = dr*dr+di*di
00131 dr = dr/den
00132 di = -di/den
00133 dlr = cr*dr-ci*di
00134 dli = cr*di+ci*dr
00135 temp = p*dlr-q*dli
00136 q = p*dli+q*dlr
00137 p = temp
00138 if (abs(dlr-1.d0)+abs(dli).lt.eps) exit
00139 if (i.eq.maxit) stop 'cf2 failed in bessjy'
00140 end do
00141 gam = (p-f)/q
00142 rjmu = sqrt(w/((p-f)*gam+q))
00143 rjmu = sign(rjmu,rjl)
00144 rymu = rjmu*gam
00145 rymup = rymu*(p+q/gam)
00146 ry1 = xmu*xi*rymu-rymup
00147 endif
00148 fact = rjmu/rjl
00149 rj = rjl1*fact
00150 rjp = rjp1*fact
00151 do i=1,nl
00152 rytemp = (xmu+i)*xi2*ry1-rymu
00153 rymu = ry1
00154 ry1 = rytemp
00155 end do
00156 ry = rymu
00157 ryp = xnu*xi*rymu-ry1
00158 return
00159 end subroutine bessjy