Skip to content

Commit debb862

Browse files
committed
Added a file
1 parent 536fc78 commit debb862

File tree

1 file changed

+190
-0
lines changed

1 file changed

+190
-0
lines changed

tests/LHC.py

Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
import numpy as np
2+
from scipy.constants import c, e, m_p
3+
4+
from PyHEADTAIL.machines.synchrotron import Synchrotron
5+
6+
7+
class EmptyObject(object):
8+
pass
9+
10+
11+
class LHC(Synchrotron):
12+
13+
def __init__(self, machine_configuration=None, optics_mode='smooth', **kwargs):
14+
15+
16+
pp = EmptyObject()
17+
pp.machine_configuration = machine_configuration
18+
pp.optics_mode = optics_mode
19+
20+
pp.longitudinal_mode = 'non-linear'
21+
pp.alpha = 3.225e-04
22+
pp.h_RF = 35640
23+
pp.mass = m_p
24+
pp.charge = e
25+
pp.RF_at = 'middle'
26+
27+
if pp.machine_configuration == 'Injection':
28+
pp.p0 = 450e9 * e / c
29+
pp.p_increment = 0.
30+
pp.accQ_x = 64.28
31+
pp.accQ_y = 59.31
32+
pp.V_RF = 6e6
33+
pp.dphi_RF = 0.
34+
elif machine_configuration == '6.5_TeV_collision_tunes':
35+
pp.p0 = 6500e9 * e / c
36+
pp.p_increment = 0.
37+
pp.accQ_x = 64.31
38+
pp.accQ_y = 59.32
39+
pp.V_RF = 12e6
40+
pp.dphi_RF = 0.
41+
else:
42+
raise ValueError('machine_configuration not recognized!')
43+
44+
if pp.optics_mode == 'smooth':
45+
if 's' in list(kwargs.keys()):
46+
raise ValueError('s vector cannot be provided if optics_mode = "smooth"')
47+
48+
pp.n_segments = kwargs['n_segments']
49+
pp.circumference = 26658.8832
50+
51+
pp.name = None
52+
53+
pp.beta_x = 92.7
54+
pp.D_x = 0
55+
pp.beta_y = 93.2
56+
pp.D_y = 0
57+
58+
pp.alpha_x = None
59+
pp.alpha_y = None
60+
61+
pp.s = None
62+
63+
elif pp.optics_mode == 'non-smooth':
64+
if 'n_segments' in list(kwargs.keys()):
65+
raise ValueError('n_segments cannot be provided if optics_mode = "non-smooth"')
66+
pp.n_segments = None
67+
pp.circumference = None
68+
69+
pp.name = kwargs['name']
70+
71+
pp.beta_x = kwargs['beta_x']
72+
pp.beta_y = kwargs['beta_y']
73+
74+
try:
75+
pp.D_x = kwargs['D_x']
76+
except KeyError:
77+
pp.D_x = 0 * np.array(kwargs['s'])
78+
try:
79+
pp.D_y = kwargs['D_y']
80+
except KeyError:
81+
pp.D_y = 0 * np.array(kwargs['s'])
82+
83+
pp.alpha_x = kwargs['alpha_x']
84+
pp.alpha_y = kwargs['alpha_y']
85+
86+
pp.s = kwargs['s']
87+
88+
else:
89+
raise ValueError('optics_mode not recognized!')
90+
91+
# detunings
92+
pp.Qp_x = 0
93+
pp.Qp_y = 0
94+
95+
pp.app_x = 0
96+
pp.app_y = 0
97+
pp.app_xy = 0
98+
99+
pp.i_octupole_focusing = None
100+
pp.i_octupole_defocusing = None
101+
pp.octupole_knob = None
102+
103+
for attr in list(kwargs.keys()):
104+
if kwargs[attr] is not None:
105+
if type(kwargs[attr]) is list or type(kwargs[attr]) is np.ndarray:
106+
str2print = '[%s ...]'%repr(kwargs[attr][0])
107+
else:
108+
str2print = repr(kwargs[attr])
109+
self.prints('Synchrotron init. From kwargs: %s = %s'
110+
% (attr, str2print))
111+
if not hasattr(pp, attr):
112+
raise NameError("I don't understand %s"%attr)
113+
114+
setattr(pp, attr, kwargs[attr])
115+
116+
117+
118+
if pp.i_octupole_focusing is not None or pp.i_octupole_defocusing is not None:
119+
if pp.octupole_knob is not None:
120+
raise ValueError('octupole_knobs and octupole currents cannot be used at the same time!')
121+
pp.app_x, pp.app_y, pp.app_xy = self._anharmonicities_from_octupole_current_settings(
122+
pp.i_octupole_focusing, pp.i_octupole_defocusing)
123+
self.i_octupole_focusing = pp.i_octupole_focusing
124+
self.i_octupole_defocusing = pp.i_octupole_defocusing
125+
126+
if pp.octupole_knob is not None:
127+
if pp.i_octupole_focusing is not None or pp.i_octupole_defocusing is not None:
128+
raise ValueError('octupole_knobs and octupole currents cannot be used at the same time!')
129+
pp.i_octupole_focusing, pp.i_octupole_defocusing = self._octupole_currents_from_octupole_knobs(pp.octupole_knob, pp.p0)
130+
pp.app_x, pp.app_y, pp.app_xy = self._anharmonicities_from_octupole_current_settings(
131+
pp.i_octupole_focusing, pp.i_octupole_defocusing)
132+
self.i_octupole_focusing = pp.i_octupole_focusing
133+
self.i_octupole_defocusing = pp.i_octupole_defocusing
134+
135+
136+
super(LHC, self).__init__(optics_mode=pp.optics_mode, circumference=pp.circumference, n_segments=pp.n_segments,
137+
s=pp.s, name=pp.name,
138+
alpha_x=pp.alpha_x, beta_x=pp.beta_x, D_x=pp.D_x, alpha_y=pp.alpha_y, beta_y=pp.beta_y, D_y=pp.D_y,
139+
accQ_x=pp.accQ_x, accQ_y=pp.accQ_y, Qp_x=pp.Qp_x, Qp_y=pp.Qp_y, app_x=pp.app_x, app_y=pp.app_y, app_xy=pp.app_xy,
140+
alpha_mom_compaction=pp.alpha, longitudinal_mode=pp.longitudinal_mode,
141+
h_RF=np.atleast_1d(pp.h_RF), V_RF=np.atleast_1d(pp.V_RF), dphi_RF=np.atleast_1d(pp.dphi_RF),
142+
p0=pp.p0, p_increment=pp.p_increment,
143+
charge=pp.charge, mass=pp.mass, RF_at=pp.RF_at)
144+
145+
146+
def _anharmonicities_from_octupole_current_settings(self, i_octupole_focusing, i_octupole_defocusing):
147+
"""Calculate the constants of proportionality app_x, app_y and
148+
app_xy (== app_yx) for the amplitude detuning introduced by the
149+
LHC octupole magnets (aka. LHC Landau octupoles) from the
150+
electric currents i_octupole_focusing [A] and i_octupole_defocusing [A] flowing
151+
through the magnets. The maximum current is given by
152+
i_max = +/- 550 [A]. The values app_x, app_y, app_xy obtained
153+
from the formulae are proportional to the strength of detuning
154+
for one complete turn around the accelerator, i.e. one-turn
155+
values.
156+
The calculation is based on formulae (3.6) taken from 'The LHC
157+
transverse coupled-bunch instability' by N. Mounet, EPFL PhD
158+
Thesis, 2012. Values (hard-coded numbers below) are valid for
159+
LHC Landau octupoles before LS1. Beta functions in x and y are
160+
correctly taken into account. Note that here, the values of
161+
app_x, app_y and app_xy are not normalized to the reference
162+
momentum p0. This is done only during the calculation of the
163+
detuning in the corresponding detune method of the
164+
AmplitudeDetuningSegment.
165+
More detailed explanations and references on how the formulae
166+
were obtained are given in the PhD thesis (pg. 85ff) cited
167+
above.
168+
"""
169+
i_max = 550. # [A]
170+
E_max = 7000. # [GeV]
171+
172+
app_x = E_max * (267065. * i_octupole_focusing / i_max -
173+
7856. * i_octupole_defocusing / i_max)
174+
app_y = E_max * (9789. * i_octupole_focusing / i_max -
175+
277203. * i_octupole_defocusing / i_max)
176+
app_xy = E_max * (-102261. * i_octupole_focusing / i_max +
177+
93331. * i_octupole_defocusing / i_max)
178+
179+
# Convert to SI units.
180+
convert_to_SI = e / (1.e-9 * c)
181+
app_x *= convert_to_SI
182+
app_y *= convert_to_SI
183+
app_xy *= convert_to_SI
184+
185+
return app_x, app_y, app_xy
186+
187+
def _octupole_currents_from_octupole_knobs(self, octupole_knob, p0):
188+
i_octupole_focusing = 19.557 * octupole_knob / (-1.5) * p0 / 2.4049285931335872e-16
189+
i_octupole_defocusing = - i_octupole_focusing
190+
return i_octupole_focusing, i_octupole_defocusing

0 commit comments

Comments
 (0)