particle.py 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  1. from sympy.core.backend import sympify
  2. from sympy.physics.vector import Point
  3. from sympy.utilities.exceptions import sympy_deprecation_warning
  4. __all__ = ['Particle']
  5. class Particle:
  6. """A particle.
  7. Explanation
  8. ===========
  9. Particles have a non-zero mass and lack spatial extension; they take up no
  10. space.
  11. Values need to be supplied on initialization, but can be changed later.
  12. Parameters
  13. ==========
  14. name : str
  15. Name of particle
  16. point : Point
  17. A physics/mechanics Point which represents the position, velocity, and
  18. acceleration of this Particle
  19. mass : sympifyable
  20. A SymPy expression representing the Particle's mass
  21. Examples
  22. ========
  23. >>> from sympy.physics.mechanics import Particle, Point
  24. >>> from sympy import Symbol
  25. >>> po = Point('po')
  26. >>> m = Symbol('m')
  27. >>> pa = Particle('pa', po, m)
  28. >>> # Or you could change these later
  29. >>> pa.mass = m
  30. >>> pa.point = po
  31. """
  32. def __init__(self, name, point, mass):
  33. if not isinstance(name, str):
  34. raise TypeError('Supply a valid name.')
  35. self._name = name
  36. self.mass = mass
  37. self.point = point
  38. self.potential_energy = 0
  39. def __str__(self):
  40. return self._name
  41. def __repr__(self):
  42. return self.__str__()
  43. @property
  44. def mass(self):
  45. """Mass of the particle."""
  46. return self._mass
  47. @mass.setter
  48. def mass(self, value):
  49. self._mass = sympify(value)
  50. @property
  51. def point(self):
  52. """Point of the particle."""
  53. return self._point
  54. @point.setter
  55. def point(self, p):
  56. if not isinstance(p, Point):
  57. raise TypeError("Particle point attribute must be a Point object.")
  58. self._point = p
  59. def linear_momentum(self, frame):
  60. """Linear momentum of the particle.
  61. Explanation
  62. ===========
  63. The linear momentum L, of a particle P, with respect to frame N is
  64. given by
  65. L = m * v
  66. where m is the mass of the particle, and v is the velocity of the
  67. particle in the frame N.
  68. Parameters
  69. ==========
  70. frame : ReferenceFrame
  71. The frame in which linear momentum is desired.
  72. Examples
  73. ========
  74. >>> from sympy.physics.mechanics import Particle, Point, ReferenceFrame
  75. >>> from sympy.physics.mechanics import dynamicsymbols
  76. >>> from sympy.physics.vector import init_vprinting
  77. >>> init_vprinting(pretty_print=False)
  78. >>> m, v = dynamicsymbols('m v')
  79. >>> N = ReferenceFrame('N')
  80. >>> P = Point('P')
  81. >>> A = Particle('A', P, m)
  82. >>> P.set_vel(N, v * N.x)
  83. >>> A.linear_momentum(N)
  84. m*v*N.x
  85. """
  86. return self.mass * self.point.vel(frame)
  87. def angular_momentum(self, point, frame):
  88. """Angular momentum of the particle about the point.
  89. Explanation
  90. ===========
  91. The angular momentum H, about some point O of a particle, P, is given
  92. by:
  93. H = r x m * v
  94. where r is the position vector from point O to the particle P, m is
  95. the mass of the particle, and v is the velocity of the particle in
  96. the inertial frame, N.
  97. Parameters
  98. ==========
  99. point : Point
  100. The point about which angular momentum of the particle is desired.
  101. frame : ReferenceFrame
  102. The frame in which angular momentum is desired.
  103. Examples
  104. ========
  105. >>> from sympy.physics.mechanics import Particle, Point, ReferenceFrame
  106. >>> from sympy.physics.mechanics import dynamicsymbols
  107. >>> from sympy.physics.vector import init_vprinting
  108. >>> init_vprinting(pretty_print=False)
  109. >>> m, v, r = dynamicsymbols('m v r')
  110. >>> N = ReferenceFrame('N')
  111. >>> O = Point('O')
  112. >>> A = O.locatenew('A', r * N.x)
  113. >>> P = Particle('P', A, m)
  114. >>> P.point.set_vel(N, v * N.y)
  115. >>> P.angular_momentum(O, N)
  116. m*r*v*N.z
  117. """
  118. return self.point.pos_from(point) ^ (self.mass * self.point.vel(frame))
  119. def kinetic_energy(self, frame):
  120. """Kinetic energy of the particle.
  121. Explanation
  122. ===========
  123. The kinetic energy, T, of a particle, P, is given by
  124. 'T = 1/2 m v^2'
  125. where m is the mass of particle P, and v is the velocity of the
  126. particle in the supplied ReferenceFrame.
  127. Parameters
  128. ==========
  129. frame : ReferenceFrame
  130. The Particle's velocity is typically defined with respect to
  131. an inertial frame but any relevant frame in which the velocity is
  132. known can be supplied.
  133. Examples
  134. ========
  135. >>> from sympy.physics.mechanics import Particle, Point, ReferenceFrame
  136. >>> from sympy import symbols
  137. >>> m, v, r = symbols('m v r')
  138. >>> N = ReferenceFrame('N')
  139. >>> O = Point('O')
  140. >>> P = Particle('P', O, m)
  141. >>> P.point.set_vel(N, v * N.y)
  142. >>> P.kinetic_energy(N)
  143. m*v**2/2
  144. """
  145. return (self.mass / sympify(2) * self.point.vel(frame) &
  146. self.point.vel(frame))
  147. @property
  148. def potential_energy(self):
  149. """The potential energy of the Particle.
  150. Examples
  151. ========
  152. >>> from sympy.physics.mechanics import Particle, Point
  153. >>> from sympy import symbols
  154. >>> m, g, h = symbols('m g h')
  155. >>> O = Point('O')
  156. >>> P = Particle('P', O, m)
  157. >>> P.potential_energy = m * g * h
  158. >>> P.potential_energy
  159. g*h*m
  160. """
  161. return self._pe
  162. @potential_energy.setter
  163. def potential_energy(self, scalar):
  164. """Used to set the potential energy of the Particle.
  165. Parameters
  166. ==========
  167. scalar : Sympifyable
  168. The potential energy (a scalar) of the Particle.
  169. Examples
  170. ========
  171. >>> from sympy.physics.mechanics import Particle, Point
  172. >>> from sympy import symbols
  173. >>> m, g, h = symbols('m g h')
  174. >>> O = Point('O')
  175. >>> P = Particle('P', O, m)
  176. >>> P.potential_energy = m * g * h
  177. """
  178. self._pe = sympify(scalar)
  179. def set_potential_energy(self, scalar):
  180. sympy_deprecation_warning(
  181. """
  182. The sympy.physics.mechanics.Particle.set_potential_energy()
  183. method is deprecated. Instead use
  184. P.potential_energy = scalar
  185. """,
  186. deprecated_since_version="1.5",
  187. active_deprecations_target="deprecated-set-potential-energy",
  188. )
  189. self.potential_energy = scalar
  190. def parallel_axis(self, point, frame):
  191. """Returns an inertia dyadic of the particle with respect to another
  192. point and frame.
  193. Parameters
  194. ==========
  195. point : sympy.physics.vector.Point
  196. The point to express the inertia dyadic about.
  197. frame : sympy.physics.vector.ReferenceFrame
  198. The reference frame used to construct the dyadic.
  199. Returns
  200. =======
  201. inertia : sympy.physics.vector.Dyadic
  202. The inertia dyadic of the particle expressed about the provided
  203. point and frame.
  204. """
  205. # circular import issue
  206. from sympy.physics.mechanics import inertia_of_point_mass
  207. return inertia_of_point_mass(self.mass, self.point.pos_from(point),
  208. frame)