rn.py 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. """Predefined R^n manifolds together with common coord. systems.
  2. Coordinate systems are predefined as well as the transformation laws between
  3. them.
  4. Coordinate functions can be accessed as attributes of the manifold (eg `R2.x`),
  5. as attributes of the coordinate systems (eg `R2_r.x` and `R2_p.theta`), or by
  6. using the usual `coord_sys.coord_function(index, name)` interface.
  7. """
  8. from typing import Any
  9. import warnings
  10. from sympy.core.symbol import (Dummy, symbols)
  11. from sympy.functions.elementary.miscellaneous import sqrt
  12. from sympy.functions.elementary.trigonometric import (acos, atan2, cos, sin)
  13. from .diffgeom import Manifold, Patch, CoordSystem
  14. __all__ = [
  15. 'R2', 'R2_origin', 'relations_2d', 'R2_r', 'R2_p',
  16. 'R3', 'R3_origin', 'relations_3d', 'R3_r', 'R3_c', 'R3_s'
  17. ]
  18. ###############################################################################
  19. # R2
  20. ###############################################################################
  21. R2 = Manifold('R^2', 2) # type: Any
  22. R2_origin = Patch('origin', R2) # type: Any
  23. x, y = symbols('x y', real=True)
  24. r, theta = symbols('rho theta', nonnegative=True)
  25. relations_2d = {
  26. ('rectangular', 'polar'): [(x, y), (sqrt(x**2 + y**2), atan2(y, x))],
  27. ('polar', 'rectangular'): [(r, theta), (r*cos(theta), r*sin(theta))],
  28. }
  29. R2_r = CoordSystem('rectangular', R2_origin, (x, y), relations_2d) # type: Any
  30. R2_p = CoordSystem('polar', R2_origin, (r, theta), relations_2d) # type: Any
  31. # support deprecated feature
  32. with warnings.catch_warnings():
  33. warnings.simplefilter("ignore")
  34. x, y, r, theta = symbols('x y r theta', cls=Dummy)
  35. R2_r.connect_to(R2_p, [x, y],
  36. [sqrt(x**2 + y**2), atan2(y, x)],
  37. inverse=False, fill_in_gaps=False)
  38. R2_p.connect_to(R2_r, [r, theta],
  39. [r*cos(theta), r*sin(theta)],
  40. inverse=False, fill_in_gaps=False)
  41. # Defining the basis coordinate functions and adding shortcuts for them to the
  42. # manifold and the patch.
  43. R2.x, R2.y = R2_origin.x, R2_origin.y = R2_r.x, R2_r.y = R2_r.coord_functions()
  44. R2.r, R2.theta = R2_origin.r, R2_origin.theta = R2_p.r, R2_p.theta = R2_p.coord_functions()
  45. # Defining the basis vector fields and adding shortcuts for them to the
  46. # manifold and the patch.
  47. R2.e_x, R2.e_y = R2_origin.e_x, R2_origin.e_y = R2_r.e_x, R2_r.e_y = R2_r.base_vectors()
  48. R2.e_r, R2.e_theta = R2_origin.e_r, R2_origin.e_theta = R2_p.e_r, R2_p.e_theta = R2_p.base_vectors()
  49. # Defining the basis oneform fields and adding shortcuts for them to the
  50. # manifold and the patch.
  51. R2.dx, R2.dy = R2_origin.dx, R2_origin.dy = R2_r.dx, R2_r.dy = R2_r.base_oneforms()
  52. R2.dr, R2.dtheta = R2_origin.dr, R2_origin.dtheta = R2_p.dr, R2_p.dtheta = R2_p.base_oneforms()
  53. ###############################################################################
  54. # R3
  55. ###############################################################################
  56. R3 = Manifold('R^3', 3) # type: Any
  57. R3_origin = Patch('origin', R3) # type: Any
  58. x, y, z = symbols('x y z', real=True)
  59. rho, psi, r, theta, phi = symbols('rho psi r theta phi', nonnegative=True)
  60. relations_3d = {
  61. ('rectangular', 'cylindrical'): [(x, y, z),
  62. (sqrt(x**2 + y**2), atan2(y, x), z)],
  63. ('cylindrical', 'rectangular'): [(rho, psi, z),
  64. (rho*cos(psi), rho*sin(psi), z)],
  65. ('rectangular', 'spherical'): [(x, y, z),
  66. (sqrt(x**2 + y**2 + z**2),
  67. acos(z/sqrt(x**2 + y**2 + z**2)),
  68. atan2(y, x))],
  69. ('spherical', 'rectangular'): [(r, theta, phi),
  70. (r*sin(theta)*cos(phi),
  71. r*sin(theta)*sin(phi),
  72. r*cos(theta))],
  73. ('cylindrical', 'spherical'): [(rho, psi, z),
  74. (sqrt(rho**2 + z**2),
  75. acos(z/sqrt(rho**2 + z**2)),
  76. psi)],
  77. ('spherical', 'cylindrical'): [(r, theta, phi),
  78. (r*sin(theta), phi, r*cos(theta))],
  79. }
  80. R3_r = CoordSystem('rectangular', R3_origin, (x, y, z), relations_3d) # type: Any
  81. R3_c = CoordSystem('cylindrical', R3_origin, (rho, psi, z), relations_3d) # type: Any
  82. R3_s = CoordSystem('spherical', R3_origin, (r, theta, phi), relations_3d) # type: Any
  83. # support deprecated feature
  84. with warnings.catch_warnings():
  85. warnings.simplefilter("ignore")
  86. x, y, z, rho, psi, r, theta, phi = symbols('x y z rho psi r theta phi', cls=Dummy)
  87. R3_r.connect_to(R3_c, [x, y, z],
  88. [sqrt(x**2 + y**2), atan2(y, x), z],
  89. inverse=False, fill_in_gaps=False)
  90. R3_c.connect_to(R3_r, [rho, psi, z],
  91. [rho*cos(psi), rho*sin(psi), z],
  92. inverse=False, fill_in_gaps=False)
  93. ## rectangular <-> spherical
  94. R3_r.connect_to(R3_s, [x, y, z],
  95. [sqrt(x**2 + y**2 + z**2), acos(z/
  96. sqrt(x**2 + y**2 + z**2)), atan2(y, x)],
  97. inverse=False, fill_in_gaps=False)
  98. R3_s.connect_to(R3_r, [r, theta, phi],
  99. [r*sin(theta)*cos(phi), r*sin(
  100. theta)*sin(phi), r*cos(theta)],
  101. inverse=False, fill_in_gaps=False)
  102. ## cylindrical <-> spherical
  103. R3_c.connect_to(R3_s, [rho, psi, z],
  104. [sqrt(rho**2 + z**2), acos(z/sqrt(rho**2 + z**2)), psi],
  105. inverse=False, fill_in_gaps=False)
  106. R3_s.connect_to(R3_c, [r, theta, phi],
  107. [r*sin(theta), phi, r*cos(theta)],
  108. inverse=False, fill_in_gaps=False)
  109. # Defining the basis coordinate functions.
  110. R3_r.x, R3_r.y, R3_r.z = R3_r.coord_functions()
  111. R3_c.rho, R3_c.psi, R3_c.z = R3_c.coord_functions()
  112. R3_s.r, R3_s.theta, R3_s.phi = R3_s.coord_functions()
  113. # Defining the basis vector fields.
  114. R3_r.e_x, R3_r.e_y, R3_r.e_z = R3_r.base_vectors()
  115. R3_c.e_rho, R3_c.e_psi, R3_c.e_z = R3_c.base_vectors()
  116. R3_s.e_r, R3_s.e_theta, R3_s.e_phi = R3_s.base_vectors()
  117. # Defining the basis oneform fields.
  118. R3_r.dx, R3_r.dy, R3_r.dz = R3_r.base_oneforms()
  119. R3_c.drho, R3_c.dpsi, R3_c.dz = R3_c.base_oneforms()
  120. R3_s.dr, R3_s.dtheta, R3_s.dphi = R3_s.base_oneforms()