This notebook was created by Sergey Tomin. Source and license info is on GitHub. May 2017.
Second order tracking with CSR effect of the 200k particles.
As an example, we will use bunch compressor BC2 of the European XFEL Injector.
The CSR module uses a fast ‘projected’ 1-D method from CSRtrack code and follows the approach presented in {Saldin et al 1998, Dohlus 2003, Dohlus 2004}. The particle tracking uses matrices up to the second order. CSR wake is calculated continuously through beam lines of arbitrary flat geometry. The transverse self-forces are neglected completely. The method calculates the longitudinal self-field of a one-dimensional beam that is obtained by a projection of the ‘real’ three-dimensional beam onto a reference trajectory. A smooth one-dimensional charge density is calculated by binning and filtering, which is crucial for the stability and accuracy of the simulation, since the instability is sensitive to high frequency components in the charge density.
In [1]:
# the output of plotting commands is displayed inline within frontends,
# directly below the code cell that produced it
%matplotlib inline
from time import time
# this python library provides generic shallow (copy) and deep copy (deepcopy) operations
from copy import deepcopy
# import from Ocelot main modules and functions
from ocelot import *
# import from Ocelot graphical modules
from ocelot.gui.accelerator import *
# load beam distribution
# this function convert CSRtrack beam distribution to Ocelot format - ParticleArray. ParticleArray is designed for tracking.
# in order to work with converters we have to import specific module from ocelot.adaptors
from ocelot.adaptors.csrtrack2ocelot import *
In [2]:
# load and convert CSRtrack file to OCELOT beam distribution
# p_array_i = csrtrackBeam2particleArray("in.fmt1", orient="H")
# save ParticleArray to compresssed numpy array
# save_particle_array("test.npz", p_array_i)
p_array_i = load_particle_array("csr_beam.npz")
# show the longitudinal phase space
plt.plot(-p_array_i.tau()*1000, p_array_i.p(), "r.")
plt.xlabel("S, mm")
plt.ylabel("dE/pc")
Out[2]:
In [3]:
b1 = Bend(l = 0.500094098121, angle=-0.03360102249639, e1=0.0, e2=-0.03360102249639, gap=0, tilt=0, fint=0.0, fintx=0.0, eid='BB.393.B2')
b2 = Bend(l = 0.500094098121, angle=0.03360102249639, e1=0.03360102249639, e2=0.0, gap=0, tilt=0, fint=0.0, fintx=0.0, eid='BB.402.B2')
b3 = Bend(l = 0.500094098121, angle=0.03360102249639, e1=0.0, e2=0.03360102249639, gap=0, tilt=0, fint=0.0, fintx=0.0, eid='BB.404.B2')
b4 = Bend(l = 0.500094098121, angle=-0.03360102249639, e1=-0.03360102249639, e2=0.0, gap=0, tilt=0, fint=0.0, fintx=0.0, eid='BB.413.B2')
d_slope = Drift(l=8.5/np.cos(b2.angle))
start_csr = Marker()
stop_csr = Marker()
# define cell frome the bends and drifts
cell = [start_csr, Drift(l=0.1), b1 , d_slope , b2, Drift(l=1.5) , b3, d_slope, b4, Drift(l= 1.), stop_csr]
In [4]:
# initialization of tracking method
method = MethodTM()
# for second order tracking we have to choose SecondTM
method.global_method = SecondTM
# for first order tracking uncomment next line
# method.global_method = TransferMap
lat = MagneticLattice(cell, method=method)
In [5]:
csr = CSR()
csr.n_bin = 300
csr.m_bin = 5
csr.sigma_min = 0.2e-6
In [6]:
navi = Navigator(lat)
# track witout CSR effect
p_array_no = deepcopy(p_array_i)
print("\n tracking without CSR effect .... ")
start = time()
tws_no, p_array_no = track(lat, p_array_no, navi)
print("\n time exec:", time() - start, "sec")
# again create Navigator with needed step in [m]
navi = Navigator(lat)
navi.unit_step = 0.1 # m
# add csr process to navigator with start and stop elements
navi.add_physics_proc(csr, start_csr, stop_csr)
# tracking
start = time()
p_array_csr = deepcopy(p_array_i)
print("\n tracking with CSR effect .... ")
tws_csr, p_array_csr = track(lat, p_array_csr, navi)
print("\n time exec:", time() - start, "sec")
In [7]:
# recalculate reference particle
from ocelot.cpbd.beam import *
recalculate_ref_particle(p_array_csr)
recalculate_ref_particle(p_array_no)
# load and convert CSRtrack file to OCELOT beam distribution
# distribution after BC2
# p_array_out = csrtrackBeam2particleArray("out.fmt1", orient="H")
# save ParticleArray to compresssed numpy array
# save_particle_array("scr_track.npz", p_array_out)
p_array_out = load_particle_array("scr_track.npz")
# standard matplotlib functions
plt.figure(2, figsize=(10, 6))
plt.subplot(121)
plt.plot(p_array_no.tau()*1000, p_array_no.p(), 'g.', label="OCELOT no CSR")
plt.plot(p_array_csr.tau()*1000, p_array_csr.p(), 'r.', label="OCELOT CSR")
plt.plot(p_array_out.tau()*1000, p_array_out.p(), 'b.', label="CSRtrack")
plt.legend(loc=3)
plt.xlabel("s, mm")
plt.ylabel("dE/pc")
plt.grid(True)
plt.subplot(122)
plt.plot(p_array_no.tau()*1000, p_array_no.p(), 'g.', label="Ocelot no CSR")
plt.plot(p_array_out.tau()*1000, p_array_out.p(), 'b.', label="CSRtrack")
plt.plot(p_array_csr.tau()*1000, p_array_csr.p(), 'r.', label="OCELOT CSR")
plt.legend(loc=3)
plt.xlabel("s, mm")
plt.ylabel("dE/pc")
plt.grid(True)
In [ ]: