1 # [Xu] = Journal of computational physics 139, 137–165
3 from __future__
import print_function
8 def qmax(M
, n
, mu
, nu
):
9 return floor(min(n
, nu
, (n
+nu
-abs(M
+mu
))/2))
11 def Qmax(M
, n
, mu
, nu
): # [Xu](60)
12 return floor(min(n
, nu
, (n
+nu
+1-abs(M
+mu
))/2))
14 def gaunta_p(M
, n
, mu
, nu
, p
): # [Xu](5)
15 #print (M,n,mu,nu,p, file=sys.stderr)
16 return (-1)**(M
+mu
) * (2*p
+1) * sqrt(
17 factorial(n
+M
) * factorial(nu
+mu
) * factorial(p
-M
-mu
)
18 / factorial(n
-M
) / factorial(nu
-mu
) / factorial(p
+M
+mu
)) * (
19 wigner_3j(n
, nu
, p
, 0, 0, 0) * wigner_3j(n
, nu
, p
, M
, mu
, -M
-mu
))
21 def bCXcoeff(M
, n
, mu
, nu
, p
): # [Xu](61)
22 #print(M,n,mu,nu,p,file=sys.stderr)
23 return (-1)**(M
+mu
) * (2*p
+ 3) * sqrt(
24 factorial(n
+M
) * factorial(nu
+mu
) * factorial(p
+1-M
-mu
)
25 / factorial(n
-M
) / factorial(nu
-mu
) / factorial(p
+1+M
+mu
)) * (
26 wigner_3j(n
, nu
, p
, 0, 0, 0) * wigner_3j(n
, nu
, p
+1, M
, mu
, -M
-mu
))
28 def ACXcoeff(m
, n
, mu
, nu
, q
): # [Xu](58)
30 return ((-1)**m
* (2*nu
+ 1) * factorial(n
+m
) * factorial(nu
-mu
) / (
31 2 * n
* (n
+1) * factorial(n
-m
) * factorial(nu
+mu
)) * I
**p
*
32 (n
*(n
+1) + nu
*(nu
+1) - p
*(p
+1)) * gaunta_p(-m
,n
,mu
,nu
,p
))
34 def BCXcoeff(m
, n
, mu
, nu
, q
): # [Xu](59)
36 return ((-1)**(m
+1) * (2*nu
+ 1) * factorial(n
+m
) * factorial(nu
-mu
) / (
37 2 * n
* (n
+1) * factorial(n
-m
) * factorial(nu
+mu
)) * I
**(p
+1) *
38 sqrt(((p
+1)**2-(n
-nu
)**2) * ((n
+nu
+1)**2-(p
+1)**2))
39 * bCXcoeff(-m
,n
,mu
,nu
,p
))
41 def printACXcoeffs(lMax
, file=sys
.stdout
):
42 for n
in IntegerRange(lMax
+1):
43 for nu
in IntegerRange(lMax
+1):
44 for m
in IntegerRange(-n
, n
+1):
45 for mu
in IntegerRange(-nu
, nu
+1):
46 for q
in IntegerRange(qmax(-m
,n
,mu
,nu
)):
47 #print(m, n, mu, nu, q, p_q(q,n,nu), file=sys.stderr)
48 coeff
= ACXcoeff(m
, n
, mu
, nu
, q
);
49 print(N(coeff
, prec
=53),
50 ", // %d, %d, %d, %d, %d," % (m
,n
,mu
,nu
,q
),
55 def printBCXcoeffs(lMax
, file=sys
.stdout
):
56 for n
in IntegerRange(lMax
+1):
57 for nu
in IntegerRange(lMax
+1):
58 for m
in IntegerRange(-n
, n
+1):
59 for mu
in IntegerRange(-nu
, nu
+1):
60 for q
in IntegerRange(1, Qmax(-m
,n
,mu
,nu
) +1 ):
61 #print(m, n, mu, nu, q, p_q(q,n,nu), file=sys.stderr)
62 coeff
= BCXcoeff(m
, n
, mu
, nu
, q
);
63 print(N(coeff
, prec
=53),
64 ", // %d, %d, %d, %d, %d," % (m
,n
,mu
,nu
,q
),
69 sphericalBessels
= (None,
76 # N.B. sage's gen_legendre_P _does_ include (-1)**m Condon-Shortley phase
77 # whereas formulae in [Xu] do not.
78 def trcoeff_ACX(m
, n
, mu
, nu
, besseltype
, kd
, th
, fi
, csphase
=1): # [Xu](58)
80 for q
in range(qmax(-m
,n
,mu
,nu
)+1):
82 res
+= ACXcoeff(m
,n
,mu
,nu
,q
) * sphericalBessels
[besseltype
](p
,kd
) * gen_legendre_P(p
, mu
-m
, cos(th
)) * (-csphase
)**(mu
-m
) # compensate for csphase
83 res
*= exp(I
*(mu
-m
)*fi
)
86 def trcoeff_BCX(m
, n
, mu
, nu
, besseltype
, kd
, th
, fi
, csphase
=1): # [Xu](59)
88 for q
in IntegerRange(1,Qmax(-m
,n
,mu
,nu
)+1):
90 res
+= BCXcoeff(m
,n
,mu
,nu
,q
) * sphericalBessels
[besseltype
](p
+1,kd
) * gen_legendre_P(p
+1, mu
-m
, cos(th
)) * (-csphase
)**(mu
-m
)
91 res
*= exp(I
*(mu
-m
)*fi
)
95 def legpi_xu(n
, m
, fi
): # momentálně neošetřeny okraje (cos(fi) == +- 1)
96 return m
/sin(fi
) * gen_legendre_P(n
, m
, cos(fi
))
98 def legtau_xu(n
, m
, fi
):
100 return -sin(fi
)*derivative(gen_legendre_P(n
,m
,locx
), locx
).substitute(locx
= cos(fi
))
102 def vswf_M_xu(besseltype
, n
, m
, kr
, th
, fi
):
103 postpart
= sphericalBessels
[besseltype
](n
, kr
) * exp(I
* m
* fi
)
104 tc
= I
*legpi_xu(n
,m
,th
) * postpart
105 fc
= -legtau_xu(n
,m
,th
) * postpart
108 def vswf_N_xu(besseltype
, n
, m
, kr
, th
, fi
):
109 eimf
= exp(I
* m
* fi
)
110 rc
= n
* (n
+1) * gen_legendre_P(n
, m
, cos(th
)) * sphericalBessels
[besseltype
](n
, kr
)/kr
* eimf
112 radpart
= derivative(krv
* sphericalBessels
[besseltype
](n
, krv
), krv
).substitute(krv
=kr
)/kr
113 tc
= legtau_xu(n
,m
,th
) * radpart
* eimf
114 fc
= I
*legpi_xu(n
,m
,th
) * radpart
* eimf
119 r
= sqrt(x
**2 + y
**2 + z
**2)
120 th
= arccos(z
/r
) if r
else 0
127 x
= r
* sinth
* cos(fi
)
128 y
= r
* sinth
* sin(fi
)
132 def sphvec2cart(loccart
, sph
):
150 x
= rx
* rc
+ tx
* tc
+ fx
* fc
151 y
= ry
* rc
+ ty
* tc
+ fy
* fc
152 z
= rz
* rc
+ tz
* tc
+ fz
* fc
155 def cart2sphvec(cart
, sph
):
169 rc
= rx
* x
+ ry
* y
+ rz
* z
170 tc
= tx
* x
+ ty
* y
+ tz
* z
171 fc
= fx
* x
+ fy
* y
+ fz
* z
174 def test_M_translation_xu(lMax
, origl
, origm
, origcartat
, cartshift
):
175 ox
, oy
, oz
= origcartat
176 sx
, sy
, sz
= cartshift
177 newcartat
= (ox
- sx
, oy
- sy
, oz
- sz
)
178 w1s
= cart2sph(origcartat
)
179 w2s
= cart2sph(newcartat
)