summaryrefslogtreecommitdiff
path: root/Dragon/src/PNSH.f90
diff options
context:
space:
mode:
Diffstat (limited to 'Dragon/src/PNSH.f90')
-rw-r--r--Dragon/src/PNSH.f90149
1 files changed, 149 insertions, 0 deletions
diff --git a/Dragon/src/PNSH.f90 b/Dragon/src/PNSH.f90
new file mode 100644
index 0000000..39a7cf0
--- /dev/null
+++ b/Dragon/src/PNSH.f90
@@ -0,0 +1,149 @@
+!
+!-----------------------------------------------------------------------
+!
+!Purpose:
+! Return the real spherical harmonics corresponding to a set of
+! direction cosines.
+!
+!Copyright:
+! Copyright (C) 2004 Ecole Polytechnique de Montreal
+! This library is free software; you can redistribute it and/or
+! modify it under the terms of the GNU Lesser General Public
+! License as published by the Free Software Foundation; either
+! version 2.1 of the License, or (at your option) any later version
+!
+!Author(s): A. Hebert
+!
+!Parameters: input
+! L Legendre order.
+! M azimuthal order.
+! ZMU X-directed direction cosine.
+! ETA Y-directed direction cosine.
+! XI Z-directed direction cosine.
+!
+!Parameters: output
+! PNOUT value of the spherical harmonics.
+!
+!-----------------------------------------------------------------------
+!
+REAL FUNCTION PNSH(L,M,ZMU,ETA,XI) RESULT(PNOUT)
+ !----
+ ! FUNCTION ARGUMENTS
+ !----
+ INTEGER L,M
+ REAL ZMU,ETA,XI
+ !----
+ ! LOCAL VARIABLES
+ !----
+ PARAMETER (PI=3.141592653589793)
+ DOUBLE PRECISION FACTOR,PHI,PNL,DZMU,COEF,ALPLGN
+ !
+ TEST=ZMU*ZMU+ETA*ETA+XI*XI
+ IF(ABS(TEST-1.0).GT.1.0E-5) THEN
+ CALL XABORT('PNSH: INVALID DIRECTION COSINES.')
+ ENDIF
+ PNOUT=0.0
+ IF((L.EQ.0).AND.(M.EQ.0)) THEN
+ PNOUT=1.0
+ ELSE IF((L.EQ.1).AND.(M.EQ.-1)) THEN
+ PNOUT=XI
+ ELSE IF((L.EQ.1).AND.(M.EQ.0)) THEN
+ PNOUT=ZMU
+ ELSE IF((L.EQ.1).AND.(M.EQ.1)) THEN
+ PNOUT=ETA
+ ELSE IF((L.EQ.2).AND.(M.EQ.-2)) THEN
+ PNOUT=SQRT(3.0)*ETA*XI
+ ELSE IF((L.EQ.2).AND.(M.EQ.-1)) THEN
+ PNOUT=SQRT(3.0)*ZMU*XI
+ ELSE IF((L.EQ.2).AND.(M.EQ.0)) THEN
+ PNOUT=0.5*(3.0*ZMU*ZMU-1.0)
+ ELSE IF((L.EQ.2).AND.(M.EQ.1)) THEN
+ PNOUT=SQRT(3.0)*ZMU*ETA
+ ELSE IF((L.EQ.2).AND.(M.EQ.2)) THEN
+ PNOUT=0.5*SQRT(3.0)*(ETA*ETA-XI*XI)
+ ELSE IF((L.EQ.3).AND.(M.EQ.-3)) THEN
+ PNOUT=SQRT(5./8.)*XI*(3.0*ETA*ETA-XI*XI)
+ ELSE IF((L.EQ.3).AND.(M.EQ.-2)) THEN
+ PNOUT=SQRT(15.0)*ETA*XI*ZMU
+ ELSE IF((L.EQ.3).AND.(M.EQ.-1)) THEN
+ PNOUT=SQRT(3./8.)*XI*(5.0*ZMU*ZMU-1.0)
+ ELSE IF((L.EQ.3).AND.(M.EQ.0)) THEN
+ PNOUT=0.5*ZMU*(5.0*ZMU*ZMU-3.0)
+ ELSE IF((L.EQ.3).AND.(M.EQ.1)) THEN
+ PNOUT=SQRT(3./8.)*ETA*(5.0*ZMU*ZMU-1.0)
+ ELSE IF((L.EQ.3).AND.(M.EQ.2)) THEN
+ PNOUT=SQRT(15.0/4.0)*ZMU*(ETA*ETA-XI*XI)
+ ELSE IF((L.EQ.3).AND.(M.EQ.3)) THEN
+ PNOUT=SQRT(5./8.)*ETA*(ETA*ETA-3.0*XI*XI)
+ ELSE IF((L.EQ.4).AND.(M.EQ.-4)) THEN
+ PNOUT=0.5*SQRT(35.)*ETA*XI*(ETA*ETA-XI*XI)
+ ELSE IF((L.EQ.4).AND.(M.EQ.-3)) THEN
+ PNOUT=0.5*SQRT(0.5*35.)*ZMU*XI*(3.*ETA*ETA-XI*XI)
+ ELSE IF((L.EQ.4).AND.(M.EQ.-2)) THEN
+ PNOUT=SQRT(5.)*(21.*ZMU*ZMU-3.)*ETA*XI/6.
+ ELSE IF((L.EQ.4).AND.(M.EQ.-1)) THEN
+ PNOUT=0.5*SQRT(2.5)*ZMU*XI*(7.*ZMU*ZMU-3.)
+ ELSE IF((L.EQ.4).AND.(M.EQ.0)) THEN
+ PNOUT=(35.*ZMU**4-30.*ZMU*ZMU+3.)/8.
+ ELSE IF((L.EQ.4).AND.(M.EQ.1)) THEN
+ PNOUT=0.5*SQRT(2.5)*ZMU*ETA*(7.*ZMU*ZMU-3.)
+ ELSE IF((L.EQ.4).AND.(M.EQ.2)) THEN
+ PNOUT=SQRT(5.)*(21.*ZMU*ZMU-3.)*(ETA*ETA-XI*XI)/12.
+ ELSE IF((L.EQ.4).AND.(M.EQ.3)) THEN
+ PNOUT=0.5*SQRT(0.5*35.)*ZMU*ETA*(ETA*ETA-3.*XI*XI)
+ ELSE IF((L.EQ.4).AND.(M.EQ.4)) THEN
+ PNOUT=SQRT(35.)*(ETA**4-6.*(ETA*XI)**2+XI**4)/8.
+ ELSE IF((L.EQ.5).AND.(M.EQ.-5)) THEN
+ PNOUT=21.*XI*(5.*ETA**4-10.*(ETA*XI)**2+XI**4)/(8.*SQRT(14.))
+ ELSE IF((L.EQ.5).AND.(M.EQ.-4)) THEN
+ PNOUT=0.5*105.*ZMU*ETA*XI*(ETA*ETA-XI*XI)/SQRT(35.)
+ ELSE IF((L.EQ.5).AND.(M.EQ.-3)) THEN
+ PNOUT=35.*(9*ZMU*ZMU-1.)*XI*(3.*ETA*ETA-XI*XI)/(8.*SQRT(70.))
+ ELSE IF((L.EQ.5).AND.(M.EQ.-2)) THEN
+ PNOUT=0.5*SQRT(105.)*ZMU*(3.*ZMU*ZMU-1.)*ETA*XI
+ ELSE IF((L.EQ.5).AND.(M.EQ.-1)) THEN
+ PNOUT=SQRT(15.)*XI*(21.*ZMU**4-14.*ZMU*ZMU+1.)/8.
+ ELSE IF((L.EQ.5).AND.(M.EQ.0)) THEN
+ PNOUT=ZMU*(63.*ZMU**4-70.*ZMU*ZMU+15.)/8.
+ ELSE IF((L.EQ.5).AND.(M.EQ.1)) THEN
+ PNOUT=SQRT(15.)*ETA*(21.*ZMU**4-14.*ZMU*ZMU+1.)/8.
+ ELSE IF((L.EQ.5).AND.(M.EQ.2)) THEN
+ PNOUT=0.25*SQRT(105.)*ZMU*(3.*ZMU*ZMU-1.)*(ETA*ETA-XI*XI)
+ ELSE IF((L.EQ.5).AND.(M.EQ.3)) THEN
+ PNOUT=35.*(9*ZMU*ZMU-1.)*ETA*(ETA*ETA-3.*XI*XI)/(8.*SQRT(70.))
+ ELSE IF((L.EQ.5).AND.(M.EQ.4)) THEN
+ PNOUT=105.*ZMU*(ETA**4-6.*(ETA*XI)**2+XI**4)/(8.*SQRT(35.))
+ ELSE IF((L.EQ.5).AND.(M.EQ.5)) THEN
+ PNOUT=21.*ETA*(ETA**4-10.*(ETA*XI)**2+5.*XI**4)/(8.*SQRT(14.))
+ ELSE
+ FACTOR=SQRT(1.0D0-ZMU*ZMU)
+ PHI=0.0D0
+ IF(XI.GE.0) THEN
+ PHI=ACOS(ETA/FACTOR)
+ ELSE IF(XI.LT.0) THEN
+ PHI=2.0D0*PI-ACOS(ETA/FACTOR)
+ ENDIF
+ COEF=SQRT(2.0D0*ALFACT(L-ABS(M))/ALFACT(L+ABS(M)))
+ DZMU=ZMU
+ PNL=ALPLGN(L,ABS(M),DZMU)
+ IF(M.GT.0) THEN
+ PNOUT=REAL(COEF*PNL*COS(M*PHI))
+ ELSE IF(M.EQ.0) THEN
+ PNOUT=REAL(PNL)
+ ELSE IF(M.LT.0) THEN
+ PNOUT=REAL(COEF*PNL*SIN(-M*PHI))
+ ENDIF
+ ENDIF
+ RETURN
+ !
+ CONTAINS
+ RECURSIVE DOUBLE PRECISION FUNCTION ALFACT(N) RESULT(OUT)
+ ! return the factorial of N
+ INTEGER N
+ IF(N.LE.1) THEN
+ OUT=1.0D0
+ ELSE
+ OUT=N*ALFACT(N-1)
+ ENDIF
+ END FUNCTION ALFACT
+END FUNCTION PNSH