def __init__(self, name, density, magnetic_field, Tx, Tz): self.name = name self.density = density self.gyro_f = parameters.gyrofrequency(B=magnetic_field, particle=name, signed=True) self.plasma_f = parameters.plasma_frequency(density, particle=name) self.Tx = Tx self.Tz = Tz self.vth_x = parameters.thermal_speed(Tx * u.K, name).value self.vth_z = parameters.thermal_speed(Tz * u.K, name).value
class dielectric: """ Benchmark that times the performance of funcions from Physics/dielectric package """ B = 2*u.T species = ['e', 'D+'] n = [1e18*u.m**-3, 1e18*u.m**-3] omega = 3.7e9*(2*pi)*(u.rad/u.s) T = 30 * 11600 * u.K particle = 'Ne' z_mean = 8 * u.dimensionless_unscaled vTh = parameters.thermal_speed(T, particle, method="most_probable") kWave = omega / vTh n_permittivity_1D_Maxwellian = 1e18 * u.cm**-3 def setup(self): pass def time_cold_plasma_permittivity_SDP(self): permittivity = S, D, P = cold_plasma_permittivity_SDP( dielectric.B, dielectric.species, dielectric.n, dielectric.omega) def time_cold_plasma_permittivity_LRP(self): permittivity = S, D, P = cold_plasma_permittivity_LRP( dielectric.B, dielectric.species, dielectric.n, dielectric.omega) def time_permittivity_1D_Maxwellian(self): permittivity_1D_Maxwellian(dielectric.omega, dielectric.kWave, dielectric.T, dielectric.n_permittivity_1D_Maxwellian, dielectric.particle, dielectric.z_mean)
def test_gyroradius(): r"""Test the gyroradius function in parameters.py.""" assert gyroradius(B, T_i=T_e).unit.is_equivalent(u.m) assert gyroradius(B, Vperp=25 * u.m / u.s).unit.is_equivalent(u.m) Vperp = 1e6 * u.m / u.s Bmag = 1 * u.T omega_ce = gyrofrequency(Bmag) analytical_result = (Vperp / omega_ce).to( u.m, equivalencies=u.dimensionless_angles()) assert gyroradius(Bmag, Vperp=Vperp) == analytical_result with pytest.raises(TypeError): gyroradius(u.T) with pytest.raises(u.UnitConversionError): gyroradius(5 * u.A, Vperp=8 * u.m / u.s) with pytest.raises(u.UnitConversionError): gyroradius(5 * u.T, Vperp=8 * u.m) with pytest.raises(ValueError): gyroradius(np.array([5, 6]) * u.T, Vperp=np.array([5, 6, 7]) * u.m / u.s) with pytest.raises(ValueError): gyroradius(np.nan * u.T, Vperp=1 * u.m / u.s) with pytest.raises(ValueError): gyroradius(3.14159 * u.T, T_i=-1 * u.K) with pytest.warns(u.UnitsWarning): assert gyroradius(1.0, Vperp=1.0) == gyroradius(1.0 * u.T, Vperp=1.0 * u.m / u.s) with pytest.warns(u.UnitsWarning): assert gyroradius(1.1, T_i=1.2) == gyroradius(1.1 * u.T, T_i=1.2 * u.K) with pytest.raises(ValueError): gyroradius(1.1 * u.T, Vperp=1 * u.m / u.s, T_i=1.2 * u.K) with pytest.raises(ValueError): gyroradius(1.1 * u.T, Vperp=1.1 * u.m, T_i=1.2 * u.K) assert gyroradius(B, particle="p", T_i=T_i).unit.is_equivalent(u.m) assert gyroradius(B, particle="p", Vperp=25 * u.m / u.s).unit.is_equivalent(u.m) # Case when Z=1 is assumed assert np.isclose(gyroradius(B, particle='p', T_i=T_i), gyroradius(B, particle='H+', T_i=T_i), atol=1e-6 * u.m) gyroPos = gyroradius(B, particle="p", Vperp=V) gyroNeg = gyroradius(B, particle="p", Vperp=-V) assert gyroPos == gyroNeg Vperp = 1e6 * u.m / u.s Bmag = 1 * u.T omega_ci = gyrofrequency(Bmag, particle='p') analytical_result = (Vperp / omega_ci).to( u.m, equivalencies=u.dimensionless_angles()) assert gyroradius(Bmag, particle="p", Vperp=Vperp) == analytical_result T2 = 1.2 * u.MK B2 = 123 * u.G particle2 = 'alpha' Vperp2 = thermal_speed(T2, particle=particle2) gyro_by_vperp = gyroradius(B2, particle='alpha', Vperp=Vperp2) assert gyro_by_vperp == gyroradius(B2, particle='alpha', T_i=T2) explicit_positron_gyro = gyroradius(1 * u.T, particle='positron', T_i=1 * u.MK) assert explicit_positron_gyro == gyroradius(1 * u.T, T_i=1 * u.MK) with pytest.raises(TypeError): gyroradius(u.T, particle="p", Vperp=8 * u.m / u.s) with pytest.raises(ValueError): gyroradius(B, particle='p', T_i=-1 * u.K) with pytest.warns(u.UnitsWarning): gyro_without_units = gyroradius(1.0, particle="p", Vperp=1.0) gyro_with_units = gyroradius(1.0 * u.T, particle="p", Vperp=1.0 * u.m / u.s) assert gyro_without_units == gyro_with_units with pytest.warns(u.UnitsWarning): gyro_t_without_units = gyroradius(1.1, particle="p", T_i=1.2) gyro_t_with_units = gyroradius(1.1 * u.T, particle="p", T_i=1.2 * u.K) assert gyro_t_with_units == gyro_t_without_units with pytest.raises(ValueError): gyroradius(1.1 * u.T, particle="p", Vperp=1 * u.m / u.s, T_i=1.2 * u.K) with pytest.raises(ValueError): gyroradius(1.1 * u.T, particle="p", Vperp=1.1 * u.m, T_i=1.2 * u.K) with pytest.raises(ValueError): gyroradius(1.1 * u.T, particle="p", Vperp=1.2 * u.m, T_i=1.1 * u.K)
def test_thermal_speed(): r"""Test the thermal_speed function in parameters.py""" assert thermal_speed(T_e).unit.is_equivalent(u.m / u.s) assert thermal_speed(T_e) > thermal_speed(T_e, 'p') # The NRL Plasma Formulary uses a definition of the electron # thermal speed that differs by a factor of sqrt(2). assert np.isclose(thermal_speed(1 * u.MK).value, 5505694.743141063) with pytest.raises(u.UnitConversionError): thermal_speed(5 * u.m) with pytest.raises(ValueError): thermal_speed(-T_e) with pytest.warns(RelativityWarning): thermal_speed(1e9 * u.K) with pytest.raises(RelativityError): thermal_speed(5e19 * u.K) with pytest.warns(u.UnitsWarning): assert thermal_speed(1e5) == thermal_speed(1e5 * u.K) assert thermal_speed(T_i, particle='p').unit.is_equivalent(u.m / u.s) # The NRL Plasma Formulary uses a definition of the particle thermal # speed that differs by a factor of sqrt(2). assert np.isclose( thermal_speed(1 * u.MK, particle='p').si.value, 128486.56960876315) # Case when Z=1 is assumed assert thermal_speed(T_i, particle='p') == thermal_speed(T_i, particle='H-1+') assert thermal_speed(1 * u.MK, particle='e+') == thermal_speed(1 * u.MK) with pytest.raises(u.UnitConversionError): thermal_speed(5 * u.m, particle='p') with pytest.raises(ValueError): thermal_speed(-T_e, particle='p') with pytest.warns(RelativityWarning): thermal_speed(1e11 * u.K, particle='p') with pytest.raises(RelativityError): thermal_speed(1e14 * u.K, particle='p') with pytest.raises(InvalidParticleError): thermal_speed(T_i, particle='asdfasd') with pytest.warns(u.UnitsWarning): assert thermal_speed(1e6, particle='p') == thermal_speed(1e6 * u.K, particle='p') assert np.isclose( thermal_speed(1e6 * u.K, method="mean_magnitude").si.value, 6212510.3969422) assert np.isclose( thermal_speed(1e6 * u.K, method="rms").si.value, 6743070.475775486) with pytest.raises(ValueError): thermal_speed(T_i, method="sadks") assert_can_handle_nparray(thermal_speed)
def time_thermal_speed(self): thermal_speed(1 * u.MK)
def permittivity_1D_Maxwellian(omega, kWave, T, n, particle, z_mean=None): r""" The classical dielectric permittivity for a 1D Maxwellian plasma. This function can calculate both the ion and electron permittivities. No additional effects are considered (e.g. magnetic fields, relativistic effects, strongly coupled regime, etc.) Parameters ---------- omega : ~astropy.units.Quantity The frequency in rad/s of the electromagnetic wave propagating through the plasma. kWave : ~astropy.units.Quantity The corresponding wavenumber, in rad/m, of the electromagnetic wave propagating through the plasma. This is often modulated by the dispersion of the plasma or by relativistic effects. See em_wave.py for ways to calculate this. T : ~astropy.units.Quantity The plasma temperature - this can be either the electron or the ion temperature, but should be consistent with density and particle. n : ~astropy.units.Quantity The plasma density - this can be either the electron or the ion density, but should be consistent with temperature and particle. particle : str The plasma particle species. z_mean : str The average ionization of the plasma. This is only required for calculating the ion permittivity. Returns ------- chi : ~astropy.units.Quantity The ion or the electron dielectric permittivity of the plasma. This is a dimensionless quantity. Notes ----- The dielectric permittivities for a Maxwellian plasma are described by the following equations [1]_ .. math:: \chi_e(k, \omega) = - \frac{\alpha_e^2}{2} Z'(x_e) \chi_i(k, \omega) = - \frac{\alpha_i^2}{2}\frac{Z}{} Z'(x_i) \alpha = \frac{\omega_p}{k v_{Th}} x = \frac{\omega}{k v_{Th}} :math:`chi_e` and :math:`chi_i` are the electron and ion permittivities respectively. :math:`Z'` is the derivative of the plasma dispersion function. :math:`\alpha` is the scattering parameter which delineates the difference between the collective and non-collective Thomson scattering regimes. :math:`x` is the dimensionless phase velocity of the EM wave propagating through the plasma. References ---------- .. [1] J. Sheffield, D. Froula, S. H. Glenzer, and N. C. Luhmann Jr, Plasma scattering of electromagnetic radiation: theory and measurement techniques. Chapter 5 Pg 106 (Academic press, 2010). Example ------- >>> from astropy import units as u >>> from plasmapy.constants import pi, c >>> T = 30 * 11600 * u.K >>> n = 1e18 * u.cm**-3 >>> particle = 'Ne' >>> z_mean = 8 * u.dimensionless_unscaled >>> vTh = parameters.thermal_speed(T, particle, method="most_probable") >>> omega = 5.635e14 * 2 * pi * u.rad / u.s >>> kWave = omega / vTh >>> permittivity_1D_Maxwellian(omega, kWave, T, n, particle, z_mean) <Quantity -6.72809257e-08+5.76037956e-07j> """ # thermal velocity vTh = parameters.thermal_speed(T=T, particle=particle, method="most_probable") # plasma frequency wp = parameters.plasma_frequency(n=n, particle=particle, z_mean=z_mean) # scattering parameter alpha. # explicitly removing factor of sqrt(2) to be consistent with Froula alpha = np.sqrt(2) * (wp / (kWave * vTh)).to(u.dimensionless_unscaled) # The dimensionless phase velocity of the propagating EM wave. zeta = (omega / (kWave * vTh)).to(u.dimensionless_unscaled) chi = alpha**2 * (-1 / 2) * plasma_dispersion_func_deriv(zeta.value) return chi.to(u.dimensionless_unscaled)
def Maxwellian_speed_3D(v, T, particle="e", v_drift=0, vTh=np.nan, units="units"): r""" Probability distribution function of speed for a Maxwellian distribution in 3D. Return the probability density function for finding a particle with speed components `vx`, `vy`, and `vz` in m/s in an equilibrium plasma of temperature `T` which follows the 3D Maxwellian distribution function. This function assumes Cartesian coordinates. Parameters ---------- v: ~astropy.units.Quantity The speed in units convertible to m/s. T: ~astropy.units.Quantity The temperature, preferably in Kelvin. particle: str, optional Representation of the particle species(e.g., `'p'` for protons, `'D+'` for deuterium, or `'He-4 +1'` for :math:`He_4^{+1}` (singly ionized helium-4)), which defaults to electrons. v_drift: ~astropy.units.Quantity The drift speed in units convertible to m/s. vTh: ~astropy.units.Quantity, optional Thermal velocity (most probable) in m/s. This is used for optimization purposes to avoid re-calculating vTh, for example when integrating over velocity-space. units: str, optional Selects whether to run function with units and unit checks (when equal to "units") or to run as unitless (when equal to "unitless"). The unitless version is substantially faster for intensive computations. Returns ------- f : ~astropy.units.Quantity Probability density in speed^-1, normalized so that: :math:`\iiint_{0}^{\infty} f(\vec{v}) d\vec{v} = 1`. Raises ------ TypeError A parameter argument is not a `~astropy.units.Quantity` and cannot be converted into a `~astropy.units.Quantity`. ~astropy.units.UnitConversionError If the parameters is not in appropriate units. ValueError If the temperature is negative, or the particle mass or charge state cannot be found. Notes ----- In 3D, the Maxwellian speed distribution function describing the distribution of particles with speed :math:`v` in a plasma with temperature :math:`T` is given by: .. math:: f = 4 \pi \vec{v}^2 (\pi v_{Th}^2)^{-3/2} \exp(-(\vec{v} - \vec{V}_{drift})^2 / v_{Th}^2) where :math:`v_{Th} = \sqrt{2 k_B T / m}` is the thermal speed. See also -------- Maxwellian_speed_1D Example ------- >>> from plasmapy.physics import Maxwellian_speed_3D >>> from astropy import units as u >>> v=1 * u.m / u.s >>> Maxwellian_speed_3D(v=v, T=30000*u.K, particle='e', v_drift=0 * u.m / u.s) <Quantity 2.60235754e-18 s / m> """ if v_drift != 0: raise NotImplementedError("Non-zero drift speed is work in progress.") if units == "units": # unit checks and conversions # checking velocity units v = v.to(u.m / u.s) # Catching case where drift velocity has default value, and # needs to be assigned units v_drift = _v_drift_units(v_drift) # convert temperature to Kelvins T = T.to(u.K, equivalencies=u.temperature_energy()) if np.isnan(vTh): # get thermal velocity and thermal velocity squared vTh = (parameters.thermal_speed(T, particle=particle, method="most_probable")) elif not np.isnan(vTh): # check units of thermal velocity vTh = vTh.to(u.m / u.s) elif np.isnan(vTh) and units == "unitless": # assuming unitless temperature is in Kelvins vTh = (parameters.thermal_speed(T * u.K, particle=particle, method="most_probable")).si.value # getting square of thermal speed vThSq = vTh**2 # get square of relative particle speed vSq = (v - v_drift)**2 # calculating distribution function coeff1 = (np.pi * vThSq)**(-3 / 2) coeff2 = 4 * np.pi * vSq expTerm = np.exp(-vSq / vThSq) distFunc = coeff1 * coeff2 * expTerm if units == "units": return distFunc.to(u.s / u.m) elif units == "unitless": return distFunc
def Maxwellian_speed_1D(v, T, particle="e", v_drift=0, vTh=np.nan, units="units"): r""" Probability distribution function of speed for a Maxwellian distribution in 1D. Return the probability density function for finding a particle with speed `v` in m/s in an equilibrium plasma of temperature `T` which follows the Maxwellian distribution function. Parameters ---------- v: ~astropy.units.Quantity The speed in units convertible to m/s. T: ~astropy.units.Quantity The temperature, preferably in Kelvin. particle: str, optional Representation of the particle species(e.g., `'p'` for protons, `'D+'` for deuterium, or `'He-4 +1'` for :math:`He_4^{+1}` (singly ionized helium-4)), which defaults to electrons. v_drift: ~astropy.units.Quantity The drift speed in units convertible to m/s. vTh: ~astropy.units.Quantity, optional Thermal velocity (most probable) in m/s. This is used for optimization purposes to avoid re-calculating vTh, for example when integrating over velocity-space. units: str, optional Selects whether to run function with units and unit checks (when equal to "units") or to run as unitless (when equal to "unitless"). The unitless version is substantially faster for intensive computations. Returns ------- f : ~astropy.units.Quantity Probability density in speed^-1, normalized so that :math:`\int_{0}^{\infty} f(v) dv = 1`. Raises ------ TypeError The parameter arguments are not Quantities and cannot be converted into Quantities. ~astropy.units.UnitConversionError If the parameters is not in appropriate units. ValueError If the temperature is negative, or the particle mass or charge state cannot be found. Notes ----- In one dimension, the Maxwellian speed distribution function describing the distribution of particles with speed v in a plasma with temperature T is given by: .. math:: f(v) = 2 \frac{1}{(\pi v_{Th}^2)^{1/2}} \exp(-(v - V_{drift})^2 / v_{Th}^2 ) where :math:`v_{Th} = \sqrt{2 k_B T / m}` is the thermal speed. Example ------- >>> from plasmapy.physics import Maxwellian_speed_1D >>> from astropy import units as u >>> v=1 * u.m / u.s >>> Maxwellian_speed_1D(v=v, T=30000 * u.K, particle='e', v_drift=0 * u.m / u.s) <Quantity 1.18326594e-06 s / m> """ if units == "units": # unit checks and conversions # checking velocity units v = v.to(u.m / u.s) # Catching case where drift velocities have default values, they # need to be assigned units v_drift = _v_drift_units(v_drift) # convert temperature to Kelvins T = T.to(u.K, equivalencies=u.temperature_energy()) if np.isnan(vTh): # get thermal velocity and thermal velocity squared vTh = (parameters.thermal_speed(T, particle=particle, method="most_probable")) elif not np.isnan(vTh): # check units of thermal velocity vTh = vTh.to(u.m / u.s) elif np.isnan(vTh) and units == "unitless": # assuming unitless temperature is in Kelvins vTh = (parameters.thermal_speed(T * u.K, particle=particle, method="most_probable")).si.value # Get thermal velocity squared vThSq = vTh**2 # Get square of relative particle velocity vSq = (v - v_drift)**2 # calculating distribution function coeff = 2 * (vThSq * np.pi)**(-1 / 2) expTerm = np.exp(-vSq / vThSq) distFunc = coeff * expTerm if units == "units": return distFunc.to(u.s / u.m) elif units == "unitless": return distFunc
def Maxwellian_velocity_3D(vx, vy, vz, T, particle="e", vx_drift=0, vy_drift=0, vz_drift=0, vTh=np.nan, units="units"): r""" Probability distribution function of velocity for a Maxwellian distribution in 3D. Return the probability density function for finding a particle with velocity components `vx`, `vy`, and `vz` in m/s in an equilibrium plasma of temperature `T` which follows the 3D Maxwellian distribution function. This function assumes Cartesian coordinates. Parameters ---------- vx: ~astropy.units.Quantity The velocity in x-direction units convertible to m/s. vy: ~astropy.units.Quantity The velocity in y-direction units convertible to m/s. vz: ~astropy.units.Quantity The velocity in z-direction units convertible to m/s. T: ~astropy.units.Quantity The temperature, preferably in Kelvin. particle: str, optional Representation of the particle species (e.g., ``'p'`` for protons, ``'D+'`` for deuterium, or ``'He-4 +1'`` for :math:`He_4^{+1}` (singly ionized helium-4)), which defaults to electrons. vx_drift: ~astropy.units.Quantity, optional The drift velocity in x-direction units convertible to m/s. vy_drift: ~astropy.units.Quantity, optional The drift velocity in y-direction units convertible to m/s. vz_drift: ~astropy.units.Quantity, optional The drift velocity in z-direction units convertible to m/s. vTh: ~astropy.units.Quantity, optional Thermal velocity (most probable) in m/s. This is used for optimization purposes to avoid re-calculating `vTh`, for example when integrating over velocity-space. units: str, optional Selects whether to run function with units and unit checks (when equal to "units") or to run as unitless (when equal to "unitless"). The unitless version is substantially faster for intensive computations. Returns ------- f : ~astropy.units.Quantity Probability density in Velocity^-1, normalized so that :math:`\iiint_{0}^{\infty} f(\vec{v}) d\vec{v} = 1`. Raises ------ TypeError A parameter argument is not a `~astropy.units.Quantity` and cannot be converted into a `~astropy.units.Quantity`. ~astropy.units.UnitConversionError If the parameters is not in appropriate units. ValueError If the temperature is negative, or the particle mass or charge state cannot be found. Notes ----- In 3D, the Maxwellian speed distribution function describing the distribution of particles with speed :math:`v` in a plasma with temperature :math:`T` is given by: .. math:: f = (\pi v_{Th}^2)^{-3/2} \exp \left [-(\vec{v} - \vec{V}_{drift})^2 / v_{Th}^2 \right ] where :math:`v_{Th} = \sqrt{2 k_B T / m}` is the thermal speed. See also -------- Maxwellian_1D Example ------- >>> from plasmapy.physics import Maxwellian_velocity_3D >>> from astropy import units as u >>> v=1 * u.m / u.s >>> Maxwellian_velocity_3D(vx=v, ... vy=v, ... vz=v, ... T=30000 * u.K, ... particle='e', ... vx_drift=0 * u.m / u.s, ... vy_drift=0 * u.m / u.s, ... vz_drift=0 * u.m / u.s) <Quantity 2.07089033e-19 s3 / m3> """ if units == "units": # unit checks and conversions # checking velocity units vx = vx.to(u.m / u.s) vy = vy.to(u.m / u.s) vz = vz.to(u.m / u.s) # catching case where drift velocities have default values, they # need to be assigned units vx_drift = _v_drift_units(vx_drift) vy_drift = _v_drift_units(vy_drift) vz_drift = _v_drift_units(vz_drift) # convert temperature to Kelvins T = T.to(u.K, equivalencies=u.temperature_energy()) if np.isnan(vTh): # get thermal velocity and thermal velocity squared vTh = (parameters.thermal_speed(T, particle=particle, method="most_probable")) elif not np.isnan(vTh): # check units of thermal velocity vTh = vTh.to(u.m / u.s) elif np.isnan(vTh) and units == "unitless": # assuming unitless temperature is in Kelvins vTh = parameters.thermal_speed(T * u.K, particle=particle, method="most_probable").si.value # accounting for thermal velocity in 3D vThSq = vTh**2 # Get square of relative particle velocity vSq = ((vx - vx_drift)**2 + (vy - vy_drift)**2 + (vz - vz_drift)**2) # calculating distribution function coeff = (vThSq * np.pi)**(-3 / 2) expTerm = np.exp(-vSq / vThSq) distFunc = coeff * expTerm if units == "units": return distFunc.to((u.s / u.m)**3) elif units == "unitless": return distFunc
def Maxwellian_speed_3D(vx, vy, vz, T, particle="e", Vx_drift=0, Vy_drift=0, Vz_drift=0, vTh=np.nan, units="units"): r""" pdf of speed for a 3D Maxwellian distribution. Return the probability of finding a particle with speed components `vx`, `vy`, and `vz` in m/s in an equilibrium plasma of temperature `T` which follows the 3D Maxwellian distribution function. This function assumes Cartesian coordinates. Parameters ---------- vx: ~astropy.units.Quantity The speed in x-direction units convertible to m/s. vy: ~astropy.units.Quantity The speed in y-direction units convertible to m/s. vz: ~astropy.units.Quantity The speed in z-direction units convertible to m/s. T: ~astropy.units.Quantity The temperature, preferably in Kelvin. particle: str, optional Representation of the particle species(e.g., 'p' for protons, 'D+' for deuterium, or 'He-4 +1' for :math:`He_4^{+1}` (singly ionized helium-4)), which defaults to electrons. Vx_drift: ~astropy.units.Quantity The drift speed in x-direction units convertible to m/s. Vy_drift: ~astropy.units.Quantity The drift speed in y-direction units convertible to m/s. Vz_drift: ~astropy.units.Quantity The drift speed in z-direction units convertible to m/s. vTh: ~astropy.units.Quantity, optional Thermal velocity (most probable) in m/s. This is used for optimization purposes to avoid re-calculating vTh, for example when integrating over velocity-space. units: str, optional Selects whether to run function with units and unit checks (when equal to "units") or to run as unitless (when equal to "unitless"). The unitless version is substantially faster for intensive computations. Returns ------- f : ~astropy.units.Quantity Probability in speed^-1, normalized so that: :math:`\iiint_{0}^{\infty} f(\vec{v}) d\vec{v} = 1`. Raises ------ TypeError A parameter argument is not a `~astropy.units.Quantity` and cannot be converted into a `~astropy.units.Quantity`. ~astropy.units.UnitConversionError If the parameters is not in appropriate units. ValueError If the temperature is negative, or the particle mass or charge state cannot be found. Notes ----- In one dimension, the Maxwellian speed distribution function describing the distribution of particles with speed :math:`v` in a plasma with temperature :math:`T` is given by: .. math:: f = 4 \pi \vec{v}^2 (\pi v_{Th}^2)^{-3/2} \exp(-(\vec{v} - \vec{V}_{drift})^2 / v_{Th}^2) where :math:`v_{Th} = \sqrt{2 k_B T / m}` is the thermal speed. See also -------- Maxwellian_speed_1D Example ------- >>> from plasmapy.physics import Maxwellian_speed_3D >>> from astropy import units as u >>> v=1*u.m/u.s >>> Maxwellian_speed_3D(vx=v, ... vy=v, ... vz=v, ... T=30000*u.K, ... particle='e', ... Vx_drift=0*u.m/u.s, ... Vy_drift=0*u.m/u.s, ... Vz_drift=0*u.m/u.s) <Quantity 1.76238544e-53 s3 / m3> """ if units == "units": # unit checks and conversions # checking velocity units vx = vx.to(u.m / u.s) vy = vy.to(u.m / u.s) vz = vz.to(u.m / u.s) # Catching case where drift velocities have default values, they # need to be assigned units Vx_drift = _v_drift_units(Vx_drift) Vy_drift = _v_drift_units(Vy_drift) Vz_drift = _v_drift_units(Vz_drift) # convert temperature to Kelvins T = T.to(u.K, equivalencies=u.temperature_energy()) if np.isnan(vTh): # get thermal velocity and thermal velocity squared vTh = (parameters.thermal_speed(T, particle=particle, method="most_probable")) elif not np.isnan(vTh): # check units of thermal velocity vTh = vTh.to(u.m / u.s) elif np.isnan(vTh) and units == "unitless": # assuming unitless temperature is in Kelvins vTh = (parameters.thermal_speed(T * u.K, particle=particle, method="most_probable")).si.value # getting distribution functions along each axis fx = Maxwellian_speed_1D(vx, T, particle=particle, V_drift=Vx_drift, vTh=vTh, units=units) fy = Maxwellian_speed_1D(vy, T, particle=particle, V_drift=Vy_drift, vTh=vTh, units=units) fz = Maxwellian_speed_1D(vz, T, particle=particle, V_drift=Vz_drift, vTh=vTh, units=units) # multiplying probabilities in each axis to get 3D probability distFunc = fx * fy * fz if units == "units": return distFunc.to((u.s / u.m)**3) elif units == "unitless": return distFunc
def Maxwellian_1D(v, T, particle="e", V_drift=0, vTh=np.nan, units="units"): r""" Returns the probability at the velocity `v` in m/s to find a particle `particle` in a plasma of temperature `T` following the Maxwellian distribution function. Parameters ---------- v: ~astropy.units.Quantity The velocity in units convertible to m/s. T: ~astropy.units.Quantity The temperature in Kelvin. particle: str, optional Representation of the particle species(e.g., `'p'` for protons, `'D+'` for deuterium, or `'He-4 +1'` for :math:`He_4^{+1}` (singly ionized helium-4), which defaults to electrons. V_drift: ~astropy.units.Quantity, optional The drift velocity in units convertible to m/s. vTh: ~astropy.units.Quantity, optional Thermal velocity (most probable) in m/s. This is used for optimization purposes to avoid re-calculating vTh, for example when integrating over velocity-space. units: str, optional Selects whether to run function with units and unit checks (when equal to "units") or to run as unitless (when equal to "unitless"). The unitless version is substantially faster for intensive computations. Returns ------- f : ~astropy.units.Quantity Probability in Velocity^-1, normalized so that :math:`\int_{-\infty}^{+\infty} f(v) dv = 1`. Raises ------ TypeError The parameter arguments are not Quantities and cannot be converted into Quantities. ~astropy.units.UnitConversionError If the parameters are not in appropriate units. ValueError If the temperature is negative, or the particle mass or charge state cannot be found. Notes ----- In one dimension, the Maxwellian distribution function for a particle of mass m, velocity v, a drift velocity V and with temperature T is: .. math:: f = \sqrt{\frac{m}{2 \pi k_B T}} e^{-\frac{m}{2 k_B T} (v-V)^2} f = (\pi * v_Th^2)^{-1/2} e^{-(v - v_{drift})^2 / v_Th^2} where :math:`v_Th = \sqrt(2 k_B T / m)` is the thermal speed Examples -------- >>> from plasmapy.physics import Maxwellian_1D >>> from astropy import units as u >>> v=1*u.m/u.s >>> Maxwellian_1D(v=v, T= 30000*u.K, particle='e',V_drift=0*u.m/u.s) <Quantity 5.91632969e-07 s / m> """ if units == "units": # unit checks and conversions # checking velocity units v = v.to(u.m / u.s) # catching case where drift velocities have default values, they # need to be assigned units if V_drift == 0: if not isinstance(V_drift, astropy.units.quantity.Quantity): V_drift = V_drift * u.m / u.s # checking units of drift velocities V_drift = V_drift.to(u.m / u.s) # convert temperature to Kelvins T = T.to(u.K, equivalencies=u.temperature_energy()) if np.isnan(vTh): # get thermal velocity and thermal velocity squared vTh = (parameters.thermal_speed(T, particle=particle, method="most_probable")) elif not np.isnan(vTh): # check units of thermal velocity vTh = vTh.to(u.m / u.s) elif np.isnan(vTh) and units == "unitless": # assuming unitless temperature is in Kelvins vTh = (parameters.thermal_speed(T * u.K, particle=particle, method="most_probable")).si.value # Get thermal velocity squared vThSq = vTh**2 # Get square of relative particle velocity vSq = (v - V_drift)**2 # calculating distribution function coeff = (vThSq * np.pi)**(-1 / 2) expTerm = np.exp(-vSq / vThSq) distFunc = coeff * expTerm if units == "units": return distFunc.to(u.s / u.m) elif units == "unitless": return distFunc
def Fermi_velocity_1D(m, T, particle="e", vTh=np.nan, units="units", E_F=0): r""" Returns the Fermi-Dirac velocity distribution of a particle of mass m, at temperature T with thermal velocity vTh and Fermi Energy E_F Parameters ---------- m: ~astropy.units.Quantity The mass of the particle convertible to kg. T: ~astropy.units.Quantity The temperature in Kelvin. particle: str, optional Representation of the particle species(e.g., ``'p'`` for protons, ``'D+'`` for deuterium, or ``'He-4 +1'`` for :math:`He_4^{+1}` (singly ionized helium-4)), which defaults to electrons. vTh: ~astropy.units.Quantity, optional Thermal velocity (most probable velocity) in m/s. This is used for optimization purposes to avoid re-calculating vTh, for example when integrating over velocity-space. E_F: ~astropy.units.Quantity The Fermi energy of the particle in units convertible to J. units: str, optional Selects whether to run function with units and unit checks (when equal to "units") or to run as unitless (when equal to "unitless"). The unitless version is substantially faster for intensive computations. Returns ------- f : ~astropy.units.Quantity Probability density in units of Velocity^-1, normalized so that :math:`\int_{-\infty}^{+\infty} f(v) dv = 1`. Raises ------ TypeError The parameter arguments are not Quantities and cannot be converted into Quantities. ~astropy.units.UnitConversionError If the parameters are not in appropriate units. ValueError If the temperature is negative, or the particle mass or charge state cannot be found. Notes ----- Examples -------- """ if units == "units": # unit checks and conversions # checking velocity units v = v.to(u.m / u.s) # Catching case where drift velocities have default values, they # need to be assigned units v_drift = _v_drift_units(v_drift) # convert temperature to Kelvins T = T.to(u.K, equivalencies=u.temperature_energy()) if np.isnan(vTh): # get thermal velocity and thermal velocity squared vTh = (parameters.thermal_speed(T, particle=particle, method="most_probable")) elif not np.isnan(vTh): # check units of thermal velocity vTh = vTh.to(u.m / u.s) elif np.isnan(vTh) and units == "unitless": # assuming unitless temperature is in Kelvins vTh = (parameters.thermal_speed(T * u.K, particle=particle, method="most_probable")).si.value distFunc = (m * vTh / pi / hbar) ** 3 / (1 + np.exp((m * vTh ** 2 / 2 - E_F) / k / T)) return distFunc