Skip to content

Commit e6d53ae

Browse files
authored
Merge pull request #197 from xsuite/release/0.25.10
Release/0.25.10
2 parents d849b93 + 837c7d5 commit e6d53ae

18 files changed

+2448
-55
lines changed

tests/test_collective_monitor.py

Lines changed: 657 additions & 0 deletions
Large diffs are not rendered by default.

tests/test_element_with_slicer_filling_scheme.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ def test_element_with_slicer_filling_scheme(buffer_round_trip, num_turns):
9292
rtol=0, atol=1e-12)
9393

9494
xo.assert_allclose(slicer2.zeta_centers,
95-
np.array([[-0.9, -0.7, -0.5, -0.3, -0.1, 0.1, 0.3, 0.5, 0.7, 0.9]]),
95+
np.array([-0.9, -0.7, -0.5, -0.3, -0.1, 0.1, 0.3, 0.5, 0.7, 0.9]),
9696
rtol=0, atol=1e-12)
9797

9898
xo.assert_allclose(slicer.zeta_range[0], -1, rtol=0, atol=1e-12)
@@ -117,8 +117,8 @@ def test_element_with_slicer_filling_scheme(buffer_round_trip, num_turns):
117117

118118
xo.assert_allclose(slicer2.num_particles,
119119
np.array([
120-
[ 5000., 5000., 5000., 5000., 5000., 5000., 5000., 5000., 5000., 5000.],
121-
]),
120+
5000., 5000., 5000., 5000., 5000., 5000., 5000., 5000., 5000., 5000.],
121+
),
122122
rtol=0, atol=1e-12)
123123

124124
z_prof, prof = ele.moments_data.get_moment_profile('num_particles', i_turn=0)

tests/test_transverse_damper.py

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
import numpy as np
2+
from scipy.constants import c
3+
from scipy.constants import physical_constants
4+
from scipy.signal import hilbert
5+
from scipy.stats import linregress
6+
7+
import xfields as xf
8+
import xtrack as xt
9+
import xpart as xp
10+
from xobjects.test_helpers import for_all_test_contexts
11+
12+
13+
exclude_contexts = ['ContextPyopencl']
14+
15+
@for_all_test_contexts(excluding=exclude_contexts)
16+
def test_transverse_damper(test_context):
17+
longitudinal_mode = 'nonlinear'
18+
# Machine settings
19+
n_turns = 1000
20+
21+
n_macroparticles = 10000
22+
intensity = 8e9
23+
24+
alpha = 53.86**-2
25+
26+
e0 = physical_constants['proton mass energy equivalent in MeV'][0]*1e6
27+
p0c = 450e9
28+
gamma = p0c/e0
29+
beta = np.sqrt(1-1/gamma**2)
30+
31+
h_rf = 35640
32+
bunch_spacing_buckets = 10
33+
num_bunches = 2
34+
n_slices = 500
35+
36+
epsn_x = 2e-6
37+
epsn_y = 2e-6
38+
taub = 0.9e-9
39+
sigma_z = taub*beta*c/4
40+
41+
circumference = 26658.883
42+
43+
momentum_compaction = alpha
44+
v_rf = 4e6
45+
f_rev = beta*c/circumference
46+
f_rf = f_rev*h_rf
47+
48+
bucket_length = circumference / h_rf
49+
zeta_range = (-0.5*bucket_length, 0.5*bucket_length)
50+
51+
filling_scheme = np.zeros(int(h_rf/bunch_spacing_buckets))
52+
filling_scheme[0: num_bunches] = 1
53+
filled_slots = np.nonzero(filling_scheme)[0]
54+
55+
one_turn_map = xt.LineSegmentMap(
56+
length=circumference,
57+
betx=70, bety=80,
58+
qx=62.31, qy=60.32,
59+
longitudinal_mode=longitudinal_mode,
60+
voltage_rf=v_rf, frequency_rf=f_rf, lag_rf=180,
61+
momentum_compaction_factor=momentum_compaction,
62+
_context=test_context
63+
)
64+
65+
gain_x = 0.01
66+
gain_y = 0.01
67+
68+
transverse_damper = xf.TransverseDamper(
69+
gain_x=gain_x, gain_y=gain_y,
70+
filling_scheme=filling_scheme,
71+
zeta_range=zeta_range,
72+
num_slices=n_slices,
73+
bunch_spacing_zeta=bunch_spacing_buckets*bucket_length,
74+
circumference=circumference,
75+
_context=test_context
76+
)
77+
78+
line = xt.Line(elements=[[one_turn_map, transverse_damper][0]],
79+
element_names=[['one_turn_map', 'transverse_damper'][0]])
80+
81+
line.particle_ref = xt.Particles(p0c=p0c)
82+
line.build_tracker(_context=test_context)
83+
84+
particles = xp.generate_matched_gaussian_multibunch_beam(
85+
_context=test_context,
86+
filling_scheme=filling_scheme,
87+
bunch_num_particles=n_macroparticles,
88+
bunch_intensity_particles=intensity,
89+
nemitt_x=epsn_x, nemitt_y=epsn_y, sigma_z=sigma_z,
90+
line=line, bunch_spacing_buckets=bunch_spacing_buckets,
91+
bunch_selection=filled_slots,
92+
rf_harmonic=[h_rf], rf_voltage=[v_rf],
93+
particle_ref=line.particle_ref,
94+
95+
)
96+
97+
# apply a distortion to the bunches
98+
amplitude = 1e-3
99+
particles.px += amplitude
100+
particles.py += amplitude
101+
102+
mean_x = np.zeros((n_turns, num_bunches))
103+
mean_y = np.zeros((n_turns, num_bunches))
104+
105+
for i_turn in range(n_turns):
106+
line.track(particles, num_turns=1)
107+
transverse_damper.track(particles, i_turn)
108+
for ib in range(num_bunches):
109+
mean_x[i_turn, ib] = np.mean(particles.x[n_macroparticles*ib:
110+
n_macroparticles*(ib+1)])
111+
mean_y[i_turn, ib] = np.mean(particles.y[n_macroparticles*ib:
112+
n_macroparticles*(ib+1)])
113+
114+
turns = np.linspace(0, n_turns-1, n_turns)
115+
116+
i_fit_start = 200
117+
i_fit_end = 600
118+
119+
for i_bunch in range(num_bunches):
120+
ampls_x = np.abs(hilbert(mean_x[:, i_bunch]))
121+
fit_x = linregress(turns[i_fit_start: i_fit_end],
122+
np.log(ampls_x[i_fit_start: i_fit_end]))
123+
124+
assert np.isclose(-fit_x.slope*2, gain_x, atol=1e-4, rtol=0)
125+
126+
ampls_y = np.abs(hilbert(mean_y[:, i_bunch]))
127+
fit_y = linregress(turns[i_fit_start: i_fit_end],
128+
np.log(ampls_y[i_fit_start: i_fit_end]))
129+
130+
assert np.isclose(-fit_y.slope*2, gain_y, atol=1e-4, rtol=0)

tests_mpi/run_all.sh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
mpiexec -n 3 pytest -v test_collective_monitor_mpi.py
2+
mpiexec -n 3 pytest -v test_transverse_damper_mpi.py

0 commit comments

Comments
 (0)