1""" 2This module has all the classes and functions related to waves in optics. 3 4**Contains** 5 6* TWave 7""" 8 9__all__ = ['TWave'] 10 11from sympy import (sympify, pi, sin, cos, sqrt, Number, Symbol, S, 12 symbols, Derivative, atan2) 13from sympy.core.expr import Expr 14from sympy.physics.units import speed_of_light, meter, second 15 16 17c = speed_of_light.convert_to(meter/second) 18 19 20class TWave(Expr): 21 22 r""" 23 This is a simple transverse sine wave travelling in a one-dimensional space. 24 Basic properties are required at the time of creation of the object, 25 but they can be changed later with respective methods provided. 26 27 Explanation 28 =========== 29 30 It is represented as :math:`A \times cos(k*x - \omega \times t + \phi )`, 31 where :math:`A` is the amplitude, :math:`\omega` is the angular frequency, 32 :math:`k` is the wavenumber (spatial frequency), :math:`x` is a spatial variable 33 to represent the position on the dimension on which the wave propagates, 34 and :math:`\phi` is the phase angle of the wave. 35 36 37 Arguments 38 ========= 39 40 amplitude : Sympifyable 41 Amplitude of the wave. 42 frequency : Sympifyable 43 Frequency of the wave. 44 phase : Sympifyable 45 Phase angle of the wave. 46 time_period : Sympifyable 47 Time period of the wave. 48 n : Sympifyable 49 Refractive index of the medium. 50 51 Raises 52 ======= 53 54 ValueError : When neither frequency nor time period is provided 55 or they are not consistent. 56 TypeError : When anything other than TWave objects is added. 57 58 59 Examples 60 ======== 61 62 >>> from sympy import symbols 63 >>> from sympy.physics.optics import TWave 64 >>> A1, phi1, A2, phi2, f = symbols('A1, phi1, A2, phi2, f') 65 >>> w1 = TWave(A1, f, phi1) 66 >>> w2 = TWave(A2, f, phi2) 67 >>> w3 = w1 + w2 # Superposition of two waves 68 >>> w3 69 TWave(sqrt(A1**2 + 2*A1*A2*cos(phi1 - phi2) + A2**2), f, 70 atan2(A1*sin(phi1) + A2*sin(phi2), A1*cos(phi1) + A2*cos(phi2))) 71 >>> w3.amplitude 72 sqrt(A1**2 + 2*A1*A2*cos(phi1 - phi2) + A2**2) 73 >>> w3.phase 74 atan2(A1*sin(phi1) + A2*sin(phi2), A1*cos(phi1) + A2*cos(phi2)) 75 >>> w3.speed 76 299792458*meter/(second*n) 77 >>> w3.angular_velocity 78 2*pi*f 79 80 """ 81 82 def __init__( 83 self, 84 amplitude, 85 frequency=None, 86 phase=S.Zero, 87 time_period=None, 88 n=Symbol('n')): 89 frequency = sympify(frequency) 90 amplitude = sympify(amplitude) 91 phase = sympify(phase) 92 time_period = sympify(time_period) 93 n = sympify(n) 94 self._frequency = frequency 95 self._amplitude = amplitude 96 self._phase = phase 97 self._time_period = time_period 98 self._n = n 99 if time_period is not None: 100 self._frequency = 1/self._time_period 101 if frequency is not None: 102 self._time_period = 1/self._frequency 103 if time_period is not None: 104 if frequency != 1/time_period: 105 raise ValueError("frequency and time_period should be consistent.") 106 if frequency is None and time_period is None: 107 raise ValueError("Either frequency or time period is needed.") 108 109 @property 110 def frequency(self): 111 """ 112 Returns the frequency of the wave, 113 in cycles per second. 114 115 Examples 116 ======== 117 118 >>> from sympy import symbols 119 >>> from sympy.physics.optics import TWave 120 >>> A, phi, f = symbols('A, phi, f') 121 >>> w = TWave(A, f, phi) 122 >>> w.frequency 123 f 124 """ 125 return self._frequency 126 127 @property 128 def time_period(self): 129 """ 130 Returns the temporal period of the wave, 131 in seconds per cycle. 132 133 Examples 134 ======== 135 136 >>> from sympy import symbols 137 >>> from sympy.physics.optics import TWave 138 >>> A, phi, f = symbols('A, phi, f') 139 >>> w = TWave(A, f, phi) 140 >>> w.time_period 141 1/f 142 """ 143 return self._time_period 144 145 @property 146 def wavelength(self): 147 """ 148 Returns the wavelength (spatial period) of the wave, 149 in meters per cycle. 150 It depends on the medium of the wave. 151 152 Examples 153 ======== 154 155 >>> from sympy import symbols 156 >>> from sympy.physics.optics import TWave 157 >>> A, phi, f = symbols('A, phi, f') 158 >>> w = TWave(A, f, phi) 159 >>> w.wavelength 160 299792458*meter/(second*f*n) 161 """ 162 return c/(self._frequency*self._n) 163 164 @property 165 def amplitude(self): 166 """ 167 Returns the amplitude of the wave. 168 169 Examples 170 ======== 171 172 >>> from sympy import symbols 173 >>> from sympy.physics.optics import TWave 174 >>> A, phi, f = symbols('A, phi, f') 175 >>> w = TWave(A, f, phi) 176 >>> w.amplitude 177 A 178 """ 179 return self._amplitude 180 181 @property 182 def phase(self): 183 """ 184 Returns the phase angle of the wave, 185 in radians. 186 187 Examples 188 ======== 189 190 >>> from sympy import symbols 191 >>> from sympy.physics.optics import TWave 192 >>> A, phi, f = symbols('A, phi, f') 193 >>> w = TWave(A, f, phi) 194 >>> w.phase 195 phi 196 """ 197 return self._phase 198 199 @property 200 def speed(self): 201 """ 202 Returns the propagation speed of the wave, 203 in meters per second. 204 It is dependent on the propagation medium. 205 206 Examples 207 ======== 208 209 >>> from sympy import symbols 210 >>> from sympy.physics.optics import TWave 211 >>> A, phi, f = symbols('A, phi, f') 212 >>> w = TWave(A, f, phi) 213 >>> w.speed 214 299792458*meter/(second*n) 215 """ 216 return self.wavelength*self._frequency 217 218 @property 219 def angular_velocity(self): 220 """ 221 Returns the angular velocity of the wave, 222 in radians per second. 223 224 Examples 225 ======== 226 227 >>> from sympy import symbols 228 >>> from sympy.physics.optics import TWave 229 >>> A, phi, f = symbols('A, phi, f') 230 >>> w = TWave(A, f, phi) 231 >>> w.angular_velocity 232 2*pi*f 233 """ 234 return 2*pi*self._frequency 235 236 @property 237 def wavenumber(self): 238 """ 239 Returns the wavenumber of the wave, 240 in radians per meter. 241 242 Examples 243 ======== 244 245 >>> from sympy import symbols 246 >>> from sympy.physics.optics import TWave 247 >>> A, phi, f = symbols('A, phi, f') 248 >>> w = TWave(A, f, phi) 249 >>> w.wavenumber 250 pi*second*f*n/(149896229*meter) 251 """ 252 return 2*pi/self.wavelength 253 254 def __str__(self): 255 """String representation of a TWave.""" 256 from sympy.printing import sstr 257 return type(self).__name__ + sstr(self.args) 258 259 __repr__ = __str__ 260 261 def __add__(self, other): 262 """ 263 Addition of two waves will result in their superposition. 264 The type of interference will depend on their phase angles. 265 """ 266 if isinstance(other, TWave): 267 if self._frequency == other._frequency and self.wavelength == other.wavelength: 268 return TWave(sqrt(self._amplitude**2 + other._amplitude**2 + 2 * 269 self._amplitude*other._amplitude*cos( 270 self._phase - other.phase)), 271 self._frequency, 272 atan2(self._amplitude*sin(self._phase) 273 + other._amplitude*sin(other._phase), 274 self._amplitude*cos(self._phase) 275 + other._amplitude*cos(other._phase)) 276 ) 277 else: 278 raise NotImplementedError("Interference of waves with different frequencies" 279 " has not been implemented.") 280 else: 281 raise TypeError(type(other).__name__ + " and TWave objects can't be added.") 282 283 def __mul__(self, other): 284 """ 285 Multiplying a wave by a scalar rescales the amplitude of the wave. 286 """ 287 other = sympify(other) 288 if isinstance(other, Number): 289 return TWave(self._amplitude*other, *self.args[1:]) 290 else: 291 raise TypeError(type(other).__name__ + " and TWave objects can't be multiplied.") 292 293 def __sub__(self, other): 294 return self.__add__(-1*other) 295 296 def __neg__(self): 297 return self.__mul__(-1) 298 299 def __radd__(self, other): 300 return self.__add__(other) 301 302 def __rmul__(self, other): 303 return self.__mul__(other) 304 305 def __rsub__(self, other): 306 return (-self).__radd__(other) 307 308 def _eval_rewrite_as_sin(self, *args, **kwargs): 309 return self._amplitude*sin(self.wavenumber*Symbol('x') 310 - self.angular_velocity*Symbol('t') + self._phase + pi/2, evaluate=False) 311 312 def _eval_rewrite_as_cos(self, *args, **kwargs): 313 return self._amplitude*cos(self.wavenumber*Symbol('x') 314 - self.angular_velocity*Symbol('t') + self._phase) 315 316 def _eval_rewrite_as_pde(self, *args, **kwargs): 317 from sympy import Function 318 mu, epsilon, x, t = symbols('mu, epsilon, x, t') 319 E = Function('E') 320 return Derivative(E(x, t), x, 2) + mu*epsilon*Derivative(E(x, t), t, 2) 321 322 def _eval_rewrite_as_exp(self, *args, **kwargs): 323 from sympy import exp, I 324 return self._amplitude*exp(I*(self.wavenumber*Symbol('x') 325 - self.angular_velocity*Symbol('t') + self._phase)) 326