medium.py 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. """
  2. **Contains**
  3. * Medium
  4. """
  5. from sympy.physics.units import second, meter, kilogram, ampere
  6. __all__ = ['Medium']
  7. from sympy.core.basic import Basic
  8. from sympy.core.symbol import Str
  9. from sympy.core.sympify import _sympify
  10. from sympy.functions.elementary.miscellaneous import sqrt
  11. from sympy.physics.units import speed_of_light, u0, e0
  12. c = speed_of_light.convert_to(meter/second)
  13. _e0mksa = e0.convert_to(ampere**2*second**4/(kilogram*meter**3))
  14. _u0mksa = u0.convert_to(meter*kilogram/(ampere**2*second**2))
  15. class Medium(Basic):
  16. """
  17. This class represents an optical medium. The prime reason to implement this is
  18. to facilitate refraction, Fermat's principle, etc.
  19. Explanation
  20. ===========
  21. An optical medium is a material through which electromagnetic waves propagate.
  22. The permittivity and permeability of the medium define how electromagnetic
  23. waves propagate in it.
  24. Parameters
  25. ==========
  26. name: string
  27. The display name of the Medium.
  28. permittivity: Sympifyable
  29. Electric permittivity of the space.
  30. permeability: Sympifyable
  31. Magnetic permeability of the space.
  32. n: Sympifyable
  33. Index of refraction of the medium.
  34. Examples
  35. ========
  36. >>> from sympy.abc import epsilon, mu
  37. >>> from sympy.physics.optics import Medium
  38. >>> m1 = Medium('m1')
  39. >>> m2 = Medium('m2', epsilon, mu)
  40. >>> m1.intrinsic_impedance
  41. 149896229*pi*kilogram*meter**2/(1250000*ampere**2*second**3)
  42. >>> m2.refractive_index
  43. 299792458*meter*sqrt(epsilon*mu)/second
  44. References
  45. ==========
  46. .. [1] https://en.wikipedia.org/wiki/Optical_medium
  47. """
  48. def __new__(cls, name, permittivity=None, permeability=None, n=None):
  49. if not isinstance(name, Str):
  50. name = Str(name)
  51. permittivity = _sympify(permittivity) if permittivity is not None else permittivity
  52. permeability = _sympify(permeability) if permeability is not None else permeability
  53. n = _sympify(n) if n is not None else n
  54. if n is not None:
  55. if permittivity is not None and permeability is None:
  56. permeability = n**2/(c**2*permittivity)
  57. return MediumPP(name, permittivity, permeability)
  58. elif permeability is not None and permittivity is None:
  59. permittivity = n**2/(c**2*permeability)
  60. return MediumPP(name, permittivity, permeability)
  61. elif permittivity is not None and permittivity is not None:
  62. raise ValueError("Specifying all of permittivity, permeability, and n is not allowed")
  63. else:
  64. return MediumN(name, n)
  65. elif permittivity is not None and permeability is not None:
  66. return MediumPP(name, permittivity, permeability)
  67. elif permittivity is None and permeability is None:
  68. return MediumPP(name, _e0mksa, _u0mksa)
  69. else:
  70. raise ValueError("Arguments are underspecified. Either specify n or any two of permittivity, "
  71. "permeability, and n")
  72. @property
  73. def name(self):
  74. return self.args[0]
  75. @property
  76. def speed(self):
  77. """
  78. Returns speed of the electromagnetic wave travelling in the medium.
  79. Examples
  80. ========
  81. >>> from sympy.physics.optics import Medium
  82. >>> m = Medium('m')
  83. >>> m.speed
  84. 299792458*meter/second
  85. >>> m2 = Medium('m2', n=1)
  86. >>> m.speed == m2.speed
  87. True
  88. """
  89. return c / self.n
  90. @property
  91. def refractive_index(self):
  92. """
  93. Returns refractive index of the medium.
  94. Examples
  95. ========
  96. >>> from sympy.physics.optics import Medium
  97. >>> m = Medium('m')
  98. >>> m.refractive_index
  99. 1
  100. """
  101. return (c/self.speed)
  102. class MediumN(Medium):
  103. """
  104. Represents an optical medium for which only the refractive index is known.
  105. Useful for simple ray optics.
  106. This class should never be instantiated directly.
  107. Instead it should be instantiated indirectly by instantiating Medium with
  108. only n specified.
  109. Examples
  110. ========
  111. >>> from sympy.physics.optics import Medium
  112. >>> m = Medium('m', n=2)
  113. >>> m
  114. MediumN(Str('m'), 2)
  115. """
  116. def __new__(cls, name, n):
  117. obj = super(Medium, cls).__new__(cls, name, n)
  118. return obj
  119. @property
  120. def n(self):
  121. return self.args[1]
  122. class MediumPP(Medium):
  123. """
  124. Represents an optical medium for which the permittivity and permeability are known.
  125. This class should never be instantiated directly. Instead it should be
  126. instantiated indirectly by instantiating Medium with any two of
  127. permittivity, permeability, and n specified, or by not specifying any
  128. of permittivity, permeability, or n, in which case default values for
  129. permittivity and permeability will be used.
  130. Examples
  131. ========
  132. >>> from sympy.physics.optics import Medium
  133. >>> from sympy.abc import epsilon, mu
  134. >>> m1 = Medium('m1', permittivity=epsilon, permeability=mu)
  135. >>> m1
  136. MediumPP(Str('m1'), epsilon, mu)
  137. >>> m2 = Medium('m2')
  138. >>> m2
  139. MediumPP(Str('m2'), 625000*ampere**2*second**4/(22468879468420441*pi*kilogram*meter**3), pi*kilogram*meter/(2500000*ampere**2*second**2))
  140. """
  141. def __new__(cls, name, permittivity, permeability):
  142. obj = super(Medium, cls).__new__(cls, name, permittivity, permeability)
  143. return obj
  144. @property
  145. def intrinsic_impedance(self):
  146. """
  147. Returns intrinsic impedance of the medium.
  148. Explanation
  149. ===========
  150. The intrinsic impedance of a medium is the ratio of the
  151. transverse components of the electric and magnetic fields
  152. of the electromagnetic wave travelling in the medium.
  153. In a region with no electrical conductivity it simplifies
  154. to the square root of ratio of magnetic permeability to
  155. electric permittivity.
  156. Examples
  157. ========
  158. >>> from sympy.physics.optics import Medium
  159. >>> m = Medium('m')
  160. >>> m.intrinsic_impedance
  161. 149896229*pi*kilogram*meter**2/(1250000*ampere**2*second**3)
  162. """
  163. return sqrt(self.permeability / self.permittivity)
  164. @property
  165. def permittivity(self):
  166. """
  167. Returns electric permittivity of the medium.
  168. Examples
  169. ========
  170. >>> from sympy.physics.optics import Medium
  171. >>> m = Medium('m')
  172. >>> m.permittivity
  173. 625000*ampere**2*second**4/(22468879468420441*pi*kilogram*meter**3)
  174. """
  175. return self.args[1]
  176. @property
  177. def permeability(self):
  178. """
  179. Returns magnetic permeability of the medium.
  180. Examples
  181. ========
  182. >>> from sympy.physics.optics import Medium
  183. >>> m = Medium('m')
  184. >>> m.permeability
  185. pi*kilogram*meter/(2500000*ampere**2*second**2)
  186. """
  187. return self.args[2]
  188. @property
  189. def n(self):
  190. return c*sqrt(self.permittivity*self.permeability)