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.

322 lines
14 KiB

6 months ago
  1. from sympy.core.function import Derivative
  2. from sympy.vector.vector import Vector
  3. from sympy.vector.coordsysrect import CoordSys3D
  4. from sympy.simplify import simplify
  5. from sympy.core.symbol import symbols
  6. from sympy.core import S
  7. from sympy.functions.elementary.trigonometric import (cos, sin)
  8. from sympy.vector.vector import Dot
  9. from sympy.vector.operators import curl, divergence, gradient, Gradient, Divergence, Cross
  10. from sympy.vector.deloperator import Del
  11. from sympy.vector.functions import (is_conservative, is_solenoidal,
  12. scalar_potential, directional_derivative,
  13. laplacian, scalar_potential_difference)
  14. from sympy.testing.pytest import raises
  15. C = CoordSys3D('C')
  16. i, j, k = C.base_vectors()
  17. x, y, z = C.base_scalars()
  18. delop = Del()
  19. a, b, c, q = symbols('a b c q')
  20. def test_del_operator():
  21. # Tests for curl
  22. assert delop ^ Vector.zero == Vector.zero
  23. assert ((delop ^ Vector.zero).doit() == Vector.zero ==
  24. curl(Vector.zero))
  25. assert delop.cross(Vector.zero) == delop ^ Vector.zero
  26. assert (delop ^ i).doit() == Vector.zero
  27. assert delop.cross(2*y**2*j, doit=True) == Vector.zero
  28. assert delop.cross(2*y**2*j) == delop ^ 2*y**2*j
  29. v = x*y*z * (i + j + k)
  30. assert ((delop ^ v).doit() ==
  31. (-x*y + x*z)*i + (x*y - y*z)*j + (-x*z + y*z)*k ==
  32. curl(v))
  33. assert delop ^ v == delop.cross(v)
  34. assert (delop.cross(2*x**2*j) ==
  35. (Derivative(0, C.y) - Derivative(2*C.x**2, C.z))*C.i +
  36. (-Derivative(0, C.x) + Derivative(0, C.z))*C.j +
  37. (-Derivative(0, C.y) + Derivative(2*C.x**2, C.x))*C.k)
  38. assert (delop.cross(2*x**2*j, doit=True) == 4*x*k ==
  39. curl(2*x**2*j))
  40. #Tests for divergence
  41. assert delop & Vector.zero is S.Zero == divergence(Vector.zero)
  42. assert (delop & Vector.zero).doit() is S.Zero
  43. assert delop.dot(Vector.zero) == delop & Vector.zero
  44. assert (delop & i).doit() is S.Zero
  45. assert (delop & x**2*i).doit() == 2*x == divergence(x**2*i)
  46. assert (delop.dot(v, doit=True) == x*y + y*z + z*x ==
  47. divergence(v))
  48. assert delop & v == delop.dot(v)
  49. assert delop.dot(1/(x*y*z) * (i + j + k), doit=True) == \
  50. - 1 / (x*y*z**2) - 1 / (x*y**2*z) - 1 / (x**2*y*z)
  51. v = x*i + y*j + z*k
  52. assert (delop & v == Derivative(C.x, C.x) +
  53. Derivative(C.y, C.y) + Derivative(C.z, C.z))
  54. assert delop.dot(v, doit=True) == 3 == divergence(v)
  55. assert delop & v == delop.dot(v)
  56. assert simplify((delop & v).doit()) == 3
  57. #Tests for gradient
  58. assert (delop.gradient(0, doit=True) == Vector.zero ==
  59. gradient(0))
  60. assert delop.gradient(0) == delop(0)
  61. assert (delop(S.Zero)).doit() == Vector.zero
  62. assert (delop(x) == (Derivative(C.x, C.x))*C.i +
  63. (Derivative(C.x, C.y))*C.j + (Derivative(C.x, C.z))*C.k)
  64. assert (delop(x)).doit() == i == gradient(x)
  65. assert (delop(x*y*z) ==
  66. (Derivative(C.x*C.y*C.z, C.x))*C.i +
  67. (Derivative(C.x*C.y*C.z, C.y))*C.j +
  68. (Derivative(C.x*C.y*C.z, C.z))*C.k)
  69. assert (delop.gradient(x*y*z, doit=True) ==
  70. y*z*i + z*x*j + x*y*k ==
  71. gradient(x*y*z))
  72. assert delop(x*y*z) == delop.gradient(x*y*z)
  73. assert (delop(2*x**2)).doit() == 4*x*i
  74. assert ((delop(a*sin(y) / x)).doit() ==
  75. -a*sin(y)/x**2 * i + a*cos(y)/x * j)
  76. #Tests for directional derivative
  77. assert (Vector.zero & delop)(a) is S.Zero
  78. assert ((Vector.zero & delop)(a)).doit() is S.Zero
  79. assert ((v & delop)(Vector.zero)).doit() == Vector.zero
  80. assert ((v & delop)(S.Zero)).doit() is S.Zero
  81. assert ((i & delop)(x)).doit() == 1
  82. assert ((j & delop)(y)).doit() == 1
  83. assert ((k & delop)(z)).doit() == 1
  84. assert ((i & delop)(x*y*z)).doit() == y*z
  85. assert ((v & delop)(x)).doit() == x
  86. assert ((v & delop)(x*y*z)).doit() == 3*x*y*z
  87. assert (v & delop)(x + y + z) == C.x + C.y + C.z
  88. assert ((v & delop)(x + y + z)).doit() == x + y + z
  89. assert ((v & delop)(v)).doit() == v
  90. assert ((i & delop)(v)).doit() == i
  91. assert ((j & delop)(v)).doit() == j
  92. assert ((k & delop)(v)).doit() == k
  93. assert ((v & delop)(Vector.zero)).doit() == Vector.zero
  94. # Tests for laplacian on scalar fields
  95. assert laplacian(x*y*z) is S.Zero
  96. assert laplacian(x**2) == S(2)
  97. assert laplacian(x**2*y**2*z**2) == \
  98. 2*y**2*z**2 + 2*x**2*z**2 + 2*x**2*y**2
  99. A = CoordSys3D('A', transformation="spherical", variable_names=["r", "theta", "phi"])
  100. B = CoordSys3D('B', transformation='cylindrical', variable_names=["r", "theta", "z"])
  101. assert laplacian(A.r + A.theta + A.phi) == 2/A.r + cos(A.theta)/(A.r**2*sin(A.theta))
  102. assert laplacian(B.r + B.theta + B.z) == 1/B.r
  103. # Tests for laplacian on vector fields
  104. assert laplacian(x*y*z*(i + j + k)) == Vector.zero
  105. assert laplacian(x*y**2*z*(i + j + k)) == \
  106. 2*x*z*i + 2*x*z*j + 2*x*z*k
  107. def test_product_rules():
  108. """
  109. Tests the six product rules defined with respect to the Del
  110. operator
  111. References
  112. ==========
  113. .. [1] https://en.wikipedia.org/wiki/Del
  114. """
  115. #Define the scalar and vector functions
  116. f = 2*x*y*z
  117. g = x*y + y*z + z*x
  118. u = x**2*i + 4*j - y**2*z*k
  119. v = 4*i + x*y*z*k
  120. # First product rule
  121. lhs = delop(f * g, doit=True)
  122. rhs = (f * delop(g) + g * delop(f)).doit()
  123. assert simplify(lhs) == simplify(rhs)
  124. # Second product rule
  125. lhs = delop(u & v).doit()
  126. rhs = ((u ^ (delop ^ v)) + (v ^ (delop ^ u)) + \
  127. ((u & delop)(v)) + ((v & delop)(u))).doit()
  128. assert simplify(lhs) == simplify(rhs)
  129. # Third product rule
  130. lhs = (delop & (f*v)).doit()
  131. rhs = ((f * (delop & v)) + (v & (delop(f)))).doit()
  132. assert simplify(lhs) == simplify(rhs)
  133. # Fourth product rule
  134. lhs = (delop & (u ^ v)).doit()
  135. rhs = ((v & (delop ^ u)) - (u & (delop ^ v))).doit()
  136. assert simplify(lhs) == simplify(rhs)
  137. # Fifth product rule
  138. lhs = (delop ^ (f * v)).doit()
  139. rhs = (((delop(f)) ^ v) + (f * (delop ^ v))).doit()
  140. assert simplify(lhs) == simplify(rhs)
  141. # Sixth product rule
  142. lhs = (delop ^ (u ^ v)).doit()
  143. rhs = (u * (delop & v) - v * (delop & u) +
  144. (v & delop)(u) - (u & delop)(v)).doit()
  145. assert simplify(lhs) == simplify(rhs)
  146. P = C.orient_new_axis('P', q, C.k) # type: ignore
  147. scalar_field = 2*x**2*y*z
  148. grad_field = gradient(scalar_field)
  149. vector_field = y**2*i + 3*x*j + 5*y*z*k
  150. curl_field = curl(vector_field)
  151. def test_conservative():
  152. assert is_conservative(Vector.zero) is True
  153. assert is_conservative(i) is True
  154. assert is_conservative(2 * i + 3 * j + 4 * k) is True
  155. assert (is_conservative(y*z*i + x*z*j + x*y*k) is
  156. True)
  157. assert is_conservative(x * j) is False
  158. assert is_conservative(grad_field) is True
  159. assert is_conservative(curl_field) is False
  160. assert (is_conservative(4*x*y*z*i + 2*x**2*z*j) is
  161. False)
  162. assert is_conservative(z*P.i + P.x*k) is True
  163. def test_solenoidal():
  164. assert is_solenoidal(Vector.zero) is True
  165. assert is_solenoidal(i) is True
  166. assert is_solenoidal(2 * i + 3 * j + 4 * k) is True
  167. assert (is_solenoidal(y*z*i + x*z*j + x*y*k) is
  168. True)
  169. assert is_solenoidal(y * j) is False
  170. assert is_solenoidal(grad_field) is False
  171. assert is_solenoidal(curl_field) is True
  172. assert is_solenoidal((-2*y + 3)*k) is True
  173. assert is_solenoidal(cos(q)*i + sin(q)*j + cos(q)*P.k) is True
  174. assert is_solenoidal(z*P.i + P.x*k) is True
  175. def test_directional_derivative():
  176. assert directional_derivative(C.x*C.y*C.z, 3*C.i + 4*C.j + C.k) == C.x*C.y + 4*C.x*C.z + 3*C.y*C.z
  177. assert directional_derivative(5*C.x**2*C.z, 3*C.i + 4*C.j + C.k) == 5*C.x**2 + 30*C.x*C.z
  178. assert directional_derivative(5*C.x**2*C.z, 4*C.j) is S.Zero
  179. D = CoordSys3D("D", "spherical", variable_names=["r", "theta", "phi"],
  180. vector_names=["e_r", "e_theta", "e_phi"])
  181. r, theta, phi = D.base_scalars()
  182. e_r, e_theta, e_phi = D.base_vectors()
  183. assert directional_derivative(r**2*e_r, e_r) == 2*r*e_r
  184. assert directional_derivative(5*r**2*phi, 3*e_r + 4*e_theta + e_phi) == 5*r**2 + 30*r*phi
  185. def test_scalar_potential():
  186. assert scalar_potential(Vector.zero, C) == 0
  187. assert scalar_potential(i, C) == x
  188. assert scalar_potential(j, C) == y
  189. assert scalar_potential(k, C) == z
  190. assert scalar_potential(y*z*i + x*z*j + x*y*k, C) == x*y*z
  191. assert scalar_potential(grad_field, C) == scalar_field
  192. assert scalar_potential(z*P.i + P.x*k, C) == x*z*cos(q) + y*z*sin(q)
  193. assert scalar_potential(z*P.i + P.x*k, P) == P.x*P.z
  194. raises(ValueError, lambda: scalar_potential(x*j, C))
  195. def test_scalar_potential_difference():
  196. point1 = C.origin.locate_new('P1', 1*i + 2*j + 3*k)
  197. point2 = C.origin.locate_new('P2', 4*i + 5*j + 6*k)
  198. genericpointC = C.origin.locate_new('RP', x*i + y*j + z*k)
  199. genericpointP = P.origin.locate_new('PP', P.x*P.i + P.y*P.j + P.z*P.k)
  200. assert scalar_potential_difference(S.Zero, C, point1, point2) == 0
  201. assert (scalar_potential_difference(scalar_field, C, C.origin,
  202. genericpointC) ==
  203. scalar_field)
  204. assert (scalar_potential_difference(grad_field, C, C.origin,
  205. genericpointC) ==
  206. scalar_field)
  207. assert scalar_potential_difference(grad_field, C, point1, point2) == 948
  208. assert (scalar_potential_difference(y*z*i + x*z*j +
  209. x*y*k, C, point1,
  210. genericpointC) ==
  211. x*y*z - 6)
  212. potential_diff_P = (2*P.z*(P.x*sin(q) + P.y*cos(q))*
  213. (P.x*cos(q) - P.y*sin(q))**2)
  214. assert (scalar_potential_difference(grad_field, P, P.origin,
  215. genericpointP).simplify() ==
  216. potential_diff_P.simplify())
  217. def test_differential_operators_curvilinear_system():
  218. A = CoordSys3D('A', transformation="spherical", variable_names=["r", "theta", "phi"])
  219. B = CoordSys3D('B', transformation='cylindrical', variable_names=["r", "theta", "z"])
  220. # Test for spherical coordinate system and gradient
  221. assert gradient(3*A.r + 4*A.theta) == 3*A.i + 4/A.r*A.j
  222. assert gradient(3*A.r*A.phi + 4*A.theta) == 3*A.phi*A.i + 4/A.r*A.j + (3/sin(A.theta))*A.k
  223. assert gradient(0*A.r + 0*A.theta+0*A.phi) == Vector.zero
  224. assert gradient(A.r*A.theta*A.phi) == A.theta*A.phi*A.i + A.phi*A.j + (A.theta/sin(A.theta))*A.k
  225. # Test for spherical coordinate system and divergence
  226. assert divergence(A.r * A.i + A.theta * A.j + A.phi * A.k) == \
  227. (sin(A.theta)*A.r + cos(A.theta)*A.r*A.theta)/(sin(A.theta)*A.r**2) + 3 + 1/(sin(A.theta)*A.r)
  228. assert divergence(3*A.r*A.phi*A.i + A.theta*A.j + A.r*A.theta*A.phi*A.k) == \
  229. (sin(A.theta)*A.r + cos(A.theta)*A.r*A.theta)/(sin(A.theta)*A.r**2) + 9*A.phi + A.theta/sin(A.theta)
  230. assert divergence(Vector.zero) == 0
  231. assert divergence(0*A.i + 0*A.j + 0*A.k) == 0
  232. # Test for spherical coordinate system and curl
  233. assert curl(A.r*A.i + A.theta*A.j + A.phi*A.k) == \
  234. (cos(A.theta)*A.phi/(sin(A.theta)*A.r))*A.i + (-A.phi/A.r)*A.j + A.theta/A.r*A.k
  235. assert curl(A.r*A.j + A.phi*A.k) == (cos(A.theta)*A.phi/(sin(A.theta)*A.r))*A.i + (-A.phi/A.r)*A.j + 2*A.k
  236. # Test for cylindrical coordinate system and gradient
  237. assert gradient(0*B.r + 0*B.theta+0*B.z) == Vector.zero
  238. assert gradient(B.r*B.theta*B.z) == B.theta*B.z*B.i + B.z*B.j + B.r*B.theta*B.k
  239. assert gradient(3*B.r) == 3*B.i
  240. assert gradient(2*B.theta) == 2/B.r * B.j
  241. assert gradient(4*B.z) == 4*B.k
  242. # Test for cylindrical coordinate system and divergence
  243. assert divergence(B.r*B.i + B.theta*B.j + B.z*B.k) == 3 + 1/B.r
  244. assert divergence(B.r*B.j + B.z*B.k) == 1
  245. # Test for cylindrical coordinate system and curl
  246. assert curl(B.r*B.j + B.z*B.k) == 2*B.k
  247. assert curl(3*B.i + 2/B.r*B.j + 4*B.k) == Vector.zero
  248. def test_mixed_coordinates():
  249. # gradient
  250. a = CoordSys3D('a')
  251. b = CoordSys3D('b')
  252. c = CoordSys3D('c')
  253. assert gradient(a.x*b.y) == b.y*a.i + a.x*b.j
  254. assert gradient(3*cos(q)*a.x*b.x+a.y*(a.x+(cos(q)+b.x))) ==\
  255. (a.y + 3*b.x*cos(q))*a.i + (a.x + b.x + cos(q))*a.j + (3*a.x*cos(q) + a.y)*b.i
  256. # Some tests need further work:
  257. # assert gradient(a.x*(cos(a.x+b.x))) == (cos(a.x + b.x))*a.i + a.x*Gradient(cos(a.x + b.x))
  258. # assert gradient(cos(a.x + b.x)*cos(a.x + b.z)) == Gradient(cos(a.x + b.x)*cos(a.x + b.z))
  259. assert gradient(a.x**b.y) == Gradient(a.x**b.y)
  260. # assert gradient(cos(a.x+b.y)*a.z) == None
  261. assert gradient(cos(a.x*b.y)) == Gradient(cos(a.x*b.y))
  262. assert gradient(3*cos(q)*a.x*b.x*a.z*a.y+ b.y*b.z + cos(a.x+a.y)*b.z) == \
  263. (3*a.y*a.z*b.x*cos(q) - b.z*sin(a.x + a.y))*a.i + \
  264. (3*a.x*a.z*b.x*cos(q) - b.z*sin(a.x + a.y))*a.j + (3*a.x*a.y*b.x*cos(q))*a.k + \
  265. (3*a.x*a.y*a.z*cos(q))*b.i + b.z*b.j + (b.y + cos(a.x + a.y))*b.k
  266. # divergence
  267. assert divergence(a.i*a.x+a.j*a.y+a.z*a.k + b.i*b.x+b.j*b.y+b.z*b.k + c.i*c.x+c.j*c.y+c.z*c.k) == S(9)
  268. # assert divergence(3*a.i*a.x*cos(a.x+b.z) + a.j*b.x*c.z) == None
  269. assert divergence(3*a.i*a.x*a.z + b.j*b.x*c.z + 3*a.j*a.z*a.y) == \
  270. 6*a.z + b.x*Dot(b.j, c.k)
  271. assert divergence(3*cos(q)*a.x*b.x*b.i*c.x) == \
  272. 3*a.x*b.x*cos(q)*Dot(b.i, c.i) + 3*a.x*c.x*cos(q) + 3*b.x*c.x*cos(q)*Dot(b.i, a.i)
  273. assert divergence(a.x*b.x*c.x*Cross(a.x*a.i, a.y*b.j)) ==\
  274. a.x*b.x*c.x*Divergence(Cross(a.x*a.i, a.y*b.j)) + \
  275. b.x*c.x*Dot(Cross(a.x*a.i, a.y*b.j), a.i) + \
  276. a.x*c.x*Dot(Cross(a.x*a.i, a.y*b.j), b.i) + \
  277. a.x*b.x*Dot(Cross(a.x*a.i, a.y*b.j), c.i)
  278. assert divergence(a.x*b.x*c.x*(a.x*a.i + b.x*b.i)) == \
  279. 4*a.x*b.x*c.x +\
  280. a.x**2*c.x*Dot(a.i, b.i) +\
  281. a.x**2*b.x*Dot(a.i, c.i) +\
  282. b.x**2*c.x*Dot(b.i, a.i) +\
  283. a.x*b.x**2*Dot(b.i, c.i)