RF Track Reference Manual
RF Track Reference Manual
Version 2.3.2
Andrea Latina
AUTHOR AND CONTACT:
Andrea Latina
Beams Department
Accelerator and Beam Physics Group
CERN
CH-1211 GENEVA 23
SWITZERLAND
Copyright and any other appropriate legal protection of this computer program and associated
documentation reserved in all countries of the world. Organisations collaborating with CERN may
receive this program and documentation freely and without charge. CERN undertakes no obligation
for the maintenance of this program, nor responsibility for its correctness, and accepts no liability
whatsoever resulting from its use. Program and documentation are provided solely for the use
of the organisation to which they are distributed. This program may not be copied or otherwise
distributed without permission. This message must be retained on this and any other authorised
copies. The material cannot be sold. CERN should be given credit in all references.
I User Manual
1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
1.1 Getting started 9
1.1.1 Conventions used in this manual . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
1.2 Installing RF-Track 10
1.2.1 On macOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
1.2.2 On Linux . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
1.2.3 On Windows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
1.3 Running RF-Track 11
1.3.1 An example program . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
1.3.2 Physical units . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
1.3.3 Predefined constants . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
1.3.4 Run-time parameters and options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
1.3.5 Random number generators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
1.4 Further information 16
1.4.1 Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
1.4.2 Citing RF-Track in publications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
2 Beam models . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
2.1 Tracking in time or in space 19
2.2 Single-bunch beams 19
2.2.1 Bunch6d . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
2.2.2 Bunch6dT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
2.2.3 Conversion between Bunch6d and Bunch6dT . . . . . . . . . . . . . . . . . . . . . . . . . 25
2.2.4 Coasting beams . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
2.2.5 Particles lifetime . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
2.3 Multi-bunch beams 26
2.3.1 Example of Beam Definition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
2.4 Twiss parameters 27
2.4.1 Bunch6d_twiss . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
2.4.2 Bunch6dT_twiss . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
2.5 Inquiring the bunch properties 28
2.5.1 Bunch6d_info . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
2.5.2 Bunch6dT_info . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
2.6 Bunch persistency 30
2.6.1 Saving and loading a beam on disk . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
2.6.2 Exporting as DST file . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
2.6.3 Exporting as SDDS file . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
2.6.4 Saving the phase space . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
4 Beamline elements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
4.1 Introduction 47
4.1.1 Methods available to all elements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
4.1.2 Tracking the beam properties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
4.2 Matrix-based elements 51
4.2.1 Drift . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
4.2.2 Quadrupole . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
4.2.3 Sector bending dipole . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
4.2.4 Rectangular bending dipole . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
4.2.5 Coil . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
4.2.6 Solenoid . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
4.2.7 Undulator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
4.2.8 Transfer Line . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
4.3 Special elements 62
4.3.1 Travelling-wave structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
4.3.2 Standing-wave structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
4.3.3 Pillbox cavity . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
4.3.4 Multipole magnet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
4.3.5 Absorber . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
4.3.6 Electron cooler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
4.3.7 Adiabatic matching device . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
4.3.8 Space-charge fields . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
4.3.9 LaserBeam . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
4.3.10 Volume as a Lattice element . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
4.4 Field maps 74
4.4.1 1D RF field maps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
4.4.2 2D RF field maps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77
4.4.3 3D RF field maps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79
4.4.4 1D static magnetic field maps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
4.4.5 2D static magnetic field maps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
4.5 Beam diagnostics 83
4.5.1 Beam position monitors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83
4.5.2 Screens . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84
6 Collective effects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89
6.1 Space charge 91
6.1.1 Space-charge in Volume . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
6.1.2 Space-charge in Lattice . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
6.1.3 Space charge models . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
6.2 Incoherent synchrotron radiation 92
6.3 Magnetic multipolar errors 92
6.4 Beam loading 94
6.4.1 Beam loading in ultrarelativistic scenarios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94
6.4.2 Beam loading in standing-wave structures . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96
6.5 Wakefields 98
6.5.1 Short-range wakefield . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98
6.5.2 Generic wakefield . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100
6.5.3 Long-range wakefield . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
6.6 Passage of particles through matter 102
6.6.1 Multiple Coulomb scattering . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102
6.6.2 Stopping power . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102
6.6.3 Energy straggling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102
8 Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107
8.1 Example of bunch creation 107
8.1.1 Bunch6d from an arbitrary user-defined distribution . . . . . . . . . . . . . . . . . . . . 107
8.1.2 Chirped Buch6d from Twiss parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108
Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109
I
User Manual
1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . 9
1.1 Getting started
1.2 Installing RF-Track
1.3 Running RF-Track
1.4 Further information
2 Beam models . . . . . . . . . . . . . . . . . . . . . . . 19
2.1 Tracking in time or in space
2.2 Single-bunch beams
2.3 Multi-bunch beams
2.4 Twiss parameters
2.5 Inquiring the bunch properties
2.6 Bunch persistency
4 Beamline elements . . . . . . . . . . . . . . . . . . 47
4.1 Introduction
4.2 Matrix-based elements
4.3 Special elements
4.4 Field maps
4.5 Beam diagnostics
6 Collective effects . . . . . . . . . . . . . . . . . . . . 89
6.1 Space charge
6.2 Incoherent synchrotron radiation
6.3 Magnetic multipolar errors
6.4 Beam loading
6.5 Wakefields
6.6 Passage of particles through matter
8 Examples . . . . . . . . . . . . . . . . . . . . . . . . . . 107
8.1 Example of bunch creation
Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109
1. Introduction
RF-Track is a tracking code developed at CERN for optimising particle accelerators, offering
outstanding flexibility and rapid simulation speed.
RF-Track can simulate beams of particles with arbitrary energy, mass, and charge, even mixed,
solving fully relativistic equations of motion. It can simulate the effects of space-charge forces,
both in bunched and continuous-wave beams. It can transport the beams through common elements
as well as through “special” ones: 1D-, 2D-, and 3D- static or oscillating radio-frequency electro-
magnetic field maps (real and complex), flux concentrators, and electron coolers. Fast, optimised,
parallel algorithms allow element overlap and direct- and indirect-space-charge calculations.
RF-Track is written in optimized and parallel C++ and uses the scripting languages Octave and
Python as user interfaces. This manual presents its functionalities, underlying physical models, and
their mathematical and numerical implementation. General knowledge of Octave or Python is rec-
ommended to get the best out of RF-Track. For this, we recommend consulting the documentation
of these two powerful tools.
Color code
This manual uses a colour code to distinguish between shell, Octave, or Python commands. Shell
commands entered at the terminal are shown in light grey:
$ command
The first character on the line is the terminal prompt and should not be typed. The dollar sign $ is
used as the standard shell prompt, although some systems may use a different character.
A command entered at the Octave command line is shown in a light ocher box:
octave:1> command
The first string is the standard Octave prompt and should not be typed. It will be, however, omitted
in most examples.
A command entered at the Python command line is shown in a light blue box:
>>> command
The three characters >>> are the standard Python prompt and should not be typed.
In the examples, variables whose name starts with a capital letter will generally refer to vectors
or matrices (e.g. X, XP, Tmatrix, . . . ), whereas variables whose name is in lowercase will refer to
scalars (e.g. mass, charge, time, . . . ).
If you intend to use RF-Track with Octave on macOS, you need to install MacPorts. If you don’t
have MacPorts installed, you will need to install it. If you already have it, it is good practice to
update and upgrade your packages before you proceed:
sudo port selfupdate
sudo port upgrade outdated
Then, you need to issue the following command to install the required packages:
$ sudo port install fftw-3 gsl octave octave-optim
Now, you should download the file RF_Track.oct from the RF-Track page and put it in the
Octave’s path to use it.
1.2.2 On Linux
If you intend to use RF-Track in Linux with Python, it is sufficient to give the command
1.3 Running RF-Track 11
If you intend to use RF-Track with Octave, the binaries provided on the RF-Track page require
Ubuntu (or package-compatible distributions). It is good practice to update all packages before you
install RF-Track:
$ sudo apt-get update
$ sudo apt-get upgrade
Then, you must install the packages needed by RF-Track. On Ubuntu 24.0.4, you can give the
following command:
$ sudo apt install libgsl libfftw octave
1.2.3 On Windows
All Ubuntu binaries also work on Windows under the WSL environment ( https://learn.
microsoft.com/en-us/windows/wsl/install). To install RF-Track on your Windows,
open PowerShell or Windows Command Prompt in administrator mode by right-clicking and
selecting "Run as administrator", then give the following sequence of commands:
wsl --install --web-download -d Ubuntu
sudo apt-get update
sudo apt-get upgrade
sudo apt install python3-pip
pip install RF_Track
sudo apt-get install python3-tk
Or you can add this command to the file .octaverc in your home directory to run it auto-
matically whenever Octave is launched. Then, to load RF-Track, it is sufficient to give the
command:
octave:1> RF_Track;
1 %% Load RF-Track
2 RF_Track;
3
4 %% Beam parameters
5 mass = RF_Track.electronmass; % particle mass in MeV/c^2
6 population = 1e10; % number of particles per bunch
7 Q = -1; % particle charge in units of e
8 Pref = 5; % reference momentum in MeV/c
9 B_rho = Pref / Q; % beam magnetic rigidity in MV/c
10
46 %% Perform tracking
47 B1 = FODO.track(B0);
48
53 %% Make plots
54 figure(1)
55 hold on
56 plot(T(:,1), T(:,2), ’b-’)
57 plot(T(:,1), T(:,3), ’r-’)
58 legend({ ’\beta_x ’, ’\beta_y ’ })
59 xlabel(’S [m]’)
60 ylabel(’\beta [m]’)
61
62 figure(2)
63 scatter(M(:,1), M(:,2), ’*’)
64 xlabel(’x [mm]’)
65 ylabel(’x’’ [mrad]’)
Line 2 stars the games, loading RF-Track into Octave. RF-Track displays a welcome message that
includes some useful information: the version number, the libraries RF-Track was compiled
with, the contact information, and the copyright notice. This call makes the entire set of
RF-Track commands and their predefined constants available to Octave (see the following
section for details about them).
Lines 5-18 declare some Octave variables related to our problem that will be useful later. They
include bunch parameters and FODO cell parameters. Notice, in line 5, the use of the RF-
Track’s constant electronmass, which contains the mass of the electron, here expressed in
MeV/c2 . Other constants exist and are listed in the following sections.
Lines 21-24 define the elements constituting our FODO cell: the focusing quadrupole, the de-
focusing quadrupole, and the drift space between them. The quadrupoles are thin, and for
practical reasons, the focusing one is divided into two, so our FODO cell starts with half a
focusing quadrupole and ends with the other half. This block of lines shows the first two
RF-Track commands we encountered: Quadrupole() and Drift(). These are two objects
that create a quadrupole magnet and a drift space. Line 24 uses a method of the object Drift,
which specifies that the drift must be divided into 100 steps. Dividing a drift into steps
doesn’t help the tracking itself, but here, it tells RF-Track that we want to sample average
quantities like the emittances, beam size and Twiss parameters 100 times along the drift. This
will produce a nice Twiss plot. The two letters “tt” mean that the specified number of steps
refers to the so-called tracking table, a table created during tracking to follow the evolution
of those beam quantities along the lattice.
Lines 27-32 define the FODO lattice itself. An object of type Lattice() is created with the
name FODO. A Lattice() is an empty sequence at creation. Lines 27 through 31 append
to FODO the elements that compose the cell. It is important to understand that internally,
RF-Track stores in FODO a copy of these elements, not the elements themselves. Therefore,
modifying Qf, Qd, or Dr after appending them will not affect FODO.
14 Chapter 1. Introduction
Lines 35-44 define the Twiss parameters and create the bunch B0, which is an instance of the
object Bunch6d() using the defined Twiss parameters. The Twiss parameters are assigned to
Twiss, an instance of Bunch6d_twiss(). B0 is here created with 10’000 macro-particles.
Line 47 tracks the bunch B0 through the FODO cell and stores the outcoming bunch in B1, another
instance of type Bunch6d().
Lines 50-51 retrieve the Twiss parameters and the phase space and store them in two Octave
variables T and M.
Lines 54-65 plot the results using the standard Octave plotting commands.
Figure 1.1 shows the output of the example: the Twiss parameters, βx and βy , and the phase space
plot.
For example, if one needs to define a time interval of 5 ps, say dt, one can write:
1.3 Running RF-Track 15
octave:1> dt = 5 * RF_Track.ps
dt = 1.4990 % 5 ps in mm/c
Parallelism
RF-Track is a parallel application. By default, RF-Track uses the maximum number of threads
available on your machine, max_number_of_threads; however, the user can change this number
(typically to reduce it not to overload the CPU) by setting the variable number_of_threads. In
Octave,
In Python,
The desired number of threads that RF-Track should use (in this example as <YOUCHOOSE>)
16 Chapter 1. Introduction
should not exceed RF_Track.max_number_of_threads. Note that the best RF-Track setup
isn’t necessarily achieved by using all the threads available to your system; sometimes, using less
can lead to faster simulations. This depends on the CPU you are using, the number of particles you
are tracking, and the simulation setup in terms of collective effects, transport table and monitors.
Each simulation case should be studied individually, and a preliminary test using different thread
numbers is recommended to find the optimum.
Environment variables
The number of threads that RF-Track uses can also be specified via the environment variable,
RF_TRACK_NUMBER_OF_THREADS. This allows the user to specify the number of threads at runtime
without modifying the input script. In this example:
Octave will execute the RF-Track script my_rft_script.m using a maximum of eight parallel
threads.
Random Number Generator
Random numbers are used in a multitude of contexts in scientific computing. RF-Track uses
high-quality random number generators. The user can use these three commands to set the desired
random number generator and its initial seed. The default random number generator is “mt19937”
of Makoto Matsumoto and Takuji Nishimura, known as the “Mersenne Twister” generator. The list
of available random number generators is Tab. 1.2.
Name Description
taus2 Maximally equidistributed combined Tausworthe generator by L’Ecuyer
mt19937 Makoto Matsumoto and Takuji Nishimura generator
gfsr4 Lagged-fibonacci generator
ranlxs0 Second-generation version of the RANLUX algorithm of Luscher
ranlxs1 Like the previous by with increased order of strength
ranlxs2 Like the previous by with increased order of strength
mrg Fifth-order multiple-recursive generator by L’Ecuyer, Blouin and Coutre
ranlux Implementation of the original algorithm developed by Luscher
ranlux389 Like the previous but gives the highest level of randomness
ranlxd1 Double precision output (48 bits) from the RANLXS generator
ranlxd2 Like the previous by with increased order of strength
Andrea Latina
"RF-Track Reference Manual", CERN, Geneva, Switzerland, 2024
DOI: 10.5281/zenodo.3887085
@techreport{,
address = {Geneva, Switzerland},
author = {Latina, Andrea},
doi = {10.5281/zenodo.3887085},
institution = {CERN},
title = {RF-Track Reference Manual},
year = {2024}
}
2. Beam models
RF-Track implements two particle tracking methods: tracking in time and tracking in space. The
tracking in time should be preferred in space-charge-dominated regimes, where the relative positions
of the particles in space matter. The tracking in space suits better space-charge-free regions, where
particles are independent of each other, and they can be transported simultaneously from the
entrance plane of an element to its end, element by element.
RF-Track provides two distinct beam types to implement these two models: Bunch6dT for
tracking in time and Bunch6d for tracking in space. A dedicated tracking environment exists for
each of these two beam types: Lattice for Bunch6d, and Volume Bunch6dT. This chapter will
describe them in detail.
2.2.1 Bunch6d
When Bunch6d is used, the tracking is performed using the accelerator longitudinal coordinate S
as the integration variable. This corresponds to what is described in accelerator physics textbooks,
which is at the basis of matrix-based beam optics. In this model, all particles are on the same plane
at a given longitudinal coordinate S at the beginning of an element and are then transported to the
end of the element, updating the arrival time as the longitudinal coordinate. In Bunch6d, the beam
is represented by a set of macro-particles whose state vector is an extended trace space:
x, x0 , y, y0 , t, P, m, Q, N
The meaning of each symbol, along with the units used by RF-Track internally, follows:
20 Chapter 2. Beam models
current_S = B.S; % m
Constructors
A new Bunch6d can be created in multiple ways. The most common ones are two: from a
set of Twiss parameters or directly from a beam matrix with the phase space. Multi-specie
bunches can be created using a beam matrix of the extended phase space. Here is the list of
constructors:
With no arguments, the default constructor allows the creation of an empty beam. The return value
is an object of type Bunch6d.
Table 2.1 shows all possible identifiers accepted by get_phase_space(). The return value
of this function, M, is a matrix with the requested phase space.
B.set_phase_space( [ X XP Y YP T P ] );
The only argument accepted by this method is a 6-column matrix containing the phase space in
Bunch6d format, that is, the phase space columns are x, y, the particle’s transverse position in mm,
x0 , y0 the angles in mrad, t the arrival time in mm/c, and P the total momentum in MeV/c, in the
order given above (x, x0 , y, y0 , t, P).
2.2.2 Bunch6dT
Bunch6dT allows tracking “in time”. When Bunch6dT is used, the time, t, is the integration
variable. The 6D phase-space coordinates of each particle are (X, Y, Z, Px , Py , Pz ). Bunch6dT
maintains, t, the clock common to all particles, updated at each integration step.
In Bunch6dT, the beam is represented by a set of macro-particles whose state vector is an
extended phase space:
X, Px , Y, Py , Z, Pz , m, Q, N, t0
The positions and momenta of each particle are updated as they are transported through the
accelerator. The meaning of each symbol, along with the units used to store the information
internally, follows:
X, Y , Z transverse and longitudinal coordinates [mm]
Px , Py , Pz transverse and longitudinal momenta [MeV/c]
m mass [MeV/c2 ]
Q charge of the single particle [e]
N number of single particles in each macro-particle [#]
t0 creation time [mm/c]
22 Chapter 2. Beam models
In Bunch6dT, a major difference from Bunch6d is the presence of t0 , the creation time of each
particle. This allows, for example, the simulation of cathodes and particle emission. Bunch6dT
also stores the time t at which the bunch is taken, which can be accessed (read and write) like
this:
Constructors
A new Bunch6dT can be created in multiple ways. The most common ones are two: from
a set of Twiss parameters or directly from a beam matrix with the phase space. Multi-specie
bunches can be created using a beam matrix of the extended phase space. Follows the list of
constructors:
B.set_phase_space( [ X Px Y Py Z Pz ] );
The only argument is a 6-column matrix containing the phase space. The input phase space’s
columns are X, Y , Z, the absolute position in mm, and Px , Py , Pz , the absolute momentum in MeV/c,
in the order given in the above (X, Px , Y , Py , Z, Pz ).
B0T = Bunch6dT(B0);
Where B0 is an object of type Bunch6d and B0T an object of type Bunch6dT. When Bunch6d is
converted into Bunch6dT, all particles are set to the same longitudinal coordinate, B0.S, and the
original longitudinal distribution, which B0 carries as distribution of arrival times, is transferred to
Bunch6dT as distribution of creation times.
B.set_coasting(L);
B.set_lifetime(T);
B.set_lifetime( RF_Track.muonlifetime );
For now, a particle that reaches the end of its lifetime is flagged as lost. No new particles are
created.
% Define a bunch
bunch = Bunch6d(mass, charge, q, phase_space);
% Define a beam
B0 = Beam(n_bunches, bunch, bunch_spacing);
Bunches can also be added to a Beam by using the method append(), that comes in three
forms:
B0.append (bunch );
B0.append (bunch, spacing );
B0.append (n_bunches, bunch, spacing );
In the first form, a bunch is added to the Beam with a specified spacing. Note that if the Beam is
empty, the spacing parameter is ignored. The second form adds n_bunches to the beam; like in
the previous form, if the Beam is empty, the spacing parameter is ignored for the first bunch. In the
2.4 Twiss parameters 27
third form, the bunch is added to the beam as it is; no particular spacing is imposed.
The input arguments are:
bunch a Bunch6d (or Bunch6dT with BeamT) [Bunch6d | Bunch6dT]
spacing the bunch spacing [mm/c | mm]
n_bunches the number of bunches to be added [INTEGER]
Follows an example,
It is important to mention that the first Bunch6d added to a Beam is added “as it is”. The arrival
time of the following bunches is adjusted to maintain the user-requested bunch spacing.
Once a Beam is initialized, it can be used for tracking. If “LATTICE” is an arbitrary beamline,
then B1 = LATTICE.track(B0); is the outcoming train, where B1{1} is the first bunch, B1{2}
is the second, etc.
Beam1 = LATTICE.track(Beam0);
B1_0 = Beam1{1}; % The first bunch
B1_1 = Beam1{2}; % The second bunch
B1_2 = Beam1{3}; % The third bunch
2.4.1 Bunch6d_twiss
T = Bunch6d_twiss();
T.emitt_x; % mm.mrad, normalised horizontal emittance x.px
T.emitt_y; % mm.mrad, normalised vertical emittance y.py
T.emitt_z; % mm.permille, normalised longitudinal emittance t.pt
T.sigma_t; % mm/c, rms bunch duration
T.sigma_pt; % permille, normalised energy spread std(E-E_ref)/P_ref
T.alpha_x;
T.alpha_y;
T.alpha_z;
T.beta_x; % m, horizontal beta function
T.beta_y; % m, vertical beta function
T.beta_z; % m, longitudinal beta function
28 Chapter 2. Beam models
Notice that the longitudinal phase space can be specified in three alternative ways:
1. Giving both the normalised longitudinal emittance emitt_z and the Twiss parameter βz .
2. Giving the normalised longitudinal emittance emitt_z and either sigma_t or sigma_pt.
3. Giving both sigma_t and sigma_pt.
2.4.2 Bunch6dT_twiss
T = Bunch6dT_twiss();
T.emitt_x; % mm.mrad, normalised horizontal emittance x.px
T.emitt_y; % mm.mrad, normalised vertical emittance y.py
T.emitt_z; % mm.permille, normalised longitudinal emittance z.pz
T.sigma_z; % mm, rms bunch length
T.sigma_pz; % permille, norm. long. momentum spread std(Pz-P_ref)/P_ref
T.alpha_x;
T.alpha_y;
T.alpha_z;
T.beta_x; % m, horizontal beta function
T.beta_y; % m, vertical beta function
T.beta_z; % m, longitudinal beta function
T.disp_x; % m, horizontal dispersion
T.disp_px; % rad, horizontal dispersion’
T.disp_y; % m, vertical dispersion
T.disp_py; % rad, vertical dispersion’
T.disp_z; % m, longitudinal dispersion
Similarly to Bunch6d_Twiss, the longitudinal phase space can be specified in three alternative
ways:
1. Giving both the normalised longitudinal emittance emitt_z and the Twiss parameter βz .
2. Giving the normalised longitudinal emittance emitt_z and either sigma_z or sigma_pz.
3. Giving both sigma_z and sigma_pz.
I = B.get_info();
2.5.1 Bunch6d_info
If B is a bunch of type Bunch6d, B.get_info() returns:
I = B.get_info();
I.S; % m
I.mean_x; % mm, average H position
I.mean_y; % mm, average V position
I.mean_t; % mm/c, average arrival time
I.mean_xp; % mrad, average H angle
I.mean_yp; % mrad, average V angle
I.mean_Px; % average Px in MeV/c
I.mean_Py; % average Py in MeV/c
I.mean_Pz; % average Pz in MeV/c
I.mean_P; % average momentum in MeV/c
I.mean_K; % average kinetic energy in MeV
I.mean_E; % average total energy in MeV
I.sigma_x; % mm
I.sigma_y; % mm
I.sigma_t; % mm/c
I.sigma_xp; % mrad
I.sigma_yp; % mrad
I.sigma_xpx; % mm*mrad
I.sigma_ypy; % mm*mrad
I.sigma_tpt; % mm/c*permille
I.sigma_E; % energy spread in MeV
I.sigma_P; % momentum spread in MeV/c
I.emitt_x; % mm.mrad, normalised emittance
I.emitt_y; % mm.mrad, normalised emittance
I.emitt_z; % mm.permille, normalised emittance (sigma_t*sigma_d)
I.emitt_4d; % mm.mrad, 4d normalised emittance
I.emitt_6d; % mm.mrad, 6d normalised emittance
I.alpha_x;
I.alpha_y;
I.alpha_z;
I.beta_x; % m
I.beta_y; % m
I.beta_z; % m
I.rmax; % mm, largest particle’s xy distance from the origin
I.transmission; % percent
2.5.2 Bunch6dT_info
If B is a bunch of type Bunch6dT, B.get_info() returns:
I = B.get_info();
30 Chapter 2. Beam models
I.t; % mm/c
I.mean_X; % mm, average H position
I.mean_Y; % mm, average V position
I.mean_S; % mm, average L position
I.mean_Px; % MeV/c, average H momentum
I.mean_Py; % MeV/c, average V momentum
I.mean_Pz; % MeV/c, average L momentum
I.mean_K; % average kinetic energy in MeV
I.mean_E; % average total energy in MeV
I.sigma_X; % mm
I.sigma_Y; % mm
I.sigma_Z; % mm
I.sigma_Px; % MeV/c
I.sigma_Py; % MeV/c
I.sigma_Pz; % MeV/c
I.sigma_XPx; % mm*MeV/c
I.sigma_YPy; % mm*MeV/c
I.sigma_ZPz; % mm*MeV/c
I.sigma_E; % energy spread in MeV
I.emitt_x; % mm.mrad normalised emittance
I.emitt_y; % mm.mrad normalised emittance
I.emitt_z; % mm.permille, normalised emittance (sigma_z*sigma_pt)
I.emitt_4d; % mm.mrad, 4d normalised emittance
I.emitt_6d; % mm.mrad, 6d normalised emittance
I.alpha_x;
I.alpha_y;
I.alpha_z;
I.beta_x; % m
I.beta_y; % m
I.beta_z; % m
I.rmax; % mm, largest particle’s xy distance from the origin
I.transmission; % percent
B.save(filename);
B.load(filename);
The beam is saved as a binary file. This ensures that the saved and loaded beams are bit-wise
identical. Note that the binary format used by each architecture to store double-precision numbers is
hardware- and architecture-dependent and may vary from computer to computer. For this reason, a
2.6 Bunch persistency 31
particular architecture may be unable to read a file saved on another hardware architecture because
their internal representation of double precision numbers is different.
B.save_as_dst_file(filename, frequency_in_MHz);
B.save_as_sdds_file(filename, description);
free regions. Volume is more flexible and can handle space-charge effects, but it’s CPU-consuming.
This chapter describes these two environments and all the elements available to the user.
3.2 Lattice
Before setting up a lattice, one needs to create an object of type Lattice:
L = Lattice ();
All options regarding the integration algorithms or the presence of collective effects are element-
dependent and must be specified element by element.
L.append(element);
L.append(lattice);
L.insert(lattice);
It is important to understand that these methods add a copy of the element to a Lattice, not the
element itself. In C++ jargon, one would say that the elements are added “by value” – and not
“by reference”. This means that, after appending or inserting an element to a Lattice, whatever
modification one applies to the original element will not affect the copy added to a Lattice.
If one wants to modify one element after the element has been added to a Lattice, and avoid
wasting memory when appending several instances of the same element, one can pass the element
“by reference”. This can be done using the following methods:
L.append_ref(element);
L.insert_ref(lattice);
For example, this could be useful when dealing with large field maps: adding multiple identical
copies of the same field map to a Lattice would be just memory-consuming and redundant.
L = Lattice (’twiss_file.tws’);
In this form, Lattice imports the entire Twiss file ’twiss_file.tws’ from MAD-X and creates
a Lattice containing the corresponding elements. The Twiss file must be saved in MAD-X using the
commands:
Elements can be misaligned by specifying their offsets when added to the Lattice or randomly
scattering them. The following variants of the method append allow an element to be added to a
Lattice by specifying its installation offsets:
Random misalignment
Elements can also be scattered randomly using the following Lattice methods:
The elements will be scattered according to normal distributions whose sigma are the parameters
specified in these commands. The arguments are:
36 Chapter 3. Tracking the beam
B1 = L.track(B0);
where the only input argument is the beam to be tracked, and the return value is the beam at the exit
of the lattice.
In Python:
In both Octave and Python, the string ’NAME’ accepts wildcards. Note that the attributes of each
element can be changed dynamically. For example,
3.3 Volume 37
3.3 Volume
V = Volume();
To place elements into Volume, you can use the method add, which comes in many flavours:
In Python:
In both Octave and Python, the string ’NAME’ accepts wildcards. Like in a Lattice, each element
can be changed dynamically. See the previous section about Lattice for an example.
B1 = V.track(B0, options);
B1 = V.track(B0);
When integrating the equations of motion, RF-Track distributes the particles among all available
CPU threads and performs parallel tracking. When a collective effect is due to be considered,
RF-Track must retrieve all particles from each thread and only then can compute the collective
effect. This mechanism necessarily breaks the parallel tracking, even though the calculation of the
collective effects is performed in parallel.
Breaking the parallelism of tracking certainly slows it down. For this reason, it is usually
desirable to apply collective effects kicks at a larger time step than the step used to integrate the
equations of motion. A convergence study is recommended to find the optimal compromise between
the tracking speed and the results’ accuracy.
Similar slowdowns occur in the periodic evaluation of the transport table entries or while saving
the beam to disk when using watchpoints.
Tracking Options
In Volume, RF-Track performs tracking by numerically integrating the equations of motion over
time. This numerical integration is staggered: larger time steps are used for collective effects, while
smaller steps are used to evolve the beam through the elements’ electromagnetic fields accurately.
RF-Track allows the user to specify these time steps and choose the algorithm to integrate the
equations of motion through the so-called TrackingOptions. A description of the Tracking-
Options is available in Table 3.1.
Integration algorithms
Among the integration algorithms, ‘leapfrog’ (which, more precisely, implements the Verlet
integration method) is the fastest. This is the default. The greater speed of Leapfrog comes at the
expense of accuracy. Excellent accuracy at a reasonable computational cost is offered by ‘rk2’, the
recommended alternative to leapfrog.
Algorithm Description
’analytic’ This algorithm solves analytically the equations of motion assuming a locally
constant field. In truly constant fields, this algorithm gives a solution that is
exact. In non-constant fields, its accuracy depends on the size of the integration
step. This algorithm is symplectic only in truly constant fields.
’leapfrog’ This algorithm updates positions and momenta at different interleaved time
points. It’s a second-order symplectic algorithm.
’rk2’ Explicit embedded Runge-Kutta (2, 3) method.
’rk4’ Explicit 4th order (classical) Runge-Kutta. Error estimation is carried out by
the step doubling method. For more efficient estimate of the error, use the
embedded methods described below.
’rkf45’ Explicit embedded Runge-Kutta-Fehlberg (4, 5) method. This method is a
good general-purpose integrator.
’rkck’ Explicit embedded Runge-Kutta Cash-Karp (4, 5) method.
’k8pd’ Explicit embedded Runge-Kutta Prince-Dormand (8, 9) method.
’msadams’ A variable-coefficient linear multistep Adams method in Nordsieck form. This
stepper uses explicit Adams-Bashforth (predictor) and implicit
Adams-Moulton (corrector) methods in P(EC)m functional iteration mode.
Method order varies dynamically between 1 and 12.
The first three are sufficient in most cases; however, we recommend performing convergence studies
and speed tests to select the most appropriate algorithm for your case.
% Create Volume
V = Volume();
% Perform tracking
V.track(B0);
42 Chapter 3. Tracking the beam
% Setting S0
V.set_s0 (z)
V.set_s0 (P0, t);
V.set_s0 (x, y, z, roll=0, pitch=0, yaw=0);
% Setting S1
V.set_s1 (z);
V.set_s1 (P0, t);
V.set_s1 (x, y, z, roll=0, pitch=0, yaw=0);
By
Latt
ice 1 ice 2
Latt
S0
S1
% A Lattice
L = Lattice();
L.append (Lattice1)
L.append (Dipole)
L.append (Lattice2)
When tracking through L is performed, the particles coming from Lattice1 are distributed over the
plane s0 of Dipole, tracked through the Volume Dipole, and collected at s1 to form a Bunch6d
suitable to continue tracking through Lattice2.
For a detailed tracking of the transport table quantities, a Volume can be sliced into slices using
the method set_tt_nsteps() like any Lattice element. Continuing with the example shown in
Fig. 3.1, and described conceptually in the previous script, the line
Dipole.set_tt_nsteps(20);
tells RF-Track that we want to track the lattice transport table in 20 steps. To calculate the Lattice
transport table, RF-Track will then distribute 20 screens perpendicular to the curved trajectory
between s0 and s1 .
44 Chapter 3. Tracking the beam
Particles that are lost during tracking can be retrieved from the Lattice or Volume in which they
were lost. This can be done using the following methods:
M = V.get_lost_particles();
M = L.get_lost_particles();
Both methods return an 11-column matrix with the information on where and when each particle
was lost. The information is given in the reference frame of the element itself.
In the case of Lattice, the 11 columns are:
1. X in mm
2. XP in mrad
3. Y in mm
4. YP in mrad
5. T in mm/c
6. P in MeV/c
7. S in mm, the longitudinal at which the particle was lost
8. MASS, in MeV/c2
9. Q in e
10. N the macro-particle charge
11. ID the particle ID
Time-dependent elements such as RF accelerator structures (be they field maps or analytical
travelling- or standing-wave structures), Screens, or the LaserBeam element for Compton scatter-
ing simulation need to know the absolute arrival time of the beam to operate synchronously and
correctly. The method set_t0(), available in any mentioned time-dependent elements, allows
the user to manually set the beam’s arrival time. However, while knowing the exact arrival time
of the beam at each element may seem relatively straightforward for ultra-relativistic beams, it
can be very tricky in the case of long beamlines or heavy particles travelling at velocities v < c.
Fortunately, RF-Track can set the phases automatically for you with the method autophase().
3.5 Synchronization of time-dependent elements with the beam 45
3.5.1 Autophasing
The autophase() method, available in both Lattice and Volume, synchronises each beamline
element with the beam by sending a test bunch and recording the beam’s arrival time, element by
element. Here is an example where B0, a Bunch6d representing an electron bunch with a total
charge of 100 pC and average momentum Pref (Pref), is used to “autophase” a lattice L.
In this example, autophase() is given a single reference particle as an input. If one gives a full
bunch, like in this case B0, the autophasing will be performed with the average particle.
After autophase(), all time-dependent elements are set to the actual arrival time of P0 at each
element, and no manual setting of t0 is required. Any subsequent use of the L lattice will use
the phases and arrival times set by this autophasing. The autophase() method returns the final
momentum achieved by the reference particle P0 after autophasing all structures and time-dependent
elements.
For RF elements, autophase() doesn’t just set the arrival time; it also finds the synchronous
phase of the structure to the beam. More precisely, it sets the RF phase of the element so that a
zero phase phid corresponds to an on-crest acceleration. This step is preciously helpful, as it frees
the user from the additional –painstaking– task of determining the actual phase of each RF element1 .
N OTE 2: Any item whose reference time has been set by the user with set_t0() will be ignored
by autophase() and will retain the user-supplied value.
.
N OTE 3: If the user omits to call autophase() explicitly, and calls track() directly, RF-Track
will perform autophase automatically.
Given k1 , RF-Track can postpone the magnet’s actual gradient setting until it knows the beam
energy. To do so, it is sufficient to provide NaN as reference momentum at the moment of the
magnet’s creation. For example,
% Define a quadrupole
Q = Quadrupole (L, P_Q, k1);
3.6 Backtracking
RF-Track can perform backtracking. Element misalignments and collective effects that don’t
involve random processes (like scattering and incoherent synchrotron radiation) are fully considered
in backtracking. Using the btrack() method, backtracking is possible in both Lattice and Volume.
Here is an example:
% Backtracking to find B0
B0 = L.btrack (B1);
Backtracking can be useful for finding the initial beam distribution providing a specific final
distribution.
4. Beamline elements
4.1 Introduction
RF-Track provides a large set of elements, from the conventional matrix-based quadrupole and
sector bends to more sophisticated ones like complex field maps and analytic fields permeating the
whole 3D space. This chapter gives a short description of the constructors for each element.
In some elements, specific attributes cannot be directly set via the constructor but can be set
using appropriate “set” methods. The most relevant methods are given for each element type. The
user can access a list of all methods using the interactive prompts of Octave and Python.
See the dedicated chapter for a list of the collective effects implemented in RF-Track.
D = Drift(1);
D.set_tt_nsteps(100);
which will track the beam through the drift D in 100 steps, sampling the phase space in that many
points. Table 4.1 lists all the accepted identifiers.
To enable a transport table in Volume(), it is sufficient to specify the option tt_dt_mm in the
tracking options, specifying the time interval, in mm/c, between two consecutive samplings. Table
4.2 lists all the accepted identifiers.
4.1 Introduction 49
4.2.1 Drift
An empty region of space.
Constructor
Set methods
These first two methods, used on a Drift, allow the simulation of localised regions of space
where a static electromagnetic field is present. For example, one could use this to simulate a static
accelerating field.
The method add_collective_effects() allows having localised regions of space where
specific collective effects act on the beam. In combination with the MultipleCoulombScattering
effect, one can, for instance, simulate regions in the air or other materials.
52 Chapter 4. Beamline elements
4.2.2 Quadrupole
A matrix-based quadrupole magnet.
Constructors
Get methods
Set methods
Q.set_K1(P_Q, k1);
Q.set_K1L(P_Q, k1L);
Q.set_length(L);
Q.set_gradient(G);
Q.set_strength(strength);
Examples
If one has a 20 cm long quadrupole, with k1 = 0.1 m−2 , for a proton beam with P = 200 MeV/c,
one can use the following lines:
Figure 4.1: The reference system for a sector-bending magnet; the signs of pole-face rotations are
positive, as shown. Figure retrieved from the MAD-X documentation.
Constructors
Get methods
Set methods
The obvious ones, plus:
S.set_h(H); % 1/m, set the curvature of the reference system
S.set_hgap(HGAP); % m, the half gap of the magnet
S.set_fint(FINT); % the fringe field integral
with g = 2 HGAP.
The default value FINT of zero corresponds to the hard-edge approximation, i.e. a rectangular
field distribution. For other approximations, one can refer to the following pre-computed values of
FINT:
Constructor
4.2.5 Coil
The element Coil creates the magnetic field generated by an electromagnetic coil.
Constructors
The coil is placed in the middle of the specified length L. When a Coil is placed in a Volume, its
field permeates the whole 3D space. Warning: When used in Lattice, the field exists only within
the extent of the specified element length, with the coil placed in the middle.
See also the element Solenoid.
58 Chapter 4. Beamline elements
4.2.6 Solenoid
The element Solenoid allows the insertion of a Solenoid magnet into a Lattice or a Volume. When
a Solenoid is inserted into a Lattice, RF-Track will treat it as a matrix element. When Solenoid
is inserted into a Volume, RF-Track will compute the 3D magnetic field of the magnet using analytic
equations. In this latter case, the field permeates the whole 3D space, overlaps with other fields in
the same Volume, and includes realistic fringe regions.
Constructor
0.6
2.5
0.4
2.0
0.2
1.5
|B| [T]
x [m]
0.0
0.2 1.0
0.4 0.5
0.6
1.00 0.75 0.50 0.25 0.00 0.25 0.50 0.75 1.00
z [m]
4.2.7 Undulator
The element Undulator allows the insertion of a planar Undulator into a Lattice or a Volume.
When particles travel through an Undulator, RF-Track computes the 3D magnetic field of the
magnet using analytic equations and integrates the equations of motion using numerical integration.
Constructor
Figure 4.3: The parameter kx2 describes the shape of the undulator’s poles.
60 Chapter 4. Beamline elements
Constructors
T = TransferLine("twiss_file.dat", Pref);
T = TransferLine(twiss_matrix, DQx, DQy, momentum_compaction, Pref);
T = TransferLine(twiss_matrix, Pref);
% Input data
Pref = 100; % MeV/c, reference momentum
L = 5; % m, length of the matching section
Table 4.3: Fourier series expansions of the TM01n electromagnetic fields in a TW structure
Quantity Value
∆ϕ
k0
L
2nπ
kn k0 +
L
ω
βn
ckn
s
ω 2
qn − (kn )2
c
(
∞ J0 (qn r) |βn | ≥ 1
Ez (r, z,t) ∑ an sin [(ωt + φ0 ) − kn z] × I (q r) |β | < 1
n=−∞
(0 n n
∞
an kn J1 (qn r) |βn | ≥ 1
Er (r, z,t) ∑ qn cos [(ωt + φ0 ) − kn z] × I (q r) |β | < 1
n=−∞ 1 n n
(
∞ a q2 + k 2
n n n J1 (qn r) |βn | ≥ 1
Bθ (r, z,t) ∑ cos [(ωt + φ0 ) − kn z] ×
n=−∞ ωqn I1 (qn r) |βn | < 1
of one cavity cell, then the Fourier series expansions of the excited TM01n modes in the cell are
given by the expressions presented in Table 4.3.
Constructors
[an, ... ] a vector with the Fourier coefficients (see Table 4.3) [V/m]
n the index of the first coefficient [INTEGER]
frequency the rf frequency [Hz]
phase_advance the structure’s phase advance per cell [rad]
number_of_cells the number of cells in the structure. [REAL]
A positive number of cells indicates that the structure starts from the middle of the cell. A negative
number indicates that the structure starts from the beginning of a cell. Follows an example with
three cells:
• number_of_cells = 3
• number_of_cells = -3
Function, respectively.
Table 4.4: Fourier series expansions of the TM01p electromagnetic fields in a SW structure. In these
equations, the flat ends of a cell are at z = 0 and z = L
Quantity Value
pπ
kp
L
s
ω 2
qp − k2p
c
(
∞ J0 (q p r) ωc ≥ k p
Ez (r, z,t) ∑ p a sin (k p z) cos (ωt + φ 0 ) ×
I (q r) ωc < k p
p=1
(0 p
∞
kp J1 (q p r) ωc ≥ k p
Er (r, z,t) a
∑ qp p cos (k p z) cos (ωt + φ 0 ) ×
p=1 I1 (q p r) ωc < k p
(
∞ q2p + k2p J1 (q p r) ωc ≥ k p
Bθ (r, z,t) a
∑ p ωq p sin (k p z) sin (ωt + φ 0 ) ×
p=1 I1 (q p r) ω < k p
c
Constructors
As for the travelling-wave structure, a positive number of cells indicates that the structure starts
from the start of the cell. A negative number indicates that the structure starts from the centre of a
cell. Follows an example with three cells:
• number_of_cells = 3
• number_of_cells = -3
% Input arguments
% maxE is the rf gradient in V/m
% phid is the rf phase in deg
% Fourier modes SW
A_SW = [ 6.192020020706116e-01 -6.953816923003616e-04 ... % k1, k2
-3.279125409035794e-01 1.043714164141073e-04 ... % k3, k4,
8.257347316504823e-02 -1.849214043458953e-04 ... % ...
8.669595750563971e-03 2.327131602259179e-04 ...
-1.597554108422184e-02 -4.434041973047716e-04 ...
5.789529950425815e-03 ];
% Fourier modes TW
A_TW = [ 0.00132212262396783 -0.01924391586275388 ...
0.29326128415666941 0.75002581163937343 ...
-0.02662679741546326 0.00126167879112374 ...
8.3563612959562393e-06 ];
66 Chapter 4. Beamline elements
% entrance coupler
SWL = SW_Structure(maxE * A_SW, freq, L_SW, 0.5); % 1/2 SW
SWL.set_t0(0.0);
SWL.set_phid(phid);
% travelling wave
TW = TW_Structure(maxE * A_TW, -3, freq, ph_adv, n_cells);
TW.set_t0(0.0);
TW.set_phid(phid+90);
% exit coupler
SWR = SW_Structure(maxE * A_SW, freq, L_SW, -0.5); % 1/2 SW
SWR.set_t0(0.0);
SWR.set_phid(phid);
In this example, a fitting procedure has been used to compute the Fourier coefficients from a 1D
field map.
4.3 Special elements 67
Table 4.5: Fourier series expansions of the TM01p electromagnetic fields in a pillbox cavity
Quantity Value
pπ
kp
L
s
ω 2
qp − k2p
c
(
∞ J0 (q p r) ω ≥ k p
Ez (r, z,t) ∑ a p cos (k p z) cos (ωt + φ0 ) × I (q r) ωc < k
p=0 0 p c p
(
ω
∞
kp J1 (q p r) c ≥ k p
Er (r, z,t) − ∑ a p sin (k p z) cos (ωt + φ0 ) ×
qp I (q r) ωc < k p
p=0
(1 p
∞ q2p + k2p J1 (q p r) ω ≥ k p
Bθ (r, z,t) ∑ a p ωq p cos (k p z) sin (ωt + φ0 ) × I (q r) ωc < k
p=0 1 p c p
Constructors
Constructors
The strengths, the multipole coefficients, and the field derivatives are vectors of complex numbers:
B̂ = By + i Bx ,
(normal) (skew)
k̂n = kn + i kn .
∂ n By mn
(normal) T·m
kn = , [1/mn+1 ]
Bρ ∂ xn T
∂ n Bx mn
(skew) T·m
kn = − n . [1/mn+1 ]
Bρ ∂x T
Get methods
The obvious ones, plus:
Set methods
The obvious ones, plus:
S.set_Bn([ B0 B1 B2 ... ]); % T/m^n, set the field derivatives
S.set_KnL(P_over_Q, [ K0L K1L K2L ... ]); % set the integrated coefficients
S.set_strengths([ S0 S1 S2 ... ]); % MV/c/m^n, set the integrated strengths
4.3.5 Absorber
The Absorber element is a block of matter where three effects affecting the beam are applied
simultaneously: Multiple Coulomb scattering, EnergyStraggling, and Stopping Power. This allows
the simulation of the interaction between the bunch particles and materials. For a detailed description
of the three effects, read the dedicated chapter.
Constructors
A = Absorber ( L, material_name );
A = Absorber ( L, X0, Z, A, density, I=-1 );
Main methods
A set of ‘enable’ and ‘disable’ methods allow the full customization of this element.
A.enable_log_term();
A.enable_fruehwirth_model(); % DEFAULT
A.enable_wentzel_model(); % DEFAULT
A.enable_stopping_power(); % DEFAULT
A.enable_energy_straggling(); % DEFAULT
A.enable_multiple_coulomb_scattering(); % DEFAULT
A.disable_log_term(); % DEFAULT
A.disable_fruehwirth_model();
A.disable_wentzel_model();
A.disable_stopping_power();
A.disable_energy_straggling();
A.disable_multiple_coulomb_scattering();
4.3 Special elements 71
% Plasma mesh
EC.set_temperature (Tr, Tl);
EC.set_electron_mesh (Nx, Ny, Nz, density, Vx, Vy, Vz); % uniform plasma
EC.set_electron_mesh (Nz, DENSITY2D, VX2d, VY2D, VZ2D); % 2D profile
EC.set_electron_mesh (DENSITY3D, VX3D, VY3D, VZ3D); % full 3D mesh
% Magnetic field
EC.set_static_Bfield (Bx, By, Bz);
Constructor
4
Bz (T)
0
0 0.05 0.1 0.15 0.2 0.25
Z (m)
4.3.9 LaserBeam
In Lattice, RF-Track can simulate inverse Compton scattering (ICS) between any charged particle
and a laser beam in an element called LaserBeam. Chapter 5 explains this element and the ICS
simulation in detail.
4.3 Special elements 73
Interpolation methods
RF-Track offers two interpolation methods
• Linear interpolation (LINT), the field is evaluated at any point by linearly interpolating with
the eight nearest mesh points. This method is very fast and is the default method.
• Cubing interpolation (CINT), the field is evaluated in any point by cubically interpolating
with the nearest 64 mesh points. This method is significantly slower but produces a smoother
field.
Constructors
RF = RF_FieldMap_1d(Ez,
hz,
length,
frequency,
direction,
P_max = 1,
P_actual = 1);
RF = RF_FieldMap_1d_CINT ( " );
The default element RF_FieldMap_1d uses linear interpolation along the longitudinal axis and
linear extrapolation in the radial direction. The variant, RF_FieldMap_1d_CINT, uses cubic
interpolation along the longitudinal axis and cubic extrapolation in the radial direction.
The required input arguments are:
Ez The on-axis electric field [V/m]
hz The mesh cell in the longitudinal direction [m]
length the total length of the element (if -1 take the field map length) [m]
frequency The RF frequency (use 0 for static fields) [Hz]
direction 0 : static field
1 : forward-travelling field
−1 : backward-travelling field
P_map The input power used to generate the input field map (default 1) [W]
P_actual The actual input power to operate the element (default 1) [W]
If the user only needs to simulate an electric or magnetic field, the constant number zero, 0, can be
provided for the unnecessary field components.
Main methods
A set of dedicated methods allows the user to set the phase, the reference time, and the actual input
power to the structure:
RF.set_t0(T0);
RF.unset_t0();
RF.set_phid(PHID);
RF.set_P_actual(P);
RF.set_smooth(N);
If the input field map already provides the nominal field, one can accept the default values Pmap = 1
and Pactual = 1 to provide an unscaled field.
4.4 Field maps 77
Constructors
RF = RF_FieldMap_2d(Er, Ez,
Bt, Bz,
hr, hz,
length,
frequency,
direction,
P_max = 1,
P_actual = 1);
RF = RF_FieldMap_2d_CINT ( " );
Main methods
A set of dedicated methods allows the user to set the phase, the reference time, and the actual input
power to the structure:
RF.set_t0(T0);
RF.unset_t0();
78 Chapter 4. Beamline elements
RF.set_phid(PHID);
RF.set_P_actual(P);
RF.set_smooth(N);
If the input field map already provides the nominal field, one can accept the default values Pmap = 1
and Pactual = 1 to provide an unscaled field.
4.4 Field maps 79
RF.unset_t0();
RF.set_phid(PHID);
RF.set_P_actual(P);
RF.set_smooth(N);
If the input field map already provides the nominal field, one can accept the default values Pmap = 1
and Pactual = 1 to provide an unscaled field.
4.4 Field maps 81
Constructors
Constructors
Constructor
After tracking, to get all Bpms’ readings at once, one can call the method get_bpm_readings()
of the Lattice object.
Get methods
Set methods
B.set_resolution(res); % accept mm
B.set_scaling_factor(X_scaling, Y_scaling = X_scaling);
84 Chapter 4. Beamline elements
4.5.2 Screens
The Screen element adds a Screen to a Lattice or Volume. A screen is a thin element that captures
a snapshot of the phase space of a Beam or just a Bunch6d when this is traversing the screen itself.
Screens can have a finite extension and a specific time window; see the methods below. When a
time window is specified, the screen is automatically synchronized to the first bunch traversing the
screen unless the user selects a specific activation time.
In a Lattice, Screens can be placed between elements with any arbitrary offset. In Volume,
Screens can be placed in any position with any orientation in space. When a bunch traverses a
screen, RF-Track retains the arrival time of each particle at the screen and creates a Bunch6d with
the bunch’s phase space in the screen’s reference system.
After tracking, the phase space of the bunch (or of the beam) can be retrieved from Volume
and Lattice using the methods get_bunch_at_screens() or get_beam_at_screens(), de-
pending on whether one is tracking a single or multi-bunch beam. These methods return a list of
Bunch6d’s or Beams objects, one per screen.
Constructor
S = Screen ();
Get methods
Set methods
5.1 Introduction
RF-Track can simulate laser beams. The laser can interact with electrons, positrons, or any other
charged particle through Thompson and Compton scattering. The element LaserBeam allows the
laser beam’s initialisation.
RF-Track provides several functions that can fine-tune the laser-beam interaction conditions.
The effects of position and angle offsets can be implemented for the laser beam, which allows for
the study of misalignments and other imperfections.
LB = LaserBeam();
LB.pulse_energy; % mJ, laser pulse energy
LB.pulse_length; % ps, laser pulse length
LB.wavelength; % nm, laser wavelength
LB.length; % m, length of the interaction region
LB.P; % laser polarization, abs(P)<=1
LB.R; % mm, laser sigma spot size, can be Gaussian or tophat profile
LB.Rx; % mm, horizontal sigma spot size
LB.Ry; % mm, vertical sigma spot size
LB.M2 = 1; % laser beam quality factor
LB.rep_frequency = 0; % Hz, the laser repetition frequency
LB.number_of_pulses = 1; % number of pulses in the train
The laser beam size can be defined in two ways: for a symmetrical laser beam profile, you can
86 Chapter 5. Inverse Compton scattering
use LB.R; if the beam is asymmetrical along two orthogonal axes, you can use LB.Rx and LB.Ry.
Note that LB.R is half the 1/e2 laser waist radius, w0 .
The parameter LB.P allows you to set the polarization of the laser beam. For the time being,
only linear polarization is implemented. The default setting, LB.P = NaN, means unpolarized laser
beam.
It should be highlighted that the length of the interaction region can be zero, meaning that one
can insert a laser-beam interaction point as a thin element in a lattice. RF-Track calculates the laser
beam interaction by reconstructing the 3D shape of the bunch in free space from the moment of
first contact between the particles and the laser beam until the moment of separation of the two
colliding bunches. This operation works also if the length of the interaction region is zero.
LB.set_position(Z);
LB.min_number_of_gammas_per_slice(nr_gamma);
Where nr_gamma is an integer for the number of photon macro-particles simulated per slice.
in RF-Track. A large number of steps improves the precision of the simulation but increases the
runtime.
LB.set_nsteps(nsteps);
Where nsteps is an integer, the number of steps taken during the simulation across the interaction
region. An odd number of steps is recommended to capture the interaction in the central step.
In RF-Track, multiple single-particle and collective effects can be added to each element and
overlapped. If, for example, one needs to simulate two collective effects, say CFX1 and CFX2, one
can do:
to have both effects act on the beam when the beam travels through the element E.
In Lattice, the effects are uniformly distributed along the element over a user-defined number
of steps set through the method set_cfx_nsteps():
E.set_cfx_nsteps( NUMBER_OF_STEPS );
The collective effect’s kicks are applied following a “velocity Verlet” algorithm, similar to the
leapfrog method. This means that if, for example, one specifies just one step, the algorithm will
apply a half-kick at the beginning of the element, track through the element in one step, and then
apply the second half-kick at the end of the element.
In Volume, the user must specify how frequently the collective effects should be computed,
setting the tracking option fx_dt_mm, a time step expressed in mm/c. Since the computation of
the collective effects could be CPU-intensive, one wants to set cfx_dt_mm as usually larger than
tracking option dt_mm, the step chosen for accurately integrating the equations of motion. This way,
the tracking is performed in parallel between two consecutive kicks of collective effects. Follows
an example:
90 Chapter 6. Collective effects
V = Volume();
V.dt_mm = 0.1; % mm/c, fine integration step
V.cfx_dt_mm = 10; % mm/c, apply collective effects every 10 mm/c
6.1 Space charge 91
V = Volume()
V.sc_dt_mm = 10; # mm/c
Like cfx_dt_mm, one typically wants sc_dt_mm larger than the integration step dt_mm to take ad-
vantage of parallel tracking in cases where the bunch charge distribution doesn’t change significantly
from one space charge kick to the next.
In Python,
This is usually done at the beginning of a script, as it affects all subsequent space charge calculations.
The default engine is SpaceCharge_PIC_FreeSpace(32, 32, 32).
I = IncoherentSynchrotronRadiation( QUANTUM=false );
If QUANTUM is set to true, the synchrotron radiation emission will be a stochastic Monte Carlo
process; otherwise, the effect will be an average energy loss. Notice that the emission of synchrotron
radiation is generated by any fields acting on the particle, both electric and magnetic.
The real part of each Bn represents the field’s “normal” component, and the imaginary part represents
the “skew” component.
94 Chapter 6. Collective effects
Constructors
Solve methods
For trains with bunches of equal charge and fixed spacing, the beam-induced gradient exhibits a
transient behaviour which, after a certain time (tfill for TW structures or 5τ for SW structures),
stabilises at the so-called steady state. In this case, the beam-induced gradient be retrieved with the
following constructors:
Set methods
Two common strategies exist for beam loading compensation: (1) Injecting bunches early in the
structure before its RF-filling and (2) optimising the input-power pulse shape in TW structures.
Bunch injection and input-power profile can be arbitrarily defined in RF-Track before tracking
using the following constructors:
Get methods
Some structure-relevant magnitudes, as well as the beam-induced and unloaded gradients, can be
retrieved from the constructors as follows:
%Structure information
BL.get_Lcell(); % Cell length, m
BL.get_tfill(); % Filling time, mm/c
BL.get_z0(); % Starting longitudinal coordinate, m
BL.get_z1(); % Ending longitudinal coordinate, m
BL.get_wake_function(); % Longitudinal wakefield, V/pC/m
The function BL.get_wake_function() retrieves the longitudinal wakefield associated with the
excitation of the fundamental mode, which is the one on which the implementation of the BL kick
is based, as discussed in [LINAC24].
Further longitudinal short-range effects arising from higher-order modes can be simulated with
ShortRangeWakefield, as presented in 6.5.1. To avoid overlap of the effects, the following
constructors allow to enable/disable the short-range BL force:
BL.disable_short_range();
BL.enable_short_range();
Get methods
The following quantities can be obtained from the BeamLoadingSW() collective effect:
6.5 Wakefields
RF-Track implements three wakefield models: ShortRangeWakefield, which implements K.
Bane’s approximation described in [SLAC-PUB-9663, 2003], LondRangeWakefield for multi-
bunch simulations, and Wakefield_1d for user-defines short- and long-range wakefield function
provided by the user.
In its second form, this effect can simulate cell-to-cell variations such as the tapering of iris
apertures. The required input parameters describe the accelerating structure’s cell geometry:
a the average iris aperture radius [m]
g the average gap length [m]
l the average cell length [m]
[ ai af ] a 2-element vector with the initial and final iris apertures [m]
[ gi gf ] a 2-element vector with the initial and final gap lengths [m]
[ li lf ] a 2-element vector with the initial and final cell lengths [m]
Ncells The number of cells in the structure [INTEGER]
The meaning of these quantities is shown in Figure 6.1.
In evaluating the wakefield effect, W⊥ (s) and W|| (s) are calculated using the analytic approximation
of the wake potential presented in [K.Bane, SLAC-PUB-9663]:
r r
4Z0 cs⊥0 s s
W⊥ (s) = 1 − 1 + exp − [V/pC/m/mm]
πa4 s⊥0 s⊥0
r
4Z0 c s
Wk (s) = 2
exp − [V/pC/m]
πa sk0
where Z0 is the impedance of free space, a is the average aperture radius of the structure, g is the
gap length, d is the length of the cell, sk0 = 0.41a0.18 g1.6 /d 2.5 and s⊥0 = 1.69a1.79 g0.38 /d 1.17 . Its
range of validity generally covers most of the cases.
Cell-to-cell misalignment
To study the impact of cell-to-cell misalignment, RF-Track can randomly scatter each cell using the
method:
6.5 Wakefields 99
Figure 6.1: The geometric parameters a, g, and l used to describe the short-range wakefield.
The parameters RANGEX and RANGEY determine the amplitude of the offset in mm. Each call to this
function offsets each of the Ncells cells of the structure within a range −RANGE/2 and +RANGE/2
according to a uniform random distribution.
100 Chapter 6. Collective effects
the first index, n, runs over the longitudinal axis of the structure, whereas the second index, m, runs
over the different modes. Thus, one can simulate a set of modes that varies along the structure.
The applied wakefield is:
πs 2πs
W⊥ (s) = − ∑ An · exp sin [V/pC/m/mm]
n Qn λn λn
1 πs 2πs
Wk (s) = λn An exp cos [V/pC/m]
2π ∑ n Qn λn λn
M = MultipleCoulombScattering( material );
M = MultipleCoulombScattering( X0, Z, A, density, I=-1 );
M.enable_log_term();
M.enable_fruehwirth_model(); % DEFAULT
M.enable_wentzel_model(); % DEFAULT
M.disable_log_term(); % DEFAULT
M.disable_fruehwirth_model();
M.disable_wentzel_model();
7.1 Introduction
The Bunch6dT_Generator structure provides a flexible framework for defining and simulating
the properties of a particle bunch in a photo injector. This data structure is designed to describe the
characteristics of a particle bunch in a photoinjector. It allows the user to define the properties of
particles and distributions in six dimensions, including spatial, temporal, and energy parameters.
% create a bunch
B0 = Bunch6d(RF_Track.electronmass, 1e12, -1, M);
% save on disk
B0.save(’my_bunch.rft’); % save the beam in RF-Track binary format
B0.save_as_dst_file(’my_bunch.dst’, 750.0); % save as DST, 750 MHz RF
B0.save_as_sdds_file(’my_bunch.sdds’, ’my useful comment’); % save as SDDS
1 %% Load RF-Track
2 RF_Track;
3
4 %% Beam
5 Pref = 100; % MeV/c, reference momentum
6 Q = -1; % electrons
7 Nparticles = 10000; % 10k particles
8
9 %% Twiss parameters
10 Twiss = Bunch6d_twiss();
11 Twiss.emitt_x = 1; % mm.mrad normalised emittance
12 Twiss.emitt_y = 1; % mm.mrad
13 Twiss.beta_x = 1; % m
14 Twiss.beta_y = 1; % m
15 Twiss.sigma_t = 1; % mm/c, bunch length
16 Twiss.sigma_pt = 5; % permille, energy spread
17 Twiss.disp_z = 1; % m, longitudinal dispersion (chirp)
18
19 %% Create bunch
20 B0 = Bunch6d(RF_Track.electronmass, 0.0, -1, Pref, Twiss, Nparticles);
Index
Symbols D
Bunch6dT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 Drift . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
Bunch6d . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
Lattice . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33 E
Volume . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
Electron cooler . . . . . . . . . . . . . . . . . . . . . . . . . . 71
autophase() . . . . . . . . . . . . . . . . . . . . . . . . . . 44
Energy straggling . . . . . . . . . . . . . . . . . . . . . . 102
Environments . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
A Exporting as DST file . . . . . . . . . . . . . . . . . . . . 31
Exporting as SDDS file . . . . . . . . . . . . . . . . . . 31
Absorber . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
Adiabatic matching device . . . . . . . . . . . . . . . 72 G
Automatic matching . . . . . . . . . . . . . . . . . . . . . 45
Automatic synchronization . . . . . . . . . . . . . . . 44 Generic wakefield . . . . . . . . . . . . . . . . . . . . . . 100
I
B
Importing MAD-X lattices . . . . . . . . . . . . 34, 60
Back tracking . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
Importing Twiss files . . . . . . . . . . . . . . . . . . . . 60
Beam loading . . . . . . . . . . . . . . . . . . . . . . . . . . . 94
Incoherent synchrotron radiation. . . . . . . . . .92
Beam position monitors . . . . . . . . . . . . . . . . . 83
Integration algorithms . . . . . . . . . . . . . . . . . . . 39
Bunch persistency . . . . . . . . . . . . . . . . . . . . . . . 30
Inverse Compton scattering . . . . . . . . . . . 72, 85
C L
Citation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 LaserBeam . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
Coasting beams . . . . . . . . . . . . . . . . . . . . . . . . . 25 Lattice . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
Coil. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .57 Long-range wakefield . . . . . . . . . . . . . . . . . . 101
110 INDEX
M V
Particles lifetime . . . . . . . . . . . . . . . . . . . . . . . . 25
Passage of particles through matter . . . . . . 102
Pillbox cavity . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
Predefined constants . . . . . . . . . . . . . . . . . . . . . 14
Quadrupole . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
Rectangular bend . . . . . . . . . . . . . . . . . . . . . . . 56
RF field maps
1D . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
2D . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77
3D . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79
Screen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84
Sector bend. . . . . . . . . . . . . . . . . . . . . . . . . . . . .54
Short-range wakefield . . . . . . . . . . . . . . . . . . . 98
Solenoid . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
Space charge . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
Standing-wave structure . . . . . . . . . . . . . . . . . 64
Static magnetic field maps
1D . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
2D . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
Stopping power . . . . . . . . . . . . . . . . . . . . . . . . 102
Tracking options . . . . . . . . . . . . . . . . . . . . . . . . 39
Transfer line . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
Transport table . . . . . . . . . . . . . . . . . . . . . . . . . . 48
Travelling-wave structure . . . . . . . . . . . . . . . . 62
Undulator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59