Example #1
0
def ion_sound_speed(*ignore,
                    T_e=0 * units.K,
                    T_i=0 * units.K,
                    gamma_e=1,
                    gamma_i=3,
                    ion='p',
                    z_mean=None):
    r"""
    Returns the ion sound speed for an electron-ion plasma.

    Parameters
    ----------
    T_e : ~astropy.units.Quantity, optional
        Electron temperature in units of temperature or energy per
        particle.  If this is not given, then the electron temperature
        is assumed to be zero.  If only one temperature is entered, it
        is assumed to be the electron temperature.

    T_i : ~astropy.units.Quantity, optional
        Ion temperature in units of temperature or energy per
        particle.  If this is not given, then the ion temperature is
        assumed to be zero.

    gamma_e : float or int
        The adiabatic index for electrons, which defaults to 1.  This
        value assumes that the electrons are able to equalize their
        temperature rapidly enough that the electrons are effectively
        isothermal.

    gamma_i : float or int
        The adiabatic index for ions, which defaults to 3.  This value
        assumes that ion motion has only one degree of freedom, namely
        along magnetic field lines.

    ion : string, 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 : 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 ion sound speed for the
        plasma where multiple charge states are present.

    Returns
    -------
    V_S : ~astropy.units.Quantity
        The ion sound speed in units of meters per second.

    Raises
    ------
    TypeError
        If any of the arguments are not entered as keyword arguments
        or are of an incorrect type.

    ValueError
        If the ion mass, adiabatic index, or temperature are invalid.

    plasmapy.utils.PhysicsError
        If an adiabatic index is less than one.

    units.UnitConversionError
        If the temperature is in incorrect units.

    UserWarning
        If the ion sound speed exceeds 10% of the speed of light, or
        if units are not provided and SI units are assumed.

    Notes
    -----
    The ion sound speed :math:`V_S` is approximately given by

    .. math::

        V_S = \sqrt{\frac{\gamma_e Z k_B T_e + \gamma_i k_B T_i}{m_i}}

    where :math:`\gamma_e` and :math:`\gamma_i` are the electron and
    ion adiabatic indices, :math:`k_B` is the Boltzmann constant,
    :math:`T_e` and :math:`T_i` are the electron and ion temperatures,
    :math:`Z` is the charge state of the ion, and :math:`m_i` is the
    ion mass.

    This function assumes that the product of the wavenumber and the
    Debye length is small. In this limit, the ion sound speed is not
    dispersive (e.g., frequency independent).

    When the electron temperature is much greater than the ion
    temperature, the ion sound velocity reduces to
    :math:`\sqrt{\gamma_e k_B T_e / m_i}`.  Ion acoustic waves can
    therefore occur even when the ion temperature is zero.

    Example
    -------
    >>> from astropy import units as u
    >>> ion_sound_speed(T_e=5e6*u.K, T_i=0*u.K, ion='p', gamma_e=1, gamma_i=3)
    <Quantity 203155.0764042 m / s>
    >>> ion_sound_speed(T_e=5e6*u.K)
    <Quantity 203155.0764042 m / s>
    >>> ion_sound_speed(T_e=500*u.eV, T_i=200*u.eV, ion='D+')
    <Quantity 229586.01860212 m / s>

    """

    if ignore:
        raise TypeError("All arguments are required to be keyword arguments "
                        "in ion_sound_speed to prevent mixing up the electron "
                        "and ion temperatures. An example call that uses the "
                        "units subpackage from astropy is: "
                        "ion_sound_speed(T_e=5*units.K, T_i=0*units.K, "
                        "ion='D+')")

    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
    except AtomicError:
        raise ValueError("Invalid ion in ion_sound_speed.")

    if not isinstance(gamma_e, (float, int)):
        raise TypeError("The adiabatic index for electrons (gamma_e) must be "
                        "a float or int in ion_sound_speed")
    if not isinstance(gamma_i, (float, int)):
        raise TypeError("The adiabatic index for ions (gamma_i) must be "
                        "a float or int in ion_sound_speed")

    if not 1 <= gamma_e <= np.inf:
        raise utils.PhysicsError(
            "The adiabatic index for electrons must be between "
            "one and infinity")
    if not 1 <= gamma_i <= np.inf:
        raise utils.PhysicsError(
            "The adiabatic index for ions must be between "
            "one and infinity")

    T_i = T_i.to(units.K, equivalencies=units.temperature_energy())
    T_e = T_e.to(units.K, equivalencies=units.temperature_energy())

    try:
        V_S_squared = (gamma_e * Z * k_B * T_e + gamma_i * k_B * T_i) / m_i
        V_S = np.sqrt(V_S_squared).to(units.m / units.s)
    except Exception:
        raise ValueError("Unable to find ion sound speed.")

    return V_S
Example #2
0
def ion_sound_speed(T_e, T_i, gamma_e=1, gamma_i=3, ion='p+', z_mean=None):
    r"""
    Return the ion sound speed for an electron-ion plasma.

    Parameters
    ----------
    T_e : ~astropy.units.Quantity
        Electron temperature in units of temperature or energy per
        particle. If this is not given, then the electron temperature
        is assumed to be zero.

    T_i : ~astropy.units.Quantity
        Ion temperature in units of temperature or energy per
        particle.  If this is not given, then the ion temperature is
        assumed to be zero.

    gamma_e : float or int
        The adiabatic index for electrons, which defaults to 1.  This
        value assumes that the electrons are able to equalize their
        temperature rapidly enough that the electrons are effectively
        isothermal.

    gamma_i : float or int
        The adiabatic index for ions, which defaults to 3.  This value
        assumes that ion motion has only one degree of freedom, namely
        along magnetic field lines.

    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 ion sound speed for the
        plasma where multiple charge states are present.

    Returns
    -------
    V_S : ~astropy.units.Quantity
        The ion sound speed in units of meters per second.

    Raises
    ------
    TypeError
        If any of the arguments are not entered as keyword arguments
        or are of an incorrect type.

    ValueError
        If the ion mass, adiabatic index, or temperature are invalid.

    ~plasmapy.utils.PhysicsError
        If an adiabatic index is less than one.

    ~astropy.units.UnitConversionError
        If the temperature is in incorrect units.

    Warns
    -----
    RelativityWarning
        If the ion sound speed exceeds 5% of the speed of light.

    ~astropy.units.UnitsWarning
        If units are not provided, SI units are assumed.

    Notes
    -----
    The ion sound speed :math:`V_S` is approximately given by

    .. math::

        V_S = \sqrt{\frac{\gamma_e Z k_B T_e + \gamma_i k_B T_i}{m_i}}

    where :math:`\gamma_e` and :math:`\gamma_i` are the electron and
    ion adiabatic indices, :math:`k_B` is the Boltzmann constant,
    :math:`T_e` and :math:`T_i` are the electron and ion temperatures,
    :math:`Z` is the charge state of the ion, and :math:`m_i` is the
    ion mass.

    This function assumes that the product of the wavenumber and the
    Debye length is small. In this limit, the ion sound speed is not
    dispersive. In other words, it is frequency independent.

    When the electron temperature is much greater than the ion
    temperature, the ion sound velocity reduces to
    :math:`\sqrt{\gamma_e k_B T_e / m_i}`.  Ion acoustic waves can
    therefore occur even when the ion temperature is zero.

    Example
    -------
    >>> from astropy import units as u
    >>> ion_sound_speed(T_e=5e6*u.K, T_i=0*u.K, ion='p', gamma_e=1, gamma_i=3)
    <Quantity 203155.0764042 m / s>
    >>> ion_sound_speed(T_e=5e6*u.K, T_i=0*u.K)
    <Quantity 203155.0764042 m / s>
    >>> ion_sound_speed(T_e=500*u.eV, T_i=200*u.eV, ion='D+')
    <Quantity 229586.01860212 m / s>

    """

    m_i = atomic.ion_mass(ion)
    Z = grab_charge(ion, z_mean)

    for gamma, particles in zip([gamma_e, gamma_i], ["electrons", "ions"]):
        if not isinstance(gamma, (float, int)):
            raise TypeError(
                f"The adiabatic index gamma for {particles} must be "
                "a float or int")
        if gamma < 1:
            raise utils.PhysicsError(
                f"The adiabatic index for {particles} must be between "
                "one and infinity")

    T_i = T_i.to(u.K, equivalencies=u.temperature_energy())
    T_e = T_e.to(u.K, equivalencies=u.temperature_energy())

    try:
        V_S_squared = (gamma_e * Z * k_B * T_e + gamma_i * k_B * T_i) / m_i
        V_S = np.sqrt(V_S_squared).to(u.m / u.s)
    except Exception:
        raise ValueError("Unable to find ion sound speed.")

    return V_S
Example #3
0
def ion_sound_speed(T_e,
                    T_i,
                    n_e=None,
                    k=None,
                    gamma_e=1,
                    gamma_i=3,
                    ion='p+',
                    z_mean=None):
    r"""
    Return the ion sound speed for an electron-ion plasma.

    Parameters
    ----------
    T_e : ~astropy.units.Quantity
        Electron temperature in units of temperature or energy per
        particle. If this is not given, then the electron temperature
        is assumed to be zero.

    T_i : ~astropy.units.Quantity
        Ion temperature in units of temperature or energy per
        particle.  If this is not given, then the ion temperature is
        assumed to be zero.
        
    n_e : ~astropy.units.Quantity
        Electron number density. If this is not given, then ion_sound_speed 
        will be approximated in the non-dispersive limit 
        (:math:`k^2 \lambda_{D}^2` will be assumed zero). If n_e is given, 
        a value for k must also be given.
        
    k : ~astropy.units.Quantity
        Wavenumber (in units of inverse length, e.g. per meter). If this 
        is not given, then ion_sound_speed will be approximated in the 
        non-dispersive limit (:math:`k^2 \lambda_{D}^2` will be assumed zero). 
        If k is given, a value for n_e must also be given.

    gamma_e : float or int
        The adiabatic index for electrons, which defaults to 1.  This
        value assumes that the electrons are able to equalize their
        temperature rapidly enough that the electrons are effectively
        isothermal.

    gamma_i : float or int
        The adiabatic index for ions, which defaults to 3.  This value
        assumes that ion motion has only one degree of freedom, namely
        along magnetic field lines.

    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 ion sound speed for the
        plasma where multiple charge states are present.

    Returns
    -------
    V_S : ~astropy.units.Quantity
        The ion sound speed in units of meters per second.

    Raises
    ------
    TypeError
        If any of the arguments are not entered as keyword arguments
        or are of an incorrect type.

    ValueError
        If the ion mass, adiabatic index, or temperature are invalid.

    ~plasmapy.utils.PhysicsError
        If an adiabatic index is less than one.

    ~astropy.units.UnitConversionError
        If the temperature, electron number density, or wavenumber 
        is in incorrect units.

    Warns
    -----
    RelativityWarning
        If the ion sound speed exceeds 5% of the speed of light.

    ~astropy.units.UnitsWarning
        If units are not provided, SI units are assumed.
        
    PhysicsWarning
        If only one of (k, n_e) is given, the non-dispersive limit 
        is assumed.

    Notes
    -----
    The ion sound speed :math:`V_S` is given by

    .. math::

        V_S = \sqrt{\frac{\gamma_e Z k_B T_e + \gamma_i k_B T_i}{m_i (1 + k^2 \lambda_{D}^2)}}

    where :math:`\gamma_e` and :math:`\gamma_i` are the electron and
    ion adiabatic indices, :math:`k_B` is the Boltzmann constant,
    :math:`T_e` and :math:`T_i` are the electron and ion temperatures,
    :math:`Z` is the charge state of the ion, :math:`m_i` is the
    ion mass, :math:`\lambda_{D}` is the Debye length, and :math:`k` is the 
    wavenumber.
    
    In the non-dispersive limit (:math:`k^2 \lambda_{D}^2` is small) the 
    equation for :math:`V_S` is approximated (the denominator reduces 
    to :math:`m_i`).

    When the electron temperature is much greater than the ion
    temperature, the ion sound velocity reduces to
    :math:`\sqrt{\gamma_e k_B T_e / m_i}`. Ion acoustic waves can
    therefore occur even when the ion temperature is zero.

    Example
    -------
    >>> from astropy import units as u
    >>> n = 5e19*u.m**-3
    >>> k_1 = 3e1*u.m**-1
    >>> k_2 = 3e7*u.m**-1
    >>> ion_sound_speed(T_e=5e6*u.K, T_i=0*u.K, ion='p', gamma_e=1, gamma_i=3)
    <Quantity 203155.0764042 m / s>
    >>> ion_sound_speed(T_e=5e6*u.K, T_i=0*u.K, n_e=n, k=k_1, ion='p', gamma_e=1, gamma_i=3)
    <Quantity 203155.03286794 m / s>
    >>> ion_sound_speed(T_e=5e6*u.K, T_i=0*u.K, n_e=n, k=k_2, ion='p', gamma_e=1, gamma_i=3)
    <Quantity 310.31329069 m / s>
    >>> ion_sound_speed(T_e=5e6*u.K, T_i=0*u.K, n_e=n, k=k_1)
    <Quantity 203155.03286794 m / s>
    >>> ion_sound_speed(T_e=500*u.eV, T_i=200*u.eV, n_e=n, k=k_1, ion='D+')
    <Quantity 229585.96150738 m / s>

    """

    m_i = atomic.particle_mass(ion)
    Z = _grab_charge(ion, z_mean)

    for gamma, particles in zip([gamma_e, gamma_i], ["electrons", "ions"]):
        if not isinstance(gamma, (numbers.Real, numbers.Integral)):
            raise TypeError(
                f"The adiabatic index gamma for {particles} must be "
                "a float or int")
        if gamma < 1:
            raise utils.PhysicsError(
                f"The adiabatic index for {particles} must be between "
                "one and infinity")

    T_i = T_i.to(u.K, equivalencies=u.temperature_energy())
    T_e = T_e.to(u.K, equivalencies=u.temperature_energy())

    # Assume non-dispersive limit if values for n_e (or k) are not specified
    klD2 = 0.0
    if (n_e is None) ^ (k is None):
        warnings.warn(
            "The non-dispersive limit has been assumed for "
            "this calculation. To prevent this, values must "
            "be specified for both n_e and k.", PhysicsWarning)
    elif n_e is not None and k is not None:
        lambda_D = Debye_length(T_e, n_e)
        klD2 = (k * lambda_D)**2

    try:
        V_S_squared = (gamma_e * Z * k_B * T_e +
                       gamma_i * k_B * T_i) / (m_i * (1 + klD2))
        V_S = np.sqrt(V_S_squared).to(u.m / u.s)
    except Exception:
        raise ValueError("Unable to find ion sound speed.")

    return V_S