Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
>>> from astropy import units as u
>>> thermal_speed(5*u.eV, 'p')
>>> thermal_speed(1e6*u.K, particle='p')
>>> thermal_speed(5*u.eV, particle='e-')
>>> thermal_speed(1e6*u.K, particle='e-')
>>> thermal_speed(1e6*u.K, method="rms")
>>> thermal_speed(1e6*u.K, method="mean_magnitude")
"""
m = mass if np.isfinite(mass) else particles.particle_mass(particle)
# different methods, as per https://en.wikipedia.org/wiki/Thermal_velocity
try:
coef = _coefficients[ndim]
except KeyError:
raise ValueError("{ndim} is not a supported value for ndim in " "thermal_speed")
try:
coef = coef[method]
except KeyError:
raise ValueError("Method {method} not supported in thermal_speed")
return np.sqrt(coef * k_B * T / m)
References
----------
.. [1] Dense plasma temperature equilibration in the binary collision
approximation. D. O. Gericke et. al. PRE, 65, 036418 (2002).
DOI: 10.1103/PhysRevE.65.036418
.. [2] Bonitz, Michael. Quantum kinetic theory. Stuttgart: Teubner, 1998.
"""
# boiler plate checks
T, masses, charges, reduced_mass, V = _boilerPlate(T=T, species=species, V=V)
if np.isnan(z_mean):
# using mean charge to get average ion density.
# If you are running this, you should strongly consider giving
# a value of z_mean as an argument instead.
Z1 = np.abs(particles.integer_charge(species[0]))
Z2 = np.abs(particles.integer_charge(species[1]))
Z = (Z1 + Z2) / 2
# getting ion density from electron density
n_i = n_e / Z
# getting Wigner-Seitz radius based on ion density
radius = Wigner_Seitz_radius(n_i)
else:
# getting ion density from electron density
n_i = n_e / z_mean
# getting Wigner-Seitz radius based on ion density
radius = Wigner_Seitz_radius(n_i)
# Coulomb potential energy between particles
if np.isnan(z_mean):
coulombEnergy = charges[0] * charges[1] / (4 * np.pi * eps0 * radius)
else:
coulombEnergy = (z_mean * e) ** 2 / (4 * np.pi * eps0 * radius)
z_mean : float
An optional float describing the average ionization of a particle
species.
Returns
-------
float
if `z_mean` was passed, `z_mean`, otherwise, the integer charge
of the `ion`.
"""
if z_mean is None:
# warnings.warn("No z_mean given, defaulting to atomic charge",
# PhysicsWarning)
Z = particles.integer_charge(ion)
else:
# using average ionization provided by user
Z = z_mean
return Z
>>> plasma_frequency(1e19*u.m**-3, particle='D+')
>>> plasma_frequency(1e19*u.m**-3)
>>> plasma_frequency(1e19*u.m**-3, to_hz=True)
"""
try:
m = particles.particle_mass(particle)
if z_mean is None:
# warnings.warn("No z_mean given, defaulting to atomic charge",
# PhysicsWarning)
try:
Z = particles.integer_charge(particle)
except Exception:
Z = 1
else:
# using user provided average ionization
Z = z_mean
Z = np.abs(Z)
# TODO REPLACE WITH Z = np.abs(_grab_charge(particle, z_mean)), some bugs atm
except Exception:
raise ValueError(f"Invalid particle, {particle}, in plasma_frequency.")
omega_p = u.rad * Z * e * np.sqrt(n / (eps0 * m))
return omega_p.si
@particles.particle_input
def Coulomb_logarithm(
T: u.K,
n_e: u.m ** -3,
species: (particles.Particle, particles.Particle),
z_mean: u.dimensionless_unscaled = np.nan * u.dimensionless_unscaled,
V: u.m / u.s = np.nan * u.m / u.s,
method="classical",
):
r"""
Estimates the Coulomb logarithm.
Parameters
----------
T : ~astropy.units.Quantity
Temperature in units of temperature or energy per particle,
is_valid_field = self.field_orientation in valid_fields
if not is_valid_field:
raise ValueError(
f"Unknown field orientation " f"'{self.field_orientation}'"
)
# values and units have already been checked by decorator
self.T_e = T_e
self.T_i = T_i
self.n_e = n_e
self.n_i = n_i
# get ion mass and charge state
if m_i is None:
try:
self.m_i = particles.particle_mass(ion)
except Exception:
raise ValueError(
f"Unable to find mass of particle: " f"{ion} in ClassicalTransport"
)
else:
self.m_i = m_i
self.Z = _grab_charge(ion, Z)
if self.Z < 0:
raise ValueError("Z is not allowed to be negative!") # TODO remove?
# decide on the particle string for the electrons
self.e_particle = "e"
self.ion = ion
# save other arguments
self.B = B
@particles.particle_input
def _boilerPlate(T: u.K, species: (particles.Particle, particles.Particle), V):
"""
Some boiler plate code for checking if inputs to functions in
collisions.py are good. Also obtains reduced in mass in a
2 particle collision system along with thermal velocity.
"""
masses = [p.mass for p in species]
charges = [np.abs(p.charge) for p in species]
# obtaining reduced mass of 2 particle collision system
reduced_mass = particles.reduced_mass(*species)
# getting thermal velocity of system if no velocity is given
V = _replaceNanVwithThermalV(V, T, reduced_mass)
_check_relativistic(V, "V")
:math:`\omega_{pi}` is the ion plasma frequency.
Example
-------
>>> from astropy import units as u
>>> lower_hybrid_frequency(0.2*u.T, n_i=5e19*u.m**-3, ion='D+')
>>> lower_hybrid_frequency(0.2*u.T, n_i=5e19*u.m**-3, ion='D+', to_hz = True)
"""
# We do not need a charge state here, so the sole intent is to
# catch invalid ions.
try:
particles.integer_charge(ion)
except Exception:
raise ValueError("Invalid ion in lower_hybrid_frequency.")
omega_ci = gyrofrequency(B, particle=ion)
omega_pi = plasma_frequency(n_i, particle=ion)
omega_ce = gyrofrequency(B)
omega_lh = ((omega_ci * omega_ce) ** -1 + omega_pi ** -2) ** -0.5
# TODO possibly optimize the above line via np.sqrt
omega_lh = omega_lh
return omega_lh
@particles.particle_input
def thermal_speed(
T: u.K,
particle: particles.Particle = "e-",
method="most_probable",
mass: u.kg = np.nan * u.kg,
ndim=3,
) -> u.m / u.s:
r"""
Return the most probable speed for a particle within a Maxwellian
distribution.
**Aliases:** `vth_`
Parameters
----------
T : ~astropy.units.Quantity