Examples

This section contains configuration examples for various cases in order to illustrate the configuration process. The examples were created on a Linux system, so in case you are using Windows you need to adjust the file paths accordingly.

Electron tracking (complete example)

In this example we walk through the complete configuration process in order to give an overview as broad as possible. Screenshots of the different GUI sections as well as the corresponding sections of configuration files are given.

The example corresponds to the LHC 6.5 TeV beam. We use the beam parameters specified here and the device parameters from here.

The corresponding (or rather emerging) configuration file can be found here.

Beams

First we are going to create a new beam by clicking the New beam button in the Beams tab.

_images/vipm-gui-beams-section.png

Create a new beam by clicking on the New beam button.

A new beam dialog opens and we first need to fill in general parameters about the beam, such as the number of particles per bunch, the beam energy and the accelerated particle type. The relativistic gamma factor is computed from the specified energy and the rest energy of the particle type, so in general either the total energy or the energy per nucleon can be used.

The advanced options allow to independently switch of the electric and magnetic field of the beam in case this is of interest for particular studies. We don’t select these options and therefore take both the electric and the magnetic field into account. The total ionization cross section parameter determines the fraction of particles that will be ionized by the particular beam, however because we have only one beam the given value is of no importance.

_images/vipm-gui-new-beam-dialog-beam.png

Under the Beam tab we specify general parameters of the beam. The parameters listed under Advanced options have already appropriate default values.

The corresponding part of the XML configuration file looks as follows:

<Beam>
    <Parameters>
        <Energy unit="TeV">6.5</Energy>
        <BunchPopulation>1.3e11</BunchPopulation>
        <ParticleType>
            <ChargeNumber>1</ChargeNumber>
            <RestEnergy unit="MeV">%(proton mass energy equivalent in MeV)</RestEnergy>
        </ParticleType>
    </Parameters>
</Beam>

Note the special syntax that we used for specifying the protons’ rest energy. Physical quantities in general can refer to constants which are specified either in scipy.constants or scipy.constants.physical_constants (see the scipy documentation) by using the syntax %(name-of-constant). In addition they support all common mathematical operations as well as can refer to math functions via numpy.<function-name> or np.<function-name> (for more information see the documentation) of the external configuration library.

Next we define the bunches and their parameters. We select a Gaussian bunch shape for which we can choose to specify the bunch length either in the laboratory frame or in the bunch frame.

_images/vipm-gui-new-beam-dialog-bunch.png

Under the Bunch tab we can specify the bunch shape and the bunch electric field model.

<Beam>
    <BunchShape>
        <Parameters>
            <LongitudinalSigmaLabFrame unit="ns">1.25 / 4</LongitudinalSigmaLabFrame>
            <TransverseSigma unit="um">[ 229, 257 ]</TransverseSigma>
        </Parameters>
        <Model>Gaussian</Model>
    </BunchShape>
    <BunchElectricField>
        <Model>BassettiErskine</Model>
    </BunchElectricField>
</Beam>

As a last step we need to define the bunch train. Because we want to simulate a single bunch only we select the SingleBunch model.

As an advanced option we could specify the offset of the bunch center in the laboratory frame with respect to \(z = 0\). If not given this parameter defaults to half of the total length of the bunch which is \(4\sigma_z\) for a Gaussian bunch shape. Because later on we will choose a specific model which ionizes all particles at \(z = 0\), the default behavior is desired. That way the simulation covers all different situations, particles being ionized at the head, center and tail of the bunch.

_images/vipm-gui-new-beam-dialog-bunch-train.png
<Beam>
    <BunchTrain>
        <Type>SingleBunch</Type>
    </BunchTrain>
</Beam>

Once we entered all the parameters we confirm our choice by pressing the Ok button in the bottom right corner of the window. The new beam then shows up in the Beams tab as a separate button (clicking this button brings back the beam configuration dialog).

_images/vipm-gui-beam-section-beam-created.png

The beam is indicated by its bunch shape (first line) and bunch electric field model (second line).

Device

Next we select the device and choose the InterpolatingIPM model. This model detects particles once they reach the specified lower y-boundary and linearly interpolates their final positions. The model doesn’t involve boundaries in z-direction, however, if this ever becomes relevant then the corresponding selection can be performed on the output data of the simulation.

_images/vipm-gui-device-section.png
<Device>
    <Parameters>
        <XBoundaries unit="mm">[ -42.5, 42.5 ]</XBoundaries>
        <YBoundaries unit="mm">[ -42.5, 42.5 ]</YBoundaries>
    </Parameters>
    <Model>InterpolatingIPM</Model>
</Device>

Particle Generation

For the particle generation we choose the VoitkivDDCS model. We specify that all particles are generated at \(z = 0\). This matches with the default longitudinal offset of our chosen SingleBunch model. The model uses a double differential cross section for the momentum sampling. The kinetic energies of ionized electrons will be sampled from the EnergyBoundaries interval containing EnergyBins different energies via the inverse transform sampling method. The same holds for the scattering angle. The energies are logarithmically distributed because smaller energies are much more probable. The cross section was initially derived for hydrogen and a concept of an “effective charge” is used in order to apply it to atoms with \(\geq 2\) electrons. Because for multi-shell atoms this concept becomes less accurate only hydrogen and helium are available. As an advanced option we can specify the beam which shall be used for generating particles. Beams are numbered starting at zero and incremented by one for each additional beam. Beause we only have one beam the default value of 0 is correct.

_images/vipm-gui-particle-generation-section.png

The double differential cross section requires additional parameters for the momentum sampling. A set of (typically sufficient) default values is already filled in by the GUI.

<ParticleGeneration>
    <Parameters>
        <ZPosition unit="m">0</ZPosition>
        <Ionization>
            <Parameters>
                <GasType>Hydrogen</GasType>
                <ScatteringAngleBins>200</ScatteringAngleBins>
                <ScatteringAngleBoundaries unit="rad">[ 0.0, %(pi) ]</ScatteringAngleBoundaries>
                <EnergyBoundaries unit="eV">[ 0.001, 300.0 ]</EnergyBoundaries>
                <EnergyBins>1500</EnergyBins>
            </Parameters>
        </Ionization>
    </Parameters>
    <Model>VoitkivDDCS</Model>
</ParticleGeneration>

Particle Tracking

We choose the Boris algorithm for the particle tracking. It initially shifts position and momentum by half a time step (Leapfrog integration) which is achieved by using the Runge-Kutta 4th order algorithm, hence the corresponding dependency is displayed in the GUI.

_images/vipm-gui-particle-tracking-section.png

Particle tracking configuration. The info box for the Boris algorithm is shown at the bottom. This info box can be obtained by clicking the “i” button in the top right corner of the model dialog.

<ParticleTracking>
    <Model>Boris</Model>
</ParticleTracking>

Guiding Fields

We choose uniform electric and magnetic guiding fields, both aligned with the y-axis.

_images/vipm-gui-electric-guiding-field-section.png _images/vipm-gui-magnetic-guiding-field-section.png
<GuidingFields>
    <Electric>
        <Parameters>
            <ElectricField unit="V/m">[ 0, 4e3 / 85e-3, 0 ]</ElectricField>
        </Parameters>
        <Model>UniformElectricField</Model>
    </Electric>
    <Magnetic>
        <Parameters>
            <MagneticField unit="T">[ 0, 0.2, 0 ]</MagneticField>
        </Parameters>
        <Model>UniformMagneticField</Model>
    </Magnetic>
</GuidingFields>

Simulation

Under the Simulation tab we specify general parameters of the simulation. We choose to simulate 10,000 electrons. The simulation time is set to \(10\,\textrm{ns}\) in order to allow all electrons to reach the detector after they have been created (the bunch has a total length of \(2.5\,\textrm{ns}\), so electrons created at the tail of the bunch still have \(7.5\,\textrm{ns}\) to reach the detector). The simulation time is divided into 10,000 steps which results in a time delta of \(\Delta t = 10^{-3}\,\textrm{ns}\). If we had specified the time delta directly then the number of simulation steps would have been deduced automatically (this holds for any combination of two of the three TimeRange parameters). The advanced options also allow for setting a seed for the random number generator in order to ensure consistency between separate runs, in case this is a requirement.

_images/vipm-gui-simulation-section.png
<Simulation>
    <RNGSeed>1234</RNGSeed>
    <NumberOfParticles>1000000</NumberOfParticles>
    <TimeRange>
        <SimulationTime unit="ns">10</SimulationTime>
        <NumberOfTimeSteps>32000</NumberOfTimeSteps>
    </TimeRange>
    <ParticleType>
        <ChargeNumber>-1</ChargeNumber>
        <RestEnergy unit="MeV">%(electron mass energy equivalent in MeV)</RestEnergy>
    </ParticleType>
</Simulation>

Output

For the output of the simulation we select the BasicRecorder model which saves the initial and final values of particle attributes. The advanced options allow for configuring which attributes should be saved.

_images/vipm-gui-output-section.png
<Simulation>
    <Output>
        <Parameters>
            <Filename>/tmp/virtual-ipm.csv</Filename>
        </Parameters>
        <Recorder>BasicRecorder</Recorder>
    </Output>
</Simulation>

Ion tracking

This example shows how to perform ion tracking for the example of the LHC 6.5 TeV beam. The Electron tracking (complete example) example serves as a basis for the configuration.

In contrast to electrons, the ions have much greater time of flights and, therefore, they will see the electric field of multiple bunches passing the simulation region. Hence, simulating a single bunch is not sufficient and we need to modify the configuration to contain multiple bunches instead.

Bunch Train

The CircularBunchTrain class emulates bunches periodically passing through the simulation region. The bunch train is centered initially around the origin of the laboratory frame (\(z = 0\)) and so it is sufficient to specify a number of 3 bunches. The bunch spacing is set to \(25\,\textrm{ns}\) which means the situation repeats every \(25\,\textrm{ns}\) with a bunch being at \(z = 0\).

_images/vipm-gui-new-beam-dialog-bunch-train1.png
<Beam>
    <BunchTrain>
        <NumberOfBunches>3</NumberOfBunches>
        <BunchSpacing unit="s">25</BunchSpacing>
        <Type>CircularBunchTrain</Type>
    </BunchTrain>
</Beam>

Particle Generation

We can use the configuration from the Electron tracking (complete example) example with a minor modification to the particle generation model. Here we need to change the particle generation model from VoitkivDDCS to ZeroMomentum because the ionization cross sections describes the momenta of ionized electrons. For the moment there is no model which samples the initial momenta of ions, so we set them to zero.

In the following, we address the issue that the ZeroMomentum model generates all particles over the whole simulation time according to the charge distribution of the beam (including all bunches) at the specified \(z\)-position. Because for the CircularBunchTrain model, bunches repeatedly arrive at \(z=0\), this would not only create particles from the first bunch but also from all following bunches. The thus generated ions are most likely not detected anymore because they are created too close towards the end of the simulation. However, since from the perspective of the generated ions the situation is the same for all bunches, it is sufficient to just create particles from the very first bunch and then use the subsequent bunches only for the electric/magnetic field generation which enters in the particle tracking.

There are two ways to achieve this:

  • Specifying two distinct beams, one for particle generation (using SingleBunch) and one for particle tracking (using CircularBunchTrain).

  • Running two simulations, the first with SingleBunch and the second using the final particle coordinates from the first run as the initial particle coordinates (e.g. via the DirectPlacement particle generation model). Then the second run would use CircularBunchTrain model.

Specifying two beams

The following setup relies on three advanced parameters of the particle generation model and the beam model:

  • BeamId - This parameter is present for each ionization based model. It allows to select the beam instance which will be used for the particle generation. The ID of each beam is also indicated on the Beams tab of the GUI. In the XML configuration files, multiple <Beam></Beam> sections are implicitly enumerated starting at 0. Hence, for the particle generation model, we need to specify the ID of the SingleBunch beam.

  • ElectricFieldOFF / MagneticFieldOFF - These are advanced parameters of each Beam instance (tab Beams/Beam in the GUI) and can be used to deactivate the contribution of this beam’s electric or magnetic field to the particle tracking. Hence, we need to select these parameters for the SingleBunch beam, which is used only for particle generation.

  • LongitudinalOffset - This is a parameter of the BunchTrain models. For the CircularBunchTrain, bunches are centered around z = 0 by default. That means, for three bunches, the center of the middle bunch will coincide with z = 0. For SingleBunch, however, the default behavior is to shift the bunch by half its total length (e.g. \(-4\sigma_z\) for a Gaussian bunch), in order to cover the entire particle generation at z = 0. Since the middle bunch of the CircularBunchTrain must be aligned with the SingleBunch, we need to specify an additional LongitudinalOffset of \(-4\sigma_z\) for the CircularBunchTrain (inserting the appropriate value for \(\sigma_z\) that agrees with the definition of the bunches).

_images/two_beams_beams_tab.png

Two beam instances are defined. id: 0 is the SingleBunch beam which will be used for particle generation and id: 1 is the CircularBunchTrain beam which will be used for particle tracking.

_images/two_beams_electric_and_magnetic_field_off.png

This is the Beam tab for the SingleBunch beam (id: 0). Here we need to select the two advanced parameters ElectricFieldOFF and MagneticFieldOFF in order to deactivate its contribution to particle tracking.

_images/two_beams_particle_generation_tab.png

At the ParticleGeneration tab, we need to make sure that the BeamId advanced parameter is set to 0 (the default) in order to ensure that particle generation relies on the SingleBunch beam.

_images/two_beams_bunch_train_tab_circular.png

For the CircularBunchTrain beam (id: 1), at the Bunch Train tab, we need to set the LongitudinalOffset advanced parameter to \(-4\sigma_z = 0.9\,\mathrm{ns}\), since that is half the bunch length. This ensures that the middle bunch of the CircularBunchTrain beam is aligned with the SingleBunch beam; that is important in order to correctly correlate the particle generation and beam fields used for particle tracking.

Running two simulations

Also here we need to account for the difference in the bunch trains. The CircularBunchTrain is centered around \(z = 0\) but the SingleBunch used in Electron tracking (complete example) had an offset of \(z_0 = -4\sigma_z\). Therefore, we need to explicitly specify the longitudinal offset as \(z_0 = 0\).

Because for the first SingleBunch run we are only interested in the initial coordinates of particles, we can use the advanced parameter Simulation -> OnlyGenerateParticles which will turn off beam field computation and tracking. Thus, this first run will finish very quickly. For the Output model, i.e. BasicRecorder, it is important to deselect the advanced parameter SkipTrackedParticles which is selected by default, in order to save the coordinates of the generated particles to the output file.

For the second run we use the DirectPlacement particle generation model in order to provide the previously obtained initial coordinates as an input to the simulation. There is a command line utility to perform the necessary conversion:

vipm-out-to-in path/to/stage-1-output.csv path/to/stage-2-input.csv --mass='proton mass'

Then we configure the DirectPlacement model to use the converted input: <Filepath>path/to/stage-2-input.csv</Filepath>.

Simulation

Ions have much longer time of flights and, therefore, we need to increase the simulation time (the appropriate value depends on the other parameters such as electric guiding field strength and the ions’ rest mass). For the “two simulations” approach, since we obtained the initial values from a previous run, it is important to use the same time delta value because particles are created at specific simulation steps and a different time delta would imply a different simulation time that corresponds to a particular step.

DC Beams

The notion of a DC beam is a single bunch beam where the bunch has an infinite length but constant charge line density. Only some specific bunch shape models are therefore suitable to be used for DC beam simulations.

Currently the HollowDCBeam and GaussianDC bunch shape models are available (see #190 and #269). The corresponding bunch electric field models have the same names as the bunch shape models and are based on analytical formulas for the respective shapes.

The dedicated bunch train class DCBeam should be used for simulating DC beams.

Example configuration

An example for the beam configuration part is given in the following. Note that the BunchPopulation parameter should always be set to 1 for DC beam simulations (instead the BeamCurrent parameter is deciding for the number of charges).

<Beam>
    <Parameters>
        <ParticleType>
            <ChargeNumber>-1</ChargeNumber>
            <RestEnergy unit="MeV">%(electron mass energy equivalent in MeV)</RestEnergy>
        </ParticleType>
        <BunchPopulation>1</BunchPopulation>
        <Energy unit="keV">10</Energy>
    </Parameters>
    <BunchShape>
        <Parameters>
            <InnerRadius unit="mm">2.4 / 2</InnerRadius>
            <OuterRadius unit="mm">3.6 / 2</OuterRadius>
            <BeamCurrent unit="A">5</BeamCurrent>
        </Parameters>
        <Model>HollowDCBeam</Model>
    </BunchShape>
    <BunchElectricField>
        <Model>HollowDCBeam</Model>
    </BunchElectricField>
    <BunchTrain>
        <Type>DCBeam</Type>
    </BunchTrain>
</Beam>

Making the particle generation more effective

All particle generation models which involve interaction with a beam generate particles during the whole specified simulation time. This is inconvenient for a DC beam because the charge density is the same for every simulation step and therefore a considerable number of particles will be generated right before the simulation stops and thus remain undetected. However a simple workaround is sufficient to overcome this problem. We can use a first (shorter) simulation run in order to generate the initial parameters of particles and then use those values as an input to a second run. For the second run we can choose the simulation time greater than for the first (such that all particles will be eventually detected).

Note

Splitting the simulation into two runs we need to make sure that the simulation step numbers from the first run correspond to the ones of the second run (because particles are created at a specific simulation step). For the second run we want to increase the simulation time but we need to make sure to use the same time step size \(\Delta t\). Therefore it is recommended to use the parameters SimulationTime and TimeDelta (instead of NumberOfTimeSteps).

In order to feed the attributes from the first run to the second we need to make sure they get saved. This can be achieved by using the BasicRecorder class and setting the parameter SkipTrackedParticles to false (deselecting the checkbox or set <SkipTrackedParticles>false</SkipTrackedParticles> in the configuration file).

There is a command line tool for converting BasicRecorder output files to DirectPlacement input files (for use in subsequent simulation runs):

vipm-out-to-in path/to/output.csv path/to/input.csv --mass=<mass-of-tracked-particles-in-kg>

Because a normal simulation run performs generation, tracking and detection of particles this would waste a lot of (CPU) time for the first run which is only used to generate the particles’ initial coordinates. There is, however, a parameter which allows to achieve exactly this: OnlyGenerateParticles (advanced parameter in the Simulation tab). If this parameter is selected then the simulation will skip particle tracking and detection and only performs particle generation. The screenshot below shows where this advanced parameter can be found in the GUI.

_images/gui-only-generate-particles.png

Select this parameter in order to skip tracking and detection of particles for speeding up the particle generation simulation run.

Multiple beams

Multiple beams can be specified during the configuration process and their effects will be taken into account collectively. That is, the superposition of electromagnetic fields of all beams will be used for particle tracking. Particle generation, however, is always only performed for a single beam (in case the particle generation process involves interaction with the beam, such as ionization). If particles generated by multiple beams are to be tracked then this can be achieved by splitting those cases over multiple runs of the simulation.

Each particle generation model which involves beam interaction has an advanced parameter BeamId which can be used for specifying the beam which shall be used for particle generation. Beams are numbered starting at zero and incremented by one for each additional beam:

<Beams>
    <Beam> ... </Beam>   <!-- This beam has id 0. -->
    <Beam> ... </Beam>   <!-- This beam has id 1. -->

    <!-- ... and so on. -->
</Beams>

That is, the order in which the beams are specified matters in this case! We can then specify the relevant beam via:

<ParticleGeneration>
    <Parameters>
        <BeamId> 1 </BeamId>
        <ZPosition unit="m"> 0 </ZPosition>
    </Parameters>
    <Model> ZeroMomentum </Model>
</ParticleGeneration>

Simulate using an HPC cluster

Often simulations take lots of time and (high performance) computing clusters are available to do the hard work. We can scale the simulation horizontally by distributing the number of simulated particles across different nodes of a compute cluster. For example if we want to simulate 100,000 particles and we have access to 100 compute nodes then we can run a 1,000 particles simulation on each node and merge the results later on.

In case that particle generation involves random number generation (and most often it will, e.g. for ionization) it is important to specify a different seed for the random number generator (RNG) for each of the sub-simulations on each of the nodes. This is to ensure that different nodes actually compute with different data.

Another option is to split the simulation into two runs: A preparatory run which generates the initial attributes for all particles (use OnlyGenerateParticles) and a subsequent run which performs the particle tracking and particle detection, each node using a subset of the generated particle coordinates.

Say we want to simulate N particles on M HPC nodes. Then we can do the following:

  1. Turn off particle tracking and particle detection via OnlyGenerateParticles.

  2. Generate the initial attributes for all N particles and save as an output of the BasicRecorder class.

  3. Convert this output file to an input file which can be used with the DirectPlacement particle generation model (using vipm-out-to-in).

  4. Split this input file into M input files which will be used on the different nodes.

  5. Turn on particle tracking and particle detection for the sub-simulations on the various compute nodes.

  6. Run the simulation using one (part-)input file for each node.

  7. Merge the results.

Note

If a particle generation model has to generate \(x < 1\) particles at any simulation step then it will create 1 particle with a probability of x.

Generate the input

We prepare the normal configuration which we want to use later on (using the BasicRecorder class with the parameter SkipTrackedParticles set to false), turn off particle tracking and particle detection via Simulation/Parameters/OnlyGenerateParticles and and perform a simulation run which will produce the desired output file with the particles’ initial coordinates.

Then we can use the vipm-out-to-in command line tool to convert the output file to an input file which is suitable for the DirectPlacement particle generation model:

vipm-out-to-in output.csv input.csv --mass=<mass-of-tracked-particles-in-kg>

Now we want to split this input file so the parts can be processed by the different nodes of the cluster. This script performs the necessary actions (it will also create a configuration and a job file for each node).

Now that we’ve done the preparatory work all that is left to do is to submit the job files to the cluster and wait for the results to appear. Don’t forget to turn on particle tracking and particle detection in the configuration files used on the cluster, though.

Merge the results

This script can be used for merging the resulting output files into a single one which can be used for post-processing of the simulation.