Beispiel #1
0
class Test_impact_parameter_perp:
    @classmethod
    def setup_class(self):
        """initializing parameters for tests """
        self.T = 11604 * u.K
        self.particles = ('e', 'p')
        self.V = 1e4 * u.km / u.s
        self.True1 = 7.200146594293746e-10

    def test_symmetry(self):
        result = impact_parameter_perp(self.T, self.particles)
        resultRev = impact_parameter_perp(self.T, self.particles[::-1])
        assert result == resultRev

    def test_known1(self):
        """
        Test for known value.
        """
        methodVal = impact_parameter_perp(self.T,
                                          self.particles,
                                          V=np.nan * u.m / u.s)
        testTrue = np.isclose(self.True1,
                              methodVal.si.value,
                              rtol=1e-1,
                              atol=0.0)
        errStr = (
            "Distance of closest approach for 90 degree Coulomb "
            f"collision, impact_parameter_perp, should be {self.True1} and "
            f"not {methodVal}.")
        assert testTrue, errStr

    def test_fail1(self):
        """
        Tests if test_known1() would fail if we slightly adjusted the
        value comparison by some quantity close to numerical error.
        """
        fail1 = self.True1 + 1e-15
        methodVal = impact_parameter_perp(self.T,
                                          self.particles,
                                          V=np.nan * u.m / u.s)
        testTrue = not np.isclose(
            methodVal.si.value, fail1, rtol=1e-16, atol=0.0)
        errStr = (f"impact_parameter_perp value test gives {methodVal} and "
                  f"should not be equal to {fail1}.")
        assert testTrue, errStr

    assert np.isclose(
        Coulomb_logarithm(1 * u.eV, 5 * u.m**-3, ('e', 'e')),
        Coulomb_logarithm(11604.5220 * u.K, 5 * u.m**-3, ('e', 'e')))
Beispiel #2
0
 def test_invalid_particle_error(self):
     """
     Tests whether an error is raised when an invalid particle name
     is given.
     """
     with pytest.raises(exceptions.InvalidParticleError):
         Coulomb_logarithm(1 * u.K, 5 * u.m**-3, ('e', 'g'))
Beispiel #3
0
def collision_rate_ion_ion(T_i, n_i, ion_particle,
                           coulomb_log=None, V=None):
    r"""
    momentum relaxation ion-ion collision rate

    From [3]_, equations (2.36) and (2.122)

    Considering a Maxwellian distribution of "test" ions colliding with
    a Maxwellian distribution of "field" ions.

    Note, it is assumed that electrons are present in such numbers as to
    establish quasineutrality, but the effects of the test ions colliding
    with them are not considered here.

    This result is an ion momentum relaxation rate, and is used in many
    classical transport expressions. It is equivalent to:
    * 1/tau_i from ref [1]_ eqn (1) pp. #,
    * 1/tau_i from ref [2]_ eqn (1) pp. #,
    * nu_i\i_S from ref [2]_ eqn (1) pp. #,

    Parameters
    ----------

    T_i : ~astropy.units.Quantity
        The electron temperature of the Maxwellian test ions

    n_i : ~astropy.units.Quantity
        The number density of the Maxwellian test ions

    ion_particle: string
        String signifying a particle type of the test and field ions,
        including charge state information. This function assumes the test
        and field ions are the same species.

    coulomb_log : float or dimensionless ~astropy.units.Quantity, optional
        option to specify a Coulomb logarithm of the electrons on the ions.
        If not specified, the Coulomb log will is calculated using the
        .transport/Coulomb_logarithm function.

    References
    ----------
    .. [1] Braginskii

    .. [2] Formulary

    .. [3] Callen Chapter 2, http://homepages.cae.wisc.edu/~callen/chap2.pdf

    """
    from plasmapy.physics.transport import Coulomb_logarithm
    T_i = T_i.to(units.K, equivalencies=units.temperature_energy())
    if coulomb_log is not None:
        coulomb_log_val = coulomb_log
    else:
        particles = [ion_particle, ion_particle]
        coulomb_log_val = Coulomb_logarithm(T_i, n_i, particles, V)
    Z_i = atomic.integer_charge(ion_particle)
    m_i = atomic.ion_mass(ion_particle)
    nu_i = 4 / 3 * np.sqrt(np.pi / m_i) / (4 * np.pi * eps0)**2 * e**4 * \
        n_i * Z_i**4 * coulomb_log_val / (k_B * T_i)**1.5
    return nu_i.to(1 / units.s)
Beispiel #4
0
 def test_unit_conversion_error(self):
     """
     Tests whether unit conversion error is raised when arguments
     are given with incorrect units.
     """
     with pytest.raises(u.UnitConversionError):
         Coulomb_logarithm(1e5 * u.g, 1 * u.m ** -3,
                           ('e', 'p'), V=29979245 * u.m / u.s)
Beispiel #5
0
def collision_rate_electron_ion(T_e,
                                n_e,
                                ion_particle,
                                coulomb_log=None,
                                V=None):
    r"""
    Momentum relaxation electron-ion collision rate

    From [3]_, equations (2.17) and (2.120)

    Considering a Maxwellian distribution of "test" electrons colliding with
    a Maxwellian distribution of "field" ions.

    This result is an electron momentum relaxation rate, and is used in many
    classical transport expressions. It is equivalent to:
    * 1/tau_e from ref [1]_ eqn (1) pp. #,
    * 1/tau_e from ref [2]_ eqn (1) pp. #,
    * nu_e\i_S from ref [2]_ eqn (1) pp. #,

    Parameters
    ----------

    T_e : ~astropy.units.Quantity
        The electron temperature of the Maxwellian test electrons

    n_e : ~astropy.units.Quantity
        The number density of the Maxwellian test electrons

    ion_particle: str
        String signifying a particle type of the field ions, including charge
        state information.

    coulomb_log : float or dimensionless ~astropy.units.Quantity, optional
        Option to specify a Coulomb logarithm of the electrons on the ions.
        If not specified, the Coulomb log will is calculated using the
        `~plasmapy.physics.transport.Coulomb_logarithm` function.

    References
    ----------
    .. [1] Braginskii

    .. [2] Formulary

    .. [3] Callen Chapter 2, http://homepages.cae.wisc.edu/~callen/chap2.pdf

    """
    from plasmapy.physics.transport import Coulomb_logarithm
    T_e = T_e.to(u.K, equivalencies=u.temperature_energy())
    if coulomb_log is not None:
        coulomb_log_val = coulomb_log
    else:
        particles = ['e', ion_particle]
        coulomb_log_val = Coulomb_logarithm(T_e, n_e, particles, V)
    Z_i = atomic.integer_charge(ion_particle)
    nu_e = 4 / 3 * np.sqrt(2 * np.pi / m_e) / (4 * np.pi * eps0) ** 2 * \
        e ** 4 * n_e * Z_i * coulomb_log_val / (k_B * T_e) ** 1.5
    return nu_e.to(1 / u.s)
Beispiel #6
0
 def test_GMS6_zmean_error(self):
     """
     Tests whether GMS-6 raises z_mean error when a z_mean is not
     provided.
     """
     with pytest.raises(ValueError):
         methodVal = Coulomb_logarithm(self.temperature2,
                                       self.density2,
                                       self.particles,
                                       method="GMS-6")
Beispiel #7
0
 def test_GMS2_negative(self):
     """
     Test for second version of Coulomb logarithm from Gericke,
     Murillo, and Schlanges PRE (2002). This checks for when
     a negative (invalid) Coulomb logarithm is returned.
     """
     with pytest.raises(exceptions.PhysicsError, match="< 0"):
         methodVal = Coulomb_logarithm(self.temperature2,
                                       self.density2,
                                       self.particles,
                                       z_mean=self.z_mean,
                                       V=np.nan * u.m / u.s,
                                       method="GMS-2")
Beispiel #8
0
 def test_GMS1_negative(self):
     """
     Test for first version of Coulomb logarithm from Gericke,
     Murillo, and Schlanges PRE (2002). This checks for when
     a negative (invalid) Coulomb logarithm is returned.
     """
     with pytest.warns(exceptions.CouplingWarning,
                       match="relies on weak coupling"):
         Coulomb_logarithm(self.temperature2,
                           self.density2,
                           self.particles,
                           z_mean=np.nan * u.dimensionless_unscaled,
                           V=np.nan * u.m / u.s,
                           method="GMS-1")
Beispiel #9
0
 def test_GMS6(self):
     """
     Test for sixth version of Coulomb logarithm from Gericke,
     Murillo, and Schlanges PRE (2002).
     """
     with pytest.warns(exceptions.PhysicsWarning,
                       match="strong coupling effects"):
         methodVal = Coulomb_logarithm(self.temperature1,
                                       self.density1,
                                       self.particles,
                                       z_mean=self.z_mean,
                                       V=np.nan * u.m / u.s,
                                       method="GMS-6")
     testTrue = np.isclose(methodVal, self.gms6, rtol=1e-15, atol=0.0)
     errStr = (f"Coulomb logarithm for GMS-6 should be "
               f"{self.gms6} and not {methodVal}.")
     assert testTrue, errStr
Beispiel #10
0
 def test_Chen_torus(self):
     """
     Tests whether Coulomb logarithm gives value consistent with
     Chen's Introduction to Plasma Physics and Controlled Fusion
     section 5.6.2 torus example.
     """
     T = 100 * u.eV
     T = T.to(u.K, equivalencies=u.temperature_energy())
     n = 1e19 * u.m**-3
     # factor of np.log(2) corrects for different definitions of thermal
     # velocity. Chen uses v**2 = k * T / m  whereas we use
     # v ** 2 = 2 * k * T / m
     lnLambdaChen = 13.7 + np.log(2)
     lnLambda = Coulomb_logarithm(T, n, ('e', 'p'))
     testTrue = np.isclose(lnLambda, lnLambdaChen, rtol=1e-1, atol=0.0)
     errStr = ("Torus value of Coulomb logarithm should be "
               f"{lnLambdaChen} and not {lnLambda}.")
     assert testTrue, errStr
Beispiel #11
0
 def test_GMS2_negative(self):
     """
     Test for second version of Coulomb logarithm from Gericke,
     Murillo, and Schlanges PRE (2002). This checks for when
     a negative (invalid) Coulomb logarithm is returned.
     """
     with pytest.warns(exceptions.PhysicsWarning, match="strong coupling effects"):
         methodVal = Coulomb_logarithm(self.temperature2,
                                       self.density2,
                                       self.particles,
                                       z_mean=self.z_mean,
                                       V=np.nan * u.m / u.s,
                                       method="GMS-2")
     testTrue = np.isclose(methodVal,
                           self.gms2_negative,
                           rtol=1e-15,
                           atol=0.0)
     errStr = (f"Coulomb logarithm for GMS-2 should be "
               f"{self.gms2_negative} and not {methodVal}.")
     assert testTrue, errStr
Beispiel #12
0
 def test_GMS5_negative(self):
     """
     Test for fifth version of Coulomb logarithm from Gericke,
     Murillo, and Schlanges PRE (2002). This checks whether
     a positive value is returned whereas the classical Coulomb
     logarithm would return a negative value.
     """
     with pytest.warns(exceptions.PhysicsWarning, match="strong coupling effects"):
         methodVal = Coulomb_logarithm(self.temperature2,
                                       self.density2,
                                       self.particles,
                                       z_mean=self.z_mean,
                                       V=np.nan * u.m / u.s,
                                       method="GMS-5")
     testTrue = np.isclose(methodVal,
                           self.gms5_negative,
                           rtol=1e-15,
                           atol=0.0)
     errStr = (f"Coulomb logarithm for GMS-5 should be "
               f"{self.gms5_negative} and not {methodVal}.")
     assert testTrue, errStr
Beispiel #13
0
 def test_single_particle_error(self):
     """
     Tests whether an error is raised if only a single particle is given.
     """
     with pytest.raises(ValueError):
         Coulomb_logarithm(1 * u.K, 5 * u.m**-3, 'e')
Beispiel #14
0
 def test_relativity_error(self):
     """Tests whether relativity error is raised at light speed."""
     with pytest.raises(exceptions.RelativityError):
         Coulomb_logarithm(1e5 * u.K, 1 * u.m**-3, ('e', 'p'), V=1.1 * c)
Beispiel #15
0
 def test_relativity_warn(self):
     """Tests whether relativity warning is raised at high velocity."""
     with pytest.warns(exceptions.RelativityWarning):
         Coulomb_logarithm(1e5 * u.K, 1 * u.m**-3, ('e', 'p'), V=0.9 * c)
Beispiel #16
0
 def test_symmetry(self):
     lnLambda = Coulomb_logarithm(self.temperature1, self.density2,
                                  self.particles)
     lnLambdaRev = Coulomb_logarithm(self.temperature1, self.density2,
                                     self.particles[::-1])
     assert lnLambda == lnLambdaRev