Phase Space¶
This plugin creates a 2D phase space image for a user-given spatial and momentum coordinate.
External Dependencies¶
The plugin is available as soon as the libSplash and HDF5 libraries are compiled in.
.cfg file¶
Example for y-pz phase space for the electron species (.cfg
file macro):
# Calculate a 2D phase space
# - momentum range in m_e c
TGB_ePSypz="--e_phaseSpace.period 10 --e_phaseSpace.filter all --e_phaseSpace.space y --e_phaseSpace.momentum pz --e_phaseSpace.min -1.0 --e_phaseSpace.max 1.0"
The distinct options are (assuming a species e
for electrons):
Option |
Usage Unit |
|
---|---|---|
|
calculate each N steps |
none |
|
Use filtered particles. Available filters are set up in particleFilters.param. |
none |
|
spatial coordinate of the 2D phase space |
none |
|
momentum coordinate of the 2D phase space |
none |
|
minimum of the momentum range |
\(m_\mathrm{species} c\) |
|
maximum of the momentum range |
\(m_\mathrm{species} c\) |
Memory Complexity¶
Accelerator¶
locally, a counter matrix of the size local-cells of space
direction times 1024
(for momentum bins) is permanently allocated.
Host¶
negligible.
Output¶
The 2D histograms are stored in .hdf5
files in the simOutput/phaseSpace/
directory.
A file is created per species, phasespace selection and time step.
Values are given as charge density per phase space bin.
In order to scale to a simpler charge of particles per \(\mathrm{d}r_i\) and \(\mathrm{d}p_i\) -bin multiply by the cell volume dV
.
Analysis Tools¶
Data Reader¶
You can quickly load and interact with the data in Python with:
from picongpu.plugins.data import PhaseSpaceData
import numpy as np
ps_data = PhaseSpaceData('/home/axel/runs/lwfa_001')
# show available iterations
ps_data.get_iterations(ps="xpx", species="e", species_filter='all')
# show available simulation times
ps_data.get_times(ps="xpx", species="e", species_filter='all')
# load data for a given iteration
ps, meta = ps_data.get(ps='ypy', species='e', species_filter='all', iteration=2000)
# unit conversion from SI
mu = 1.e6 # meters to microns
e_mc_r = 1. / (9.109e-31 * 2.9979e8) # electrons: kg * m / s to beta * gamma
Q_dr_dp = np.abs(ps) * meta.dV # C s kg^-1 m^-2
extent = meta.extent * [mu, mu, e_mc_r, e_mc_r] # spatial: microns, momentum: beta*gamma
# load data for a given time
ps, ps_meta = ps_data.get(ps="xpx", species="e", species_filter='all', time=1.3900e-14)
# load data for multiple iterations
ret = ps_data.get(ps="xpx", species="e", species_filter='all', iteration=[2000, 4000])
# data and metadata for iteration 2000
# (data is in same order as the value passed to the 'iteration' parameter)
ps, meta = ret[0]
Note that the spatial extent of the output over time might change when running a moving window simulation.
Matplotlib Visualizer¶
You can quickly plot the data in Python with:
from picongpu.plugins.plot_mpl import PhaseSpaceMPL
import matplotlib.pyplot as plt
# create a figure and axes
fig, ax = plt.subplots(1, 1)
# create the visualizer
ps_vis = PhaseSpaceMPL('path/to/run_dir', ax)
# plot
ps_vis.visualize(ps="xpx", iteration=200, species='e', species_filter='all')
plt.show()
# specifying simulation time is also possible (granted there is a matching iteration for that time)
ps_vis.visualize(ps="xpx", time=2.6410e-13, species='e', species_filter='all')
plt.show()
# plotting data for multiple simulations simultaneously also works:
ps_vis = PhaseSpaceMPL([
("sim1", "path/to/sim1"),
("sim2", "path/to/sim2"),
("sim3", "path/to/sim3")], ax)
ps_vis.visualize(ps="xpx", iteration=10000, species="e", species_filter='all')
plt.show()
The visualizer can also be used from the command line (for a single simulation only) by writing
python phase_space_visualizer.py
with the following command line options
Options |
Value |
---|---|
-p |
Path and filename to the run directory of a simulation. |
-i |
An iteration number |
-s (optional, defaults to ‘e’) |
Particle species abbreviation (e.g. ‘e’ for electrons) |
-f (optional, defaults to ‘all’) |
Species filter string |
-m (optional, defaults to ‘ypy’) |
Momentum string to specify the phase space |
Jupyter Widget¶
If you want more interactive visualization, then start a jupyter notebook and make
sure that ipywidgets
and ìpympl
are installed.
After starting the notebook server write the following
# this is required!
%matplotlib widget
import matplotlib.pyplot as plt
plt.ioff()
from IPython.display import display
from picongpu.plugins.jupyter_widgets import PhaseSpaceWidget
# provide the paths to the simulations you want to be able to choose from
# together with labels that will be used in the plot legends so you still know
# which data belongs to which simulation
w = PhaseSpaceWidget(run_dir_options=[
("scan1/sim4", "/path/to/scan1/sim4"),
("scan1/sim5", "/path/to/scan1/sim5")])
display(w)
and then interact with the displayed widgets.
Plase note that per default the widget allows selection only of the ypy
phase space slice for particles labelled by e
.
To visualize, for instance the ypy
, xpx
and ypz
slices for particles labelled by e
(as a rule background electrons)
and by b
(here electrons of a particle bunch) the above has to be augmented by setting w.ps.options
and w.species.options
.
The final script snippet then reads:
# this is required!
%matplotlib widget
import matplotlib.pyplot as plt
plt.ioff()
from IPython.display import display
from picongpu.plugins.jupyter_widgets import PhaseSpaceWidget
# provide the paths to the simulations you want to be able to choose from
# together with labels that will be used in the plot legends so you still know
# which data belongs to which simulation
w = PhaseSpaceWidget(run_dir_options=[
("scan1/sim4", "/path/to/scan1/sim4"),
("scan1/sim5", "/path/to/scan1/sim5")])
w.ps.set_trait('options', ('ypy', 'xpx', 'ypz'))
w.species.set_trait('options', ('e', 'b'))
display(w)
Out-of-Range Behavior¶
Particles that are not in the range of <ValL>
/<ValR>
get automatically mapped to the lowest/highest bin respectively.
Take care about that when setting your range and during analysis of the results.
Known Limitations¶
only one range per selected space-momentum-pair possible right now (naming collisions)
charge deposition uses the counter shape for now (would need one more write to neighbors to evaluate it correctly according to the shape)
the user has to define the momentum range in advance
the resolution is fixed to
1024 bins
in momentum and the number of cells in the selected spatial dimensionthis plugin does not yet use openPMD markup.
References¶
The internal algorithm is explained in pull request #347 and in [Huebl2014].
- Huebl2014
A. Huebl. Injection Control for Electrons in Laser-Driven Plasma Wakes on the Femtosecond Time Scale, chapter 3.2, Diploma Thesis at TU Dresden & Helmholtz-Zentrum Dresden - Rossendorf for the German Degree “Diplom-Physiker” (2014), https://doi.org/10.5281/zenodo.15924