Beispiel #1
0
def test_particle_exb_drift():
    r"""
        Tests the particle stepper for a field with magnetic field in the Z
        direction, electric field in the y direction. This should produce a
        drift in the negative X direction, with the drift velocity

        v_e = ExB / B^2

        which is independent of ion charge.
    """
    test_plasma = uniform_magnetic_field()
    test_plasma.electric_field[1] = 1 * u.V / u.m
    expected_drift_velocity = -(test_plasma.electric_field_strength /
                                test_plasma.magnetic_field_strength).mean() \
        .to(u.m / u.s)

    s = Species(test_plasma, 'p', 5, dt=1e-10 * u.s, nt=int(5e3))
    s.v[:, 2] += np.random.normal(size=s.N) * u.m / u.s

    s.run()

    p_init = models.Polynomial1D(degree=1)
    for x in s.position_history[:, :, 0].T:
        fit_p = fitting.LinearLSQFitter()
        p = fit_p(p_init, s.t, x)
        fit_velocity = p.parameters[1] * u.m / u.s

        assert np.allclose(x, p(s.t), atol=1e-3 * u.m), \
            "x position doesn't follow linear fit!"

        assert np.isclose(expected_drift_velocity, fit_velocity,
                          atol=1e-3 * u.m / u.s), \
            "x velocity doesn't agree with expected drift velocity!"

    s.test_kinetic_energy()
Beispiel #2
0
def test_basic_species_functionality():
    plasma = uniform_magnetic_field()

    s = Species(plasma=plasma, dt=1e-3 * u.s, nt=1)
    assert np.isclose(s.kinetic_energy, 0 * u.J, atol=1e-4 * u.J)

    # this should crash as neither `dt` nor `NT` are not provided
    with pytest.raises(ValueError):
        Species(plasma=plasma)
Beispiel #3
0
def test_particle_uniform_magnetic():
    """
        Tests the particle stepper for a uniform magnetic field motion.
    """
    test_plasma = uniform_magnetic_field()

    particle_type = 'N-14++'
    s = Species(test_plasma,
                particle_type=particle_type,
                dt=1e-2 * u.s,
                nt=int(1e4))

    perp_speed = 0.01 * u.m / u.s
    parallel_speed = 1e-5 * u.m / u.s
    mean_B = test_plasma.magnetic_field_strength.mean()
    expected_gyrofrequency = (s.q * mean_B / s.m).to(1 / u.s)
    expected_gyroradius = perp_speed / expected_gyrofrequency
    expected_gyroperiod = 2 * np.pi / expected_gyrofrequency

    dt = expected_gyroperiod / 100

    s = Species(test_plasma, particle_type=particle_type, dt=dt, nt=int(1e4))
    s.v[:, 1] = perp_speed

    s.v[:, 2] = parallel_speed
    s.run()

    x = s.position_history[:, 0, 0]
    z = s.position_history[:, 0, 2]

    try:
        params, stds = fit_sine_curve(x, s.t, expected_gyrofrequency)
    except RuntimeError as e:
        print(s)
        raise e
    estimated_gyroradius = np.abs(params[0]) * u.m
    estimated_gyroradius_std = np.abs(stds[0]) * u.m
    estimated_gyrofrequency = np.abs(params[1]) / u.s
    estimated_gyrofrequency_std = np.abs(stds[1]) / u.s

    assert np.isclose(expected_gyroradius, estimated_gyroradius,
                      atol=estimated_gyroradius_std), \
        "Gyroradii don't match!"

    assert np.isclose(expected_gyrofrequency, estimated_gyrofrequency,
                      atol=estimated_gyrofrequency_std), \
        "Gyrofrequencies don't match!"

    p_init = models.Polynomial1D(degree=1)
    fit_p = fitting.LinearLSQFitter()
    p = fit_p(p_init, s.t, z)

    assert np.allclose(z, p(s.t), atol=1e-4 * u.m), \
        "z-velocity doesn't stay constant!"

    s.test_kinetic_energy()
Beispiel #4
0
def test_particle_nonuniform_grid():
    '''
        Test the particle stepper when the spatial domain dimensions
        are unequal
    '''
    x = np.linspace(0, 1, 10) * u.m
    y = np.linspace(0, 1, 20) * u.m
    z = np.linspace(0, 1, 30) * u.m

    plasma = Plasma(x, y, z)

    Species(plasma, 'e', dt=1e-14 * u.s, nt=5).run()
Beispiel #5
0
def test_particle_exb_drift():
    r"""
        Tests the particle stepper for a field with magnetic field in the Z
        direction, electric field in the y direction. This should produce a
        drift in the negative X direction, with the drift velocity

        v_e = ExB / B^2

        which is independent of ion charge.
    """
    test_plasma = uniform_magnetic_field()
    test_plasma.electric_field[1] = 1 * u.V / u.m
    expected_drift_velocity = -(test_plasma.electric_field_strength /
                                test_plasma.magnetic_field_strength).mean() \
        .to(u.m / u.s)

    s = Species(test_plasma, 'p', 5, dt=1e-10 * u.s, nt=int(5e3))
    s.v[:, 2] += np.random.normal(size=s.N) * u.m / u.s

    s.run()

    p_init = models.Polynomial1D(degree=1)
    for x in s.position_history[:, :, 0].T:
        fit_p = fitting.LinearLSQFitter()
        p = fit_p(p_init, s.t, x)
        fit_velocity = p.parameters[1] * u.m / u.s

        assert np.allclose(x, p(s.t), atol=1e-3 * u.m), \
            "x position doesn't follow linear fit!"

        assert np.isclose(expected_drift_velocity, fit_velocity,
                          atol=1e-3 * u.m / u.s), \
            "x velocity doesn't agree with expected drift velocity!"

    s.test_kinetic_energy()
Beispiel #6
0
############################################################
# Initialize the fields. We'll take $\vec{B}$ in the $\hat{x}$ direction
# and $E$ in the $\hat{y}$ direction, which gets us an $E \times B$ drift
# in $\hat{z}$.

B0 = 4 * u.T
plasma.magnetic_field[0, :, :, :] = np.ones((10, 10, 10)) * B0

E0 = 2 * u.V / u.m
plasma.electric_field[1, :, :, :] = np.ones((10, 10, 10)) * E0

############################################################
# Initialize the particle. We'll take one proton `p` with a timestep of
# $10^{-10}s$ and run it for 10000 iterations.

species = Species(plasma, 'p', 1, 1, 1e-10 * u.s, 10000)

############################################################
# Initialize the particle's velocity. We'll limit ourselves to one in the
# $\hat{x}$ direction, parallel to the magnetic field $\vec{B}$ - that
# way, it won't turn in the $\hat{z}$ direction.

V0 = 1 * (u.m / u.s)
species.v[0][0] = V0

############################################################
# Run the pusher and plot the trajectory versus time.

species.run()
species.plot_time_trajectories()
Beispiel #7
0
############################################################
# Initialize the fields. We'll take $\vec{B}$ in the $\hat{x}$ direction
# and $E$ in the $\hat{y}$ direction, which gets us an $E \times B$ drift
# in $\hat{z}$.

B0 = 4 * u.T
plasma.magnetic_field[0, :, :, :] = np.ones((10, 10, 10)) * B0

E0 = 2 * u.V / u.m
plasma.electric_field[1, :, :, :] = np.ones((10, 10, 10)) * E0

############################################################
# Initialize the particle. We'll take one proton `p` with a timestep of
# $10^{-10}s$ and run it for 10000 iterations.

species = Species(plasma, 'p', 1, 1, 1e-10 * u.s, 10000)

############################################################
# Initialize the particle's velocity. We'll limit ourselves to one in the
# $\hat{x}$ direction, parallel to the magnetic field $\vec{B}$ - that
# way, it won't turn in the $\hat{z}$ direction.

V0 = 1 * (u.m / u.s)
species.v[0][0] = V0

############################################################
# Run the pusher and plot the trajectory versus time.

species.run()
species.plot_time_trajectories()