Beispiel #1
0
def test_species(scaling):
    g = PeriodicTestGrid(1e-8, 1, 100, c=lightspeed, epsilon_0=epsilon_zero)
    species = Species(electric_charge,
                      electron_rest_mass,
                      1,
                      g,
                      scaling=scaling)
    species.v[:, 0] = 10
    kinetic_energy_single_electron = 4.554692e-29
    assert np.isclose(species.kinetic_energy,
                      kinetic_energy_single_electron * scaling)
Beispiel #2
0
    def __init__(self, filename, n_macroparticles, n_cells):
        """
        A simulation of laser-hydrogen shield interaction.

        Parameters
        ----------
        filename : str
            Filename for the simulation.
        n_macroparticles : int
            Number of macroparticles for each species. The simulation is
            normalized to 75000 macroparticles by default,
        n_cells : int
            Number of grid cells.
        """
        grid = PeriodicGrid(T=total_time, L=length, NG=int(n_cells), c =lightspeed, epsilon_0 =epsilon_zero)


        cells_per_wl = laser_wavelength / grid.dx
        print(cells_per_wl)
        vtherm = 2 * np.pi / cells_per_wl * lightspeed * 10
        print(vtherm / lightspeed)


        if n_macroparticles:
            electrons = Species(-electric_charge, electron_rest_mass,
                                n_macroparticles, grid, "electrons", scaling)
            electrons.random_velocity_init(vtherm)
            protons = Species(electric_charge, proton_mass, n_macroparticles,
                              grid, "protons", scaling)
            list_species = [electrons, protons]

            omega_p = (cold_plasma_frequency(electrons.scaling * electrons.N / grid.dx, electron_rest_mass, epsilon_zero, electric_charge)**2 + 3 * (grid.NG * 2 * np.pi / grid.L * vtherm)**2)**0.5
            debye_length = vtherm / omega_p
            print(grid.dx, debye_length)
            print("grid stability", grid.dx , 3.4 * debye_length, grid.dx < 3.4 * debye_length)
            print("step stability", grid.dt , 2/omega_p, grid.dt < 2/omega_p)
        else:
            list_species = []

        description = "Stability test"

        super().__init__(grid, list_species,
                         filename=filename,
                         category_type="stability",
                         config_version=VERSION,
                         title=description,
                         considered_large = True)
        print("Simulation prepared.")
Beispiel #3
0
def test_relativistic_magnetic_field(g, _n_particles, _v0):
    """Tests movement in uniform magnetic field in the z direction. The
    particle should move in a uniform circle. This also covers the
    non-relativistic case at small velocities.
    """
    B0 = 1
    s = Species(1, 1, _n_particles, g, individual_diagnostics=True)
    t = np.arange(0, g.T, g.dt * s.save_every_n_iterations) - g.dt / 2
    s.v[:, 1] = _v0

    def uniform_magnetic_field(*args, **kwargs):
        return np.array([[0, 0, 0]], dtype=float), np.array([[0, 0, B0]],
                                                            dtype=float)

    gamma = physics.gamma_from_v(s.v, s.c)[0, 0]
    vy_analytical = _v0 * np.cos(s.q * B0 * (t - g.dt / 2) / (s.m * gamma))

    s.velocity_push(uniform_magnetic_field, 0.5)
    for i in range(g.NT):
        s.save_particle_values(i)
        s.velocity_push(uniform_magnetic_field)
        s.position_push()
    assert (s.velocity_history < g.c).all(), plot(
        t, vy_analytical, s.velocity_history[:, 0, 1],
        f"Velocity went over c! Max velocity: {s.velocity_history.max()}")
    assert np.allclose(s.kinetic_energy_history[1:-1],
                       s.kinetic_energy_history[1:-1].mean(),
                       atol=atol,
                       rtol=rtol), "Energy is off!"

    assert np.allclose(s.velocity_history[:, 0, 1],
                       vy_analytical,
                       atol=atol,
                       rtol=rtol)
    return Simulation(g, [s])
Beispiel #4
0
def test_relativistic_harmonic_oscillator(g, _n_particles, E0):
    """Tests relativistic particle movement in a harmonic oscillator trajectory.
    The velocity is compared to an analytical result."""
    E0 = 1
    omega = 2 * np.pi / g.T
    s = Species(1, 1, _n_particles, g, individual_diagnostics=True)
    t = np.arange(0, g.T, g.dt * s.save_every_n_iterations) - g.dt / 2

    t_s = t - g.dt / 2
    v_analytical = E0 * s.c * s.q * np.sin(
        omega * t_s) / np.sqrt((E0 * s.q * np.sin(omega * t_s))**2 +
                               (s.m * omega * s.c)**2)

    def electric_field(x, t):
        return np.array([[1, 0, 0]], dtype=float) * E0 * np.cos(
            omega * t), np.array([[0, 0, 0]], dtype=float)

    s.velocity_push(lambda x: electric_field(x, 0), 0.5)
    for i in range(g.NT):
        s.save_particle_values(i)
        s.velocity_push(lambda x: electric_field(x, i * g.dt))
        s.position_push()

    s.save_particle_values(g.NT - 1)
    assert (s.velocity_history < 1).all(), plot(
        t, v_analytical, s.velocity_history[:, 0, 0],
        f"Velocity went over c! Max velocity: {s.velocity_history.max()}")
    assert np.allclose(s.velocity_history[:, 0, 0], v_analytical, atol=atol, rtol=rtol), \
        plot(t, v_analytical, s.velocity_history[:, 0, 0], )
Beispiel #5
0
def test_periodic_particles(g):
    """Tests that particles on periodic grids don't disappear."""
    s = Species(1, 1, 100, g, individual_diagnostics=True)
    s.distribute_uniformly(g.L)
    s.v[:] = 0.5
    for i in range(g.NT):
        force = lambda x: (np.array([[0, 0, 0]], dtype=float),
                           np.array([[0, 0, 0]], dtype=float))
        s.velocity_push(force)
        s.position_push()
        g.apply_particle_bc(s)
    assert s.N_alive == s.N, "They're dead, Jim."
def test_density_helper(_fraction, _second_fraction, _profile, _N_particles):

    g = PeriodicTestGrid(1, 100, 100)
    s = Species(1, 1, _N_particles, g)

    moat_length = g.L * _fraction
    ramp_length = g.L * _second_fraction
    plasma_length = 2*ramp_length
    # plasma_length = plasma_length if plasma_length > ramp_length else ramp_length

    s.distribute_nonuniformly(moat_length, ramp_length, plasma_length,
                              profile=_profile)
    return s, g, moat_length, plasma_length, _profile
Beispiel #7
0
def test_nonperiodic_particles(g_aperiodic):
    """Tests that particles on nonperiodic grids disappear when running out
    the cell boundaries."""
    g = g_aperiodic
    s = Species(1, 1, 100, g, individual_diagnostics=True)
    s.distribute_uniformly(g.L)
    s.v[:] = 0.5
    for i in range(g.NT):
        force = lambda x: (np.array([[0, 0, 0]], dtype=float),
                           np.array([[0, 0, 0]], dtype=float))
        s.velocity_push(force)
        s.position_push()
        g.apply_particle_bc(s)
    assert s.N_alive == 0
def test_many_particles_periodic_deposition(N, _velocity):
    NG = 10
    L = NG
    g = Grid(1, L=L, NG=NG, periodic=True)
    s = Species(1.0 / N, 1, N, g)
    s.distribute_uniformly(L)
    s.v[:, 0] = _velocity
    s.v[:, 1] = 1
    s.v[:, 2] = -1
    dt = g.dx / s.c
    g.gather_current([s])
    longitudinal_collected_weights = g.current_density_x[1:-2].sum(
        axis=0) / s.v[0, 0]
    transversal_collected_weights = g.current_density_yz[2:-2].sum(
        axis=0) / s.v[0, 1:]
    label = {0: 'x', 1: 'y', 2: 'z'}

    def plot():
        fig, ax = plt.subplots()
        i = 0
        fig.suptitle(
            f"Longitudinal weights: {longitudinal_collected_weights}, transversal: {transversal_collected_weights}"
        )
        ax.plot(g.x,
                g.current_density_x[1:-2],
                alpha=(3 - i) / 3,
                lw=1 + i,
                label=f"{label[i]}")
        ax.scatter(s.x, np.zeros_like(s.x))
        ax.legend(loc='lower right')
        ax.set_xticks(g.x)
        ax.grid()
        for i in range(1, 3):
            ax.plot(g.x,
                    g.current_density_yz[2:-2, i - 1],
                    alpha=(3 - i) / 3,
                    lw=1 + i,
                    label=f"{label[i]}")
            ax.scatter(s.x, np.zeros_like(s.x))
            ax.legend(loc='lower right')
            ax.set_xticks(g.x)
            ax.grid()
        filename = f"data_analysis/test/periodic_multiple_{N}_{_velocity:.2f}.png"
        make_sure_path_exists(filename)
        fig.savefig(filename)
        fig.clf()
        plt.close(fig)

    assert np.allclose(longitudinal_collected_weights,
                       1), ("Longitudinal weights don't match!", plot())
    assert np.allclose(transversal_collected_weights,
                       1), ("Transversal weights don't match!", plot())
Beispiel #9
0
def test_relativistic_constant_field(g, _n_particles):
    """Tests relativistic movement in constant electric field along the
    direction of motion."""
    s = Species(1, 1, _n_particles, g, individual_diagnostics=True)
    t = np.arange(0, g.T, g.dt * s.save_every_n_iterations) - g.dt / 2

    def uniform_field(*args, **kwargs):
        return np.array([[1, 0, 0]], dtype=float), np.array([[0, 0, 0]],
                                                            dtype=float)

    v_analytical = (t - g.dt / 2) / np.sqrt((t - g.dt / 2)**2 + 1)
    s.velocity_push(uniform_field, -0.5)
    for i in range(g.NT):
        s.save_particle_values(i)
        s.velocity_push(uniform_field)
        s.position_push()

    s.save_particle_values(g.NT - 1)
    assert (s.velocity_history < 1).all(), plot(
        t, v_analytical, s.velocity_history[:, 0, 0],
        f"Velocity went over c! Max velocity: {s.velocity_history.max()}")
    assert np.allclose(s.velocity_history[:, 0, 0], v_analytical, atol=atol, rtol=rtol), \
        plot(t, v_analytical, s.velocity_history[:, 0, 0], )
    return Simulation(g, [s])
Beispiel #10
0
    def __init__(self,
                 filename,
                 n_macroparticles,
                 n_cells,
                 impulse_duration,
                 laser_intensity,
                 perturbation_amplitude,
                 laser_polarization="Ez",
                 individual_diagnostics=False):
        """
        A simulation of laser-hydrogen shield interaction.

        Parameters
        ----------
        filename : str
            Filename for the simulation.
        n_macroparticles : int
            Number of macroparticles for each species. The simulation is
            normalized to 75000 macroparticles by default,
        impulse_duration : float
            Duration of the laser impulse.
        laser_intensity : float
            Laser impulse intensity, in W/m^2. A good default is 1e21.
        perturbation_amplitude : float
            Amplitude of the initial position perturbation.
        """
        if laser_intensity:
            bc_laser = BoundaryCondition.bcs[laser_polarization](
                laser_intensity=laser_intensity,
                laser_wavelength=laser_wavelength,
                envelope_center_t=total_time / 2,
                envelope_width=impulse_duration,
                envelope_power=6,
                c=lightspeed,
                epsilon_0=epsilon_zero,
            )
            print(f"Laser amplitude: {bc_laser.laser_amplitude:e}")
            bc = bc_laser
        else:
            bc = BoundaryCondition.BC()
        grid = NonperiodicGrid(T=total_time,
                               L=length,
                               NG=n_cells,
                               c=lightspeed,
                               epsilon_0=epsilon_zero,
                               bc=bc)

        cells_per_wl = laser_wavelength / grid.dx
        print(f"{cells_per_wl:.1f} grid cells per laser wavelength.")
        vtherm = 2 * np.pi / cells_per_wl * lightspeed
        print(
            f"Thermal velocity for this simulation should be on the order of {vtherm / lightspeed:.3f}c."
        )

        if n_macroparticles:
            electrons = Species(-electric_charge,
                                electron_rest_mass,
                                n_macroparticles,
                                grid,
                                "electrons",
                                scaling,
                                individual_diagnostics=individual_diagnostics)
            protons = Species(electric_charge,
                              proton_mass,
                              n_macroparticles,
                              grid,
                              "protons",
                              scaling,
                              individual_diagnostics=individual_diagnostics)
            list_species = [electrons, protons]
        else:
            list_species = []

        self.perturbation_amplitude = perturbation_amplitude  # in units of dx

        description = "Hydrogen shield-laser interaction"

        super().__init__(grid,
                         list_species,
                         filename=filename,
                         category_type="laser-shield",
                         config_version=VERSION,
                         title=description,
                         considered_large=True)
        print("Simulation prepared.")
Beispiel #11
0
def test_species(scaling):
    g = PeriodicTestGrid(1e-8, 1, 100, c=lightspeed, epsilon_0=epsilon_zero)
    species = Species(electric_charge, electron_rest_mass, 1, g, scaling=scaling)
    species.v[:, 0] = 10
    kinetic_energy_single_electron = 4.554692e-29
    assert np.isclose(species.kinetic_energy, kinetic_energy_single_electron*scaling)
def test_two_particles_deposition(_position, _velocity, _truefalse,
                                  _truefalse2):
    NG = 7
    L = NG
    g = Grid(1, L=L, NG=NG)
    c = 1
    dt = g.dx / c
    positions = [_position * g.dx, (L - _position * g.dx) % L]
    # print(positions)
    for position in positions:
        s = Particle(g, position, _velocity, 1, -1)
        # print(f"\n======PARTICLE AT {position}=======")
        # print(s)
        # print(s.x)
        # print(s.v)
        if _truefalse:
            longitudinal_current_deposition(g.current_density_x, s.v[:, 0],
                                            s.x, g.dx, dt, s.q)
        if _truefalse2:
            transversal_current_deposition(g.current_density_yz, s.v, s.x,
                                           g.dx, dt, s.q)
        # print(g.current_density)

    collected_weights_x = g.current_density_x.sum(axis=0) / _velocity
    collected_weights_yz = g.current_density_yz.sum(axis=0) / np.array(
        [1, -1], dtype=float)

    g2 = Grid(1, L=L, NG=NG)
    s = Species(1, 1, 2, g2)
    s.x[:] = positions
    s.v[:, 0] = _velocity
    s.v[:, 1] = 1
    s.v[:, 2] = -1
    # print("\n\n======TWO PARTICLES=======")
    # print(s)
    # print(s.x)
    # print(s.v)
    if _truefalse:
        longitudinal_current_deposition(g2.current_density_x, s.v[:, 0], s.x,
                                        g2.dx, dt, s.q)
    if _truefalse2:
        transversal_current_deposition(g2.current_density_yz, s.v, s.x, g2.dx,
                                       dt, s.q)
    # print(g2.current_density)
    collected_weights_x2 = g2.current_density_x.sum(axis=0) / s.v[0, 0]
    collected_weights_yz2 = g2.current_density_yz.sum(axis=0) / np.array(
        [1, -1], dtype=float)
    label = {0: 'x', 1: 'y', 2: 'z'}

    def plot():
        fig, (ax1, ax2) = plt.subplots(2)
        plt.suptitle(f"x: {positions}, vx: {_velocity}")
        i = 0
        ax1.plot(g.x,
                 g.current_density_x[1:-2],
                 alpha=(3 - i) / 3,
                 lw=1 + i,
                 label=f"1 {label[i]}")
        ax1.plot(g.x,
                 g2.current_density_x[1:-2],
                 alpha=(3 - i) / 3,
                 lw=1 + i,
                 label=f"2 {label[i]}")
        ax2.plot(g.x, (g.current_density_x - g2.current_density_x)[1:-2],
                 alpha=(3 - i) / 3,
                 lw=1 + i,
                 label=f"1 - 2 {label[i]}")
        for i in range(1, 3):
            ax1.plot(g.x,
                     g.current_density_yz[2:-2, i - 1],
                     alpha=(3 - i) / 3,
                     lw=1 + i,
                     label=f"1 {label[i]}")
            ax1.plot(g.x,
                     g2.current_density_yz[2:-2, i - 1],
                     alpha=(3 - i) / 3,
                     lw=1 + i,
                     label=f"2 {label[i]}")
            ax2.plot(g.x,
                     (g.current_density_yz - g2.current_density_yz)[2:-2,
                                                                    i - 1],
                     alpha=(3 - i) / 3,
                     lw=1 + i,
                     label=f"1 - 2 {label[i]}")
        for ax in [ax1, ax2]:
            ax.scatter(s.x, np.zeros_like(s.x))
            ax.legend(loc='lower right')
            ax.set_xticks(g.x)
            ax.grid()
        fig.savefig(
            f"data_analysis/deposition/{_position:.2f}_{_velocity:.2f}.png")

    assert np.allclose(
        g.current_density_x,
        g2.current_density_x), ("Longitudinal currents don't match!", plot())
    assert np.allclose(
        g.current_density_yz,
        g2.current_density_yz), ("Transversal currents don't match!", plot())
    assert np.allclose(
        collected_weights_x,
        collected_weights_x2), ("Longitudinal weights don't match!", plot())
    assert np.allclose(
        collected_weights_yz,
        collected_weights_yz2), ("Transversal weights don't match!", plot())
Beispiel #13
0
    def __init__(self,
                 filename,
                 n_macroparticles,
                 impulse_duration,
                 laser_intensity,
                 perturbation_amplitude,
                 additional_scaling=1):
        """
        A simulation of laser-hydrogen shield interaction.

        Parameters
        ----------
        filename : str
            Filename for the simulation.
        n_macroparticles : int
            Number of macroparticles for each species. The simulation is
            normalized to 75000 macroparticles by default,
        impulse_duration : float
            Duration of the laser impulse.
        laser_intensity : float
            Laser impulse intensity, in W/m^2. A good default is 1e21.
        perturbation_amplitude : float
            Amplitude of the initial position perturbation.
        """
        if laser_intensity:
            bc_laser = BoundaryCondition.Laser(
                laser_intensity=laser_intensity,
                laser_wavelength=laser_wavelength,
                envelope_center_t=total_time / 2,
                envelope_width=impulse_duration,
                envelope_power=6,
                c=lightspeed,
                epsilon_0=epsilon_zero,
            )
            print(f"Laser amplitude: {bc_laser.laser_amplitude:e}")
            bc = bc_laser.laser_pulse
        else:
            bc = lambda x: None
        grid = Grid(T=total_time,
                    L=length,
                    NG=number_cells,
                    c=lightspeed,
                    epsilon_0=epsilon_zero,
                    bc=bc,
                    periodic=False)

        if n_macroparticles:
            scaling = default_scaling * N_MACROPARTICLES / n_macroparticles * additional_scaling
            electrons = Species(-electric_charge, electron_rest_mass,
                                n_macroparticles, grid, "electrons", scaling)
            protons = Species(electric_charge, proton_mass, n_macroparticles,
                              grid, "protons", scaling)
            list_species = [electrons, protons]
        else:
            list_species = []

        self.perturbation_amplitude = perturbation_amplitude  # in units of dx

        description = "Hydrogen shield-laser interaction"

        super().__init__(grid,
                         list_species,
                         filename=filename,
                         category_type="laser-shield",
                         config_version=VERSION,
                         title=description,
                         considered_large=True)
        print("Simulation prepared.")