0% found this document useful (0 votes)
32 views110 pages

RF Track Reference Manual

The RF-Track Reference Manual, version 2.3.2, provides comprehensive guidance on the installation and usage of the RF-Track program, developed by Andrea Latina at CERN. It includes detailed instructions on running the program, managing beam models, tracking beams, and working with beamline elements. The manual also outlines copyright information and contact details for the author.

Uploaded by

Fazel Taft
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
32 views110 pages

RF Track Reference Manual

The RF-Track Reference Manual, version 2.3.2, provides comprehensive guidance on the installation and usage of the RF-Track program, developed by Andrea Latina at CERN. It includes detailed instructions on running the program, managing beam models, tracking beams, and working with beamline elements. The manual also outlines copyright information and contact details for the author.

Uploaded by

Fazel Taft
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 110

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

[email protected]

Copyright © 2024 by CERN, Geneva, 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.

Started in April 2020


Contents

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

3 Tracking the beam . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33


3.1 Tracking environments 33
3.2 Lattice 34
3.2.1 Adding elements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
3.2.2 Importing a MAD-X lattice . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
3.2.3 Element misalignment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
3.2.4 Tracking the beam . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
3.2.5 Accessing and modifying the elements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
3.3 Volume 37
3.3.1 Adding elements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
3.3.2 Accessing and modifying the elements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
3.3.3 Volume as a Lattice element . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
3.3.4 Transport table and Screens . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
3.4 Particle losses 44
3.5 Synchronization of time-dependent elements with the beam 44
3.5.1 Autophasing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
3.5.2 Automatic matching of the magnetic elements . . . . . . . . . . . . . . . . . . . . . . . . 45
3.6 Backtracking 46

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

5 Inverse Compton scattering . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85


5.1 Introduction 85
5.1.1 General parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
5.1.2 Particles-laser interaction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
5.2 Collecting the generated photons 87

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

7 Bunch generation at a photocathode . . . . . . . . . . . . . . . . . . . . . . . . 103


7.1 Introduction 103
7.1.1 Particle Properties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
7.1.2 Longitudinal Distribution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
7.1.3 Transverse Spatial Distribution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
7.1.4 Transverse Momentum Distribution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104
7.1.5 Additional Parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104
7.2 Example of photocathode 104

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

3 Tracking the beam . . . . . . . . . . . . . . . . . . 33


3.1 Tracking environments
3.2 Lattice
3.3 Volume
3.4 Particle losses
3.5 Synchronization of time-dependent elements with
the beam
3.6 Backtracking

4 Beamline elements . . . . . . . . . . . . . . . . . . 47
4.1 Introduction
4.2 Matrix-based elements
4.3 Special elements
4.4 Field maps
4.5 Beam diagnostics

5 Inverse Compton scattering . . . . . . . . . . 85


5.1 Introduction
5.2 Collecting the generated photons

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

7 Bunch generation at a photocathode 103


7.1 Introduction
7.2 Example of photocathode

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.

1.1 Getting started


RF-Track was developed on macOS in C++17 but runs on GNU/Linux and other POSIX-compliant
systems. This manual section will describe preparing a suitable environment for compiling and
running RF-Track.
RF-Track is a binary module loadable within the scientific language Octave [1] and Python with
its numerical package NumPy [4, 5]. The user interacts with RF-Track through Octave or Python
scripts. Two libraries are necessary to compile and run RF-Track: the GNU Scientific Library [3]
and the FFTW library [2].
The packages mentioned are open-source and readily available to most package managers for
macOS and various Linux distributions. In this section, we will use MacPorts on macOS and APT
on Ubuntu as examples.
10 Chapter 1. Introduction

1.1.1 Conventions used in this manual


This manual contains numerous examples which can be typed on the keyboard. Some examples
refer to shell commands, others to Octave or Python scripts. For practical reasons, all examples of
RF-Track simulation scripts will be given in Octave. The conversion from Octave to Python should
be straightforward.

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, . . . ).

1.2 Installing RF-Track


1.2.1 On macOS
If you intend to use RF-Track on macOS with Python, it is sufficient to give the command
$ pip install RF_Track

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

$ pip install RF_Track

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

1.3 Running RF-Track


When using RF-Track with Octave, it is enough for your Octave to know where the RF-Track
binary file is located. You can start your Octave scripts with, e.g., the command:
octave:1> addpath(’/Users/<USERNAME>/Codes/rf-track-2.3.0’);

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;

To load RF-Track in Python, it is sufficient to give the command:


>>> import RF_Track

1.3.1 An example program


The following Octave script demonstrates how RF-Track works. In the example, a FODO cell is
created, and a beam is tracked through it to plot the Twiss parameters and the final phase space.
The FODO lattice is designed to have a 90-degree phase advance, and the beam consists of a
bunch of electrons matched to the cell. The bunch is then tracked through the cell, and the Twiss
parameters, βx and βy , are plotted. The lines are numbered, and each block is commented on
below.
12 Chapter 1. Introduction

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

11 %% FODO cell parameters


12 Lcell = 2; % cell length in m
13 Lquad = 0.0; % m, zero-length quadrupole (thin quadrupole)
14 Ldrift = Lcell/2 - Lquad; % drift space between the two quadrupoles
15

16 mu = 90; % phase advance per cell in deg


17 k1L = sind(mu/2) / (Lcell/4); % 1/m, quadrupole focusing strength
18 strength = k1L * B_rho; % MeV/m, quadrupole strength
19

20 %% Create the elements


21 Qf = Quadrupole(Lquad/2, strength/2); % half focusing quadrupole
22 Qd = Quadrupole(Lquad, -strength); % defocusing quadrupole
23 Dr = Drift(Ldrift); % drift space
24 Dr.set_tt_nsteps(100); % number of steps for the transport table
25

26 %% Create the lattice


27 FODO = Lattice(); % Create a new object Lattice() called FODO
28 FODO.append(Qf); % 1/2 F
29 FODO.append(Dr); % O
30 FODO.append(Qd); % D
31 FODO.append(Dr); % O
32 FODO.append(Qf); % 1/2 F
33

34 %% Define Twiss parameters


35 Twiss = Bunch6d_twiss();
36 Twiss.beta_x = Lcell * (1 + sind(mu/2)) / sind(mu); % m
37 Twiss.beta_y = Lcell * (1 - sind(mu/2)) / sind(mu); % m
38 Twiss.alpha_x = 0.0;
39 Twiss.alpha_y = 0.0;
40 Twiss.emitt_x = 1; % mm.mrad, normalized emittances
41 Twiss.emitt_y = 1; % mm.mrad
42

43 %% Create the bunch


44 B0 = Bunch6d(mass, population, Q, Pref, Twiss, 10000);
45
1.3 Running RF-Track 13

46 %% Perform tracking
47 B1 = FODO.track(B0);
48

49 %% Retrieve the Twiss plot and the phase space


50 T = FODO.get_transport_table(’%S %beta_x %beta_y’);
51 M = B1.get_phase_space(’%x %xp %y %yp’);
52

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.

Figure 1.1: The output of the example.

1.3.2 Physical units


Internally, RF-Track stores each physical quantity in the most suitable units for numerical computa-
tion in accelerator physics. Table 1.1 shows the units grouped by conceptual category. Regarding
positions and angles, notice that all beam-related quantities are in units of millimeters or milliradi-
ans, whereas all machine-related quantities are expressed in meters and radians.

1.3.3 Predefined constants


Several constants are predefined within RF-Track for the user’s convenience:

clight % speed of light, in m/s


muonmass % muon mass in MeV/c^2
protonmass % proton mass, in MeV/c^2
electronmass % electron mass, in MeV/c^2
muonlifetime % muon lifetime, in mm/c
s, ms, us, ns, ps, fs % various units if time, in mm/c
C, mC, uC, nC, pC % various units of charge, in e

For example, if one needs to define a time interval of 5 ps, say dt, one can write:
1.3 Running RF-Track 15

Table 1.1: RF-Track physical units.


Quantity Symbols Unit
Bunch population N number of particles
Particle mass m MeV/c2
Particle charge Q e
Particle positions x, y, z mm
Particle angles x 0 , y0 mrad
Particle momenta Px , Py , Pz , P MeV/c
Particle energy E MeV
Time t mm/c
Element offsets and positions Xo , Yo , Zo m
Element pitch Xo0 rad
Element yaw Yo0 rad
Element roll Zo0 rad

octave:1> dt = 5 * RF_Track.ps
dt = 1.4990 % 5 ps in mm/c

1.3.4 Run-time parameters and options


Once RF-Track is loaded, a few variables become available to the user to customize how RF-Track
operates.

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,

% The number of threads that RF-Track must use


RF_Track.number_of_threads = <YOUCHOOSE>;

% The max number of threads supported by your CPU [read-only]


RF_Track.max_number_of_threads

In Python,

% The number of threads that RF-Track must use


RF_Track.cvar.number_of_threads = <YOUCHOOSE>

% The max number of threads supported by your CPU [read-only]


RF_Track.max_number_of_threads

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:

$ RF_TRACK_NUMBER_OF_THREADS=8 octave-cli my_rft_script.m

Octave will execute the RF-Track script my_rft_script.m using a maximum of eight parallel
threads.
Random Number Generator

rng_set(name) % change the random number generator (RNG)


rng_set_seed(seed) % set the seed for the RNG
rng_get() % return what is the current RNG

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.

1.3.5 Random number generators


Table 1.2 shows a list of the random number generators available to RF-Track. Consult [3] for
a detailed description of each of them. The default is mt19937, which is among the fastest
high-quality generators available.
Version number

RF_Track.version % the RF-Track version number [read-only]

Returns the RF-Track version number.

1.4 Further information


1.4.1 Acknowledgments
The author is very thankful to all those who contributed to RF-Track, especially those brave enough
to use the code before this manual existed. A special thank goes to Roberto Corsini of CERN
for his encouragement and support, and to Costanza Agazzi, Stefano Benedetti, Mohsen Dayyani
Kelisani, Yanliang Han, Yongke Zhao, Laura Gambino, Javier Olivares Herrador, Vlad Mus, at, Avni
Aksoy, Elena Fol, and Bernd Michael Stechauner for their essential contributions, which provided
RF-Track with many of its unique features.
1.4 Further information 17

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

Table 1.2: List of random number generators available to RF-Track

1.4.2 Citing RF-Track in publications


We have invested a lot of time and effort in creating RF-Track; please cite it when using it.
To cite RF-Track in publications, use:

Andrea Latina
"RF-Track Reference Manual", CERN, Geneva, Switzerland, 2024
DOI: 10.5281/zenodo.3887085

A BibTeX entry for LaTeX users is:

@techreport{,
address = {Geneva, Switzerland},
author = {Latina, Andrea},
doi = {10.5281/zenodo.3887085},
institution = {CERN},
title = {RF-Track Reference Manual},
year = {2024}
}
2. Beam models

2.1 Tracking in time or in space

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 Single-bunch beams

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

x, y transverse coordinates [mm]


x 0 , y0
transverse angles [mrad]
t arrival time at S [mm/c]
P total momentum [MeV/c]
m mass [MeV/c2 ]
Q charge of the single particle [e]
N number of single particles in each macro-particle [#]
Bunch6d also stores the longitudinal coordinate S of the bunch, which can be accessed like
this:

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:

B = Bunch6d(mass, population, charge, Pref, Twiss, nParticles, sigmaCut=0 );


B = Bunch6d(mass, population, charge, [ X XP Y YP T P ID ] );
B = Bunch6d(mass, population, charge, [ X XP Y YP T P ] );
B = Bunch6d( [ X XP Y YP T P MASS Q N ID ] );
B = Bunch6d( [ X XP Y YP T P MASS Q N ] );
B = Bunch6d( [ X XP Y YP T P MASS Q ] );
B = Bunch6d();

The possible arguments are:


mass the mass of the single particle [MeV/c2 ]
population the total number of real particles in the bunch [#]
charge charge of the single particle [e]
Pref reference momentum [MeV/c]
Twiss instance of object Bunch6d_twiss (see section 2.4.1)
nParticles number of macro-particles in bunch [#]
sigmaCut if > 0 cuts the distributions at sigma_cut sigmas [#]
X column vector of the horizontal coordinates [mm]
Y column vector of the vertical coordinates [mm]
T column vector of the arrival times [mm/c]
P column vector of the total momenta [MeV/c]
XP column vector of the x0 angles [mrad]
YP column vector of the y0 angles [mrad]
MASS column vector of masses [MeV/c2 ]
Q column vector of single-particle charges [e]
N column vector of numbers of single particles per macro particle [#]
ID column vector of particle ID’s [INTEGER]
2.2 Single-bunch beams 21

With no arguments, the default constructor allows the creation of an empty beam. The return value
is an object of type Bunch6d.

Accessing the phase space


The particle coordinates can be inquired using the method get_phase_space(). This method
allows retrieving the bunch’s particle distribution in multiple ways.

M = B.get_phase_space(format_fmt=’%x %xp %y %yp %t %Pc’, which=’good’);

The two arguments are:


format_fmt This parameter allows the user to specify and format what phase
space representation should be returned
which ’all’ | ’good’. This parameter specified whether all particles
should be returned, including the lost ones, or just the good ones
(default=’good’)

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.

Modifying the phase space


The particle coordinates can be changed by the user using the method set_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

%x horizontal coordinate [mm]


%y vertical coordinate [mm]
%t arrival time, t [mm/c]
%dt relative arrival time, t − t0 [mm/c]
%z longitudinal coordinate w.r.t. the reference particle [mm]
%deg@MHz longitudinal coordinate in degrees at a specified frequency in [deg]
MHz, e.g. %deg@750 for degrees at 750 MHz
%K kinetic energy [MeV]
%E total energy [MeV]
%P total momentum [MeV/c]
%d relative momentum, δ = (P − P0 )/P0 [permille]
%xp horizontal angle, Px /Pz [mrad]
%yp vertical angle, Py /Pz [mrad]
%Px horizontal momentum, Px [MeV/c]
%Py vertical momentum, Py [MeV/c]
%Pz longitudinal momentum, Pz [MeV/c]
%px normalized horizontal momentum, Px /P0 [mrad]
%py normalized vertical momentum, Py /P0 [mrad]
%pz normalized longitudinal momentum, Pz /P0 [mrad]
%pt normalized relative energy difference, pt = (E − E0 )/P0 c [permille]
%Vx horizontal velocity [c]
%Vy vertical velocity [c]
%Vz longitudinal velocity [c]
%m mass [MeV/c2 ]
%Q charge [e+ ]
%N number of particles per macro particle [#]
%id particle’s id [#]

Table 2.1: List of identifiers accepted by Bunch6d::get_phase_space().


2.2 Single-bunch beams 23

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:

current_time = B.t; % mm/c

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 = Bunch6dT(mass, population, charge, Pref, Twiss, nParticles, sigma_cut=0 );


B = Bunch6dT(mass, population, charge, [ X Px Y Py Z Pz ID ] );
B = Bunch6dT(mass, population, charge, [ X Px Y Py Z Pz ] );
B = Bunch6dT( [ X Px Y Py Z Pz MASS Q N T0 ID ] );
B = Bunch6dT( [ X Px Y Py Z Pz MASS Q N T0 ] );
B = Bunch6dT( [ X Px Y Py Z Pz MASS Q N ] );
B = Bunch6dT( [ X Px Y Py Z Pz MASS Q ] );
B = Bunch6dT();

The possible arguments are:


mass the mass of the single particle [MeV/c2 ]
population the total number of real particles in the bunch [#]
charge charge of the single particle [e]
Pref reference momentum [MeV/c]
Twiss instance of object Bunch6d_twiss (see section 2.4.1)
nParticles number of macro-particles in bunch [#]
sigmaCut if > 0 cuts the distributions at sigma_cut sigmas [#]
X column vector of the horizontal coordinates [mm]
Y column vector of the vertical coordinates [mm]
Z column vector of the longitudinal coordinates [mm]
Px column vector of the horizontal momenta [MeV/c]
Py column vector of the vertical momenta [MeV/c]
Pz column vector of the longitudinal momenta [MeV/c]
MASS column vector of masses [MeV/c2 ]
Q column vector of single-particle charges [e]
N column vector of numbers of single particles per macro particle [#]
T0 column vector of creation times [mm/c]
ID column vector of particle ID’s [INTEGER]
A default constructor allows the creation of an empty beam. The return value is an object of type
Bunch6dT.
24 Chapter 2. Beam models

%X horizontal coordinate [mm]


%Y vertical coordinate [mm]
%Z longitudinal coordinate [mm]
%deg@MHz longitudinal coordinate in degrees at a specified frequency in [deg]
MHz, e.g. %deg@750 for degrees at 750 MHz
%K kinetic energy [MeV]
%E total energy [MeV]
%P total momentum [MeV/c]
%d relative momentum, δ = (P − P0 )/P0 [permille]
%t0 creation time [mm/c]
%xp horizontal angle, Px /Pz [mrad]
%yp vertical angle, Py /Pz [mrad]
%Px horizontal momentum, Px [MeV/c]
%Py vertical momentum, Py [MeV/c]
%Pz longitudinal momentum, Pz [MeV/c]
%px normalized horizontal momentum, Px /P0 [mrad]
%py normalized vertical momentum, Py /P0 [mrad]
%pz normalized longitudinal momentum, Pz /P0 [mrad]
%pt normalized relative energy difference, pt = (E − E0 )/P0 c [permille]
%Vx horizontal velocity [c]
%Vy vertical velocity [c]
%Vz longitudinal velocity [c]
%m mass [MeV/c2 ]
%Q charge [e+ ]
%N number of particles per macro particle [#]
%id particle’s id [#]

Table 2.2: List of identifiers accepted by Bunch6dT::get_phase_space().

Accessing the phase space


The particle coordinates can be inquired using the method get_phase_space(). This method
allows one to retrieve the bunch’s information in multiple ways.

M = B.get_phase_space(format_fmt=’%X %Px %Y %Py %Z %Pz’, which=’good’);

The two arguments are:


format_fmt this parameter allows the user to specify what phase space repre-
sentation should be returned
which this parameter specified whether ’all’ particles should be re-
turned, including the lost ones, of just the ’good’ ones
The default values correspond to the internal representation of the beam for all the “good” particles.
Table 2.2 shows all possible identifiers. The return value M is a matrix with the requested phase
space.
2.2 Single-bunch beams 25

Modifying the phase space


The user can change particle coordinates using the method set_phase_space().

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 ).

2.2.3 Conversion between Bunch6d and Bunch6dT


From Bunch6d to Bunch6dT
An object of type Bunch6d can be converted into an object of type Bunch6dT by calling the
dedicated constructor:

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.

From Bunch6dT to Bunch6d


Since a Bunch6dT represents a particle distribution in the 3D space, a bunch of type Bunch6dT
cannot be converted into a bunch of type Bunch6d, where all the particles are sampled at the same
longitudinal location.

2.2.4 Coasting beams


Both types Bunch6d and Bunch6dT can represent coasting beams. The method set_coasting()
allows the user to specify that the beam is coasting:

B.set_coasting(L);

The only argument of this method is:


L the period length [mm]
If a beam is coasting, each particle is followed and preceded by a virtually infinite number of
particles, separated by periods of length L. This beam property affects the space charge calculation
and has no other effect on the tracking.

2.2.5 Particles lifetime


The particle lifetime can be set using the method set_lifetime(T) of both the objects Bunch6d
and Bunch6dT. Example:

B.set_lifetime(T);

The only argument of this method is:


26 Chapter 2. Beam models

T the lifetime [mm/c]


For convenience, the muon lifetime is predefined so that one can use it directly:

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.

2.3 Multi-bunch beams


RF-Track can simulate multi-bunch beams. In RF-Track, a Beam is a set of single bunches that the
user can specify individually at arbitrary distances from each other.
This model allows a specialised implementation of long-range collective effects for multi-
bunch beams. For example, specific single-bunch effects such as space charge are applied to each
bunch individually, while bunch-to-bunch effects such as long-range wakefields can be computed
considering the large spacing between bunches using a dedicated long-range algorithm. In addition,
accessing information about each bunch and analysing the results after tracking is much easier.
The “Beam” model provides high flexibility, for example, by allowing the user to simulate
bunch trains where some bunches are multi-particles and others single particles, thus speeding up
simulations where one needs to focus on a specific bunch. Moreover, the bunches can be arbitrarily
and irregularly spaced, have different charges and even be of different species.

2.3.1 Example of Beam Definition


The following lines provide an example declaration of a train consisting of 30 equally spaced
bunches:

% Define a bunch
bunch = Bunch6d(mass, charge, q, phase_space);

% Define the train structure


n_bunches = 30; % number of bunches in the train
bunch_spacing = 1/3 * RF_Track.ns; % mm/c, bunch spacing

% 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,

B0 = Bunch6d([...]); % create a bunch

Beam0 = Beam(); % create an empty beam

Beam0.append( B0 ); % add a first bunch


Beam0.append( B0, 10 * RF_Track.ps ); % add a bunch, 10 ps from the 1st
Beam0.append( B0, 20 * RF_Track.ps ); % add a bunch, 20 ps from the 2nd

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 Twiss parameters


The structures Bunch6d_twiss and Bunch6dT_twiss gather all the information to generate a
beam from the Twiss parameters.

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

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

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.

2.5 Inquiring the bunch properties


The user can inquire about a bunch’s statistical quantities, such as the average value or the standard
deviation of the phase space variables, the emittances, or the Twiss parameters, by calling the
method:

I = B.get_info();

Two versions exist, for Bunch6d and for Bunch6dT.


2.5 Inquiring the bunch properties 29

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

2.6 Bunch persistency


Both Bunch6d and Bunch6dT can be loaded and saved on disk and exported in multiple ways.

2.6.1 Saving and loading a beam on disk


Two methods can be used to save and load the beam:

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.

2.6.2 Exporting as DST file


One can save the beam in DST binary format:

B.save_as_dst_file(filename, frequency_in_MHz);

The RF frequency (expressed in MHz) is required.

2.6.3 Exporting as SDDS file


One can save the beam in binary format in SDDS files:

B.save_as_sdds_file(filename, description);

The string description is optional.

2.6.4 Saving the phase space


There are also alternative ways to save a beam as a file. For example, one can extract the phase
space using get_phase_space() and then save the phase-space matrix using appropriate Octave
or Python commands.
3. Tracking the beam

3.1 Tracking environments


RF-Track offers two distinct environments to track particles: the Lattice and the Volume.
The environment Lattice represents the accelerator as a list of consecutive elements. Lattice
works with Bunch6d and transports the beam, element by element, from the entrance to the exit
plane of each element.
The environment Volume provides more flexibility than Lattice: it can simulate elements
with arbitrary position and orientation in the three-dimensional space and allows elements to
overlap. Volume works with Bunch6dT, which is more suitable for space-charge calculations.
The possibility for Bunch6dT to handle particle creation at any time and location also allows the
simulation of cathodes, field emission, and dark currents. In a Volume, particles can propagate in
any direction (even backwards). Several “special” elements, unavailable to Lattice, allow taking
full advantage of the flexibility of Volume: e.g., analytic coils and solenoids, where the magnetic
field is computed from analytic formulæ and permeates the whole 3D space, allowing for the
simulation of realistic fringe fields.
It must be mentioned that the environment Lattice can also apply space-charge effects to the
beam. However, since Bunch6d maintains the distribution of the particles on the same longitudinal
plane, the calculation of the space-charge force needs an on-the-fly extrapolation of each particle’s
longitudinal position, using the arrival time and the velocity to reconstruct the three-dimensional
spatial distribution. Because of this somehow nonphysical manipulation of the phase space, we
deem Lattice more suitable for sections of the accelerator free of space-charge effects. On the
contrary, Volume –which through Bunch6dT maintains the full spatial distribution of the beam–
should be the preferred choice in space-charge-dominated regimes. These considerations and the
capability to superimpose elements make Volume perfect for the simulation of injectors, where a
solenoidal magnetic field typically surrounds the gun’s acceleration field, and space charge effects
are critical. The additional flexibility of Volume comes at the cost of being computationally more
expensive.
Summarising, Lattice is straightforward and fast, and its use is recommended in space-charge-
34 Chapter 3. Tracking the beam

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.

3.2.1 Adding elements


One can use the methods append or insert to add elements to a Lattice. With both methods,
one adds elements at the end of the existing Lattice. The method append accepts individual
elements or lattices. When a Lattice is appended to another Lattice, it is seen by the enclosing
Lattice as a single element that embeds other elements. This can be useful to simulate “girders”
for example, rigid supports holding several elements together. Given that each element can be
misaligned independently, one can have misaligned “girders” holding misaligned elements.
When a Lattice is added to another Lattice using the method insert, its single elements are
appended one by one to the new Lattice, and the notion of the initial Lattice as a container is
lost.

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.

3.2.2 Importing a MAD-X lattice


A dedicated constructor allows RF-Track to convert an entire MAD-X Twiss file into an RF-Track
Lattice:
3.2 Lattice 35

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:

save, flag=twiss, full;


twiss, file=twiss_file.tws;

3.2.3 Element misalignment

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:

L.append(element, dX, dY, dZ, reference = "entrance");


L.append(element, dX, dY, dZ, roll, pitch, yaw, reference = "entrance");
L.append_ref(element, dX, dY, dZ, reference = "entrance");
L.append_ref(element, dX, dY, dZ, roll, pitch, yaw, reference = "entrance");

The arguments are:


element the element to be added
lattice the lattice to be added
dX the horizontal position of the new element [m]
dY the vertical position of the new element [m]
dZ the longitudinal position of the new element [m]
roll the rotation angle around the Z axis [rad]
pitch the rotation angle around the X axis [rad]
yaw the rotation angle around the Y axis [rad]
reference reference point for position and angles: it can be either
’entrance’, ’center’, or ’exit’
The angles follow the Tait–Bryan definition: yaw, pitch, and roll. Note that no approximations are
made, such as small angles or small offsets.

Random misalignment
Elements can also be scattered randomly using the following Lattice methods:

L.scatter_elements(type, dX, dY, dZ, roll, pitch, yaw, reference=’entrance’);


L.scatter_elements(dX, dY, dZ, roll, pitch, yaw, reference=’entrance’);

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

type the type of element to be scattered; it can be one among:


’bpm’
’sbend’
’lattice’
’absorber’
’solenoid’
’sextupole’
’multipole’
’corrector’
’rf_elememt’

dX the rms horizontal scattering [mm]


dY the rms vertical scattering [mm]
dZ the rms longitudinal scattering [mm]
roll the rms rotation angle around the Z axis [mrad]
pitch the rms rotation angle around the X axis [mrad]
yaw the rms rotation angle around the Y axis [mrad]
reference reference point for position and angles: it can be either
’entrance’, ’center’, or ’exit’
In the second form, where the element type to be scattered is not specified, all elements in the
lattice will be scattered, including the elements in nested Lattices.

3.2.4 Tracking the beam


To track a beam, e.g., B0 through a Lattice, L, one can call the method track:

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.

3.2.5 Accessing and modifying the elements


Once the elements have been added to a Lattice, they can be accessed in two ways: by index or by
name.
In Octave:

L{1} % return the first element


L{’NAME’} % return all the elements called ’NAME’

In Python:

L[0] # return the first element


L[’NAME’] # return all the elements called ’NAME’

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

% Define the elements


F = Quadrupole(0.2, +1); % focusing quad
D = Quadrupole(0.2, -1); % defocuding quad
O = Drift(1); % drift

% Define the lattice


L = Lattice();
L.append(F);
L.append(O);
L.append(D);
L.append(O);

% Modify the strength of the first quadrupole


L{1}.set_strength(2); % Now the first quadrupole has strength 2

3.3 Volume

To set up a Volume, it is sufficient to create an object of type Volume:

V = Volume();

There are no input options.

3.3.1 Adding elements

To place elements into Volume, you can use the method add, which comes in many flavours:

V.add(element, Xpos, Ypos, Zpos, reference=’entrance’);


V.add(element, Xpos, Ypos, Zpos, roll, pitch, yaw, reference=’entrance’);
V.add(lattice, Xpos, Ypos, Zpos, reference=’entrance’);
V.add(lattice, Xpos, Ypos, Zpos, roll, pitch, yaw, reference=’entrance’);
V.add(volume, Xpos, Ypos, Zpos, reference=’entrance’);
V.add(volume, Xpos, Ypos, Zpos, roll, pitch, yaw, reference=’entrance’);
V.add_ref( ... );

The possible arguments are:


38 Chapter 3. Tracking the beam

element the element to be added


lattice the lattice to be added
volume the volume to be added
Xpos the horizontal position of the element in the Volume [m]
Ypos the vertical position of the element in the Volume [m]
Zpos the longitudinal position of the element in the Volume [m]
roll the rotation angle around the Z axis [rad]
pitch the rotation angle around the X axis [rad]
yaw the rotation angle around the Y axis [rad]
reference reference point for position and angles: it can be either
’entrance’, ’center’, or ’exit’. This means that the spec-
ified position and angles denote the entrance, the exit, or the
center of the element.
The angles follow the Tait-Bryan definition of yaw, pitch and roll. No approximations such as
“small angles” or “small offsets” are made. When a Lattice or Volume is added, its individual
elements are added one by one.
As with Lattice, the methods add(...) add a copy of the new element to the Volume. If
you want to add a reference to an element rather than a copy, i.e. in such a way that modifying
the element after it has been added will directly affect the tracking in Volume, one can use the
add_ref(...) methods.

3.3.2 Accessing and modifying the elements


Once the elements have been added to a Volume, they can be accessed in two ways: by index or by
name.
In Octave:

V{1} % return the first element


V{’NAME’} % return all the elements called ’NAME’

In Python:

V[0] # return the first element


V[’NAME’] # return all the elements called ’NAME’

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.

Tracking the beam


To track a beam, e.g., B0 through a Volume, V, one can call the method track:

B1 = V.track(B0, options);
B1 = V.track(B0);

The possible arguments are:


3.3 Volume 39

B0 the beam to be tracked, a Bunch6dT


options a set of TrackingOptions. See the next subsection for details.
The tracking continues until the slowest particle has left the Volume. The return value, B1, is the
Bunch6dT at that moment. See page 42 to learn more about the “End-of-tracking condition”.

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.

As already mentioned, we recommend performing a convergence study to obtain stable and


accurate results. This study must be aimed at comparing different integration algorithms and time
steps until a reasonable compromise between simulation speed and accuracy is achieved.

Follows a list of available integration algorithms:


40 Chapter 3. Tracking the beam

Table 3.1: A list of all the TrackingOptions

odeint_algorithm the integration algorithm, available algorithms are


’leapfrog’, ’rk2’, ’rkf45’, and more. See the fol-
lowing paragraphs.
Default = ‘leapfrog’ [STRING]
odeint_epsabs absolute error tolerance (’rk’ algorithms only) [REAL]
odeint_epsrel relative error tolerance (’rk’ algorithms only) [REAL]
dt_mm the integration step, the suffix mm stresses the units [mm/c]
t_max_mm sets the max tracking time.
Default = ∞ [mm/c]
t_min_mm sets the min tracking time (used for backtracking).
Default = −∞ [mm/c]
sc_dt_mm apply a space-charge kick every sc_dt_mm mm/c [mm/c]
cfx_dt_mm apply the other collective effects every cfx_dt_mm [mm/c]
mm/c
tt_dt_mm add an entry of the Transport table every tt_dt_mm [mm/c]
mm/c
tt_select select what particles should be included in the
transport table computation. It can be one
among: ‘all’, ‘active’, ‘all_in_volume’, or
‘active_in_volume’. ‘all’ also includes particles
that haven’t yet come into existence, for instance, par-
ticles at the cathode in a photoinjector simulation.
Default = ‘all’ [STRING]
wp_dt_mm wp = “watch point”; save the beam on disk every [mm/c]
wp_dt_mm mm/c
wp_basename base name for the files on disk.
Default “watch_beam”. The files will have names: [STRING]
“watch_beam.XXXXXXX”.
wp_gzip compress the watch-point files automatically.
Default = false [BOOLEAN]
verbosity verbosity level during tracking. 0 = silent; 1 = talkative;
2 = more talkative.
Default = 0; [INTEGER]
3.3 Volume 41

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.

Time limits of the integration


In Volume, unless t_max_mm or t_min_mm are set, tracking (or backtracking) continues until the
last particle has left the Volume. See the next paragraphs for more details.

Setting the tracking options


A Volume itself is an instance of the structure TrackingOptions; this allows one to set the
volume’s tracking options in this possibly clearer way:

% Create Volume
V = Volume();

% Set the tracking options


V.odeint_algorithm = ’rk2’;
V.dt_mm = 0.1; % mm/c
V.verbosity = 2;

% Add a few elements


V.add (ELEMENT1, 0, 0, 0);
V.add (ELEMENT2, 0, 0, 0);
V.add (ELEMENT3, 0, 0, 0);

% Perform tracking
V.track(B0);
42 Chapter 3. Tracking the beam

End-of-tracking condition, the planes s0 and s1


Two planes, orthogonal to the Z axis, define the longitudinal extension of a Volume: s0 and s1 .
A Volume extends from s0 to s1 . When one adds elements to a Volume, RF-Track automatically
moves s0 backwards and s1 forward to accommodate space for the component.
Tracking in Volume continues as long as particles exist between these two planes, or until the
maximum tracking time (tracking option t_max_mm) is reached. Beware that if a particle gets
trapped in the Volume, tracking will continue indefinitely unless the max tracking time is reached
t_max_mm.
The planes s0 or s1 can have any position and orientation in space, and setting them can be done
in multiple ways:

% 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);

% Setting one w.r.t. the other


V.set_s0_from_s1 (P0, l);
V.set_s1_from_s0 (P0, l);

In these commands, the arguments are:


x, y, z coordinates [m]
t the tracking time [mm/c]
l a distance [m]
P0 a reference particle [Bunch6dT]
roll the rotation angle around the Z axis [rad]
pitch the rotation angle around the X axis [rad]
yaw the rotation angle around the Y axis [rad]

3.3.3 Volume as a Lattice element


Once a Volume has been initialized, adding all its elements and setting its planes s0 and s1 , one can
insert it into a Lattice and treat it as a standard Lattice element. Figure 3.1 gives a pictorial repre-
sentation of a potential simulation scenario. An illustrative example script follows:

% A reference particle placed in (0, 0, 0) with Pz = 100 MeV/c


P0 = Bunch6dT (mass, 0.0, +1, [ 0 0 0 0 0 100 ]);
3.3 Volume 43

By

Latt
ice 1 ice 2
Latt

S0
S1

Figure 3.1: A Volume can be sandwiched between two Lattices.

% A Volume containing the field map in the figure


Dipole = Volume();
Dipole.dt_mm = 1.0;
Dipole.odeint_algorithm = ’rk2’;
Dipole.add (DIPOLE_MAP, 0, 0, 0, ’center’);
Dipole.set_00 (P0, -150); % track backward P0 by 150 mm/c to set s0
Dipole.set_s1 (P0, +150); % track forward P0 by 150 mm/c to set s1
Dipole.set_tt_nsteps(20);

% 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.

3.3.4 Transport table and Screens

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

3.4 Particle losses

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

In the case of Volume, the 11 columns are:


1. X in mm
2. Px in MeV/c
3. Y in mm
4. Py in MeV/c
5. Z in mm
6. Pz in MeV/c
7. T in mm/c, the time 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

3.5 Synchronization of time-dependent elements with the beam

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.

% First, let’s create a reference particle


P0 = Bunch6d (electronmass, 100*pC, -1, [ 0 0 0 0 0 Pref ]);

% Let’s run the autophase


Pfinal = L.autophase (P0);

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 .

Three important notes


N OTE 1: Autophase should be considered an integral step in the preparation and initialization of a
Lattice or Volume and should be performed prior to performing any tracking.

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.

3.5.2 Automatic matching of the magnetic elements


To describe the field of a magnet, RF-Track usually uses the magnetic strength or the gradient –
see, for example, the description of the Quadrupole and Multipole elements in the next chapter.
However, when designing, for example, a linac composed of FODO cells embedding RF structures,
it may be difficult to know the exact gradient of the magnets since the magnetic strength depends
on the beam momentum along the linac, which is usually unknown a priori. In these cases, it is
easier to know the normalised strengths of the magnets, such as k1 for quadrupoles, which are
energy-independent and driven by the optical properties of the system.
1 We recall that the Complex field maps of RF elements generated by notorious electromagnetic codes are returned in
an undefined phase.
46 Chapter 3. Tracking the beam

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,

% We know the normalized focusing strength, k1,


% but we don’t know yet the beam rigidity

k1 = 0.12; % m^-2, normalized strength


L = 0.1; % m, quadrupole length
P_Q = NaN; % Unknown, for the time being

% Define a quadrupole
Q = Quadrupole (L, P_Q, k1);

The quadrupole strength will be automatically computed and set by autophase().

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:

% B1 is the bunch I want to get from my Lattice


B1 = Bunch6d ( ... );

% 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.

4.1.1 Methods available to all elements


Many practical methods are available to all elements to achieve specific setups.

Setting the element name


The element can have an optional name that can be used to look up the elements in the tracking
environments. Two methods allow to set and get an element’s name:
E.set_name( STRING );
E.get_name();

Setting the aperture


All elements are equipped with an aperture, which, by default, is not considered. The aperture can
be set and inquired using the following set of methods:
E.set_aperture_x( Rx ); % m
E.set_aperture_y( Ry ); % m
E.set_aperture_shape( SHAPE ); % m
E.set_aperture( Rx, Ry, SHAPE ); % m
E.get_aperture_x(); % return m
E.get_aperture_y(); % return m
48 Chapter 4. Beamline elements

E.get_aperture_shape(); % return a string

The arguments are:


Rx, Ry the aperture radii [m]
SHAPE a string among ’none’, ’rectangular’, and ‘circular’ [STRING]
The ‘circular’ aperture becomes elliptical when Rx 6= Ry. The aperture is checked at each integration
step.

Adding constant magnetic and electric fields


Available to almost all element types, two methods allow embedding an element in a constant,
magnetic or electric field with any orientation in space:
E.set_static_Bfield( Bx, By, Bz ); % T
E.set_static_Efield( Ex, Ey, Ez ); % V/m

Where E is the instance of an element.

Activating collective effects


Collective effects can be added to any element using the method:
E.add_collective_effects( CFX );

See the dedicated chapter for a list of the collective effects implemented in RF-Track.

4.1.2 Tracking the beam properties


Both Lattice() and Volume() offer the possibility of storing average beam quantities, such as
beam size, emittance, energy spread, dispersion, etc., during tracking into a “transport table”. After
tracking, such a transport table can be retrieved using the method get_transport_table()
available to both Lattice and Volume.
Like get_phase_space() for the beam, get_transport_table() allows the user to in-
quire about specific quantities.
In Lattice(), the user can choose the number of points at which the phase space is sampled
using the element’s method set_tt_nsteps(). For example:

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

Table 4.1: List of identifiers accepted by Lattice::get_transport_table()


%S longitudinal position [m]
%mean_x average horizontal position [mm]
%mean_y average vertical position [mm]
%mean_t average arrival time [mm/c]
%mean_xp average horizontal divergence [mrad]
%mean_yp average vertical divergence [mrad]
%mean_Px average horizontal momentum [MeV/c]
%mean_Py average vertical momentum [MeV/c]
%mean_Pz average longitudinal momentum [MeV/c]
%mean_P average total momentum [MeV/c]
%mean_K average kinetic energy [MeV]
%mean_E average total energy [MeV]
%emitt_x normalized horizontal emittance [mm.mrad]
%emitt_y normalized vertical emittance [mm.mrad]
%emitt_z normalized longitudinal emittance [mm.permille]
%emitt_4d normalized transverse emittance [mm.mrad]
%emitt_6d normalized 6d emittance [mm.mrad]
%disp_x horizontal dispersion function [m]
%disp_y vertical dispersion function [m]
%disp_z longitudinal dispersion function [m]
%disp_px horizontal dispersion-prime function [rad]
%disp_py vertical dispersion-prime function [rad]
%beta_x horizontal beta function [m]
%beta_y vertical beta function [m]
%beta_z longitudinal beta function [m]
%alpha_x horizontal alpha function [-]
%alpha_y vertical alpha function [-]
%alpha_z longitudinal alpha function [-]
%sigma_x horizontal spread [mm]
%sigma_y vertical spread [mm]
%sigma_t longitudinal spread [mm/c]
%sigma_pt normalized energy spread σE /Pref [permille]
%sigma_Px horizontal momentum spread [MeV/c]
%sigma_Py vertical momentum spread [MeV/c]
%sigma_Pz longitudinal momentum spread [MeV/c]
%sigma_P total momentum spread [MeV/c]
%rmax transverse envelope (all particles) [mm]
%rmax99.9 transverse envelope (99.9% of the particles) [mm]
%rmax99 transverse envelope (99% of the particles) [mm]
%rmax90 transverse envelope (90% of the particles) [mm]
%N transmission [e]
50 Chapter 4. Beamline elements

Table 4.2: List of identifiers accepted by Volume::get_transport_table()


%t time [mm/c]
%mean_X average horizontal position [mm]
%mean_Y average vertical position [mm]
%mean_S average longitudinal coordinate [mm]
%mean_K average kinetic energy [MeV]
%mean_E average total energy [MeV]
%mean_P average total momentum [MeV/c]
%mean_Px average horizontal momentum [MeV/c]
%mean_Py average vertical momentum [MeV/c]
%mean_Pz average longitudinal momentum [MeV/c]
%emitt_x normalized horizontal emittance [mm.mrad]
%emitt_y normalized vertical emittance [mm.mrad]
%emitt_z normalized longitudinal emittance [mm.permille]
%emitt_4d normalized transverse emittance [mm.mrad]
%emitt_6d normalized 6d emittance [mm.mrad]
%disp_x horizontal dispersion function [m]
%disp_y vertical dispersion function [m]
%disp_z longitudinal dispersion function [m]
%disp_px horizontal dispersion-prime function [rad]
%disp_py vertical dispersion-prime function [rad]
%beta_x horizontal beta function [m]
%beta_y vertical beta function [m]
%beta_z longitudinal beta function [m]
%alpha_x horizontal alpha function [-]
%alpha_y vertical alpha function [-]
%alpha_z longitudinal alpha function [-]
%sigma_X horizontal spread [mm]
%sigma_Y vertical spread [mm]
%sigma_Z longitudinal spread [mm]
%sigma_Px horizontal momentum spread [MeV/c]
%sigma_Py vertical momentum spread [MeV/c]
%sigma_Pz longitudinal momentum spread [MeV/c]
%rmax transverse envelope (all particles) [mm]
%rmax99.9 transverse envelope (99.9% of the particles) [mm]
%rmax99 transverse envelope (99% of the particles) [mm]
%rmax90 transverse envelope (90% of the particles) [mm]
%N transmission [e]
4.2 Matrix-based elements 51

4.2 Matrix-based elements


All matrix-based elements are, by definition, symplectic.

4.2.1 Drift
An empty region of space.

Constructor

D = Drift (L=0); % L [m]

The only parameter, L, is the length of the drift space in meters.

Set methods

D.set_static_Bfield(Bx, By, Bz); % T


D.set_static_Efield(Ex, Ey, Ez); % V/m
D.add_collective_effects( CFX );

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

Q = Quadrupole (L=0, strength=0);


Q = Quadrupole (L, P_Q, k1);

The possible arguments are:


L the quadrupole length [m]
strength the integrated focusing strength, S [MV/c/m]
P_Q the beam’s magnetic rigidity, P/q [MV/c]
If NaN, RF-Track will set it a tracking time using autophase()
k1 the focusing strength, k1 [1/m2 ]
Here follow a few formulæ to disentangle the relations between the integrated strength, S; the
focusing strength, k1 ; the quadrupole gradient, G; and the beam rigidity, P/q or Bρ:
   
P/q k1 L
S= 2
[MV/c/m]
MV/c 1/m m
  
G Tm
k1 = [1/m2 ]
T/m Bρ

Get methods

k1 = Q.get_K1(P_Q); % return 1/m^2


k1L = Q.get_K1L(P_Q); % return 1/m
G = Q.get_gradient(); % return T/m
strength = Q.get_strength(); % return MV/c/m

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:

P = 200; % MeV/c, reference momentum


k1 = 0.1; % 1/m^2, focusing strength
Lquad = 0.2; % m, quadrupole length
Q = Quadrupole(Lquad, P, k1);

Or, given the quadrupole gradient, G:


4.2 Matrix-based elements 53

Lquad = 0.2; % m, quadrupole length


G = 1.2; % T/m, quadrupole gradient
Q = Quadrupole(Lquad);
Q.set_gradient(G);
54 Chapter 4. Beamline elements

4.2.3 Sector bending dipole


SBend is a sector-bending magnet on a curved reference system. Like MAD-X, a positive bend
angle represents a bend to the right, i.e. towards negative x values. Figure 4.1 will help understand
this convention.

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

S = SBend (L, angle, P_Q, E1=0, E2=0);


S = SBend (L=0);

The arguments are:


L the bending magnet length [m]
angle the bending angle [rad]
P_Q the beam’s magnetic rigidity, P/q [MV/c]
E1, E2 the entrance and the exit angles [rad]

Get methods

S.get_E1(); % the entrance edge angle in rad


S.get_E2(); % the exit edge angle in rad
S.get_E1d(); % the entrance edge angle in deg
S.get_E2d(); % the exit edge angle in deg
S.get_angle(); % the bending angle in rad
S.get_angled(); % the bending angle in deg
S.get_h(); % 1/m, the inverse of the bending radius
S.get_K0(); % 1/m, the reference trajectory’s bending radius
S.get_K1(); % 1/m**2, the quadrupolar focusing strength
S.get_Bfield(); % T, return the By field
4.2 Matrix-based elements 55

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

The parameter FINT follows the same definitions as in MAD-X:

By (s) (B0 − By (s))


Z ∞
FINT = ds,
−∞ g B20

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:

Linear field drop-off 1/6


Clamped “Rogowski” fringing field 0.4
Unclamped “Rogowski” fringing field 0.7
“Square-edged” non-saturating magnet 0.45
56 Chapter 4. Beamline elements

4.2.4 Rectangular bending dipole


RBend is a rectangular bend, a bending magnet whose entrance and exit windows are parallel. Its
reference system is curved by default, and its length is intended to be the length of the straight line
joining the entry and exit points.

Constructor

R = RBend (L, angle, P_Q, E1=0, E2=0);

The arguments are:


L the rectangular bending magnet length [m]
angle the bending angle [rad]
P_Q the beam’s magnetic rigidity, P/q [MV/c]
E1, E2 the entrance and the exit angles [rad]
As the RBend is internally implemented as a SBend with appropriate entrance and exit edge angles,
this element features the same “Set” and “Get” methods of a sector bend.
4.2 Matrix-based elements 57

4.2.5 Coil
The element Coil creates the magnetic field generated by an electromagnetic coil.

Constructors

C = Coil (L, B0, R );

The input arguments describing the material are:


L the element length [m]
B0 the peak on-axis field [T]
R the coil radius. [m]

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

S = Solenoid (L=0, B0=0, R=0);


S = Solenoid (L, B0, Rmin, Rmax, nsheets);

The arguments are:


L the length of the solenoid [m]
B0 the on-axis peak field, [T]
R the solenoid radius [m]
Rmin inner radius [m]
Rmax outer radius [m]
nsheets number of current sheets [INTEGER]
In both Lattice and Volume, the argument radius, R, sets the aperture radius of the magnet. In
Volume, its value is also used to compute the 3D field. Figure 4.2 shows the Solenoid field computed
by RF-Track.

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]

Figure 4.2: The Solenoid field computed by RF-Track.


4.2 Matrix-based elements 59

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

U = Undulator (lperiod, K, nperiods, kx2=0);

The arguments are:


lperiod the length of an undulator period [m]
K the undulator K parameter in x direction [-]
nperiods the number of periods [INTEGER]
kx2 kx2 , the curvature of the pole surface (default 0) [1/m2 ]
When kx2> 0, the poles are bent inwards; when kx2< 0, the poles are bent outwards. See
Figure 4.3.

kx2 > 0 kx2 < 0


<latexit sha1_base64="gj0BCCXOgkMQsH16hQ6f9e47E3k=">AAAB8XicbVBNS8NAEJ3Ur1q/oh69LBbBU0mKVE9S9OKxgv3ANpbNdtMu3WzC7kYsof/CiwdFvPpvvPlv3LQ5aOuDgcd7M8zM82POlHacb6uwsrq2vlHcLG1t7+zu2fsHLRUlktAmiXgkOz5WlDNBm5ppTjuxpDj0OW374+vMbz9SqVgk7vQkpl6Ih4IFjGBtpPtx/+mhii6RU+rbZafizICWiZuTMuRo9O2v3iAiSUiFJhwr1XWdWHsplpoRTqelXqJojMkYD2nXUIFDqrx0dvEUnRhlgIJImhIazdTfEykOlZqEvukMsR6pRS8T//O6iQ4uvJSJONFUkPmiIOFIRyh7Hw2YpETziSGYSGZuRWSEJSbahJSF4C6+vExa1Ypbq9Ruz8r1qzyOIhzBMZyCC+dQhxtoQBMICHiGV3izlPVivVsf89aClc8cwh9Ynz9ohY9z</latexit> <latexit sha1_base64="5oe3VtZEkdrJSQAyK7+S5M+EkpA=">AAAB8XicbVBNS8NAEJ3Ur1q/oh69LBbBU0mKVA8eil48VrAf2May2W7apZtN2N2IJfRfePGgiFf/jTf/jZs2B219MPB4b4aZeX7MmdKO820VVlbX1jeKm6Wt7Z3dPXv/oKWiRBLaJBGPZMfHinImaFMzzWknlhSHPqdtf3yd+e1HKhWLxJ2exNQL8VCwgBGsjXQ/7j89VNElckp9u+xUnBnQMnFzUoYcjb791RtEJAmp0IRjpbquE2svxVIzwum01EsUjTEZ4yHtGipwSJWXzi6eohOjDFAQSVNCo5n6eyLFoVKT0DedIdYjtehl4n9eN9HBhZcyESeaCjJfFCQc6Qhl76MBk5RoPjEEE8nMrYiMsMREm5CyENzFl5dJq1pxa5Xa7Vm5fpXHUYQjOIZTcOEc6nADDWgCAQHP8ApvlrJerHfrY95asPKZQ/gD6/MHZXePcQ==</latexit>

Figure 4.3: The parameter kx2 describes the shape of the undulator’s poles.
60 Chapter 4. Beamline elements

4.2.8 Transfer Line


The element TransferLine allows inserting a Twiss file from MAD-X or a Twiss matrix and
tracking through it directly. TransferLine can simulate entire beamlines without specifying
each element individually. In addition, this element allows the simulation of matching sections
quickly. If the input Twiss matrix contains just one row, RF-Track will match the current beam to
the specified Twiss parameters.
Like the other elements, in a TransferLine, the tracking can be segmented into steps, and
collective effects can be applied.

Constructors

T = TransferLine("twiss_file.dat", Pref);
T = TransferLine(twiss_matrix, DQx, DQy, momentum_compaction, Pref);
T = TransferLine(twiss_matrix, Pref);

The arguments are:


"twiss_file.dat" a Twiss file from MAD-X
twiss_matrix a matrix containing the Twiss parameters,
each row must contain:
[ S, βx , αx , µx , βy , αy , µy , [ Dx , D px , Dy , D py ]]
(the last four columns are optional)
DQx, DQy the horizontal and vertical chromaticities [2 π]
momentum_compaction the momentum compaction
Pref the reference momentum [MeV/c]
This element works only in Lattice.

Example of matching section


We propose the example of a matching section implemented as a TransferLine, matching a set of
Twiss parameters [ β0,x , α0,x , β0,y , α0,y ] into [ β1,x , α1,x , β1,y , α1,y ], with phase advance µx and
µy over a length L:

% Input data
Pref = 100; % MeV/c, reference momentum
L = 5; % m, length of the matching section

% Initial Twiss parameters


b0_x = 1; % m, horizontal beta function
b0_y = 2; % m, m, vertical beta function
a0_x = a0_y = 0; % alpha

% Final Twiss parameters


b1_x = 5; % m, horizontal beta function
b1_y = 10; % m, m, vertical beta function
a1_x = a1_y = 0; % alpha
4.2 Matrix-based elements 61

% Phase advance between initial and final


mu_x = pi/2; % phase advance in x
mu_y = pi/3; % phase advance in y

% Input matrix for the constructor


T = [ 0 b0_x a0_x 0 b0_x a0_y 0
L b1 x a1 x mu x b1_x a1_y mu_y ];
_ _ _

% Matching section element for Lattice


M = TransferLine(T, Pref);
62 Chapter 4. Beamline elements

4.3 Special elements


4.3.1 Travelling-wave structure
The element TW_Structure allows the simulation of the TM01n modes in a travelling-wave (TW)
structure. A TW structure is a metallic enclosure where electromagnetic fields travelling with a
specific phase advance along the structure can be excited. Figure 4.4 shows a model example of a
travelling-wave structure. For such structures, if L and ∆ϕ indicate the length and phase advance

Figure 4.4: A model of a metallic travelling-wave structure.

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

T = TW_Structure([ an, ... ], n, frequency, phase_advance, number_of_cells);


T = TW_Structure();

The arguments are:


4.3 Special elements 63

[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

Example of travelling-wave structure


We show the example of an ideal travelling-wave structure with three cells having phase advance
2π/3, running at 12 GHz with a gradient of 100 MV/m.

a0 = 100e6; % V/m, gradient


freq = 12e9; % Hz
ph_adv = 2*pi/3; % radian
n_cells = 3; % number of cells

TW = TW_Structure(a0, 0, freq, ph_adv, n_cells);


64 Chapter 4. Beamline elements

4.3.2 Standing-wave structure


The element SW_Structure allows the simulation of the standing-wave (SW) structures connecting
a beampipe with a TW structure. This enables the realistic simulation of a full TW structure, which
must be preceded and followed by a SW structure. Figure 4.5 shows a model example of a standing-
wave structure. In Table 4.4, Jn and In are the mth ordinary Bessel function and mth modified Bessel

Figure 4.5: A model of a metallic standing-wave structure.

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

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

S = SW_Structure([ a1, ... ], frequency, cell_length, number_of_cells );


S = SW_Structure();

The arguments are:


[a1, ... ] a vector with the Fourier coefficients (see Table 4.4) [V/m]
frequency the rf frequency [Hz]
cell_length the length of each cell [m]
number_of_cells the number of cells in the structure. [REAL]
4.3 Special elements 65

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

Example of a full structure


In this example, we propose an Octave function that builds a realistic 2.856 GHz structure composed
of: (1) half a standing-wave cell as the input coupler, (2) three cells of a travelling-wave structure,
and (3) half a standing-wave cell as the output coupler.

% Input arguments
% maxE is the rf gradient in V/m
% phid is the rf phase in deg

function TWS = make_tws (maxE, phid)


RF_Track;
n_cells = 3;
freq = 2.856e9; % Hz
ph_adv = 2*pi/3; % radian, phase advance per cell
L_SW = 1.748602173202614e-01; % m, coupler length

% 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);

% concatenate the three structures


TWS = Lattice();
TWS.append(SWL);
TWS.append(TW);
TWS.append(SWR);
end

In this example, a fitting procedure has been used to compute the Fourier coefficients from a 1D
field map.
4.3 Special elements 67

4.3.3 Pillbox cavity


The element SW_Pillbox_Cavity allows the simulation of the TM01n modes in a standing-wave
pillbox cavity. A pillbox cavity is a metallic enclosure where electromagnetic fields travelling with
no phase advance can be excited. In this model, the flat ends of the cavity are at z = 0 and z = L.
In Table 4.5, Jn and In are the mth ordinary Bessel function and mth modified Bessel Function,
respectively.

Table 4.5: Fourier series expansions of the TM01p electromagnetic fields in a pillbox cavity
Quantity Value

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

S = Pillbox_Cavity ([ a0, ... , ap ], frequency, cell_length, n_cells );


S = Pillbox_Cavity ();

The arguments are:


[a0, ... , ap ] a vector with the Fourier coefficients (see Table 4.5) [V/m]
frequency the rf frequency [Hz]
cell_length the length of each cell [m]
n_cells the number of cells in the structure. [REAL]
68 Chapter 4. Beamline elements

4.3.4 Multipole magnet


Multipole is a multipole magnet. The definition of the normal and skew coefficients is the same
as that of MAD-X. In a Multipole, RF-Track tracks the particles using numerical integration.
The user can select the integration algorithm and number of steps using the set methods mentioned
below (see Set and Get methods).

Constructors

M = Multipole (L, P_Q, [ K0L K1L K2L ... ]);


M = Multipole (L, [ S0 S1 S2 ... ]);
M = Multipole (L=0);

The arguments are:


L the multipole magnet length [m]
P_Q the beam’s magnetic rigidity, P/q [MV/c]
S0, S1, . . . , Sn the (complex) multipole strengths [MV/c/mn ]
K0L, K1L, . . . , KnL the (complex) multipole coefficients [T/mn ]
Here follow a few formulæ to disentangle the relations between the integrated strengths, S; the
integrated focusing strengths, kn L; the field derivatives (gradients), Bn ; and the beam rigidity, P/q:
! 
k̂n L
kn L = n+1
[1/mn ]
1/m m
  ! 
P/q k̂n L
Sn = n+1
[MV/c/mn ]
MV/c 1/m m
 n
∂ B̂ mn

Bn = [T /mn ]
∂ xn T

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 .

We recall the definition of “normal” and “skew” coefficients:

∂ 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:

S.get_Bn(); % the field derivatives in T/m^n


S.get_KnL(P_over_Q); % the integrated coefficient in 1/m^n
S.get_strengths(); % the integrated strength in MV/c/m^n
4.3 Special elements 69

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

Two methods allow to set the tracking options:


S.set_nsteps(N); % set the number of integration steps [default 10]
S.set_odeint_algorithm(name); % e.g. ’rk2’, ’leapfrog’, etc.
70 Chapter 4. Beamline elements

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 );

The input arguments describing the material are:


L absorber length [m]
material_name a material among: ‘air’, ‘water’, ‘beryllium’, [STRING]
‘lithium’, ‘liquid_hydrogen’
X0 radiation length [cm]
Z atomic number of absorber [INTEGER]
A atomic mass of absorber [g mol−1 ]
density density of the absorber [g cm−3 ]
I mean excitation energy. If unspecified or -1, an empirical [eV]
approximation is used.

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

4.3.6 Electron cooler


RF-Track can simulate electron cooling through a sophisticated hybrid kinetic model in which
the beam’s macro particles interact with a cold, magnetised electron plasma. The electron plasma
is modelled with 3D meshes, allowing the user to specify arbitrary transverse and longitudinal
variations of density and current. The following panel presents its constructor and the main methods
to customize the electron cooler simulation fully:

EC = ElectronCooler (L, rx, ry, density, Vz);

% 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);

% Plasma particle (default: electron)


EC.set_Q (Q=-1);
EC.set_mass (mass=electronmass);

The main input arguments are:


L the electron cooler’s length [m]
rx, ry the horizontal and vertical radius of the plasma [m]
Tr, Tl the radial and longitudinal temperature of the plasma [eV]
density the plasma density [m−3 ]
DENSITY2D the plasma density as a Nx×Ny matrix [m−3 ]
DENSITY3D the plasma density as a Nx×Ny×Nz matrix [m−3 ]
Bx, By, Bz the constant magnetic field magnetizing the plasma [T]
Vx, Vy, Vz the velocity of the plasma beam [c]
VX2D, VY2D, VZ2D the velocity of the plasma beam as a Nx×Ny matrix [c]
VX3D, VY3D, VZ3D the velocity of the plasma beam as a Nx×Ny×Nz matrix [c]
72 Chapter 4. Beamline elements

4.3.7 Adiabatic matching device


An AdiabaticMatchingDevice (AMD) is a magnetic element providing a strong tapered
solenoid field, typically used in positron sources. This device, also known as a “Flux Concentrator”,
is essential to capture the positrons right after their creation. In RF-Track, this element is imple-
mented as an analytic 3D field. The on-axis field provided by an AMD is purely longitudinal and is
described as,
B0
Bz (z) = .
1 + αz
Figure 4.6 shows the on-axis field Bz as a function of z for an AMD with B0 = 7 T and α = 60 m−1 .

Constructor

AMD = AdiabaticMatchingDevice( L, B0, ALPHA );

4
Bz (T)

0
0 0.05 0.1 0.15 0.2 0.25
Z (m)

Figure 4.6: Magnetic profile in an AMD.

The arguments are:


L the AMD length [m]
B0 the peak on-axis field, B0 [T]
ALPHA the parameter α [m−1 ]

4.3.8 Space-charge fields


SpaceCharge_Field

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

4.3.10 Volume as a Lattice element


The tracking environment Volume can be inserted into a Lattice like any standard element. When a
Bunch6d, which is being tracked through a Lattice, enters a Volume that has been inserted into a
Lattice as an element, its particles are placed over the are emitted one by one from the Volume’s
surface S0 , according to their time coordinate. Tracking is then performed in the Volume by time
integration and stops when no more particles exist between S0 and S1 .
During tracking, when a particle reaches S1 and leaves the Volume, its position at S1 and its
arrival time are recorded, and a bunch of type Bunch6d is formed for propagation through the rest
of the lattice. This way, a section where time integration is used with all the flexibility offered by
Volume can be placed in a Lattice.
Note that the planes S0 and S1 can have any orientation in space. This allows for changes in the
reference system, for example, when tracking in the field map of a bending magnet or when joining
regions at an angle.
74 Chapter 4. Beamline elements

4.4 Field maps


One of RF-Track’s strengths is tracking in field maps. Real and complex field maps, in one, two, or
three dimensions, are accepted to simulate static fields, backward— or forward-travelling fields, or
standing-wave radiofrequency fields.
Elements based on a one-dimensional on-axis field map still provide three-dimensional fields.
By proving the longitudinal component of the field along the axis of symmetry, RF-Track extends the
field off-axis according to Maxwell’s equations, assuming cylindrical symmetry. Two-dimensional
field maps allow the simulation of cylindrical-symmetric fields from the field over a plane. Three-
dimensional field maps allow tracking in most generic electromagnetic fields. All field maps accept
3D Cartesian mesh grids with regular spacing.

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.

Particle losses in field maps


In RF-Track, three-dimensional field maps can contain more information than the field itself. They
can contain information about the walls of the element in which the field is embedded, using the
special value “not-a-number” (NaN). In floating-point arithmetic, NaN is a numeric data type that
can be interpreted as an undefined value. RF-Track interprets the presence of NaNs in a field map as
a “wall”. If a particle hits a NaN, RF-Track flags the particle as lost. This allows precise detection
of losses in 3D space, even in complex geometries.

Interpolation method and losses detection


In the case of LINT, the interpolation uses the eight closest vertexes of the 3D mesh cell enclosing
the point of interest. Notice that, in this case, the granularity of the loss detection coincides with the
mesh cell size. In the case of CINT, the interpolation uses the 64 closest vertexes, as it considers
the cube with 3 × 3 × 3 mesh cells surrounding the point of interest. This means that the granularity
of the loss detection is effectively three times the size of a mesh cell.
CINT is generally smoother than LINT, as it considers four adjacent points instead of 2. The
price for the increased smoothness is computational time.
4.4 Field maps 75

4.4.1 1D RF field maps


An RF_FieldMap_1d provides an RF oscillating electromagnetic field based on the on-axis electric
field. RF-Track assumes cylindrical symmetry around the structure’s axis and reconstructs the
off-axis transverse and longitudinal electromagnetic field, fulfilling Maxwell’s equations. The user
must provide a regular Cartesian 1D mesh of the longitudinal electric field Ez as complex (travelling
waves) or real (standing waves) numbers.

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);

The input parameters are:


76 Chapter 4. Beamline elements

T0 the reference time [mm/c]


PHID the phase of the RF element [deg]
P the input power [W]
N number of points [INTEGER]
The method set_smooth(N) applies a Gaussian filter to the field map to reduce numerical noise.
The parameter N indicates the radius of the Gaussian function, kernel of the filter, in units of mesh
points. Mathematically, a Gaussian filter corresponds to a convolution with a Gaussian function.

On the reference time


By default, the reference time of an RF element, t0 , is not set. The method set_t0(T0) allows
the user to set the reference time of the RF element. When t0 is not explicitly set, RF-Track sets
it automatically with an “autophasing” (see dedicated section). This is the most common and
straightforward way of setting it.

On the input power


Electromagnetic solvers generally use a pre-defined input power of 1 W to compute the RF elec-
tromagnetic field in the structure. If this is the case, one can directly give RF-Track the field as
the solver computed it, Emap , with the indication of the input power used for its computation, Pmap .
For tracking, though, one should provide the power at which the structure is operated to obtain the
actual field acting on the particles. The relation between these quantities is the following:
s
Pactual
Eactual = Emap .
Pmap

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

4.4.2 2D RF field maps


An RF_FieldMap_2d provides an RF oscillating electromagnetic field based on a field map defined
over a 2D plane. RF-Track assumes cylindrical symmetry around the structure axis. The user must
provide a regular Cartesian 2D mesh per each field component: Er , Ez , and Bt , Bz . The four 2D
meshes can be either complex numbers (travelling waves) or real numbers (standing waves). Their
elements,
Eri j , Ezi j , , and Bti j , Bzi j ,
have two indexes, i j: the first, i, runs along the longitudinal direction, and the second, j, along the
radial direction.

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 ( " );

The default element RF_FieldMap_2d uses linear interpolation.


The variant, RF_FieldMap_2d_CINT, provides cubic interpolation.
The required input arguments are:
Er, Ez 2D mesh of the radial and longitudinal electric field, or zero 0 if [V/m]
the electric field is absent
Bt, Bz 2D mesh of the azimuthal and longitudinal magnetic field, or [T]
zero 0 if the magnetic field is absent
hr, hz The sizes of a mesh cell in the radial and longitudinal directions [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();
78 Chapter 4. Beamline elements

RF.set_phid(PHID);
RF.set_P_actual(P);
RF.set_smooth(N);

The input parameters are:


T0 the reference time [mm/c]
PHID the phase of the RF element [deg]
P the input power [W]
N number of points [INTEGER]
The method set_smooth(N) applies a Gaussian filter to the field map to reduce numerical noise.
The parameter N indicates the radius of the Gaussian function, kernel of the filter, in units of mesh
points. Mathematically, a Gaussian filter corresponds to a convolution with a Gaussian function.

On the reference time


By default, the reference time of an RF element, t0 , is not set. The method set_t0(T0) allows
the user to set the reference time of the RF element. When t0 is not explicitly set, RF-Track sets it
automatically with an “autophasing” (see dedicated section). This is the most common and simple
situation.

On the input power


Electromagnetic solvers generally use a pre-defined input power of 1 W to compute the RF elec-
tromagnetic field in the structure. If this is the case, one can directly give RF-Track the field as
the solver computed it, Emap , with the indication of the input power used for its computation, Pmap .
For tracking, though, one should provide the power at which the structure is operated to obtain the
actual field acting on the particles. The relation between these quantities is the following:
s
Pactual
Eactual = Emap .
Pmap

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

4.4.3 3D RF field maps


An RF_FieldMap provides an RF oscillating electromagnetic field. The user must provide a
regular Cartesian 3D mesh per each field component: Ex , Ey , Ez , and Bx , By , Bz , or alternatively the
constant 0 when the field is unknown or null.
The 3D meshes can be either complex numbers (travelling waves) or real numbers (standing
waves). Their elements,
Exi jk , Eyi jk , Ezi jk , and Bxi jk , Byi jk , Bzi jk ,
have three indexes, i jk: the first, i, runs along the horizontal direction, x; the second, j, runs along
the vertical direction, y; and the third, k, runs along the longitudinal direction z.
Constructors

RF = RF_FieldMap (Ex, Ey, Ez,


Bx, By, Bz,
x0, y0,
hx, hy, hz,
length,
frequency,
direction,
P_max = 1,
P_actual = 1);
_ _
RF = RF FieldMap CINT ( " );

The default element RF_FieldMap uses linear interpolation.


The variant RF_FieldMap_CINT provides cubic interpolation.
The required input arguments are:
Ex, Ey, Ez 3D mesh of the electric field, or zero, 0 [V/m]
Bx, By, Bz 3D mesh of the magnetic field, or zero, 0 [T]
x0, y0 The position of the bottom-left point of the field map in the x − y [m]
plane
hx, hy, hz The sizes of a mesh cell in the x, y, and z directions [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);
80 Chapter 4. Beamline elements

RF.unset_t0();
RF.set_phid(PHID);
RF.set_P_actual(P);
RF.set_smooth(N);

The input parameters are:


T0 the reference time [mm/c]
PHID the phase of the RF element [deg]
P the input power [W]
N number of points [INTEGER]
The method set_smooth(N) applies a Gaussian filter to the field map to reduce numerical noise.
The parameter N indicates the radius of the Gaussian function, kernel of the filter, in units of mesh
points. Mathematically, a Gaussian filter corresponds to a convolution with a Gaussian function.

On the reference time


By default, the reference time of an RF element, t0 , is not set. The method set_t0(T0) allows
the user to set the reference time of the RF element. When t0 is not explicitly set, RF-Track sets it
automatically with an “autophasing” (see dedicated section). This is the most common and simple
situation.

On the input power


Electromagnetic solvers generally use a pre-defined input power of 1 W to compute the RF elec-
tromagnetic field in the structure. If this is the case, one can directly give RF-Track the field as
the solver computed it, Emap , with the indication of the input power used for its computation, Pmap .
For tracking, though, one should provide the power at which the structure is operated to obtain the
actual field acting on the particles. The relation between these quantities is the following:
s
Pactual
Eactual = Emap .
Pmap

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

4.4.4 1D static magnetic field maps


An Static_Magnetic_FieldMap_1d provides a static magnetic field based on the on-axis field.
RF-Track assumes cylindrical symmetry around the structure’s axis and reconstructs the field’s
off-axis transverse and longitudinal components, fulfilling Maxwell’s equations. The user must
provide a regular Cartesian 1D mesh of the longitudinal magnetic field Bz .

Constructors

M = Static_Magnetic_FieldMap_1d (Bz, hz, length=-1 );


M = Static_Magnetic_FieldMap_1d_CINT ( " );

The element Static_Magnetic_FieldMap_1d uses linear interpolation along the longitudinal


axis and linear extrapolation in the radial direction. Static_Magnetic_FieldMap_1d_CINT
uses cubic interpolation along the longitudinal axis and cubic extrapolation in the radial direction.
The required input arguments are:
Bz The on-axis magnetic field [T]
hz The mesh cell length in the longitudinal direction [m]
length the total length of the element (if -1 take the field map length) [m]
82 Chapter 4. Beamline elements

4.4.5 2D static magnetic field maps


An element of type Static_Magnetic_FieldMap_2d provides a magnetic field based on a field
map defined over a 2D plane. RF-Track assumes cylindrical symmetry around the element’s axis.
The user must provide a regular Cartesian 2D mesh per each field component: Br and Bz . The two
input 2D meshes,
Bri j , Bzi j
have two indexes, i j: the first, i, runs along the longitudinal direction, and the second, j, along the
radial direction.

Constructors

S = Static_Magnetic_FieldMap_2d (Br, Bz, hr, hr, length=-1);


S = Static_Magnetic_FieldMap_2d_CINT ( " );

The element Static_Magnetic_FieldMap_2d uses linear interpolation.


The variant, Static_Magnetic_FieldMap_2d_CINT, provides cubic interpolation.
The required input arguments are:
Br, Bz 2D mesh of the radial and longitudinal magnetic field [T]
hr, hz The sizes of a mesh cell in the radial and longitudinal directions [m]
length the total length of the element (if -1 take the field map length) [m]
4.5 Beam diagnostics 83

4.5 Beam diagnostics


4.5.1 Beam position monitors
The Bpm element adds a beam position monitor to a Lattice. The Bpm can be thick and have a
user-defined resolution. The scaling error can also be applied. Reading a Bpm can be done after
tracking a beam. Note that subsequent readings for the same Bpms will result in different readings,
as each measurement is affected by the resolution error.
The Bpm element is currently only implemented in Lattice.

Constructor

B = Bpm (L, resolution );

The input arguments describing the material are:


L the element length. The reading occurs in the middle of the [m]
specified length.
resolution the resolution [mm]

After tracking, to get all Bpms’ readings at once, one can call the method get_bpm_readings()
of the Lattice object.

Get methods

[X,Y] = B.get_reading(); % return mm


res = B.get_resolution(); % return mm

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

B = S.get_bunch(); % return a Bunch6d


B = S.get_beam(); % return a Beam
t0 = S.get_t0(); % returns the reference time in mm/c

Set methods

S.set_width (W); % mm, screen width W


S.set_height (H); % mm, screen height H
S.set_time_window (T); % mm/c, screen time window T
S.set_t0 (t0); % set reference time [default: unset]
S.unset_t0 (); % unset the reference time

The input arguments are:


W Width. Particles hit the screen if −W/2 ≤ x ≤ W/2. [mm]
H Height. Particles hit the screen if −H/2 ≤ y ≤ H/2. [mm]
T Time window. Particles are stored if −T/2 ≤ (t − t0) ≤ T/2. [mm/c]
t0 the reference time [default unset]
By default, a new Screen has infinite extension and a boundless time window.
5. Inverse Compton scattering

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.

5.1.1 General parameters


Structure LaserBeam contains all information required to define a laser beam from its general
parameters. The possible arguments are:

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.

Define direction of laser


The direction of propagation of the laser beam can be completely arbitrary and is provided as a
vector in the 3D space.

LB.set_direction(nx, ny, nz);

The possible arguments are:


nx horizontal component [a.u.]
ny vertical component [a.u.]
nz longitudinal component [a.u.]
For example, for a full head-on collision, one must set nx = 0, ny = 0, and nz = −1. Notice that the
length of the vector defined by nz , ny , and nz is irrelevant, only its direction matters.

5.1.2 Particles-laser interaction


Distinct functions and parameters define the laser-beam interactions in the LaserBeam element.

Define the interaction point


If the length of the LaserBeam element is not zero, you need to set the position of the interaction
point between the incoming beam and the laser along the longitudinal axis.

LB.set_position(Z);

Set number of generated macro-particles per slice


RF-Track implements macro-particles for tracking. The beam(s) generated from interactions are
also structured in macro-particles. This function allows you to adjust the number of macro photons
generated in each slice to ensure that enough macro photons are created in one run to generate
statistics. This affects both the precision of the interaction simulation and its runtime.

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.

Define the number of steps taken by the simulation


Tracking through elements is inherently discrete, as the beam is advanced through an element in a
discrete number of steps. The number of steps taken across the interaction space can be changed
5.2 Collecting the generated photons 87

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.

5.2 Collecting the generated photons


When a bunch traverses a LaserBeam element, RF-Track computes the Compton scattering
between the bunch and the laser. All photons generated during the interaction are added to the
travelling bunch. The user can retrieve them using the Bunch6d’s method get_phase_space().
In particular, inquiring about the mass or the charge of the particles in the bunch allows the
discrimination between the bunch’s particles and photons. Follows an example:

% L is a lattice containing a LaserBeam element


B1 = L.track(B0); % tracks B0 through the lattice

% Read the output phase space


M1 = B1.get_phase_space(’%x %xp %y %yp %t %P %m’);

% Separate the photons


is_photon = M1(:,7) == 0; % pick the photons (mass == 0)
M1p = M1( is_photon,:); % photons
M1e = M1(~is_photon,:); % other particles

% plot the XX’ photons’ phase space


scatter(M1p(:,1), M1p(:,2));
xlabel(’x [mm]’);
ylabel(’x’’ [mrad]’);
6. Collective effects

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:

E = Drift(1.0); % or whatever element


E.add_collective_effects( CFX1 );
E.add_collective_effects( CFX2 );

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

6.1 Space charge


Space charge effects are treated differently from the other collective effects. Space charge is
intrinsically associated with the bunch, whereas other collective effects are typically related to
specific elements. For example, Wakefields are associated with accelerating structures (e.g. short-
range wakes) or particular sections of beamlines (e.g. resistive-wall wakes); similarly, spurious
magnetic multipolar components are associated with specific magnetic elements, etc.

6.1.1 Space-charge in Volume


As mentioned in Chapter 2, which describes the beam models, Volume (time integration) is the
most appropriate environment for space-charge-dominated regimes, such as injectors and low-
energy setups. In Volume, space charge effects permeate the whole 3D space. One can activate
space-charge effects using the tracking option sc_dt_mm to set how frequently a space-charge kick
should be applied:

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.

6.1.2 Space-charge in Lattice


Space-charge effects can also be simulated in Lattice, but some tricks are needed to deal with space
integration. When using space integration, i.e. Bunch6d, at any given longitudinal position, the
bunch has all particles on the same longitudinal plane, and the arrival time is the fifth phase space
coordinate. But to calculate the effect of the space-charge force, one needs to know the position of
the particles in space at the same time, not their arrival time at the same location. For this reason,
RF-Track expands the bunch “on the fly” so that the bunch particles are all simultaneous and their
average longitudinal position corresponds to the current longitudinal position. A drift step is applied
to each particle. This drift is thus used only to calculate the kicks due to the space-charge force
applied to each particle.
In Lattice, to enable space charge effects, one must specify how many kicks of space charge
one wants to consider, element by element:

E = Element() % whichever element


E.set_sc_nsteps ( NUMBER_OF_STEPS );

where NUMBER_OF_STEPS is a positive integer number.

6.1.3 Space charge models


RF-Track implements two space charge algorithms:

SC = SpaceCharge_PIC_FreeSpace (Nx=16, Ny=16, Nz=16);


SC = SpaceCharge_P2P ();
92 Chapter 6. Collective effects

SpaceCharge_PIC_FreeSpace() implements a free-space fast Fourier algorithm based on 3D


retarded integrated Green’s functions. This is the default algorithm and should be preferred to the
other. The numbers Nx, Ny, and Nz allow the user to specify how many mesh points should be used
for the computation. They can be any integer number, even or odd. The grid is updated at each
kick. Unlike most simulation codes, RF-Track calculates the effects of space charge considering
both electric and magnetic forces. This means that beam-beam effects are automatically included
and simulated.
SpaceCharge_P2P() implements a particle-2-particle algorithm which computes the electromag-
netic interaction between all pairs of particles within the bunch. This is significantly slower than
SpaceCharge_PIC_FreeSpace() and more subjected to artificial effects when macroparticles
with considerable charge are too close. This was implemented as an academic exercise and has been
kept in the code for self-consistency checks. SpaceCharge_PIC_FreeSpace() is recommended.

Setting the space-charge algorithm


The space charge computing engine can be changed by setting the RF-Track settings’ variable
SC_engine. In Octave, this is done like in the following example:

SC = SpaceCharge_PIC_FreeSpace(40, 40, 40);


RF_Track.SC_engine = SC;

In Python,

SC = SpaceCharge_PIC_FreeSpace(40, 40, 40)


RF_Track.cvars.SC_engine = SC

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).

6.2 Incoherent synchrotron radiation


The impact of synchrotron radiation emission can be considered using the collective effect
IncoherentSynchrotronRadiation, which accepts just one optional, boolean argument:

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.

6.3 Magnetic multipolar errors


MultipoleKick allows the attachment of multipole magnetic errors to any element. It accepts a
list of complex gradients:

M = MultipoleKick ([ B0, B1, ... Bn ]);


6.3 Magnetic multipolar errors 93

The argument is:


B0, B1, . . . , Bn the (complex) gradients [T/mn ]
with
∂ n B̂ mn
 
Bn = [T /mn ]
∂ xn T

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

6.4 Beam loading


The beam loading effect is the gradient reduction in the accelerating structure due to the beam’s
excitation of the fundamental accelerating mode. This translates into a transient effect for long
trains where the late bunches will be affected by the EM field left by earlier bunches. RF-Track
allows the consideration of this effect both in travelling-wave and standing-wave structures.

6.4.1 Beam loading in ultrarelativistic scenarios


The beam loading effect in ultrarelativistic scenarios (v ' c) is considered for both travelling-wave
structures and standing-wave structures using the collective effect BeamLoading(). The following
constructors distinguish between transient and steady-state:

Constructors

% Steady state beam loading - For trains entering after tfill


% Fixed charge per bunch
BL = BeamLoading(Ncells, freq, ph_ad, Q, r_Q, vg, q, particles_bunch, ...
fb, nbins);
% Transient beam loading - For bunches entering before tfill.
% No assumption on the train distribution
BL = BeamLoading(Ncells, freq, ph_ad, Q, r_Q, vg, nbins);

The possible arguments are:


Ncells Number of cells of the TW structure
freq RF-Frequency [Hz]
ph_ad Phase advance [rad]
Q Quality factor array
r_Q Normalised shunt impedance per unit length array (r/Q) [Ω/m]
vg Group-velocity array [c]
nbins Number of bins for single-bunch longitudinal slicing
q Single particle charge [e]
particles_bunch Number of particles per bunch
fb Bunch injection frequency [Hz]

If no nbins value is provided, the default value is nbins=16.

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:

BL.solve_pde_steady(q_bunch, fb, ffactor);


BL.solve_pde_transient(q_bunch, fb, Nbunches, ffactor);

The possible arguments are:


6.4 Beam loading 95

q_bunch Total charge per bunch [e]


Nbunches Number of bunches of the train
ffactor Bunch form factor
The most common bunch distributions and associated form factors are given below:
ω 2 σz2
GAUSSIAN: F(ω) = exp −
2c2
sin x 1
UNIFORM: F(ω) = , with x = ωtb
x 2
Here, σz refers to the longitudinal single-bunch energy spread and tb is the time-range of it. If no
ffactor is given, the default value is ffactor = 1.

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:

% Set unloaded gradient according to Pinput for BL compensation in TW structures


BL.set_unloaded_gradient(Pinput, dt_Pinput, t_inj, RF_Structure );
% Set early injection time for BL compensation in SW structures
BL.set_early_injection(t_inj, RF_Structure );

The required arguments are:


Pinput Input power spline [W]
dt_Pinput Time step associated to the Pinput spline [mm/c]
t_inj Injection time with respect to the origin of Pinput [mm/c]
RF_Structure RF-Element with the TW/SW field map

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

% Interpolated splines of figures of merit along the structure


BL.get_vg(); % Group velocity, c
BL.get_dvg(); % Group velocity spatial derivative, c/mm
BL.get_Q(); % Quality factor
BL.get_rho(); % Normalized shunt impedance per unit length, Ohm/m
BL.get_drho(); % Normalized shunt impedance p.u.l derivative, Ohm/m/mm
96 Chapter 6. Collective effects

% Structure gradient - After solve methods


BL.get_G(); % Transient beam-induced gradient, V/m
BL.get_G_steady(); % Steady beam-induced gradient, V/m

% Structure gradient - After Set methods


BL.get_G_unloaded(); % Transient unloaded gradient, V/m
BL.get_G_unloaded_steady(); % Steady unloaded gradient, V/m
BL.get_dt(); % Time-step in transient gradient matrices, mm/c

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();

6.4.2 Beam loading in standing-wave structures


The beam loading effect in standing-wave structures for non-ultrarelativistic scenarios is taken
into account using the collective effect BeamLoadingSW(), which accepts the following argu-
ments:

% Transient BL effect in SW structures


BL = BeamLoadingSW(SWS, Q, r_Q, Ncells, mass, q, tinj);

In this case, the arguments are:


SWS RF-Element with the SW field map
Q Loaded quality factor array
r_Q Normalized shunt impedance per unit length array (r/Q) [Ω/m]
Ncells Number of cells of the TW structure
mass Particle mass [MeV/c2 ]
q Single particle charge [e]
tinj Injection time of the bunch [τ]
2Q
For SW structures, τ = ω .

Get methods
The following quantities can be obtained from the BeamLoadingSW() collective effect:

BL.get_Lcell(); % Cell length, m


BL.get_tfill(); % Filling time, mm/c
BL.get_tinj(); % Injection time, mm/c
6.4 Beam loading 97

BL.get_TT1(); % Time-transit factor array for the first cell


BL.get_TT2(); % Time-transit factor array for any complete cell
98 Chapter 6. Collective effects

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.

6.5.1 Short-range wakefield


ShortRangeWakefield implements the transverse and longitudinal effect of short-range wake-
fields.

SRWF = ShortRangeWakefield (a, g, l);


SRWF = ShortRangeWakefield ([ai af], [gi gf], [li lf], Ncells);

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.

Inquiring the wake function


The user can inquire RF-Track about the single-particle Wake function using the method:
Wl = SRWF.w_long ( S ); % return V/pC/m
Wt = SRWF.w_transv ( S ); % return V/pC/m/mm

where the input parameter:


S is the longitudinal distance in meters from the source particle. Since the [m]
Wakefield can only affect the trailing particles, S<0.

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.

SRWF.scatter_cells (RANGEX, RANGEY ); % mm

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

6.5.2 Generic wakefield


The collective effect Wakefield_1d allows the user to provide an arbitrary single-particle wake
function, or Green’s function, using two 1d vectors sampling the function.

WF = Wakefield_1d (Wt, Wl, hz);

The required input parameters describe wakefield are:


Wt A 1d vector with the transverse component of the wake function [V/pC/mm/m]
Wl A 1d vector with the longitudinal component of the wake function [V/pC/m]
hz the 1d mesh spacing of Wt and Wl [m]

Inquiring the wake function


The user can inquire RF-Track about the single-particle Wake function using the method:
Wl = SRWF.w_long ( S ); % return V/pC/m
Wt = SRWF.w_transv ( S ); % return V/pC/m/mm

where the input parameter:


S is the longitudinal distance in meters from the source particle. Since the [m]
Wakefield can only affect the trailing particles, S<0.
6.5 Wakefields 101

6.5.3 Long-range wakefield


In the case of multi-bunch operation, long-range wakefield effects can become significant. In
RF-Track, the command LongRangeWakefield allows the simulation of long-range wakefield
effects. Its input arguments are:

LRWF = LongRangeWakefield (A, freq, Q);

The required input parameters describe the transverse high-order modes:


A A vector or a matrix containing the modes’ amplitudes [V/pC/mm/m]
freq A vector or a matrix containing the modes’ frequencies [Hz]
Q A vector or a matrix containing the modes’ Q factors [unit less]

When A, freq, and Q are matrices, e.g.


 
A11 A12 · · · A1m
A =  ... ..  , (6.1)

. 
An1 An2 · · · Anm

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

with λn being the wavelength corresponding to the frequency fn .

Inquiring the wake function


The user can inquire RF-Track about the single-particle Wake function using the method:
Wl = SRWF.w_long ( S ); % return V/pC/m
Wt = SRWF.w_transv ( S ); % return V/pC/m/mm

where the input parameter:


S is the longitudinal distance in meters from the source particle. Since the [m]
Wakefield can only affect the trailing particles, S<0.
102 Chapter 6. Collective effects

6.6 Passage of particles through matter


6.6.1 Multiple Coulomb scattering
The Multiple Coulomb Scattering module allows the simulation of the interaction between the
bunch particles and a material. This effect can be added to any elements to simulate beam tracking
through matter. Follows a list of the constructor and the main methods:

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();

The input arguments describing the material are:


material a material among: ‘air’, ‘water’, ‘beryllium’, [STRING]
‘lithium’, ‘liquid_hydrogen’
X0 the radiation length [cm]
Z the atomic number of absorber [INTEGER]
A the atomic mass of absorber [g mol−1 ]
density the material density [g cm−3 ]
I the mean excitation energy. If not provided, RF-Track will [eV]
compute it using the approximation proposed by Bloch.

6.6.2 Stopping power


Charged particles lose energy as they pass through matter, governed by the Bethe-Bloch equation,
which describes how the energy loss depends on the properties of the material and the particle. The
energy loss per unit path length is defined as
α 2 ρZ 1 h 1 2me γ 2 β 2 Tmax
 
dE 2
i
− = 4πNA ln − β . (6.2)
ds me A β 2 2 I2
In RF-Track, Eq. (6.2) is automatically applied as the default energy loss model when the command
MultipleCoulombScattering(material) is used. For electrons in water and electrons in
air, RF-Track uses the data tabulated by the National Institute of Standards and Technology,
https://physics.nist.gov/PhysRefData/Star/Text/ESTAR.html, for muons in liquid
hydrogen, RF-Track uses the data tabulated by the Particle Data Group https://pdg.lbl.gov/
2022/AtomicNuclearProperties/MUE/muE_hydrogen_liquid.txt.

6.6.3 Energy straggling


While a bunch traverses a material, the energy loss is not the same for all the particles. Hence,
particles incident on the foil with the same energy emerge with different energies. This energy
distribution caused by the scattering material is known as the particles’ ’straggling”.
7. Bunch generation at a photocathode

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.

7.1.1 Particle Properties


• species [STRING]: Type of particle (e.g., “electron”).
• noise_reduc [BOOL]: Indicates whether noise reduction is active.
• rand_generator [STRING]: Random generator type (e.g., “halton”, “sobol”, ... ).
• cathode [BOOL]: Whether is a cathode or 3D distribution.
• charge [REAL]: Charge of the particle.
• mass [REAL]: Mass of the particle in MeV/c2 .
• p_ref [REAL]: Reference momentum in MeV/c.

7.1.2 Longitudinal Distribution


• dist_z [STRING]: Type of longitudinal particle distribution (e.g., “gaussian”, “fd_300”).
• sig_z [REAL]: RMS value of the bunch length in mm.
• shape_z [REAL]: Shape parameter of the generalized Gaussian distribution. (default: 2,
Gaussian)
• c_sig_z [REAL]: Cutoff for the Gaussian distribution.
• lz [REAL]: Length of the bunch in mm.
• rz [REAL]: Rising edge of the bunch in mm (for plateau distribution).

7.1.3 Transverse Spatial Distribution


• dist_x [STRING]: Horizontal distribution type (e.g., “gaussian”, “pleateau”, . . . ).
104 Chapter 7. Bunch generation at a photocathode

• dist_y [STRING]: Vertical distribution type (e.g., “gaussian”, “pleateau”, . . . ).


• sig_x [REAL]: RMS size in the horizontal direction (mm).
• sig_y [REAL]: RMS size in the vertical direction (mm).
• shape_x [REAL]: Shape parameter for the horizontal distribution. (default: 2, Gaussian)
• shape_y [REAL]: Shape parameter for the vertical distribution. (default: 2, Gaussian)
• c_sig_x [REAL]: Cutoff for the horizontal distribution.
• c_sig_y [REAL]: Cutoff for the vertical distribution.
• lx [REAL]: Width of the horizontal distribution in mm.
• ly [REAL]: Width of the vertical distribution in mm.
• rx [REAL]: Rising edge of the horizontal distribution in mm.
• ry [REAL]: Rising edge of the vertical distribution in mm.
• x_off [REAL]: Horizontal offset in mm.
• y_off [REAL]: Vertical offset in mm.
• disp_x [REAL]: Horizontal dispersion in meters.
• disp_y [REAL]: Vertical dispersion in meters.

7.1.4 Transverse Momentum Distribution


• dist_px [STRING]: Horizontal momentum distribution type (e.g., “gaussian”).
• nemit_x [REAL]: Normalized transverse emittance in horizontal direction (mm mrad).
• sig_px [REAL]: RMS value of horizontal momentum (keV/c).
• c_sig_px [REAL]: Cutoff for the horizontal momentum distribution.
• lpx [REAL]: Width of the horizontal momentum distribution (keV/c).
• rpx [REAL]: Rising edge of the horizontal momentum distribution (keV/c).
• cor_px [REAL]: Correlated beam divergence in horizontal direction (mrad).

7.1.5 Additional Parameters


• emit_z [REAL]: Longitudinal emittance in keV mm.
• emit_t [REAL]: Temporal emittance in keV ps.
• cor_ekin [REAL]: Correlated energy spread in keV.
• e_photon [REAL]: Photon energy for Fermi-Dirac distribution (eV).
• phi_eff [REAL]: Effective work function for Fermi-Dirac distribution (eV).

7.2 Example of photocathode


Follows an example:

%% Beam creation at cathode


G = Bunch6dT_Generator();

G.species = ’electrons’; % species


G.cathode = true; % cathode, true or false
G.noise_reduc = true; % noise reduction (quasi-random)
G.q_total = Q_pC/1e3; % nC bunch charge
G.ref_ekin = 0; % MeV energy of reference particle
G.ref_zpos = 0; % m position of reference particle
G.ref_clock = 0; % ns clock of reference particle
7.2 Example of photocathode 105

G.phi_eff = 3.5; % eV, effective work function


G.e_photon = 4.73; % eV, photon energy for Fermi-Dirac distribution.
G.dist_x = ’g’; % Specifies the horizontal particle distribution.
G.dist_y = ’g’; % Specifies the vertical particle distribution.
G.sig_x = sigr; % mm, rms bunch size in the horizontal direction.
G.sig_y = sigr; % mm, rms bunch size in the vertical direction.
G.sig_t = sigt; % ns, rms emission time
G.c_sig_x = 3; % cuts off a Gaussian horizontal distribution.
G.c_sig_y = 3; % cuts off a Gaussian vertical distribution.
G.c_sig_t = 3; % cuts off a Gaussian longitudinal distribution.
G.dist_pz = ’fd_300’; % Cathode emission following a Fermi-Dirac dist.

Nparticles = 10000; % number of macroparticles


B0 = Bunch6dT (G, Nparticles);
8. Examples

8.1 Example of bunch creation


8.1.1 Bunch6d from an arbitrary user-defined distribution
For an example of a bunch created from the Twiss parameters, see Chapter 1. The following
example creates a bunch from a matrix. The matrix has dimensions N × 6, where 6 is the size of
the phase space, and N is the number of macroparticles in the bunch.

% create a bunch of 1e12 100 MeV/c electrons, using 1000 macroparticles


P = 100; % MeV/c total momentum
O = zeros(1000,1); % define a column vector of zeros
I = ones(1000,1); % define a column vector of ones
X = randn(1000,1); % mm, column vector of Gaussian-distributed positions
Y = randn(1000,1); % mm, column vector of Gaussian-distributed positions

% create the beam matrix


M = [ X O Y O O P*I ]; % Bunch6d %x %xp %y %yp %t %P

% create a bunch
B0 = Bunch6d(RF_Track.electronmass, 1e12, -1, M);

% retrieve the phase space following MAD-X convention


T0 = B0.get_phase_space("%x %px %y %py %Z %pt");

% retrieve the phase space following the TRANSPORT convention


T0 = B0.get_phase_space("%x %xp %y %yp %dt %d");
108 Chapter 8. Examples

% retrieve the phase space following PLACET convention


T0 = B0.get_phase_space("%E %x %y %dt %xp %yp");

% 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

% save as an Octave matrix


save -text my_bunch.txt T0;

8.1.2 Chirped Buch6d from Twiss parameters

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

Magnetic multipolar errors . . . . . . . . . . . . . . . 92 Volume . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37


Multi-bunch beams . . . . . . . . . . . . . . . . . . . . . . 26
Multiple Coulomb scattering . . . . . . . . . . . . 102 W
Multipole magnet . . . . . . . . . . . . . . . . . . . . . . . 68
Wakefields . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98

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

You might also like