REAL(Kind=WP_Kind) FUNCTION plm_fun(l, mm, x) USE Numeric_Kinds_Module USE fileunits_Module ! IMPLICIT NONE INTEGER l, mm, m, mtest, i, lm1, mu REAL(Kind=WP_Kind) x, xm, p1, p2, p3, z, xtest, xi, rat, xl REAL(Kind=WP_Kind) xmu, xnorm, xlm, xlp CHARACTER(LEN=21), PARAMETER:: ProcName='plm_fun' ! computes normalized associated legendre polynomials by recursion. ! the phase is that of abramowitz and stegun and gradshteyn and ryzhik. ! recurs up in l via gr 8.832.2 then up in abs(mm) via 8.735.1 and 8.73 ! for large abs(x), recurs down in abs(mm) via gr 8.733.1d and 8.733.3 ! then each plm is normalized to 1.0 on (-1.,1.). ! for either positive or negative mm, multiplication by exp(i*mm*phi)/ ! sqrt(2.*pi) gives the spherical harmonics of condon and shortley, ros ! messiah, and jackson. ! to get the phase of mclean and yoshimine, replace statement 333 by 44 ! program of r. nerf modified by s. green and r. pack. m=iabs(mm) xl=float(l) xm=float(m) IF(m > l .or. l < 0) go to 100 IF(abs(x) > 1.d0) go to 100 p1=1.d0 p2=x IF(l == 0) go to 70 IF(m == 0) go to 10 ! if x is small enough, use the recursion expected to be faster. xtest=0.499d0*(1.d0+1.d0/xm) mtest=l/3 IF(m > mtest .or. abs(x) > xtest) go to 40 10 DO 20 i=1, l xi=float(i) p3=((2.d0*xi+1.d0)*x*p2-xi*p1)/(xi+1.d0) p1=p2 p2=p3 20 continue IF(m == 0) go to 70 ! at end of loop p1=p(l, 0, x) z=sqrt(1.d0-x*x) IF(z < 1.d-6) go to 110 ! if z=0, then x=1 and plm(1.)=0 for m > 0. ! recur up in abs(mm) p2=(xl+1.d0)*(p2-x*p1)/z DO 30 i=1,m xi=float(i) p3=-2.d0*x/z*p2*xi-(xl+xi)*(xl-xi+1.d0)*p1 p1=p2 p2=p3 30 continue go to 70 ! recur down in abs(mm) if abs(x) is large 40 z=sqrt(1.d0-x*x) IF(z < 1.d-6) go to 110 ! if z=0 then x=1 and plm=0 for m>0 ! calc ratio of factorials for pll rat=1.d0 DO 50 i=1, l xi=float(i) rat=0.5d0*(xl+xi)*rat 50 continue ! calculate pll p1=rat*(-z)**l IF(m == l) go to 70 p2=p1 p1=-x*p2/z lm1=l-1 IF(m == lm1) go to 70 lm1=l-m-1 ! recur downward in abs(mm) DO 60 i=1, lm1 mu=l-i-1 xmu=float(mu) p3=p2 p2=p1 p1=2.d0*(xmu+1.d0)*x*p2/z+p3 p1=-p1/((xl-xmu)*(xl+xmu+1.d0)) 60 continue ! normalization..... 70 xnorm=(2.d0*xl+1.d0)/2.d0 IF(m == 0) go to 90 xlm=xl+1.d0 xlp=xl DO 80 i=1, m xlm=xlm-1.d0 xlp=xlp+1.d0 xnorm=xnorm/(xlm*xlp) 80 continue 90 plm_fun=p1*sqrt(xnorm) IF(mm < 0) plm_fun=plm_fun*(-1)**(m) ! 444 IF(m /= 0) plm=plm*(-1)**m RETURN 100 WRITE(Out_Unit,120) l, mm, x 110 plm_fun=0.d0 RETURN ! 120 FORMAT(//,' error. argument out of range for plm(', 2i6 & , e14.7, ' ).') END