m2m模型翻译
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

339 lines
9.3 KiB

7 months ago
  1. from sympy.core.numbers import (I, pi)
  2. from sympy.core.singleton import S
  3. from sympy.core.symbol import symbols
  4. from sympy.functions.elementary.exponential import exp
  5. from sympy.functions.elementary.miscellaneous import sqrt
  6. from sympy.functions.elementary.trigonometric import (cos, sin)
  7. from sympy.functions.special.spherical_harmonics import Ynm
  8. from sympy.matrices.dense import Matrix
  9. from sympy.physics.wigner import (clebsch_gordan, wigner_9j, wigner_6j, gaunt,
  10. racah, dot_rot_grad_Ynm, wigner_3j, wigner_d_small, wigner_d)
  11. from sympy.core.numbers import Rational
  12. # for test cases, refer : https://en.wikipedia.org/wiki/Table_of_Clebsch%E2%80%93Gordan_coefficients
  13. def test_clebsch_gordan_docs():
  14. assert clebsch_gordan(Rational(3, 2), S.Half, 2, Rational(3, 2), S.Half, 2) == 1
  15. assert clebsch_gordan(Rational(3, 2), S.Half, 1, Rational(3, 2), Rational(-1, 2), 1) == sqrt(3)/2
  16. assert clebsch_gordan(Rational(3, 2), S.Half, 1, Rational(-1, 2), S.Half, 0) == -sqrt(2)/2
  17. def test_clebsch_gordan1():
  18. j_1 = S.Half
  19. j_2 = S.Half
  20. m = 1
  21. j = 1
  22. m_1 = S.Half
  23. m_2 = S.Half
  24. assert clebsch_gordan(j_1, j_2, j, m_1, m_2, m) == 1
  25. j_1 = S.Half
  26. j_2 = S.Half
  27. m = -1
  28. j = 1
  29. m_1 = Rational(-1, 2)
  30. m_2 = Rational(-1, 2)
  31. assert clebsch_gordan(j_1, j_2, j, m_1, m_2, m) == 1
  32. j_1 = S.Half
  33. j_2 = S.Half
  34. m = 0
  35. j = 1
  36. m_1 = S.Half
  37. m_2 = S.Half
  38. assert clebsch_gordan(j_1, j_2, j, m_1, m_2, m) == 0
  39. j_1 = S.Half
  40. j_2 = S.Half
  41. m = 0
  42. j = 1
  43. m_1 = S.Half
  44. m_2 = Rational(-1, 2)
  45. assert clebsch_gordan(j_1, j_2, j, m_1, m_2, m) == sqrt(2)/2
  46. j_1 = S.Half
  47. j_2 = S.Half
  48. m = 0
  49. j = 0
  50. m_1 = S.Half
  51. m_2 = Rational(-1, 2)
  52. assert clebsch_gordan(j_1, j_2, j, m_1, m_2, m) == sqrt(2)/2
  53. j_1 = S.Half
  54. j_2 = S.Half
  55. m = 0
  56. j = 1
  57. m_1 = Rational(-1, 2)
  58. m_2 = S.Half
  59. assert clebsch_gordan(j_1, j_2, j, m_1, m_2, m) == sqrt(2)/2
  60. j_1 = S.Half
  61. j_2 = S.Half
  62. m = 0
  63. j = 0
  64. m_1 = Rational(-1, 2)
  65. m_2 = S.Half
  66. assert clebsch_gordan(j_1, j_2, j, m_1, m_2, m) == -sqrt(2)/2
  67. def test_clebsch_gordan2():
  68. j_1 = S.One
  69. j_2 = S.Half
  70. m = Rational(3, 2)
  71. j = Rational(3, 2)
  72. m_1 = 1
  73. m_2 = S.Half
  74. assert clebsch_gordan(j_1, j_2, j, m_1, m_2, m) == 1
  75. j_1 = S.One
  76. j_2 = S.Half
  77. m = S.Half
  78. j = Rational(3, 2)
  79. m_1 = 1
  80. m_2 = Rational(-1, 2)
  81. assert clebsch_gordan(j_1, j_2, j, m_1, m_2, m) == 1/sqrt(3)
  82. j_1 = S.One
  83. j_2 = S.Half
  84. m = S.Half
  85. j = S.Half
  86. m_1 = 1
  87. m_2 = Rational(-1, 2)
  88. assert clebsch_gordan(j_1, j_2, j, m_1, m_2, m) == sqrt(2)/sqrt(3)
  89. j_1 = S.One
  90. j_2 = S.Half
  91. m = S.Half
  92. j = S.Half
  93. m_1 = 0
  94. m_2 = S.Half
  95. assert clebsch_gordan(j_1, j_2, j, m_1, m_2, m) == -1/sqrt(3)
  96. j_1 = S.One
  97. j_2 = S.Half
  98. m = S.Half
  99. j = Rational(3, 2)
  100. m_1 = 0
  101. m_2 = S.Half
  102. assert clebsch_gordan(j_1, j_2, j, m_1, m_2, m) == sqrt(2)/sqrt(3)
  103. j_1 = S.One
  104. j_2 = S.One
  105. m = S(2)
  106. j = S(2)
  107. m_1 = 1
  108. m_2 = 1
  109. assert clebsch_gordan(j_1, j_2, j, m_1, m_2, m) == 1
  110. j_1 = S.One
  111. j_2 = S.One
  112. m = 1
  113. j = S(2)
  114. m_1 = 1
  115. m_2 = 0
  116. assert clebsch_gordan(j_1, j_2, j, m_1, m_2, m) == 1/sqrt(2)
  117. j_1 = S.One
  118. j_2 = S.One
  119. m = 1
  120. j = S(2)
  121. m_1 = 0
  122. m_2 = 1
  123. assert clebsch_gordan(j_1, j_2, j, m_1, m_2, m) == 1/sqrt(2)
  124. j_1 = S.One
  125. j_2 = S.One
  126. m = 1
  127. j = 1
  128. m_1 = 1
  129. m_2 = 0
  130. assert clebsch_gordan(j_1, j_2, j, m_1, m_2, m) == 1/sqrt(2)
  131. j_1 = S.One
  132. j_2 = S.One
  133. m = 1
  134. j = 1
  135. m_1 = 0
  136. m_2 = 1
  137. assert clebsch_gordan(j_1, j_2, j, m_1, m_2, m) == -1/sqrt(2)
  138. def test_clebsch_gordan3():
  139. j_1 = Rational(3, 2)
  140. j_2 = Rational(3, 2)
  141. m = S(3)
  142. j = S(3)
  143. m_1 = Rational(3, 2)
  144. m_2 = Rational(3, 2)
  145. assert clebsch_gordan(j_1, j_2, j, m_1, m_2, m) == 1
  146. j_1 = Rational(3, 2)
  147. j_2 = Rational(3, 2)
  148. m = S(2)
  149. j = S(2)
  150. m_1 = Rational(3, 2)
  151. m_2 = S.Half
  152. assert clebsch_gordan(j_1, j_2, j, m_1, m_2, m) == 1/sqrt(2)
  153. j_1 = Rational(3, 2)
  154. j_2 = Rational(3, 2)
  155. m = S(2)
  156. j = S(3)
  157. m_1 = Rational(3, 2)
  158. m_2 = S.Half
  159. assert clebsch_gordan(j_1, j_2, j, m_1, m_2, m) == 1/sqrt(2)
  160. def test_clebsch_gordan4():
  161. j_1 = S(2)
  162. j_2 = S(2)
  163. m = S(4)
  164. j = S(4)
  165. m_1 = S(2)
  166. m_2 = S(2)
  167. assert clebsch_gordan(j_1, j_2, j, m_1, m_2, m) == 1
  168. j_1 = S(2)
  169. j_2 = S(2)
  170. m = S(3)
  171. j = S(3)
  172. m_1 = S(2)
  173. m_2 = 1
  174. assert clebsch_gordan(j_1, j_2, j, m_1, m_2, m) == 1/sqrt(2)
  175. j_1 = S(2)
  176. j_2 = S(2)
  177. m = S(2)
  178. j = S(3)
  179. m_1 = 1
  180. m_2 = 1
  181. assert clebsch_gordan(j_1, j_2, j, m_1, m_2, m) == 0
  182. def test_clebsch_gordan5():
  183. j_1 = Rational(5, 2)
  184. j_2 = S.One
  185. m = Rational(7, 2)
  186. j = Rational(7, 2)
  187. m_1 = Rational(5, 2)
  188. m_2 = 1
  189. assert clebsch_gordan(j_1, j_2, j, m_1, m_2, m) == 1
  190. j_1 = Rational(5, 2)
  191. j_2 = S.One
  192. m = Rational(5, 2)
  193. j = Rational(5, 2)
  194. m_1 = Rational(5, 2)
  195. m_2 = 0
  196. assert clebsch_gordan(j_1, j_2, j, m_1, m_2, m) == sqrt(5)/sqrt(7)
  197. j_1 = Rational(5, 2)
  198. j_2 = S.One
  199. m = Rational(3, 2)
  200. j = Rational(3, 2)
  201. m_1 = S.Half
  202. m_2 = 1
  203. assert clebsch_gordan(j_1, j_2, j, m_1, m_2, m) == 1/sqrt(15)
  204. def test_wigner():
  205. def tn(a, b):
  206. return (a - b).n(64) < S('1e-64')
  207. assert tn(wigner_9j(1, 1, 1, 1, 1, 1, 1, 1, 0, prec=64), Rational(1, 18))
  208. assert wigner_9j(3, 3, 2, 3, 3, 2, 3, 3, 2) == 3221*sqrt(
  209. 70)/(246960*sqrt(105)) - 365/(3528*sqrt(70)*sqrt(105))
  210. assert wigner_6j(5, 5, 5, 5, 5, 5) == Rational(1, 52)
  211. assert tn(wigner_6j(8, 8, 8, 8, 8, 8, prec=64), Rational(-12219, 965770))
  212. # regression test for #8747
  213. half = S.Half
  214. assert wigner_9j(0, 0, 0, 0, half, half, 0, half, half) == half
  215. assert (wigner_9j(3, 5, 4,
  216. 7 * half, 5 * half, 4,
  217. 9 * half, 9 * half, 0)
  218. == -sqrt(Rational(361, 205821000)))
  219. assert (wigner_9j(1, 4, 3,
  220. 5 * half, 4, 5 * half,
  221. 5 * half, 2, 7 * half)
  222. == -sqrt(Rational(3971, 373403520)))
  223. assert (wigner_9j(4, 9 * half, 5 * half,
  224. 2, 4, 4,
  225. 5, 7 * half, 7 * half)
  226. == -sqrt(Rational(3481, 5042614500)))
  227. def test_gaunt():
  228. def tn(a, b):
  229. return (a - b).n(64) < S('1e-64')
  230. assert gaunt(1, 0, 1, 1, 0, -1) == -1/(2*sqrt(pi))
  231. assert isinstance(gaunt(1, 1, 0, -1, 1, 0).args[0], Rational)
  232. assert isinstance(gaunt(0, 1, 1, 0, -1, 1).args[0], Rational)
  233. assert tn(gaunt(
  234. 10, 10, 12, 9, 3, -12, prec=64), (Rational(-98, 62031)) * sqrt(6279)/sqrt(pi))
  235. def gaunt_ref(l1, l2, l3, m1, m2, m3):
  236. return (
  237. sqrt((2 * l1 + 1) * (2 * l2 + 1) * (2 * l3 + 1) / (4 * pi)) *
  238. wigner_3j(l1, l2, l3, 0, 0, 0) *
  239. wigner_3j(l1, l2, l3, m1, m2, m3)
  240. )
  241. threshold = 1e-10
  242. l_max = 3
  243. l3_max = 24
  244. for l1 in range(l_max + 1):
  245. for l2 in range(l_max + 1):
  246. for l3 in range(l3_max + 1):
  247. for m1 in range(-l1, l1 + 1):
  248. for m2 in range(-l2, l2 + 1):
  249. for m3 in range(-l3, l3 + 1):
  250. args = l1, l2, l3, m1, m2, m3
  251. g = gaunt(*args)
  252. g0 = gaunt_ref(*args)
  253. assert abs(g - g0) < threshold
  254. if m1 + m2 + m3 != 0:
  255. assert abs(g) < threshold
  256. if (l1 + l2 + l3) % 2:
  257. assert abs(g) < threshold
  258. def test_racah():
  259. assert racah(3,3,3,3,3,3) == Rational(-1,14)
  260. assert racah(2,2,2,2,2,2) == Rational(-3,70)
  261. assert racah(7,8,7,1,7,7, prec=4).is_Float
  262. assert racah(5.5,7.5,9.5,6.5,8,9) == -719*sqrt(598)/1158924
  263. assert abs(racah(5.5,7.5,9.5,6.5,8,9, prec=4) - (-0.01517)) < S('1e-4')
  264. def test_dot_rota_grad_SH():
  265. theta, phi = symbols("theta phi")
  266. assert dot_rot_grad_Ynm(1, 1, 1, 1, 1, 0) != \
  267. sqrt(30)*Ynm(2, 2, 1, 0)/(10*sqrt(pi))
  268. assert dot_rot_grad_Ynm(1, 1, 1, 1, 1, 0).doit() == \
  269. sqrt(30)*Ynm(2, 2, 1, 0)/(10*sqrt(pi))
  270. assert dot_rot_grad_Ynm(1, 5, 1, 1, 1, 2) != \
  271. 0
  272. assert dot_rot_grad_Ynm(1, 5, 1, 1, 1, 2).doit() == \
  273. 0
  274. assert dot_rot_grad_Ynm(3, 3, 3, 3, theta, phi).doit() == \
  275. 15*sqrt(3003)*Ynm(6, 6, theta, phi)/(143*sqrt(pi))
  276. assert dot_rot_grad_Ynm(3, 3, 1, 1, theta, phi).doit() == \
  277. sqrt(3)*Ynm(4, 4, theta, phi)/sqrt(pi)
  278. assert dot_rot_grad_Ynm(3, 2, 2, 0, theta, phi).doit() == \
  279. 3*sqrt(55)*Ynm(5, 2, theta, phi)/(11*sqrt(pi))
  280. assert dot_rot_grad_Ynm(3, 2, 3, 2, theta, phi).doit().expand() == \
  281. -sqrt(70)*Ynm(4, 4, theta, phi)/(11*sqrt(pi)) + \
  282. 45*sqrt(182)*Ynm(6, 4, theta, phi)/(143*sqrt(pi))
  283. def test_wigner_d():
  284. half = S(1)/2
  285. alpha, beta, gamma = symbols("alpha, beta, gamma", real=True)
  286. d = wigner_d_small(half, beta).subs({beta: pi/2})
  287. d_ = Matrix([[1, 1], [-1, 1]])/sqrt(2)
  288. assert d == d_
  289. D = wigner_d(half, alpha, beta, gamma)
  290. assert D[0, 0] == exp(I*alpha/2)*exp(I*gamma/2)*cos(beta/2)
  291. assert D[0, 1] == exp(I*alpha/2)*exp(-I*gamma/2)*sin(beta/2)
  292. assert D[1, 0] == -exp(-I*alpha/2)*exp(I*gamma/2)*sin(beta/2)
  293. assert D[1, 1] == exp(-I*alpha/2)*exp(-I*gamma/2)*cos(beta/2)