Skip to content

Commit 889de72

Browse files
committed
BLonD v1.5.0. See README.md for details.
1 parent b51e1ec commit 889de72

22 files changed

+716
-303
lines changed

.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,9 @@ stats.html
2020
# _doc/buil folder #
2121
#######################
2222
/__doc/build/
23+
24+
# Figure folder #
25+
#################
26+
/__EXAMPLE_MAIN_FILES/fig/
27+
/__EXAMPLE_MAIN_FILES/*.h5
28+
/__EXAMPLE_MAIN_FILES/null

README.md

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@ longitudinal beam dynamics with collective effects.
99

1010
Developers:
1111

12-
Theodoros Argyropoulos (Theodoros.Argyropoulos@cern.ch)
13-
Alexandre Lasheen (alexandre.lasheen@cern.ch)
14-
Juan Esteban Muller (juan.fem@cern.ch)
15-
Danilo Quartullo (danilo.quartullo@cern.ch)
16-
Helga Timko (Helga.Timko@cern.ch)
12+
Theodoros Argyropoulos (Theodoros.Argyropoulos (at) cern.ch)
13+
Alexandre Lasheen (alexandre.lasheen (at) cern.ch)
14+
Juan Esteban Muller (juan.fem (at) cern.ch)
15+
Danilo Quartullo (danilo.quartullo (at) cern.ch)
16+
Helga Timko (Helga.Timko (at) cern.ch)
1717

1818

1919
The structure is as follows:
@@ -37,6 +37,13 @@ The structure is as follows:
3737
VERSION CONTENTS
3838
==========
3939

40+
2014-10-13
41+
v1.5.0 - Phase loop implemented and tested
42+
- New feedback features in plotting and monitoring
43+
- Removed average values (beta etc.) from input_parameters
44+
- Plotting: formatting setup is separate, files made "uniform"
45+
- Calculated synchronous phase now has the same array length as momentum
46+
4047
2014-10-13
4148
v1.4.0 - The name of the code has been changed from PyLongitudinal to BLond and
4249
a new repository has been created especially for this code.

__EXAMPLE_MAIN_FILES/_Acceleration.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
# Simulation parameters --------------------------------------------------------
1818
# Bunch parameters
19-
N_b = 1.e9 # Intensity
19+
N_b = 1.e9 # Intensity
2020
N_p = 50000 # Macro-particles
2121
tau_0 = 0.4 # Initial bunch length, 4 sigma [ns]
2222

@@ -55,7 +55,7 @@
5555
# Define beam and distribution
5656
beam = Beam(general_params, N_p, N_b)
5757
longitudinal_bigaussian(general_params, rf_params, beam, tau_0/4,
58-
xunit = 'ns', reinsertion = 'on')
58+
xunit = 'ns', reinsertion = 'on')
5959

6060

6161
print "Beam set and distribution generated..."
@@ -94,7 +94,7 @@
9494
print " Gaussian bunch length %.4e rad" %beam.bl_gauss
9595
print ""
9696
# In plots, you can choose following units: rad, ns, m
97-
plot_long_phase_space(beam, general_params, rf_params, 0, 0.0001763, -400, 400, separatrix_plot = True)
97+
plot_long_phase_space(beam, general_params, rf_params, 0, 0.0001763, -400, 400, separatrix_plot = True)
9898

9999
# Track
100100
for m in map_:

__EXAMPLE_MAIN_FILES/_Main_long_ps_booster.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -166,8 +166,7 @@
166166

167167
plot_bunch_length_evol(my_beam, 'beam', general_params, n_turns)
168168

169-
plot_position_evol(i+1, my_beam, 'beam', general_params, unit = None, dirname = 'fig')
170-
169+
plot_position_evol(my_beam, 'beam', general_params, i+1, unit = None, dirname = 'fig')
171170

172171
print "Done!"
173172

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
# Example input for longitudinal simulation with phase loop (LHC)
2+
# No intensity effects
3+
4+
5+
import time
6+
import numpy as np
7+
8+
from llrf.RF_noise import *
9+
from input_parameters.general_parameters import *
10+
from input_parameters.rf_parameters import *
11+
from trackers.longitudinal_tracker import *
12+
from llrf.feedbacks import *
13+
from beams.beams import *
14+
from beams.longitudinal_distributions import *
15+
from beams.slices import *
16+
from monitors.monitors import *
17+
from longitudinal_plots.plot_settings import *
18+
from longitudinal_plots.plot_beams import *
19+
from longitudinal_plots.plot_llrf import *
20+
from longitudinal_plots.plot_slices import *
21+
22+
23+
24+
# Simulation parameters --------------------------------------------------------
25+
# Bunch parameters
26+
N_b = 1.e9 # Intensity
27+
N_p = 10001 # Macro-particles
28+
tau_0 = 0.4 # Initial bunch length, 4 sigma [ns]
29+
30+
# Machine and RF parameters
31+
C = 26658.883 # Machine circumference [m]
32+
p_s = 450.e9 # Synchronous momentum [eV]
33+
h = 35640 # Harmonic number
34+
V = 6.e6 # RF voltage [eV]
35+
dphi = 0 # Phase modulation/offset
36+
gamma_t = 55.759505 # Transition gamma
37+
alpha = 1./gamma_t/gamma_t # First order mom. comp. factor
38+
39+
# Tracking details
40+
N_t = 1001 # Number of turns to track
41+
dt_plt = 200 # Time steps between plots
42+
dt_mon = 1 # Time steps between monitoring
43+
44+
45+
# Simulation setup -------------------------------------------------------------
46+
print "Setting up the simulation..."
47+
print ""
48+
49+
# Define general parameters
50+
general_params = GeneralParameters(N_t, C, alpha, p_s, 'proton')
51+
52+
# Define RF station parameters, phase loop, and corresponding tracker
53+
RF_params = RFSectionParameters(general_params, 1, h, V, dphi)
54+
PL_gain = 1./(5.*general_params.t_rev[0])
55+
print "PL gain is %.4e 1/s, Trev = %.4e s" %(PL_gain, general_params.t_rev[0])
56+
PL = PhaseLoop(general_params, RF_params, PL_gain, sampling_frequency = 1,
57+
machine = 'LHC')
58+
long_tracker = RingAndRFSection(RF_params, PhaseLoop=PL)
59+
60+
print "General and RF parameters set..."
61+
62+
63+
# Define beam and distribution
64+
beam = Beam(general_params, N_p, N_b)
65+
# Generate new distribution
66+
longitudinal_bigaussian(general_params, RF_params, beam, tau_0/4, seed=1234,
67+
xunit = 'ns', reinsertion = 'on')
68+
print "Beam set and distribution generated..."
69+
70+
71+
# Need slices for the Gaussian fit; slice for the first plot
72+
slice_beam = Slices(beam, 100, slicing_coord = 'theta')#, #fit_option = 'gaussian',
73+
#slice_immediately = 'on')
74+
75+
# Define what to save in file
76+
bunchmonitor = BunchMonitor('output_data', N_t+1, "Longitudinal", PhaseLoop=PL)#slice_beam, PL)
77+
78+
print "Statistics set..."
79+
80+
# Initialize plots
81+
PlotSettings().set_plot_format()
82+
83+
# Accelerator map
84+
map_ = [slice_beam] + [bunchmonitor] +[long_tracker]
85+
print "Map set"
86+
print ""
87+
88+
89+
# Initial injection kick/error
90+
beam.theta += 1.e-5
91+
#beam.dE *= -1.
92+
bunchmonitor.track(beam)
93+
slice_beam.track(beam)
94+
95+
96+
# Tracking ---------------------------------------------------------------------
97+
for i in range(N_t):
98+
t0 = time.clock()
99+
100+
101+
# Plot has to be done before tracking (at least for cases with separatrix)
102+
if (i % dt_plt) == 0:
103+
print "Outputting at time step %d..." %i
104+
print " Beam momentum %.6e eV" %beam.momentum
105+
print " Beam gamma %3.3f" %beam.gamma_r
106+
print " Beam beta %3.3f" %beam.beta_r
107+
print " Beam energy %.6e eV" %beam.energy
108+
print " Four-times r.m.s. bunch length %.4e rad" %(4.*beam.sigma_theta)
109+
#print " Gaussian bunch length %.4e rad" %beam.bl_gauss
110+
print ""
111+
# In plots, you can choose following units: rad, ns, m
112+
plot_long_phase_space(beam, general_params, RF_params, 0, 0.0001763,
113+
-450, 450, separatrix_plot = True)
114+
plot_beam_profile(i, general_params, slice_beam)
115+
plot_COM_motion(beam, general_params, RF_params, 'output_data',
116+
0.8e-4, 1.1e-4, -75, 75, separatrix_plot = False)
117+
118+
119+
# Track
120+
slice_beam.track(beam)
121+
#slice_beam.mean_theta = beam.theta[0] # For single particle
122+
long_tracker.track(beam)
123+
bunchmonitor.track(beam)
124+
125+
# These plots have to be done after the tracking
126+
if (i % dt_plt) == 0 and i > dt_mon:
127+
plot_bunch_length_evol(beam, 'output_data', general_params, i,
128+
output_freq=dt_mon, unit='ns')
129+
#plot_bunch_length_evol_gaussian(beam, 'output_data', general_params,
130+
# slice_beam, i, output_freq=dt_mon, unit='ns')
131+
plot_position_evol(beam, 'output_data', general_params, i,
132+
output_freq=dt_mon, unit = None, style = '.')
133+
plot_PL_phase_corr(PL, 'output_data', i, output_freq=dt_mon)
134+
plot_PL_freq_corr(PL, 'output_data', i, output_freq=dt_mon)
135+
136+
137+
# Define losses according to separatrix and/or longitudinal position
138+
#beam.losses_separatrix(general_params, rf_params)
139+
#beam.losses_longitudinal_cut(0.28e-4, 0.75e-4)
140+
141+
142+
bunchmonitor.h5file.close()
143+
print "Done!"
144+
print ""
145+

__EXAMPLE_MAIN_FILES/_RFnoise.py

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,8 @@
4242
# Pre-processing: RF phase noise -----------------------------------------------
4343
f = np.arange(0, 5.6227612455e+03, 1.12455000e-02)
4444
spectrum = np.concatenate((1.11100000e-07 * np.ones(4980), np.zeros(495021)))
45-
noise_t, noise_dphi = PhaseNoise(f, spectrum, seed1=1234, seed2=7564).spectrum_to_phase_noise()
45+
RFnoise = PhaseNoise(f, spectrum, seed1=1234, seed2=7564)
46+
RFnoise.spectrum_to_phase_noise()
4647

4748
# Hermitian vs complex FFT (gives the same result)
4849
# plot_noise_spectrum(f, spectrum, sampling=100)
@@ -62,10 +63,10 @@
6263
# os.rename('temp/phase_noise.png', 'temp/phase_noise_c.png')
6364

6465
plot_noise_spectrum(f, spectrum, sampling=100)
65-
plot_phase_noise(noise_t, noise_dphi, sampling=100)
66-
#plot_phase_noise(noise_t[0:10000], noise_dphi[0:10000], sampling=1)
67-
print " Sigma of RF noise is %.4e" %np.std(noise_dphi)
68-
print " Time step of RF noise is %.4e" %noise_t[1]
66+
plot_phase_noise(RFnoise.t, RFnoise.dphi, sampling=100)
67+
#plot_phase_noise(RFnoise.t[0:10000], RFnoise.dphi[0:10000], sampling=1)
68+
print " Sigma of RF noise is %.4e" %np.std(RFnoise.dphi)
69+
print " Time step of RF noise is %.4e" %RFnoise.t[1]
6970
print ""
7071

7172

@@ -74,11 +75,10 @@
7475
print ""
7576

7677
# Define general parameters
77-
general_params = GeneralParameters(N_t, C, alpha, p_s,
78-
'proton')
78+
general_params = GeneralParameters(N_t, C, alpha, p_s,'proton')
7979

8080
# Define RF station parameters and corresponding tracker
81-
rf_params = RFSectionParameters(general_params, 1, h, V, dphi)
81+
rf_params = RFSectionParameters(general_params, 1, h, V, RFnoise.dphi[0:N_t+1])
8282
long_tracker = RingAndRFSection(rf_params)
8383

8484
print "General and RF parameters set..."
@@ -96,7 +96,8 @@
9696

9797

9898
# Need slices for the Gaussian fit; slice for the first plot
99-
slice_beam = Slices(beam, 100, slicing_coord = 'theta', fit_option = 'gaussian', slice_immediately = 'on')
99+
slice_beam = Slices(beam, 100, slicing_coord = 'theta', fit_option = 'gaussian',
100+
slice_immediately = 'on')
100101

101102
# Define what to save in file
102103
bunchmonitor = BunchMonitor('output_data', N_t+1, "Longitudinal", slice_beam)

beams/beams.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
import numpy as np
99
import warnings
1010
from scipy.constants import c, e, m_p
11-
11+
import cython_functions.stats as cp
1212
from scipy.optimize import curve_fit
1313
from trackers.longitudinal_utilities import is_in_separatrix
1414
from scipy import ndimage

beams/longitudinal_distributions.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -677,6 +677,7 @@ def longitudinal_bigaussian(GeneralParameters, RFSectionParameters, beam,
677677
warnings.warn("longitudinal_bigaussian for multiple RF is not yet implemented")
678678

679679
counter = RFSectionParameters.counter[0]
680+
680681
harmonic = RFSectionParameters.harmonic[0,counter]
681682
energy = RFSectionParameters.energy[counter]
682683
beta = RFSectionParameters.beta_r[counter]

beams/slices.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ def __init__(self, Beam, n_slices, n_sigma = None, cut_left = None,
7373
raise RuntimeError('The slicing_coord is not recognized')
7474

7575
#: *Number of macroparticles per slice (~profile).*
76-
self.n_macroparticles = np.zeros(n_slices, dtype='uint32')
76+
self.n_macroparticles = np.zeros(n_slices)
7777

7878
#: *Edges positions of the slicing*
7979
self.edges = np.zeros(n_slices + 1)
@@ -311,8 +311,7 @@ def beam_spectrum_generation(self, n_sampling_fft, filter_option = None, only_rf
311311
self.beam_spectrum_freq = rfftfreq(n_sampling_fft, time_step)
312312

313313
if not only_rfft:
314-
self.beam_spectrum = rfft(self.n_macroparticles, n_sampling_fft)
315-
314+
self.beam_spectrum = rfft(self.n_macroparticles, n_sampling_fft)
316315

317316

318317
def beam_profile_derivative(self, mode = 'gradient', coord = 'theta'):

impedances/longitudinal_impedance.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -333,8 +333,7 @@ def track(self, Beam):
333333
self.induced_voltage_generation(Beam)
334334

335335
induced_voltage_kick = np.interp(Beam.tau, self.slices.bins_centers, self.induced_voltage)
336-
Beam.dE += induced_voltage_kick
337-
336+
Beam.dE += induced_voltage_kick
338337

339338

340339
class InductiveImpedance(object):

0 commit comments

Comments
 (0)