def check_validity(self): r"""Check the unit and value validity of the characteristic.""" if len(self.bias.shape) != 1: raise ValueError("Non-1D array for voltage!") if len(self.current.shape) != 1: raise ValueError("Non-1D array for current!") if len(self.bias) != len(self.current): raise ValueError(f"Unequal array lengths of bias " f"({len(self.bias)}) and current " f"({len(self.current)}).") if len(np.unique(self.bias)) != len(self.bias): raise ValueError(f"Bias array contains duplicate values.") utils._check_quantity(self.bias, 'bias', str(self), u.V, can_be_negative=True, can_be_complex=False, can_be_inf=False, can_be_nan=True) utils._check_quantity(self.current, 'bias', str(self), u.A, can_be_negative=True, can_be_complex=False, can_be_inf=False, can_be_nan=True)
def deBroglie_wavelength(V, particle): r""" Calculates the de Broglie wavelength. Parameters ---------- V : ~astropy.units.Quantity Particle velocity in units convertible to meters per second. particle : str or ~astropy.units.Quantity Representation of the particle species (e.g., `'e'`, `'p'`, `'D+'`, or `'He-4 1+'`, or the particle mass in units convertible to kilograms. Returns ------- lambda_dB : ~astropy.units.Quantity The de Broglie wavelength in units of meters. Raises ------ TypeError The velocity is not a `~astropy.units.Quantity` and cannot be converted into a ~astropy.units.Quantity. ~astropy.units.UnitConversionError If the velocity is not in appropriate units. ~plasmapy.utils.RelativityError If the magnitude of `V` is faster than the speed of light. Warns ----- UserWarning If `V` is not a `~astropy.units.Quantity`, then a `UserWarning` will be raised and units of meters per second will be assumed. Notes ----- The de Broglie wavelength is given by .. math:: \lambda_{dB} = \frac{h}{p} = \frac{h}{\gamma m V} where :math:`h` is the Planck constant, :math:`p` is the relativistic momentum of the particle, :math:`gamma` is the Lorentz factor, :math:`m` is the particle's mass, and :math:`V` is the particle's velocity. Examples -------- >>> from astropy import units as u >>> velocity = 1.4e7*u.m/u.s >>> deBroglie_wavelength(velocity, 'e') <Quantity 5.18997095e-11 m> >>> deBroglie_wavelength(V = 0*u.m/u.s, particle = 'D+') <Quantity inf m> """ utils._check_quantity(V, 'V', 'deBroglie_wavelength', u.m / u.s) V = np.abs(V) if np.any(V >= c): raise utils.RelativityError( "Velocity input in deBroglie_wavelength cannot " "be greater than or equal to the speed of " "light.") if not isinstance(particle, u.Quantity): try: # TODO: Replace with more general routine! m = atomic.ion_mass(particle) except Exception: raise ValueError("Unable to find particle mass.") else: try: m = particle.to(u.kg) except Exception: raise u.UnitConversionError("The second argument for deBroglie" " wavelength must be either a " "representation of a particle or a" " Quantity with units of mass.") if V.size > 1: lambda_dBr = np.ones(V.shape) * np.inf * u.m indices = V.value != 0 lambda_dBr[indices] = h / (m * V[indices] * Lorentz_factor(V[indices])) else: if V == 0 * u.m / u.s: lambda_dBr = np.inf * u.m else: lambda_dBr = h / (Lorentz_factor(V) * m * V) return lambda_dBr.to(u.m)
def deBroglie_wavelength(V, particle): r""" Calculates the de Broglie wavelength. Parameters ---------- V : ~astropy.units.Quantity Particle velocity in units convertible to meters per second. particle : str or ~astropy.units.Quantity Representation of the particle species (e.g., `'e'`, `'p'`, `'D+'`, or `'He-4 1+'`, or the particle mass in units convertible to kilograms. Returns ------- lambda_dB : ~astropy.units.Quantity The de Broglie wavelength in units of meters. Raises ------ TypeError The velocity is not a `~astropy.units.Quantity` and cannot be converted into a ~astropy.units.Quantity. ~astropy.units.UnitConversionError If the velocity is not in appropriate units. ~plasmapy.utils.RelativityError If the magnitude of `V` is faster than the speed of light. Warns ----- ~astropy.units.UnitsWarning If units are not provided, SI units are assumed Notes ----- The de Broglie wavelength is given by .. math:: \lambda_{dB} = \frac{h}{p} = \frac{h}{\gamma m V} where :math:`h` is the Planck constant, :math:`p` is the relativistic momentum of the particle, :math:`gamma` is the Lorentz factor, :math:`m` is the particle's mass, and :math:`V` is the particle's velocity. Examples -------- >>> from astropy import units as u >>> velocity = 1.4e7*u.m/u.s >>> deBroglie_wavelength(velocity, 'e') <Quantity 5.18997095e-11 m> >>> deBroglie_wavelength(V = 0*u.m/u.s, particle = 'D+') <Quantity inf m> """ utils._check_quantity(V, 'V', 'deBroglie_wavelength', u.m / u.s) V = np.abs(V) if np.any(V >= c): raise utils.RelativityError( "Velocity input in deBroglie_wavelength cannot " "be greater than or equal to the speed of " "light.") if not isinstance(particle, u.Quantity): try: # TODO: Replace with more general routine! m = atomic.ion_mass(particle) except Exception: raise ValueError("Unable to find particle mass.") else: try: m = particle.to(u.kg) except Exception: raise u.UnitConversionError("The second argument for deBroglie" " wavelength must be either a " "representation of a particle or a" " Quantity with units of mass.") if V.size > 1: lambda_dBr = np.ones(V.shape) * np.inf * u.m indices = V.value != 0 lambda_dBr[indices] = h / (m * V[indices] * Lorentz_factor(V[indices])) else: if V == 0 * u.m / u.s: lambda_dBr = np.inf * u.m else: lambda_dBr = h / (Lorentz_factor(V) * m * V) return lambda_dBr.to(u.m)
def Lorentz_factor(V): r""" Return the Lorentz factor. Parameters ---------- V : ~astropy.units.Quantity The velocity in units convertible to meters per second. Returns ------- gamma : float or ~numpy.ndarray The Lorentz factor associated with the inputted velocities. Raises ------ TypeError The `V` is not a `~astropy.units.Quantity` and cannot be converted into a ~astropy.units.Quantity. ~astropy.units.UnitConversionError If the `V` is not in appropriate units. ValueError If the magnitude of `V` is faster than the speed of light. UserWarning If `V` is not a `~astropy.units.Quantity`, then a `UserWarning` will be raised and units of meters per second will be assumed. Notes ----- The Lorentz factor is a dimensionless number given by .. math:: \gamma = \frac{1}{\sqrt{1-\frac{V^2}{c^2}}} The Lorentz factor is approximately one for sub-relativistic velocities, and goes to infinity as the velocity approaches the speed of light. Examples -------- >>> from astropy import units as u >>> velocity = 1.4e8*u.m/u.s >>> Lorentz_factor(velocity) 1.130885603948959 >>> Lorentz_factor(299792458*u.m/u.s) inf """ utils._check_quantity(V, 'V', 'Lorentz_factor', u.m / u.s) if not np.all(np.abs(V) <= c): raise utils.RelativityError( "The Lorentz factor cannot be calculated for " "speeds faster than the speed of light. ") if V.size > 1: gamma = np.zeros_like(V.value) equals_c = np.abs(V) == c is_slow = ~equals_c gamma[is_slow] = ((1 - (V[is_slow] / c)**2)**-0.5).value gamma[equals_c] = np.inf else: if np.abs(V) == c: gamma = np.inf else: gamma = ((1 - (V / c)**2)**-0.5).value return gamma
def gyroradius(B, *args, Vperp=None, T_i=None, particle='e-'): r"""Returns the particle gyroradius. Parameters ---------- B : ~astropy.units.Quantity The magnetic field magnitude in units convertible to tesla. Vperp : ~astropy.units.Quantity, optional The component of particle velocity that is perpendicular to the magnetic field in units convertible to meters per second. T_i : ~astropy.units.Quantity, optional The particle temperature in units convertible to kelvin. particle : str, optional Representation of the particle species (e.g., `'p'` for protons, `'D+'` for deuterium, or `'He-4 +1'` for singly ionized helium-4), which defaults to electrons. If no charge state information is provided, then the particles are assumed to be singly charged. args : ~astropy.units.Quantity If the second positional argument is a ~astropy.units.Quantity with units appropriate to `Vperp` or `T_i`, then this argument will take the place of that keyword argument. Returns ------- r_Li : ~astropy.units.Quantity The particle gyroradius in units of meters. This ~astropy.units.Quantity will be based on either the perpendicular component of particle velocity as inputted, or the most probable speed for an particle within a Maxwellian distribution for the particle temperature. Raises ------ TypeError The arguments are of an incorrect type ~astropy.units.UnitConversionError The arguments do not have appropriate units ValueError If any argument contains invalid values UserWarning If units are not provided and SI units are assumed Notes ----- One but not both of `Vperp` and `T_i` must be inputted. If any of `B`, `Vperp`, or `T_i` is a number rather than a `~astropy.units.Quantity`, then SI units will be assumed and a warning will be raised. The particle gyroradius is also known as the particle Larmor radius and is given by .. math:: r_{Li} = \frac{V_{\perp}}{omega_{ci}} where :math:`V_{\perp}` is the component of particle velocity that is perpendicular to the magnetic field and :math:`\omega_{ci}` is the particle gyrofrequency. If a temperature is provided, then :math:`V_\perp` will be the most probable thermal velocity of an particle at that temperature. Examples -------- >>> from astropy import units as u >>> gyroradius(0.2*u.T, 1e5*u.K, particle='p+') <Quantity 0.00212087 m> >>> gyroradius(0.2*u.T, 1e5*u.K, particle='p+') <Quantity 0.00212087 m> >>> gyroradius(5*u.uG, 1*u.eV, particle='alpha') <Quantity 288002.38837768 m> >>> gyroradius(400*u.G, 1e7*u.m/u.s, particle='Fe+++') <Quantity 48.23129811 m> >>> gyroradius(B = 0.01*u.T, T_i = 1e6*u.K) <Quantity 0.00313033 m> >>> gyroradius(B = 0.01*u.T, Vperp = 1e6*u.m/u.s) <Quantity 0.00056856 m> >>> gyroradius(0.2*u.T, 1e5*u.K) <Quantity 4.94949252e-05 m> >>> gyroradius(5*u.uG, 1*u.eV) <Quantity 6744.2598183 m> >>> gyroradius(400*u.G, 1e7*u.m/u.s) <Quantity 0.00142141 m> """ if Vperp is not None and T_i is not None: raise ValueError("Cannot have both Vperp and T_i as arguments to " "gyroradius") if len(args) == 1 and isinstance(args[0], u.Quantity): arg = args[0].si if arg.unit == u.T and B.si.unit in [u.J, u.K, u.m / u.s]: B, arg = arg, B if arg.unit == u.m / u.s: Vperp = arg elif arg.unit in (u.J, u.K): T_i = arg.to(u.K, equivalencies=u.temperature_energy()) else: raise u.UnitConversionError("Incorrect units for positional " "argument in gyroradius") elif len(args) > 0: raise ValueError("Incorrect inputs to gyroradius") utils._check_quantity(B, 'B', 'gyroradius', u.T) if Vperp is not None: utils._check_quantity(Vperp, 'Vperp', 'gyroradius', u.m / u.s) elif T_i is not None: utils._check_quantity(T_i, 'T_i', 'gyroradius', u.K) Vperp = thermal_speed(T_i, particle=particle) omega_ci = gyrofrequency(B, particle) r_Li = np.abs(Vperp) / omega_ci return r_Li.to(u.m, equivalencies=u.dimensionless_angles())
def Alfven_speed(B, density, ion="p+", z_mean=None): r""" Returns the Alfven speed. Parameters ---------- B : ~astropy.units.Quantity The magnetic field magnitude in units convertible to tesla. density : ~astropy.units.Quantity Either the ion number density in units convertible to 1 / m**3, or the mass density in units convertible to kg / m**3. ion : str, optional Representation of the ion species (e.g., `'p'` for protons, `'D+'` for deuterium, or `'He-4 +1'` for singly ionized helium-4), which defaults to protons. If no charge state information is provided, then the ions are assumed to be singly charged. z_mean : ~astropy.units.Quantity, optional The average ionization (arithmetic mean) for a plasma where the a macroscopic description is valid. If this quantity is not given then the atomic charge state (integer) of the ion is used. This is effectively an average Alfven speed for the plasma where multiple charge states are present. Returns ------- V_A : ~astropy.units.Quantity with units of velocity The Alfven velocity of the plasma in units of meters per second. Raises ------ TypeError The magnetic field and density arguments are not Quantities and cannot be converted into Quantities. ~astropy.units.UnitConversionError If the magnetic field or density is not in appropriate units. ~plasmapy.utils.RelativityError If the Alfven velocity is greater than or equal to the speed of light ValueError If the density is negative, or the ion mass or charge state cannot be found. UserWarning if units are not provided and SI units are assumed. Warns ----- ~plasmapy.utils.RelativityWarning If the Alfven velocity exceeds 10% of the speed of light Notes ----- The Alfven velocity :math:`V_A` is the typical propagation speed of magnetic disturbances in a plasma, and is given by: .. math:: V_A = \frac{B}{\sqrt{\mu_0\rho}} where the mass density is :math:`\rho = n_i m_i + n_e m_e`. This expression does not account for relativistic effects, and loses validity when the resulting speed is a significant fraction of the speed of light. This function switches B and density when B has units of number density or mass density and density has units of magnetic field strength. Examples -------- >>> from astropy import units as u >>> from plasmapy.constants import m_p, m_e >>> B = 0.014*u.T >>> n = 5e19*u.m**-3 >>> rho = n*(m_p+m_e) >>> ion = 'p' >>> Alfven_speed(B, n, ion) <Quantity 43173.87029559 m / s> >>> Alfven_speed(B, rho, ion) <Quantity 43173.87029559 m / s> >>> Alfven_speed(B, rho, ion).to(u.cm/u.us) <Quantity 4.31738703 cm / us> """ utils._check_quantity(B, 'B', 'Alfven_speed', u.T) utils._check_quantity(density, 'density', 'Alfven_speed', [u.m**-3, u.kg / u.m**3], can_be_negative=False) B = B.to(u.T) density = density.si if density.unit == u.m**-3: try: m_i = atomic.ion_mass(ion) if z_mean is None: # warnings.warn("No z_mean given, defaulting to atomic charge", # PhysicsWarning) try: Z = atomic.integer_charge(ion) except AtomicError: Z = 1 else: # using average ionization provided by user Z = z_mean # ensuring positive value of Z Z = np.abs(Z) except AtomicError: raise ValueError("Invalid ion in Alfven_speed.") rho = density * m_i + Z * density * m_e elif density.unit == u.kg / u.m**3: rho = density try: V_A = (np.abs(B) / np.sqrt(mu0 * rho)).to(u.m / u.s) except Exception: raise ValueError("Unable to find Alfven speed") return V_A