9 #include <PB3D_macros.h>
18 character(len=max_str_ln) :: err_msg
74 integer function dtorh1(z,m,nmax,pl,ql,newn,mode,ipre)
result(ierr)
75 character(*),
parameter :: rout_name =
'DTORH1'
78 real(
dp),
intent(in) :: z
79 integer,
intent(in) :: m
80 integer,
intent(in) :: nmax
81 real(
dp),
intent(inout) :: pl(0:nmax)
82 real(
dp),
intent(inout) :: ql(0:nmax)
83 integer,
intent(inout) :: newn
84 integer,
intent(in),
optional :: mode
85 integer,
intent(in),
optional :: ipre
88 INTEGER nmaxp,mp,np,n,ical,i
89 INTEGER :: mode_loc, ipre_loc
90 REAL(
dp) over,tinysq,qz,pisq,fl,cc,ar,gamma,fc,qdc1,qargu,&
91 &ARGU1,DFACQS,FCP,DD,D1,QM0,DFAC3,DFAC4,PL0
92 real(dp),
allocatable :: pl_loc(:), ql_loc(:)
97 REAL(
dp) qlmm(0:1001),pr(2)
98 real(
dp),
PARAMETER :: eps=1.e-14_dp, tiny=1.e-290_dp
106 err_msg =
'Lowest possible degree is 0. Use recursive properties &
107 &of toroidal functions if you need lower.'
113 if (
present(mode)) mode_loc = mode
115 if (
present(ipre)) ipre_loc = ipre
119 IF ((ipre_loc.NE.1).AND.(ipre_loc.NE.2))
THEN
121 err_msg =
'IPRE MUST BE 1 OR 2'
136 err_msg =
'IMPROPER ARGUMENT. Z MUST BE GREATER THAN 1'
143 cc=abs(float(int(fl))-fl)
144 IF (cc.LT.0.4_dp)
THEN
155 IF ((z/m).GT.pr(ipre_loc)) ical=2
158 ELSE IF (z.GT.20.d0)
THEN
159 IF ((mode_loc.NE.2).AND.(ical.EQ.1)) ical=0
163 chckerr(
'YOU MUST CHOOSE MODE=2')
175 IF(nmaxp.LT.2) nmaxp=2
178 allocate(pl_loc(0:nmaxp+1))
179 allocate(ql_loc(0:nmaxp+1))
181 IF (mode_loc.EQ.0)
THEN
182 gamma=gammah(m,over)*ar*pisq
183 IF (abs(gamma).LT.tiny)
THEN
185 err_msg =
'M IS TOO LARGE FOR MODE=0, BETTER TRY MODE=1'
195 ierr = frac(z,m,0,eps,tinysq,fc)
205 argu1=dsqrt(2._dp/(z+1._dp))
206 qlmm(0)=argu1*ellip1(argu1)
207 qlmm(1)=-1._dp/dsqrt(2._dp*(qz-1._dp))*ellip2(argu1)
212 IF (mode_loc.EQ.0)
THEN
213 1
IF ((mp.LE.m).AND.(abs(qlmm(mp)).LT.over))
THEN
214 qlmm(mp+1)=-2._dp*mp*qargu*qlmm(mp)-&
215 &(mp-0.5_dp)*(mp-0.5_dp)*qlmm(mp-1)
219 IF ((mp-1).NE.m)
THEN
221 err_msg =
'M IS TOO LARGE FOR MODE=0, BETTER TRY MODE=1'
226 qlmm(1)=qlmm(1)*2._dp/pisq
227 2
IF ((mp.LE.m).AND.(abs(qlmm(mp)).LT.over))
THEN
229 qlmm(mp+1)=-2._dp*mp*qargu*qlmm(mp)/d1&
230 &-(mp-0.5_dp)*qlmm(mp-1)/d1
234 IF ((mp-1).NE.m)
THEN
236 err_msg =
'M IS TOO LARGE FOR MODE=1,2'
241 dfacqs=-(gamma/qlmm(m+1))*gamma/
pi
249 ierr = fracps(qargu,m+1,0,eps,tinysq,fcp)
252 IF (mode_loc.NE.0)
THEN
256 pl_loc(0)=dfacqs/dsqrt(qdc1)/(1._dp-fcp*qlmm(m)/qlmm(m+1))
258 CALL expan(z,mode_loc,ipre_loc,over,qargu,m,pl0)
262 dfac3=(gamma/qm0)*gamma/
pi/(0.5_dp-m)
263 pl_loc(1)=pl_loc(0)*fc+dfac3
268 3
IF ((np.LE.nmaxp).AND.(abs((np-m+0.5_dp)*pl_loc(np)).LT.over))
THEN
269 pl_loc(np+1)=(2._dp*np*z*pl_loc(np)-(np+m-0.5_dp)*pl_loc(np-1))/&
276 dfac4=(factco(nmaxp,pl_loc(nmaxp+1),m)*gamma)*gamma/
pi/(nmaxp+m+0.5_dp)
280 ierr = frac(z,m,nmaxp,eps,tinysq,fc)
288 ql_loc(nmaxp)=dfac4/(1._dp-fc*pl_loc(nmaxp)/pl_loc(nmaxp+1))
289 ql_loc(nmaxp+1)=ql_loc(nmaxp)*fc
296 ql_loc(n)=((np+np)*z*ql_loc(np)-(np-m+0.5_dp)*ql_loc(np+1))/&
306 integer function frac(Z,M,NMAX,EPS,TINYSQ,FC)
result(ierr)
307 character(*),
parameter :: rout_name =
'FRAC'
310 REAL(
dp) z,eps,tinysq,fc,dz2,dn0,dn1,dn2,dn3,dn4,b,a,c0,d0,delta
329 IF (dabs(d0).LT.tinysq) d0=tinysq
331 IF (dabs(c0).LT.tinysq) c0=tinysq
336 a=-(1.d0+dn4/(dn3+mm))
337 b=dz2*(dn1+mm)/(dn2+mm)
338 IF (mm.LT.1000000)
THEN
339 IF (dabs(delta-1.d0).GT.eps)
GOTO 81
341 IF (mm.EQ.1000000)
then
343 err_msg =
'CF CONVERGENCE FAILS FOR Z = '//trim(
r2str(z))
348 integer function fracps(QZ,M,N,EPS,TINYSQ,FC)
result(ierr)
349 character(*),
parameter :: rout_name =
'FRACPS'
352 REAL(
dp) qz,eps,tinysq,fc,dn2,dz2,dm,b,a,c0,d0,delta
367 IF (dabs(d0).LT.tinysq) d0=tinysq
369 IF (dabs(c0).LT.tinysq) c0=tinysq
374 a=dn2-(mm+dm)*(mm+dm)
376 IF (mm.LT.1000000)
THEN
377 IF (abs(delta-1._dp).GT.eps)
GOTO 82
379 IF (mm.EQ.1000000)
then
381 err_msg =
'CF CONVERGENCE FAILS FOR QZ = '//trim(
r2str(qz))
386 REAL(
dp) function ellip2(ak)
390 q=(1._dp-ak)*(1._dp+ak)
391 ellip2=drf(q)-(ak)**2*drd(q)/3.d0
394 REAL(dp) function ellip1(ak)
397 ellip1=drf((1._dp-ak)*(1._dp+ak))
404 REAL(dp) function drf (y)
405 REAL(dp) epslon, errtol
406 REAL(dp) c1, c2, c3, e2, e3, lamda
407 REAL(dp) mu, s, xn, xndev
408 REAL(dp) xnroot, y, yn, yndev, ynroot, zn, zndev, znroot
410 SAVE errtol,c1,c2,c3,first
426 30 mu = (xn+yn+zn)/3.0_dp
427 xndev = 2.0_dp - (mu+xn)/mu
428 yndev = 2.0_dp - (mu+yn)/mu
429 zndev = 2.0_dp - (mu+zn)/mu
430 epslon = max(abs(xndev),abs(yndev),abs(zndev))
431 IF (epslon.LT.errtol)
GO TO 40
435 lamda = xnroot*(ynroot+znroot) + ynroot*znroot
436 xn = (xn+lamda)*0.250_dp
437 yn = (yn+lamda)*0.250_dp
438 zn = (zn+lamda)*0.250_dp
441 40 e2 = xndev*yndev - zndev*zndev
442 e3 = xndev*yndev*zndev
443 s = 1.0_dp + (c1*e2-0.10_dp-c2*e3)*e2 + c3*e3
448 REAL(dp) function drd (y)
449 REAL(dp) epslon, errtol
450 REAL(dp) c1, c2, c3, c4, ea, eb, ec, ed, ef, lamda
451 REAL(dp) mu, power4, sigma, s1, s2, xn, xndev
452 REAL(dp) xnroot, y, yn, yndev, ynroot, zn, zndev, znroot
454 SAVE errtol, c1, c2, c3, c4, first
477 30 mu = (xn+yn+3.0_dp*zn)*0.20_dp
481 epslon = max(abs(xndev), abs(yndev), abs(zndev))
482 IF (epslon.LT.errtol)
GO TO 40
486 lamda = xnroot*(ynroot+znroot) + ynroot*znroot
487 sigma = sigma + power4/(znroot*(zn+lamda))
488 power4 = power4*0.250_dp
489 xn = (xn+lamda)*0.250_dp
490 yn = (yn+lamda)*0.250_dp
491 zn = (zn+lamda)*0.250_dp
499 s1 = ed*(-c1+0.250_dp*c3*ed-1.50_dp*c4*zndev*ef)
500 s2 = zndev*(c2*ef+zndev*(-c3*ec+zndev*c4*ea))
501 drd = 3.0_dp*sigma + power4*(1.0_dp+s1+s2)/(mu*sqrt(mu))
504 REAL(dp) function gammah(n,over)
511 85
IF ((j.GE.1).AND.(gammah.LT.over))
THEN
512 gammah=gammah*j/2._dp
522 REAL(dp) function factco(n,pl,m)
531 factco=factco*(j+x1)/(j+x2)
537 SUBROUTINE expan(Z,MODE,IPRE,OVER,QARGU,M,PL)
538 INTEGER mode,ipre,m,k,i
539 REAL(dp) z,over,qargu,pl,pisq,db,fl,cc,dz,gamma,ar,&
540 &DFAC,DF1,A0,Z2I,DA1,DA2,DELTA,SUM,DCC,DCCP,DKK
548 cc=abs(float(int(fl))-fl)
549 IF (cc.LT.0.4_dp)
THEN
559 gamma=gammah(m,over)*ar*pisq
563 dfac=2._dp/pi*dz*gamma/pisq
565 a0=1._dp/dsqrt(2._dp*z)
572 87 delta=(df1+da1)*da2*a0
577 da2=da2*dccp*dcc/(dkk*dkk)
578 da1=da1+1._dp/dkk-1._dp/dccp-1._dp/dcc
581 IF (abs(delta/sum).GT.preci(ipre))
GOTO 87
585 REAL(dp) function factor(m,k)
596 factor=factor*(j+x1)/i/i
605 REAL(dp) function psi(m,k)
607 REAL(dp) factr1,factr2
615 factr1=factr1+1._dp/j
622 factr2=factr2+1._dp/(2._dp*i-1._dp)
626 IF (n.EQ.0) factr2=0._dp
627 psi=factr1-2._dp*factr2