Merlin++ Code Base and Design PhilosophyMerlin++ is a result of the requirement for object-orientated design (OOD) methodologies in particle accelerator design software. This is mostly due to the extensive lifetime accelerator design software packages tend to have (decades), giving rise to a need for code maintainability and sustainability. C++ was chosen as it excels in this regard, while also allowing for low-level processes to written where necessary, to maintain optimal performance.
There are two key design philosophies behind Merlin++ (not mutually exclusive):
1. To be able to do the job required in the simplest, but most flexible form
2. To produce a set of loosely coupled software components which are easily maintainable, extendible, and re-usable
The Merlin++ developers encourage that all users and future developers adhere to this design philosophy, too.
Understand the Design Fundamentals
Merlin++ is a C++ class library for performing charged particle tracking and particle accelerator simulations. The library can be loosely divided into two parts:
1. Accelerator Model construction
2. Beam dynamics and tracking simulation
The model of the accelerator system being studied contains only a description of the physical components e.g. magnets, diagnostics, vacuum chambers, cavities, power supplies, support structures. The classes responsible for performing the required beam dynamics simulations use this information to construct the more abstract algorithm-related representation of the model (e.g. construction of a map for particle tracking.) In this respect, the accelerator model can be thought of as a form of database.
This separation allows (in principle) the same accelerator model to be used repeatedly for different forms of beam dynamics simulations, without the need to modify the accelerator model code directly.
Currently, the only beam dynamics package supported is particle tracking (i.e. ray tracing.)
Accelerator ModelThe accelerator model (class AcceleratorModel) is constructed from model elements (class ModelElement). All accelerator components types have a common base class, AcceleratorComponent The majority of these model elements represent the traditional beamline components found in other optics codes, see Table 2.
Table 1: Accelerator component types and their corresponding classes.
|Component Type||Merlin++ class|
|Drift Section||class Drift|
|Sector Bend||class SectorBend|
|Standing-wave RF Cavity||class SWRFStructure|
|Traveling-wave RF Cavity||class TWRFStructure|
|Horizontal Correctors (xcor)||class XCor|
|Vertical Correctors (ycor)||class YCor|
|Beam Position Monitors (BPM)||class BPM|
|Profile Monitors||class RMSProfileMonitor|
Table 2: Accelerator component attributes and their corresponding classes.
|Component Attribute||Merlin++ class|
|Electro-Magnetic Field||class EMField|
In Merlin, an AcceleratorGeometry is an important concept and serves several functions. Primarily it is responsible for calculating coordinate transformations to and from the local component coordinate frame during tracking operations.
By ‘tracking’, we generally mean either tracking some representation of the beam through the accelerator beamline, or propagating some map. The Merlin class library has been designed to allow addition of different forms of tracking without the need to modify existing code (in particular the accelerator model classes.) Currently, the Merlin library only supports particle tracking (i.e. ray tracing.)
Merlin separates the responsibilities for tracking (iterating) over a beamline and performing the necessary coordinate transformations between component (frames), and actually tracking, or integrating through a component (e.g. a quadrupole.) The latter is the job of the ComponentTracker class, which supplies the primary tracking interface to the accelerator components.
A ComponentTracker contains a set of Integrators which perform the physical tracking through a component. Typically, there is one integrator object per component class in the accelerator model, although there are often less integrators than component types, e.g. the particle tracker uses a single integrator to deal with all rectangular multipoles magnets. The job of the ComponentTracker class, therefore, is to simply select the correct integrator for the current component.
To add a new tracking module, we must perform the following to steps:
- Derive a new class from ComponentTracker
- Construct a set of integrators specific to that tracker for each relevant component in the accelerator model.
The ‘Process’ Concept
The ComponentTracker concept dealt with in the last section is responsible for performing some concrete tracking algorithm though individual components. Generally, we perform such tracking on a sequence of such components that represents some lattice or beamline. The applications programmer could simply write a do-loop that iterated over the components, but Merlin supplies a much higher-level concept to do this, under the control of one or more so-called Processes.
The TrackingSimulation class is a top-level abstraction for performing some accelerator simulation. Exactly what form that simulation takes is defined by one or more processes (class BunchProcess). Generally, processes fall into two categories:
- A process which increments the independent variable (usually s ), i.e. actually tracks through a step ds ; these processes are know as Transport Processes
- A process that does not actual increment s, but applies some impulse to the bunch; these are know as Impulse Processes
A TrackingSimulation generally has at least one Transport Process that does the ‘tracking. As an example, the class ParticleTracker provides the primary interface to the particle tracking module. ParticleTracker inherits from TrackingSimulation , and on construction, automatically adds a ParticleTransportProcess to its list of processes. Additional processes (e.g. SynchRadParticleProcess ) can be added if required. ParticleTransportProcess uses a ComponentTracker to track through each component.
The real power behind a process is that taken together, the list of processes defines the finite steps taken through each component. As an example, you can tell the SynchRadParticleProcess to take twenty equidistant steps through each magnet. TrackingSimulation is responsible for managing the step length. It determines the next step to take (ds ) after interrogating each of its processes in turn, after which it tells each process to take that step. Note that processes can be turned on or off, or made active for only certain types of/specific components.