Spaces:
Sleeping
Sleeping
""" | |
This module has all the classes and functions related to waves in optics. | |
**Contains** | |
* TWave | |
""" | |
__all__ = ['TWave'] | |
from sympy.core.basic import Basic | |
from sympy.core.expr import Expr | |
from sympy.core.function import Derivative, Function | |
from sympy.core.numbers import (Number, pi, I) | |
from sympy.core.singleton import S | |
from sympy.core.symbol import (Symbol, symbols) | |
from sympy.core.sympify import _sympify, sympify | |
from sympy.functions.elementary.exponential import exp | |
from sympy.functions.elementary.miscellaneous import sqrt | |
from sympy.functions.elementary.trigonometric import (atan2, cos, sin) | |
from sympy.physics.units import speed_of_light, meter, second | |
c = speed_of_light.convert_to(meter/second) | |
class TWave(Expr): | |
r""" | |
This is a simple transverse sine wave travelling in a one-dimensional space. | |
Basic properties are required at the time of creation of the object, | |
but they can be changed later with respective methods provided. | |
Explanation | |
=========== | |
It is represented as :math:`A \times cos(k*x - \omega \times t + \phi )`, | |
where :math:`A` is the amplitude, :math:`\omega` is the angular frequency, | |
:math:`k` is the wavenumber (spatial frequency), :math:`x` is a spatial variable | |
to represent the position on the dimension on which the wave propagates, | |
and :math:`\phi` is the phase angle of the wave. | |
Arguments | |
========= | |
amplitude : Sympifyable | |
Amplitude of the wave. | |
frequency : Sympifyable | |
Frequency of the wave. | |
phase : Sympifyable | |
Phase angle of the wave. | |
time_period : Sympifyable | |
Time period of the wave. | |
n : Sympifyable | |
Refractive index of the medium. | |
Raises | |
======= | |
ValueError : When neither frequency nor time period is provided | |
or they are not consistent. | |
TypeError : When anything other than TWave objects is added. | |
Examples | |
======== | |
>>> from sympy import symbols | |
>>> from sympy.physics.optics import TWave | |
>>> A1, phi1, A2, phi2, f = symbols('A1, phi1, A2, phi2, f') | |
>>> w1 = TWave(A1, f, phi1) | |
>>> w2 = TWave(A2, f, phi2) | |
>>> w3 = w1 + w2 # Superposition of two waves | |
>>> w3 | |
TWave(sqrt(A1**2 + 2*A1*A2*cos(phi1 - phi2) + A2**2), f, | |
atan2(A1*sin(phi1) + A2*sin(phi2), A1*cos(phi1) + A2*cos(phi2)), 1/f, n) | |
>>> w3.amplitude | |
sqrt(A1**2 + 2*A1*A2*cos(phi1 - phi2) + A2**2) | |
>>> w3.phase | |
atan2(A1*sin(phi1) + A2*sin(phi2), A1*cos(phi1) + A2*cos(phi2)) | |
>>> w3.speed | |
299792458*meter/(second*n) | |
>>> w3.angular_velocity | |
2*pi*f | |
""" | |
def __new__( | |
cls, | |
amplitude, | |
frequency=None, | |
phase=S.Zero, | |
time_period=None, | |
n=Symbol('n')): | |
if time_period is not None: | |
time_period = _sympify(time_period) | |
_frequency = S.One/time_period | |
if frequency is not None: | |
frequency = _sympify(frequency) | |
_time_period = S.One/frequency | |
if time_period is not None: | |
if frequency != S.One/time_period: | |
raise ValueError("frequency and time_period should be consistent.") | |
if frequency is None and time_period is None: | |
raise ValueError("Either frequency or time period is needed.") | |
if frequency is None: | |
frequency = _frequency | |
if time_period is None: | |
time_period = _time_period | |
amplitude = _sympify(amplitude) | |
phase = _sympify(phase) | |
n = sympify(n) | |
obj = Basic.__new__(cls, amplitude, frequency, phase, time_period, n) | |
return obj | |
def amplitude(self): | |
""" | |
Returns the amplitude of the wave. | |
Examples | |
======== | |
>>> from sympy import symbols | |
>>> from sympy.physics.optics import TWave | |
>>> A, phi, f = symbols('A, phi, f') | |
>>> w = TWave(A, f, phi) | |
>>> w.amplitude | |
A | |
""" | |
return self.args[0] | |
def frequency(self): | |
""" | |
Returns the frequency of the wave, | |
in cycles per second. | |
Examples | |
======== | |
>>> from sympy import symbols | |
>>> from sympy.physics.optics import TWave | |
>>> A, phi, f = symbols('A, phi, f') | |
>>> w = TWave(A, f, phi) | |
>>> w.frequency | |
f | |
""" | |
return self.args[1] | |
def phase(self): | |
""" | |
Returns the phase angle of the wave, | |
in radians. | |
Examples | |
======== | |
>>> from sympy import symbols | |
>>> from sympy.physics.optics import TWave | |
>>> A, phi, f = symbols('A, phi, f') | |
>>> w = TWave(A, f, phi) | |
>>> w.phase | |
phi | |
""" | |
return self.args[2] | |
def time_period(self): | |
""" | |
Returns the temporal period of the wave, | |
in seconds per cycle. | |
Examples | |
======== | |
>>> from sympy import symbols | |
>>> from sympy.physics.optics import TWave | |
>>> A, phi, f = symbols('A, phi, f') | |
>>> w = TWave(A, f, phi) | |
>>> w.time_period | |
1/f | |
""" | |
return self.args[3] | |
def n(self): | |
""" | |
Returns the refractive index of the medium | |
""" | |
return self.args[4] | |
def wavelength(self): | |
""" | |
Returns the wavelength (spatial period) of the wave, | |
in meters per cycle. | |
It depends on the medium of the wave. | |
Examples | |
======== | |
>>> from sympy import symbols | |
>>> from sympy.physics.optics import TWave | |
>>> A, phi, f = symbols('A, phi, f') | |
>>> w = TWave(A, f, phi) | |
>>> w.wavelength | |
299792458*meter/(second*f*n) | |
""" | |
return c/(self.frequency*self.n) | |
def speed(self): | |
""" | |
Returns the propagation speed of the wave, | |
in meters per second. | |
It is dependent on the propagation medium. | |
Examples | |
======== | |
>>> from sympy import symbols | |
>>> from sympy.physics.optics import TWave | |
>>> A, phi, f = symbols('A, phi, f') | |
>>> w = TWave(A, f, phi) | |
>>> w.speed | |
299792458*meter/(second*n) | |
""" | |
return self.wavelength*self.frequency | |
def angular_velocity(self): | |
""" | |
Returns the angular velocity of the wave, | |
in radians per second. | |
Examples | |
======== | |
>>> from sympy import symbols | |
>>> from sympy.physics.optics import TWave | |
>>> A, phi, f = symbols('A, phi, f') | |
>>> w = TWave(A, f, phi) | |
>>> w.angular_velocity | |
2*pi*f | |
""" | |
return 2*pi*self.frequency | |
def wavenumber(self): | |
""" | |
Returns the wavenumber of the wave, | |
in radians per meter. | |
Examples | |
======== | |
>>> from sympy import symbols | |
>>> from sympy.physics.optics import TWave | |
>>> A, phi, f = symbols('A, phi, f') | |
>>> w = TWave(A, f, phi) | |
>>> w.wavenumber | |
pi*second*f*n/(149896229*meter) | |
""" | |
return 2*pi/self.wavelength | |
def __str__(self): | |
"""String representation of a TWave.""" | |
from sympy.printing import sstr | |
return type(self).__name__ + sstr(self.args) | |
__repr__ = __str__ | |
def __add__(self, other): | |
""" | |
Addition of two waves will result in their superposition. | |
The type of interference will depend on their phase angles. | |
""" | |
if isinstance(other, TWave): | |
if self.frequency == other.frequency and self.wavelength == other.wavelength: | |
return TWave(sqrt(self.amplitude**2 + other.amplitude**2 + 2 * | |
self.amplitude*other.amplitude*cos( | |
self.phase - other.phase)), | |
self.frequency, | |
atan2(self.amplitude*sin(self.phase) | |
+ other.amplitude*sin(other.phase), | |
self.amplitude*cos(self.phase) | |
+ other.amplitude*cos(other.phase)) | |
) | |
else: | |
raise NotImplementedError("Interference of waves with different frequencies" | |
" has not been implemented.") | |
else: | |
raise TypeError(type(other).__name__ + " and TWave objects cannot be added.") | |
def __mul__(self, other): | |
""" | |
Multiplying a wave by a scalar rescales the amplitude of the wave. | |
""" | |
other = sympify(other) | |
if isinstance(other, Number): | |
return TWave(self.amplitude*other, *self.args[1:]) | |
else: | |
raise TypeError(type(other).__name__ + " and TWave objects cannot be multiplied.") | |
def __sub__(self, other): | |
return self.__add__(-1*other) | |
def __neg__(self): | |
return self.__mul__(-1) | |
def __radd__(self, other): | |
return self.__add__(other) | |
def __rmul__(self, other): | |
return self.__mul__(other) | |
def __rsub__(self, other): | |
return (-self).__radd__(other) | |
def _eval_rewrite_as_sin(self, *args, **kwargs): | |
return self.amplitude*sin(self.wavenumber*Symbol('x') | |
- self.angular_velocity*Symbol('t') + self.phase + pi/2, evaluate=False) | |
def _eval_rewrite_as_cos(self, *args, **kwargs): | |
return self.amplitude*cos(self.wavenumber*Symbol('x') | |
- self.angular_velocity*Symbol('t') + self.phase) | |
def _eval_rewrite_as_pde(self, *args, **kwargs): | |
mu, epsilon, x, t = symbols('mu, epsilon, x, t') | |
E = Function('E') | |
return Derivative(E(x, t), x, 2) + mu*epsilon*Derivative(E(x, t), t, 2) | |
def _eval_rewrite_as_exp(self, *args, **kwargs): | |
return self.amplitude*exp(I*(self.wavenumber*Symbol('x') | |
- self.angular_velocity*Symbol('t') + self.phase)) | |