def time_Debye_length(self): Debye_length(5e6*u.K, 5e15*u.m**-3)
def test_Debye_length(): r"""Test the Debye_length function in parameters.py.""" assert Debye_length(T_e, n_e).unit.is_equivalent(u.m) assert np.isclose(Debye_length(1 * u.eV, 1 * u.cm**-3).value, 7.43, atol=0.005) with pytest.warns(u.UnitsWarning): Debye_length(5, 5 * u.m**-3) with pytest.raises(u.UnitConversionError): Debye_length(56 * u.kg, 5 * u.m**-3) with pytest.raises(ValueError): Debye_length(5 * u.eV, -5 * u.m**-3) with pytest.raises(ValueError): Debye_length(-45 * u.K, 5 * u.m**-3) Tarr2 = np.array([1, 2]) * u.K narr3 = np.array([1, 2, 3]) * u.m**-3 with pytest.raises(ValueError): Debye_length(Tarr2, narr3) with pytest.warns(u.UnitsWarning): assert Debye_length(2.0, 2.0) == Debye_length(2.0 * u.K, 2.0 * u.m**-3) with pytest.warns(u.UnitsWarning): assert Debye_length(2.0 * u.K, 2.0) == Debye_length(2.0, 2.0 * u.m**-3) assert_can_handle_nparray(Debye_length)
def impact_parameter(T, n_e, particles, z_mean=np.nan * u.dimensionless_unscaled, V=np.nan * u.m / u.s, method="classical"): r"""Impact parameters for classical and quantum Coulomb collision Parameters ---------- T : ~astropy.units.Quantity Temperature in units of temperature or energy per particle, which is assumed to be equal for both the test particle and the target particle n_e : ~astropy.units.Quantity The electron density in units convertible to per cubic meter. particles : tuple A tuple containing string representations of the test particle (listed first) and the target particle (listed second) z_mean : ~astropy.units.Quantity, optional The average ionization (arithmetic mean) for a plasma where the a macroscopic description is valid. This is used to recover the average ion density (given the average ionization and electron density) for calculating the ion sphere radius for non-classical impact parameters. V : ~astropy.units.Quantity, optional The relative velocity between particles. If not provided, thermal velocity is assumed: :math:`\mu V^2 \sim 2 k_B T` where `mu` is the reduced mass. method: str, optional Selects which theory to use when calculating the Coulomb logarithm. Defaults to classical method. Returns ------- bmin, bmax : tuple of floats The minimum and maximum impact parameters (distances) for a Coulomb collision. Raises ------ ValueError If the mass or charge of either particle cannot be found, or any of the inputs contain incorrect values. UnitConversionError If the units on any of the inputs are incorrect TypeError If the n_e, T, or V are not Quantities. Warns ----- ~astropy.units.UnitsWarning If units are not provided, SI units are assumed ~plasmapy.utils.RelativityWarning If the input velocity is greater than 5% of the speed of light. Notes ----- The minimum and maximum impact parameters may be calculated in a variety of ways. The maximum impact parameter is typically the Debye length. For quantum plasmas the maximum impact parameter can be the quadratic sum of the debye length and ion radius (Wigner_Seitz) [1]_ .. math:: b_{max} = \left(\lambda_{De}^2 + a_i^2\right)^{1/2} The minimum impact parameter is typically some combination of the thermal deBroglie wavelength and the distance of closest approach for a 90 degree Coulomb collision. A quadratic sum is used for all GMS methods, except for GMS-5, where b_min is simply set to the distance of closest approach [1]_. .. math:: b_{min} = \left(\Lambda_{deBroglie}^2 + \rho_{\perp}^2\right)^{1/2} Examples -------- >>> from astropy import units as u >>> n = 1e19*u.m**-3 >>> T = 1e6*u.K >>> particles = ('e', 'p') >>> impact_parameter(T, n, particles) (<Quantity 1.05163088e-11 m>, <Quantity 2.18225522e-05 m>) >>> impact_parameter(T, n, particles, V=1e6*u.m/u.s) (<Quantity 2.53401778e-10 m>, <Quantity 2.18225522e-05 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 """ # boiler plate checks T, masses, charges, reduced_mass, V = _boilerPlate(T=T, particles=particles, V=V) # catching error where mean charge state is not given for non-classical # methods that require the ion density if method == "GMS-2" or method == "GMS-5" or method == "GMS-6": if np.isnan(z_mean): raise ValueError("Must provide a z_mean for GMS-2, GMS-5, and " "GMS-6 methods.") # Debye length lambdaDe = Debye_length(T, n_e) # deBroglie wavelength lambdaBroglie = hbar / (2 * reduced_mass * V) # distance of closest approach in 90 degree Coulomb collision bPerp = b_perp(T=T, particles=particles, V=V) # obtaining minimum and maximum impact parameters depending on which # method is requested if method == "classical": bmax = lambdaDe # Coulomb-style collisions will not happen for impact parameters # shorter than either of these two impact parameters, so we choose # the larger of these two possibilities. That is, between the # deBroglie wavelength and the distance of closest approach. if bPerp > lambdaBroglie: bmin = bPerp else: bmin = lambdaBroglie elif method == "GMS-1": # 1st method listed in Table 1 of reference [1] # This is just another form of the classical Landau-Spitzer # approach, but bmin is interpolated between the deBroglie # wavelength and distance of closest approach. bmax = lambdaDe bmin = (lambdaBroglie ** 2 + bPerp ** 2) ** (1 / 2) elif method == "GMS-2": # 2nd method listed in Table 1 of reference [1] # Another Landau-Spitzer like approach, but now bmax is also # being interpolated. The interpolation is between the Debye # length and the ion sphere radius, allowing for descriptions # of dilute plasmas. # Mean ion density. n_i = n_e / z_mean # mean ion sphere radius. ionRadius = Wigner_Seitz_radius(n_i) bmax = (lambdaDe ** 2 + ionRadius ** 2) ** (1 / 2) bmin = (lambdaBroglie ** 2 + bPerp ** 2) ** (1 / 2) elif method == "GMS-3": # 3rd method listed in Table 1 of reference [1] # same as GMS-1, but not Lambda has a clamp at Lambda_min = 2 # where Lambda is the argument to the Coulomb logarithm. bmax = lambdaDe bmin = (lambdaBroglie ** 2 + bPerp ** 2) ** (1 / 2) elif method == "GMS-4": # 4th method listed in Table 1 of reference [1] bmax = lambdaDe bmin = (lambdaBroglie ** 2 + bPerp ** 2) ** (1 / 2) elif method == "GMS-5": # 5th method listed in Table 1 of reference [1] # Mean ion density. n_i = n_e / z_mean # mean ion sphere radius. ionRadius = Wigner_Seitz_radius(n_i) bmax = (lambdaDe ** 2 + ionRadius ** 2) ** (1 / 2) bmin = bPerp elif method == "GMS-6": # 6th method listed in Table 1 of reference [1] # Mean ion density. n_i = n_e / z_mean # mean ion sphere radius. ionRadius = Wigner_Seitz_radius(n_i) bmax = (lambdaDe ** 2 + ionRadius ** 2) ** (1 / 2) bmin = (lambdaBroglie ** 2 + bPerp ** 2) ** (1 / 2) else: raise ValueError(f"Method {method} not found!") return bmin.to(u.m), bmax.to(u.m)