Ejemplo n.º 1
0
    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)
Ejemplo n.º 2
0
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)
Ejemplo n.º 3
0
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)
Ejemplo n.º 4
0
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
Ejemplo n.º 5
0
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())
Ejemplo n.º 6
0
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