import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import os
os.chdir('..')
import proppy as pp
sim = pp.Simulation()
# source
nr_particles = 5
source_pos = np.array([0.0, 0.0, 0.0], dtype=np.float32)
energy = 10**15 # eV
phi = 0
pitch_angle = 2*np.pi * 54.74/360
source = pp.PointSourceOriented(energy, source_pos, nr_particles, pitch_angle, phi)
sim.add_source(source)
# propagator
nr_steps = 4*10**4
step_size = 0.5*10**10 # [m]
mfp = np.array([2.13*10**12/2.0, 2.13*10**12/2.0, 2.1078*10**12], dtype=np.float32) # [m]
rms = 1 # [Gaus]
magnetic_field = pp.OrderedBackgroundField(rms, [0,0,1]).magnetic_field
propagator = pp.AnisotropicPropagator(magnetic_field, mfp, nr_steps, step_size)
sim.add_propagator(propagator)
# observer
substeps = [True, True, True] # observe only steps (no substeps)
observer = pp.ObserverAllSteps(substeps)
sim.add_observer(observer)
start simulation Propagator initialized Observer initialized
%time sim.run_simulation()
sim.save_data('data/data_tut_3')
CPU times: user 4.34 s, sys: 90.4 ms, total: 4.43 s Wall time: 4.43 s saved data file data/data_tut_3.pkl
Even though individual trajectories of particles performing a random walk have no physical meaning, their visualization is helpful in many respects:
First load simulated data file and create a trajectory object. As we simulated a 3d trajectory, we choose 3 dimensions and initialize the object with the dataframe. We also want to get a list of ids of our particles.
df = pd.read_pickle("data/data_tut_3.pkl")
df_time_evolution_observer = df.loc[df['radius'] == -1.0]
tra = pp.Trajectory(df_time_evolution_observer)
particle_ids = tra.get_particle_ids()
init trajectory plotting class
The visualization of the substeps clarifies whether the implementation works as desired. We choose only a few steps of a single particle to have a good resolution.
substep_0 = 0 # positions after 1. substep
substep_1 = 2 # positions after 3. substep -> final position after each step for 3d
nr_steps = 10
file_name = None # where to save figure (None doesn't save a figure)
tra.plot_trjectory_substeps(substep_0, substep_1, particle_ids[0], nr_steps, file_name)
The initial ballistic character of the propagation becomes visible when plotting only a few steps.
nr_steps = 2*10**2
tra.plot_trajectory('x', 'y', 'd', particle_ids[0], nr_steps, None)
tra.plot_trajectory('d', 'z', 'd', particle_ids[0], nr_steps, None)
The diffusive character becomes visible on large time scales.
nr_steps = -1
tra.plot_trajectory('x', 'y', 'd', particle_ids[:10], nr_steps, None)
df
id | i | d | x | y | z | phi | pitch_angle | radius | sub_step | |
---|---|---|---|---|---|---|---|---|---|---|
0 | 0.0 | 1.0 | 0.000000e+00 | -2.163573e+08 | 2.878789e+09 | 0.000000e+00 | 0.150029 | 0.955393 | -1.0 | 0.0 |
1 | 0.0 | 1.0 | 0.000000e+00 | -3.070836e+09 | 2.447292e+09 | 0.000000e+00 | 0.150029 | 0.955393 | -1.0 | 1.0 |
2 | 0.0 | 1.0 | 5.000000e+09 | -3.070836e+09 | 2.447292e+09 | -2.886438e+09 | 0.150029 | 0.955393 | -1.0 | 2.0 |
3 | 0.0 | 2.0 | 5.000000e+09 | -3.715045e+09 | 5.261405e+09 | -2.886438e+09 | 0.300058 | 0.955393 | -1.0 | 0.0 |
4 | 0.0 | 2.0 | 5.000000e+09 | -6.472964e+09 | 4.408106e+09 | -2.886438e+09 | 0.300058 | 0.955393 | -1.0 | 1.0 |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
599995 | 4.0 | 39999.0 | 1.999900e+14 | -3.317307e+11 | -1.267863e+11 | -4.635639e+12 | 717.871826 | 0.955393 | -1.0 | 1.0 |
599996 | 4.0 | 39999.0 | 1.999950e+14 | -3.317307e+11 | -1.267863e+11 | -4.638525e+12 | 717.871826 | 0.955393 | -1.0 | 2.0 |
599997 | 4.0 | 40000.0 | 1.999950e+14 | -3.288486e+11 | -1.269511e+11 | -4.638525e+12 | 717.721802 | 0.955393 | -1.0 | 0.0 |
599998 | 4.0 | 40000.0 | 1.999950e+14 | -3.292289e+11 | -1.298129e+11 | -4.638525e+12 | 717.721802 | 0.955393 | -1.0 | 1.0 |
599999 | 4.0 | 40000.0 | 2.000000e+14 | -3.292289e+11 | -1.298129e+11 | -4.641412e+12 | 717.721802 | 0.955393 | -1.0 | 2.0 |
600000 rows × 10 columns