L_long = 43 * 0.374 # interaction length [m] R_shunt_long = L_long**2 * R2 / 8 # shunt impedance [Ohm] damping_time_long = 2 * np.pi * L_long / vg * (1 + 0.0946) n_cav_long = 2 # factor 2 because of two cavities are used for tracking L_short = 32 * 0.374 # interaction length [m] R_shunt_short = L_short**2 * R2 / 8 # shunt impedance [Ohm] damping_time_short = 2 * np.pi * L_short / vg * (1 + 0.0946) n_cav_short = 4 # factor 4 because of four cavities are used for tracking longCavity = TravelingWaveCavity(n_cav_long * R_shunt_long, fr, damping_time_long) longCavityFreq = InducedVoltageFreq(beam, profile, [longCavity], frequency_step) longCavityIntensity = TotalInducedVoltage(beam, profile, [longCavityFreq]) shortCavity = TravelingWaveCavity(n_cav_short * R_shunt_short, fr, damping_time_short) shortCavityFreq = InducedVoltageFreq(beam, profile, [shortCavity], frequency_step) shortCavityIntensity = TotalInducedVoltage(beam, profile, [shortCavityFreq]) # FB parameters if FB_strength == 'present': FBstrengthLong = 1.05 FBstrengthShort = 0.73 elif FB_strength == 'future': # -26dB FBstrengthLong = 1.8 FBstrengthShort = FBstrengthLong
imp_list, RFParams=RF_sct_par, frequency_resolution=1e3, multi_turn_wake=True, mtw_mode='time') ind_volt_time = InducedVoltageTime(beam, slice_beam, imp_list, RFParams=RF_sct_par, wake_length=n_turns * bucket_length, multi_turn_wake=True) ind_volt_freq_periodic = InducedVoltageFreq(beam, slice_beam, imp_list) total_ind_volt_freq = TotalInducedVoltage(beam, slice_beam, [ind_volt_freq]) total_ind_volt_time = TotalInducedVoltage(beam, slice_beam, [ind_volt_time]) total_ind_volt_freq_periodic = TotalInducedVoltage(beam, slice_beam, [ind_volt_freq_periodic]) # ACCELERATION MAP------------------------------------------------------------- map_ = [total_ind_volt_freq] + [total_ind_volt_time] total_ind_volt_freq_periodic.track() # FIRST COMPARISON: CONSTANT REVOLUTION FREQUENCY ----------------------------- for i in range(n_turns):
longitudinal_tracker = RingAndRFTracker(RF_sct_par,beam) full_tracker = FullRingAndRF([longitudinal_tracker]) # INDUCED VOLTAGE FROM IMPEDANCE----------------------------------------------- R_S = 95e3 frequency_R = 10e9 Q = 1.0 frequency_resolution_input = 1e7 Zres = Resonators(R_S, frequency_R, Q) ind_volt = InducedVoltageFreq(beam, slice_beam, [Zres], frequency_resolution=frequency_resolution_input) total_induced_voltage = TotalInducedVoltage(beam, slice_beam, [ind_volt]) beam_generation_output = matched_from_distribution_function(beam, full_tracker, distribution_type=distribution_type, emittance=emittance, distribution_variable=distribution_variable, main_harmonic_option='lowest_freq', TotalInducedVoltage=total_induced_voltage, n_iterations=20, seed=1256) [sync_freq_distribution_left, sync_freq_distribution_right], \ [emittance_array_left, emittance_array_right], \ [delta_time_left, delta_time_right], \ particleDistributionFreq, synchronous_time = \ synchrotron_frequency_distribution(beam, full_tracker, TotalInducedVoltage=beam_generation_output[1])
ring.t_rev[0])) mpiprint(" SL gain is %.4e turns" % PL.gain2) mpiprint(" Omega_s0 = %.4e s at flat bottom, %.4e s at flat top" % (rf.omega_s0[0], rf.omega_s0[n_turns])) mpiprint(" SL a_i = %.4f a_f = %.4f" % (PL.lhc_a[0], PL.lhc_a[n_turns])) mpiprint(" SL t_i = %.4f t_f = %.4f" % (PL.lhc_t[0], PL.lhc_t[n_turns])) # Injecting noise in the cavity, PL on # Define machine impedance from http://impedance.web.cern.ch/impedance/ ZTot = np.loadtxt(os.path.join(inputDir, 'Zlong_Allthemachine_450GeV_B1_LHC_inj_450GeV_B1.dat'), skiprows=1) ZTable = InputTable(ZTot[:, 0], ZTot[:, 1], ZTot[:, 2]) indVoltage = InducedVoltageFreq( beam, profile, [ZTable], frequency_resolution=freq_res) totVoltage = TotalInducedVoltage(beam, profile, [indVoltage]) # TODO add the noiseFB tracker = RingAndRFTracker(rf, beam, BeamFeedback=PL, Profile=profile, interpolation=True, TotalInducedVoltage=totVoltage, solver='simple') # interpolation=True, TotalInducedVoltage=None) mpiprint("PL, SL, and tracker set...") # Fill beam distribution fullring = FullRingAndRF([tracker]) # Juan's fit to LHC profiles: binomial w/ exponent 1.5 # matched_from_distribution_function(beam, fullring, # main_harmonic_option = 'lowest_freq', # distribution_exponent = 1.5, distribution_type='binomial', # bunch_length = 1.1e-9, bunch_length_fit = 'fwhm', # distribution_variable = 'Action')
R_S = 5e4 frequency_R = 10e6 Q = 1e2 resonator = Resonators(R_S, frequency_R, Q) # INDUCED VOLTAGE FROM IMPEDANCE----------------------------------------------- imp_list = [resonator] ind_volt_freq = InducedVoltageFreq(beam, slice_beam, imp_list, frequency_resolution=1e4) ind_volt_time = InducedVoltageTime(beam, slice_beam, imp_list) total_ind_volt_freq = TotalInducedVoltage(beam, slice_beam, [ind_volt_freq]) total_ind_volt_time = TotalInducedVoltage(beam, slice_beam, [ind_volt_time]) total_ind_volt_ZoN = TotalInducedVoltage(beam, slice_beam, [ZoN]) # PLOTS # ACCELERATION MAP------------------------------------------------------------- map_ = [slice_beam] + [total_ind_volt_freq] + [total_ind_volt_time] + \ [total_ind_volt_ZoN] + [ring_RF_section] # TRACKING + PLOTS------------------------------------------------------------- beam.split() for i in range(n_turns):
class TestCavityFeedback(unittest.TestCase): def setUp(self): C = 2*np.pi*1100.009 # Ring circumference [m] gamma_t = 18.0 # Gamma at transition alpha = 1/gamma_t**2 # Momentum compaction factor p_s = 25.92e9 # Synchronous momentum at injection [eV] h = 4620 # 200 MHz system harmonic phi = 0. # 200 MHz RF phase # With this setting, amplitude in the two four-section, five-section # cavities must converge, respectively, to # 2.0 MV = 4.5 MV * 4/18 * 2 # 2.5 MV = 4.5 MV * 5/18 * 2 V = 4.5e6 # 200 MHz RF voltage N_t = 1 # Number of turns to track self.ring = Ring(C, alpha, p_s, Particle=Proton(), n_turns=N_t) self.rf = RFStation(self.ring, h, V, phi) N_m = 1e6 # Number of macro-particles for tracking N_b = 72*1.0e11 # Bunch intensity [ppb] # Gaussian beam profile self.beam = Beam(self.ring, N_m, N_b) sigma = 1.0e-9 bigaussian(self.ring, self.rf, self.beam, sigma, seed=1234, reinsertion=False) n_shift = 1550 # how many rf-buckets to shift beam self.beam.dt += n_shift * self.rf.t_rf[0, 0] self.profile = Profile( self.beam, CutOptions=CutOptions( cut_left=(n_shift-1.5)*self.rf.t_rf[0, 0], cut_right=(n_shift+2.5)*self.rf.t_rf[0, 0], n_slices=4*64)) self.profile.track() # Cavities l_cav = 43*0.374 v_g = 0.0946 tau = l_cav/(v_g*c)*(1 + v_g) f_cav = 200.222e6 n_cav = 2 # factor 2 because of two four/five-sections cavities short_cavity = TravelingWaveCavity(l_cav**2 * n_cav * 27.1e3 / 8, f_cav, 2*np.pi*tau) shortInducedVoltage = InducedVoltageTime(self.beam, self.profile, [short_cavity]) l_cav = 54*0.374 tau = l_cav/(v_g*c)*(1 + v_g) long_cavity = TravelingWaveCavity(l_cav**2 * n_cav * 27.1e3 / 8, f_cav, 2*np.pi*tau) longInducedVoltage = InducedVoltageTime(self.beam, self.profile, [long_cavity]) self.induced_voltage = TotalInducedVoltage( self.beam, self.profile, [shortInducedVoltage, longInducedVoltage]) self.induced_voltage.induced_voltage_sum() self.cavity_tracker = RingAndRFTracker( self.rf, self.beam, Profile=self.profile, interpolation=True, TotalInducedVoltage=self.induced_voltage) self.OTFB = SPSCavityFeedback( self.rf, self.beam, self.profile, G_llrf=5, G_tx=0.5, a_comb=15/16, turns=50, Commissioning=CavityFeedbackCommissioning()) self.OTFB_tracker = RingAndRFTracker(self.rf, self.beam, Profile=self.profile, TotalInducedVoltage=None, CavityFeedback=self.OTFB, interpolation=True) def test_FB_pre_tracking(self): digit_round = 3 Vind4_mean = np.mean(np.absolute(self.OTFB.OTFB_4.V_coarse_tot))/1e6 Vind4_std = np.std(np.absolute(self.OTFB.OTFB_4.V_coarse_tot))/1e6 Vind4_mean_exp = 1.99886351363 Vind4_std_exp = 2.148426e-6 Vind5_mean = np.mean(np.absolute(self.OTFB.OTFB_5.V_coarse_tot))/1e6 Vind5_std = np.std(np.absolute(self.OTFB.OTFB_5.V_coarse_tot))/1e6 Vind5_mean_exp = 2.49906605189 Vind5_std_exp = 2.221665e-6 self.assertAlmostEqual(Vind4_mean, Vind4_mean_exp, places=digit_round, msg='In TestCavityFeedback test_FB_pretracking: ' + 'mean value of four-section cavity differs') self.assertAlmostEqual(Vind4_std, Vind4_std_exp, places=digit_round, msg='In TestCavityFeedback test_FB_pretracking: standard ' + 'deviation of four-section cavity differs') self.assertAlmostEqual(Vind5_mean, Vind5_mean_exp, places=digit_round, msg='In TestCavityFeedback test_FB_pretracking: ' + 'mean value of five-section cavity differs') self.assertAlmostEqual(Vind5_std, Vind5_std_exp, places=digit_round, msg='In TestCavityFeedback test_FB_pretracking: standard ' + 'deviation of five-section cavity differs') def test_FB_pre_tracking_IQ_v1(self): rtol = 1e-3 # relative tolerance atol = 0 # absolute tolerance # interpolate from coarse mesh to fine mesh V_fine_tot_4 = np.interp( self.profile.bin_centers, self.OTFB.OTFB_4.rf_centers, self.OTFB.OTFB_4.V_coarse_ind_gen) V_fine_tot_5 = np.interp( self.profile.bin_centers, self.OTFB.OTFB_5.rf_centers, self.OTFB.OTFB_5.V_coarse_ind_gen) V_tot_4 = V_fine_tot_4/1e6 V_tot_5 = V_fine_tot_5/1e6 V_sum = self.OTFB.V_sum/1e6 # expected generator voltage is only in Q V_tot_4_exp = 2.0j*np.ones(256) V_tot_5_exp = 2.5j*np.ones(256) V_sum_exp = 4.5j*np.ones(256) np.testing.assert_allclose(V_tot_4, V_tot_4_exp, rtol=rtol, atol=atol, err_msg='In TestCavityFeedback test_FB_pretracking_IQ: total voltage ' + 'in four-section cavity differs') np.testing.assert_allclose(V_tot_5, V_tot_5_exp, rtol=rtol, atol=atol, err_msg='In TestCavityFeedback test_FB_pretracking_IQ: total voltage ' + 'in five-section cavity differs') np.testing.assert_allclose(V_sum, V_sum_exp, rtol=rtol, atol=atol, err_msg='In TestCavityFeedback test_FB_pretracking_IQ: voltage sum ' + ' differs') def test_rf_voltage(self): digit_round = 9 # compute voltage self.cavity_tracker.rf_voltage_calculation() # compute voltage after OTFB pre-tracking self.OTFB_tracker.rf_voltage_calculation() # Since there is a systematic offset between the voltages, # compare the maxium of the ratio max_ratio = np.max(self.cavity_tracker.rf_voltage / self.OTFB_tracker.rf_voltage) max_ratio = max_ratio max_ratio_exp = 1.0008217052569774 self.assertAlmostEqual(max_ratio, max_ratio_exp, places=digit_round, msg='In TestCavityFeedback test_rf_voltage: ' + 'RF-voltages differ') def test_beam_loading(self): digit_round = 9 # Compute voltage with beam loading self.cavity_tracker.rf_voltage_calculation() cavity_tracker_total_voltage = self.cavity_tracker.rf_voltage \ + self.cavity_tracker.totalInducedVoltage.induced_voltage self.OTFB.track() self.OTFB_tracker.rf_voltage_calculation() OTFB_tracker_total_voltage = self.OTFB_tracker.rf_voltage max_ratio = np.max(cavity_tracker_total_voltage / OTFB_tracker_total_voltage) max_ration_exp = 1.0051759770680779 self.assertAlmostEqual(max_ratio, max_ration_exp, places=digit_round, msg='In TestCavityFeedback test_beam_loading: ' + 'total voltages differ') def test_Vsum_IQ(self): rtol = 1e-7 # relative tolerance atol = 0 # absolute tolerance self.OTFB.track() V_sum = self.OTFB.V_sum/1e6 V_sum_exp = np.array([-7.40650823e+01+4497812.99202967j, -7.40650823e+01+4497812.99202967j, -7.40650823e+01+4497812.99202967j, -7.40650823e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j, -7.40650823e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j, -7.40650822e+01+4497812.99202968j, -7.40650822e+01+4497812.99202967j, -7.40650822e+01+4497812.99202968j, -7.40650822e+01+4497812.99202968j, -7.40650822e+01+4497812.99202968j, -7.40650822e+01+4497812.99202968j, -7.40650822e+01+4497812.99202968j, -7.40650822e+01+4497812.99202968j, -7.40650822e+01+4497812.99202968j, -7.40650822e+01+4497812.99202968j, -7.40650822e+01+4497812.99202968j, -7.40650822e+01+4497812.99202968j, -7.40650822e+01+4497812.99202968j, -7.40650822e+01+4497812.99202968j, -7.40650822e+01+4497812.99202968j, -7.40650822e+01+4497812.99202968j, -7.40650822e+01+4497812.99202968j, -7.40650822e+01+4497812.99202968j, -7.40650822e+01+4497812.99202968j, -7.40650822e+01+4497812.99202968j, -7.40650822e+01+4497812.99202968j, -7.40650822e+01+4497812.99202968j, -7.40650822e+01+4497812.99202968j, -7.40650822e+01+4497812.99202968j, -7.40650822e+01+4497812.99202968j, -7.40650822e+01+4497812.99202968j, -6.02318851e+01+4497817.94162674j, -1.98390915e+01+4497835.4539936j, 1.93158486e+01+4497855.56826354j, 4.37055412e+01+4497871.87009121j, 7.72626261e+01+4497900.35036866j, 1.08879867e+02+4497930.96118169j, 1.36226374e+02+4497965.43834138j, 1.83914308e+02+4498039.43198652j, 2.58060957e+02+4498182.7842137j, 3.46527521e+02+4498400.20917783j, 4.26706222e+02+4498667.15544146j, 4.94661306e+02+4499027.56784064j, 5.43482338e+02+4499582.92538958j, 5.37601327e+02+4500375.11759629j, 4.18116316e+02+4501483.68340875j, 1.06781854e+02+4502992.29896325j, -5.18346745e+02+4504994.88486696j, -1.49458714e+03+4507337.42385509j, -3.01163886e+03+4510119.3419273j, -5.32851179e+03+4513546.45481774j, -8.74569640e+03+4517649.58201841j, -1.36711235e+04+4522515.97696859j, -2.06268308e+04+4528145.57335092j, -3.07188747e+04+4534772.43779405j, -4.42705242e+04+4541938.02912512j, -6.14651616e+04+4548954.45228089j, -8.23300421e+04+4555211.22162217j, -1.09421551e+05+4560368.34346543j, -1.43885886e+05+4563628.1865127j, -1.85808399e+05+4563383.852869j, -2.36208282e+05+4558209.23829535j, -2.94836934e+05+4546270.53281669j, -3.63317854e+05+4525133.07455768j, -4.41779074e+05+4492246.31582297j, -5.28977031e+05+4445197.26263046j, -6.24427353e+05+4380854.18329653j, -7.28570463e+05+4294604.34393273j, -8.41413067e+05+4180725.12037253j, -9.58666802e+05+4036850.21934613j, -1.07489637e+06+3861588.24443417j, -1.18692079e+06+3650150.96222293j, -1.28868132e+06+3402561.33925834j, -1.37503355e+06+3113868.12951949j, -1.44047679e+06+2779413.13521708j, -1.47644078e+06+2402815.35953829j, -1.47522678e+06+1985042.23744602j, -1.42897968e+06+1528424.34271266j, -1.32931255e+06+1034805.30411738j, -1.16912937e+06 + 511261.80102318j, -9.43345126e+05 - 30406.39494472j, -6.44543913e+05 - 585971.64269612j, -2.67898382e+05-1147041.0353738j, 1.87647422e+05-1699739.23544117j, 7.19585769e+05-2229855.79356738j, 1.32653137e+06-2725965.80099238j, 2.00691053e+06-3178849.17084715j, 2.75728744e+06-3578075.86057957j, 3.56230981e+06-3910440.14562456j, 4.40408617e+06-4164575.91355405j, 5.28572695e+06-4338227.19020188j, 6.19719564e+06-4426787.10912655j, 7.11277008e+06-4425807.66220696j, 8.01692653e+06-4335730.38899002j, 8.89765817e+06-4159572.80505286j, 9.74683705e+06-3900763.99853979j, 1.05559999e+07-3564480.67012727j, 1.13018718e+07-3165395.29765105j, 1.19781005e+07-2712267.95526922j, 1.25833208e+07-2214895.26359232j, 1.31112101e+07-1685734.89623327j, 1.35640429e+07-1132761.26804116j, 1.39371556e+07 - 573495.98893318j, 1.42323033e+07 - 19883.35687916j, 1.44559502e+07 + 521811.95451886j, 1.46134106e+07+1043190.45283868j, 1.47105373e+07+1534116.02749795j, 1.47549265e+07+1994083.71851812j, 1.47545428e+07+2416602.70892133j, 1.47166958e+07+2794242.30539414j, 1.46493955e+07+3129779.93382244j, 1.45593030e+07+3424466.23125072j, 1.44539743e+07+3677716.51226699j, 1.43401341e+07+3889644.33404043j, 1.42224899e+07+4064982.31004726j, 1.41063737e+07+4205965.72167177j, 1.39946111e+07+4317244.42689922j, 1.38886184e+07+4403883.23649077j, 1.37894739e+07+4469861.27187975j, 1.36989283e+07+4518194.75268176j, 1.36191316e+07+4551305.81768837j, 1.35495619e+07+4572524.22309931j, 1.34903101e+07+4584597.89085099j, 1.34406305e+07+4589814.4489974j, 1.33976876e+07+4590220.82697034j, 1.33615022e+07+4587255.76269093j, 1.33327026e+07+4582254.09185628j, 1.33096130e+07+4576070.77968165j, 1.32911752e+07+4569436.1321998j, 1.32768524e+07+4562928.08977976j, 1.32656893e+07+4556810.85976046j, 1.32570926e+07+4551309.42853408j, 1.32504722e+07+4546502.73564931j, 1.32453253e+07+4542354.45990368j, 1.32414716e+07+4539159.11692844j, 1.32386032e+07+4536873.63706821j, 1.32362022e+07+4534949.63932622j, 1.32341515e+07+4533397.43716764j, 1.32323621e+07+4532141.64712087j, 1.32307439e+07+4531156.20064611j, 1.32292493e+07+4530633.17835778j, 1.32277994e+07+4530492.96280951j, 1.32263821e+07+4530446.25647796j, 1.32249901e+07+4530405.83108728j, 1.32236081e+07+4530431.11420123j, 1.32222495e+07+4530467.44843446j, 1.32208432e+07+4530611.48233323j, 1.32193886e+07+4530847.10244979j, 1.32179361e+07+4531084.60180009j, 1.32164993e+07+4531317.55923836j, 1.32150516e+07+4531560.32993118j, 1.32135685e+07+4531829.29611484j, 1.32120853e+07+4532098.20168656j, 1.32106022e+07+4532367.04664624j, 1.32091191e+07+4532635.83099376j, 1.32076359e+07+4532904.55472902j, 1.32061675e+07+4533173.93875581j, 1.32046990e+07+4533443.26260922j, 1.32032158e+07+4533711.80494598j, 1.32017326e+07+4533980.28666989j, 1.32002495e+07+4534248.70778084j, 1.31987663e+07+4534517.06827872j, 1.31972831e+07+4534785.36816343j, 1.31957999e+07+4535053.60743485j, 1.31943167e+07+4535321.78609287j, 1.31928335e+07+4535589.90413737j, 1.31913503e+07+4535857.96156826j, 1.31898671e+07+4536125.95838542j, 1.31883839e+07+4536393.89458873j, 1.31869007e+07+4536661.77017809j, 1.31854174e+07+4536929.58515338j, 1.31839342e+07+4537197.33951451j, 1.31824510e+07+4537465.03326134j, 1.31809677e+07+4537732.66639378j, 1.31794845e+07+4538000.23891172j, 1.31780012e+07+4538267.75081504j, 1.31765179e+07+4538535.20210364j, 1.31750347e+07+4538802.5927774j, 1.31735514e+07+4539069.92283622j, 1.31720681e+07+4539337.19227997j, 1.31705848e+07+4539604.40110857j, 1.31691016e+07+4539871.54932188j, 1.31676183e+07+4540138.63691982j, 1.31661350e+07+4540405.66390225j, 1.31646517e+07+4540672.63026908j, 1.31631684e+07+4540939.53602019j, 1.31616850e+07+4541206.38115549j, 1.31602017e+07+4541473.16567484j, 1.31587184e+07+4541739.88957815j, 1.31572351e+07+4542006.55286531j, 1.31557517e+07+4542273.1555362j, 1.31542684e+07+4542539.69759073j, 1.31527850e+07+4542806.17902876j, 1.31513017e+07+4543072.59985021j, 1.31498183e+07+4543338.96005496j, 1.31483350e+07+4543605.2596429j, 1.31468516e+07+4543871.49861392j, 1.31453682e+07+4544137.6769679j, 1.31438848e+07+4544403.79470476j, 1.31424014e+07+4544669.85182436j, 1.31409181e+07+4544935.84832662j, 1.31394347e+07+4545201.7842114j, 1.31379513e+07+4545467.65947862j, 1.31364679e+07+4545733.47412815j, 1.31349844e+07+4545999.22815989j, 1.31335010e+07+4546264.92157373j, 1.31320176e+07+4546530.55436956j, 1.31305342e+07+4546796.12654728j, 1.31290507e+07+4547061.63810677j, 1.31275673e+07+4547327.08904792j, 1.31260839e+07+4547592.47937064j, 1.31246004e+07+4547857.8090748j, 1.31231170e+07+4548123.0781603j, 1.31216335e+07+4548388.28662704j, 1.31201500e+07+4548653.4344749j, 1.31186666e+07+4548918.52170378j, 1.31171831e+07+4549183.54831356j, 1.31156996e+07+4549448.51430414j, 1.31142161e+07+4549713.41967541j, 1.31127326e+07+4549978.26442727j])/1e6 np.testing.assert_allclose(V_sum_exp, V_sum, rtol=rtol, atol=atol, err_msg='In TestCavityFeedback test_Vsum_IQ: total voltage ' + 'is different from expected values!')
mpiprint(" Omega_s0 = %.4e s at flat bottom, %.4e s at flat top" % (rf.omega_s0[0], rf.omega_s0[n_turns])) mpiprint(" SL a_i = %.4f a_f = %.4f" % (PL.lhc_a[0], PL.lhc_a[n_turns])) mpiprint(" SL t_i = %.4f t_f = %.4f" % (PL.lhc_t[0], PL.lhc_t[n_turns])) # Injecting noise in the cavity, PL on # Define machine impedance from http://impedance.web.cern.ch/impedance/ ZTot = np.loadtxt(os.path.join( inputDir, 'Zlong_Allthemachine_450GeV_B1_LHC_inj_450GeV_B1.dat'), skiprows=1) ZTable = InputTable(ZTot[:, 0], ZTot[:, 1], ZTot[:, 2]) indVoltage = InducedVoltageFreq(beam, profile, [ZTable], frequency_resolution=freq_res) totVoltage = TotalInducedVoltage(beam, profile, [indVoltage]) # TODO add the noiseFB tracker = RingAndRFTracker(rf, beam, BeamFeedback=PL, Profile=profile, interpolation=True, TotalInducedVoltage=totVoltage) # interpolation=True, TotalInducedVoltage=None) mpiprint("PL, SL, and tracker set...") # Fill beam distribution fullring = FullRingAndRF([tracker]) # Juan's fit to LHC profiles: binomial w/ exponent 1.5 # matched_from_distribution_function(beam, fullring, # main_harmonic_option = 'lowest_freq',
def test_vind(self): # randomly chose omega_c from allowed range np.random.seed(1980) factor = np.random.uniform(0.9, 1.1) # round results to this digits digit_round = 8 # SPS parameters C = 2 * np.pi * 1100.009 # Ring circumference [m] gamma_t = 18.0 # Gamma at transition alpha = 1 / gamma_t**2 # Momentum compaction factor p_s = 25.92e9 # Synchronous momentum at injection [eV] h = 4620 # 200 MHz system harmonic V = 4.5e6 # 200 MHz RF voltage phi = 0. # 200 MHz RF phase # Beam and tracking parameters N_m = 1e5 # Number of macro-particles for tracking N_b = 1.0e11 # Bunch intensity [ppb] N_t = 1 # Number of turns to track ring = Ring(C, alpha, p_s, Proton(), n_turns=N_t) rf = RFStation(ring, h, V, phi) beam = Beam(ring, N_m, N_b) bigaussian(ring, rf, beam, 3.2e-9 / 4, seed=1234, reinsertion=True) n_shift = 5 # how many rf-buckets to shift beam beam.dt += n_shift * rf.t_rf[0, 0] profile = Profile(beam, CutOptions=CutOptions( cut_left=(n_shift - 1.5) * rf.t_rf[0, 0], cut_right=(n_shift + 1.5) * rf.t_rf[0, 0], n_slices=140)) profile.track() l_cav = 16.082 v_g = 0.0946 tau = l_cav / (v_g * c) * (1 + v_g) TWC_impedance_source = TravelingWaveCavity(l_cav**2 * 27.1e3 / 8, 200.222e6, 2 * np.pi * tau) # Beam loading by convolution of beam and wake from cavity inducedVoltageTWC = InducedVoltageTime(beam, profile, [TWC_impedance_source]) induced_voltage = TotalInducedVoltage(beam, profile, [inducedVoltageTWC]) induced_voltage.induced_voltage_sum() V_ind_impSource = np.around(induced_voltage.induced_voltage, digit_round) # Beam loading via feed-back system OTFB_4 = SPSOneTurnFeedback(rf, beam, profile, 4, n_cavities=1) OTFB_4.counter = 0 # First turn OTFB_4.omega_c = factor * OTFB_4.TWC.omega_r # Compute impulse response OTFB_4.TWC.impulse_response_beam(OTFB_4.omega_c, profile.bin_centers) # Compute induced voltage in (I,Q) coordinates OTFB_4.beam_induced_voltage(lpf=False) # convert back to time V_ind_OTFB \ = OTFB_4.V_fine_ind_beam.real \ * np.cos(OTFB_4.omega_c*profile.bin_centers) \ + OTFB_4.V_fine_ind_beam.imag \ * np.sin(OTFB_4.omega_c*profile.bin_centers) V_ind_OTFB = np.around(V_ind_OTFB, digit_round) self.assertListEqual( V_ind_impSource.tolist(), V_ind_OTFB.tolist(), msg="In TravelingWaveCavity test_vind: induced voltages differ")
deriv_mode='gradient') PS_intensity_plot = InducedVoltageFreq( beam, profile, ResonatorsList10MHz + ImpedanceTableList10MHz + ResonatorsListRest + ImpedanceTableListRest, frequency_step, RFParams=rf_params, multi_turn_wake=True, front_wake_length=front_wake_length) # PS_longitudinal_intensity = TotalInducedVoltage( # beam, profile, [PS_intensity_freq_10MHz, PS_intensity_freq_Rest, PS_inductive]) PS_longitudinal_intensity = TotalInducedVoltage( beam, profile, [PS_intensity_freq_Rest, PS_inductive]) # RF tracker tracker = RingAndRFTracker(rf_params, beam, interpolation=True, Profile=profile, TotalInducedVoltage=PS_longitudinal_intensity) full_tracker = FullRingAndRF([tracker]) # Beam generation distribution_options = { 'type': 'parabolic_amplitude', 'density_variable': 'Hamiltonian', 'bunch_length': bunch_length }
def setUp(self): C = 2*np.pi*1100.009 # Ring circumference [m] gamma_t = 18.0 # Gamma at transition alpha = 1/gamma_t**2 # Momentum compaction factor p_s = 25.92e9 # Synchronous momentum at injection [eV] h = 4620 # 200 MHz system harmonic phi = 0. # 200 MHz RF phase # With this setting, amplitude in the two four-section, five-section # cavities must converge, respectively, to # 2.0 MV = 4.5 MV * 4/18 * 2 # 2.5 MV = 4.5 MV * 5/18 * 2 V = 4.5e6 # 200 MHz RF voltage N_t = 1 # Number of turns to track self.ring = Ring(C, alpha, p_s, Particle=Proton(), n_turns=N_t) self.rf = RFStation(self.ring, h, V, phi) N_m = 1e6 # Number of macro-particles for tracking N_b = 72*1.0e11 # Bunch intensity [ppb] # Gaussian beam profile self.beam = Beam(self.ring, N_m, N_b) sigma = 1.0e-9 bigaussian(self.ring, self.rf, self.beam, sigma, seed=1234, reinsertion=False) n_shift = 1550 # how many rf-buckets to shift beam self.beam.dt += n_shift * self.rf.t_rf[0,0] self.profile = Profile( self.beam, CutOptions=CutOptions( cut_left=(n_shift-1.5)*self.rf.t_rf[0,0], cut_right=(n_shift+2.5)*self.rf.t_rf[0,0], n_slices=4*64)) self.profile.track() # Cavities l_cav = 43*0.374 v_g = 0.0946 tau = l_cav/(v_g*c)*(1 + v_g) f_cav = 200.222e6 n_cav = 2 # factor 2 because of two four/five-sections cavities short_cavity = TravelingWaveCavity(l_cav**2 * n_cav * 27.1e3 / 8, f_cav, 2*np.pi*tau) shortInducedVoltage = InducedVoltageTime(self.beam, self.profile, [short_cavity]) l_cav = 54*0.374 tau = l_cav/(v_g*c)*(1 + v_g) long_cavity = TravelingWaveCavity(l_cav**2 * n_cav * 27.1e3 / 8, f_cav, 2*np.pi*tau) longInducedVoltage = InducedVoltageTime(self.beam, self.profile, [long_cavity]) self.induced_voltage = TotalInducedVoltage( self.beam, self.profile, [shortInducedVoltage, longInducedVoltage]) self.induced_voltage.induced_voltage_sum() self.cavity_tracker = RingAndRFTracker( self.rf, self.beam, Profile=self.profile, interpolation=True, TotalInducedVoltage=self.induced_voltage) self.OTFB = SPSCavityFeedback( self.rf, self.beam, self.profile, G_llrf=5, G_tx=0.5, a_comb=15/16, turns=50, Commissioning=CavityFeedbackCommissioning()) self.OTFB_tracker = RingAndRFTracker(self.rf, self.beam, Profile=self.profile, TotalInducedVoltage=None, CavityFeedback=self.OTFB, interpolation=True)
class TestCavityFeedback(unittest.TestCase): def setUp(self): C = 2*np.pi*1100.009 # Ring circumference [m] gamma_t = 18.0 # Gamma at transition alpha = 1/gamma_t**2 # Momentum compaction factor p_s = 25.92e9 # Synchronous momentum at injection [eV] h = 4620 # 200 MHz system harmonic phi = 0. # 200 MHz RF phase # With this setting, amplitude in the two four-section, five-section # cavities must converge, respectively, to # 2.0 MV = 4.5 MV * 4/18 * 2 # 2.5 MV = 4.5 MV * 5/18 * 2 V = 4.5e6 # 200 MHz RF voltage N_t = 1 # Number of turns to track self.ring = Ring(C, alpha, p_s, Particle=Proton(), n_turns=N_t) self.rf = RFStation(self.ring, h, V, phi) N_m = 1e6 # Number of macro-particles for tracking N_b = 72*1.0e11 # Bunch intensity [ppb] # Gaussian beam profile self.beam = Beam(self.ring, N_m, N_b) sigma = 1.0e-9 bigaussian(self.ring, self.rf, self.beam, sigma, seed=1234, reinsertion=False) n_shift = 1550 # how many rf-buckets to shift beam self.beam.dt += n_shift * self.rf.t_rf[0,0] self.profile = Profile( self.beam, CutOptions=CutOptions( cut_left=(n_shift-1.5)*self.rf.t_rf[0,0], cut_right=(n_shift+2.5)*self.rf.t_rf[0,0], n_slices=4*64)) self.profile.track() # Cavities l_cav = 43*0.374 v_g = 0.0946 tau = l_cav/(v_g*c)*(1 + v_g) f_cav = 200.222e6 n_cav = 2 # factor 2 because of two four/five-sections cavities short_cavity = TravelingWaveCavity(l_cav**2 * n_cav * 27.1e3 / 8, f_cav, 2*np.pi*tau) shortInducedVoltage = InducedVoltageTime(self.beam, self.profile, [short_cavity]) l_cav = 54*0.374 tau = l_cav/(v_g*c)*(1 + v_g) long_cavity = TravelingWaveCavity(l_cav**2 * n_cav * 27.1e3 / 8, f_cav, 2*np.pi*tau) longInducedVoltage = InducedVoltageTime(self.beam, self.profile, [long_cavity]) self.induced_voltage = TotalInducedVoltage( self.beam, self.profile, [shortInducedVoltage, longInducedVoltage]) self.induced_voltage.induced_voltage_sum() self.cavity_tracker = RingAndRFTracker( self.rf, self.beam, Profile=self.profile, interpolation=True, TotalInducedVoltage=self.induced_voltage) self.OTFB = SPSCavityFeedback( self.rf, self.beam, self.profile, G_llrf=5, G_tx=0.5, a_comb=15/16, turns=50, Commissioning=CavityFeedbackCommissioning()) self.OTFB_tracker = RingAndRFTracker(self.rf, self.beam, Profile=self.profile, TotalInducedVoltage=None, CavityFeedback=self.OTFB, interpolation=True) def test_FB_pre_tracking(self): digit_round = 3 Vind4_mean = np.around( np.mean(np.absolute(self.OTFB.OTFB_4.V_coarse_tot))/1e6, digit_round) Vind4_std = np.around( np.std(np.absolute(self.OTFB.OTFB_4.V_coarse_tot))/1e6, digit_round) Vind4_mean_exp = np.around(1.99886351363, digit_round) Vind4_std_exp = np.around(2.148426e-6, digit_round) Vind5_mean = np.around( np.mean(np.absolute(self.OTFB.OTFB_5.V_coarse_tot))/1e6, digit_round) Vind5_std = np.around( np.std(np.absolute(self.OTFB.OTFB_5.V_coarse_tot))/1e6, digit_round) Vind5_mean_exp = np.around(2.49906605189, digit_round) Vind5_std_exp = np.around(2.221665e-6, digit_round) self.assertEqual(Vind4_mean, Vind4_mean_exp, msg='In TestCavityFeedback test_FB_pretracking: ' +'mean value of four-section cavity differs') self.assertEqual(Vind4_std, Vind4_std_exp, msg='In TestCavityFeedback test_FB_pretracking: standard ' +'deviation of four-section cavity differs') self.assertEqual(Vind5_mean, Vind5_mean_exp, msg='In TestCavityFeedback test_FB_pretracking: ' +'mean value of five-section cavity differs') self.assertEqual(Vind5_std, Vind5_std_exp, msg='In TestCavityFeedback test_FB_pretracking: standard '+ 'deviation of five-section cavity differs') def test_FB_pre_tracking_IQ_v1(self): digit_round = 2 # interpolate from coarse mesh to fine mesh V_fine_tot_4 = np.interp( self.profile.bin_centers, self.OTFB.OTFB_4.rf_centers, self.OTFB.OTFB_4.V_coarse_ind_gen) V_fine_tot_5 = np.interp( self.profile.bin_centers, self.OTFB.OTFB_5.rf_centers, self.OTFB.OTFB_5.V_coarse_ind_gen) V_tot_4 = np.around(V_fine_tot_4/1e6, digit_round) V_tot_5 = np.around(V_fine_tot_5/1e6, digit_round) V_sum = np.around(self.OTFB.V_sum/1e6, digit_round) # expected generator voltage is only in Q V_tot_4_exp = 2.0j*np.ones(256) V_tot_5_exp = 2.5j*np.ones(256) V_sum_exp = 4.5j*np.ones(256) self.assertListEqual(V_tot_4.tolist(), V_tot_4_exp.tolist(), msg='In TestCavityFeedback test_FB_pretracking_IQ: total voltage ' +'in four-section cavity differs') self.assertListEqual(V_tot_5.tolist(), V_tot_5_exp.tolist(), msg='In TestCavityFeedback test_FB_pretracking_IQ: total voltage ' +'in five-section cavity differs') self.assertListEqual(V_sum.tolist(), V_sum_exp.tolist(), msg='In TestCavityFeedback test_FB_pretracking_IQ: voltage sum ' +' differs') def test_rf_voltage(self): digit_round = 8 # compute voltage self.cavity_tracker.rf_voltage_calculation() # compute voltage after OTFB pre-tracking self.OTFB_tracker.rf_voltage_calculation() # Since there is a systematic offset between the voltages, # compare the maxium of the ratio max_ratio = np.max(self.cavity_tracker.rf_voltage / self.OTFB_tracker.rf_voltage) max_ratio = np.around(max_ratio, digit_round) max_ratio_exp = np.around(1.0008217052569774, digit_round) self.assertAlmostEqual(max_ratio, max_ratio_exp, places=digit_round, msg='In TestCavityFeedback test_rf_voltage: ' + 'RF-voltages differ') def test_beam_loading(self): digit_round = 10 # Compute voltage with beam loading self.cavity_tracker.rf_voltage_calculation() cavity_tracker_total_voltage = self.cavity_tracker.rf_voltage \ + self.cavity_tracker.totalInducedVoltage.induced_voltage self.OTFB.track() self.OTFB_tracker.rf_voltage_calculation() OTFB_tracker_total_voltage = self.OTFB_tracker.rf_voltage max_ratio = np.around(np.max(cavity_tracker_total_voltage / OTFB_tracker_total_voltage), digit_round) max_ration_exp = np.around(1.0051759770680779, digit_round) self.assertEqual(max_ratio, max_ration_exp, msg='In TestCavityFeedback test_beam_loading: ' + 'total voltages differ') def test_Vsum_IQ(self): digit_round = 4 self.OTFB.track() V_sum = np.around(self.OTFB.V_sum/1e6, digit_round) V_sum_exp = np.around(np.array([-7.40650823e+01+4497812.99202967j, -7.40650823e+01+4497812.99202967j, -7.40650823e+01+4497812.99202967j, -7.40650823e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j, -7.40650823e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j,-7.40650822e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j,-7.40650822e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j,-7.40650822e+01+4497812.99202967j, -7.40650822e+01+4497812.99202968j,-7.40650822e+01+4497812.99202967j, -7.40650822e+01+4497812.99202968j,-7.40650822e+01+4497812.99202968j, -7.40650822e+01+4497812.99202968j,-7.40650822e+01+4497812.99202968j, -7.40650822e+01+4497812.99202968j,-7.40650822e+01+4497812.99202968j, -7.40650822e+01+4497812.99202968j,-7.40650822e+01+4497812.99202968j, -7.40650822e+01+4497812.99202968j,-7.40650822e+01+4497812.99202968j, -7.40650822e+01+4497812.99202968j,-7.40650822e+01+4497812.99202968j, -7.40650822e+01+4497812.99202968j,-7.40650822e+01+4497812.99202968j, -7.40650822e+01+4497812.99202968j,-7.40650822e+01+4497812.99202968j, -7.40650822e+01+4497812.99202968j,-7.40650822e+01+4497812.99202968j, -7.40650822e+01+4497812.99202968j,-7.40650822e+01+4497812.99202968j, -7.40650822e+01+4497812.99202968j,-7.40650822e+01+4497812.99202968j, -7.40650822e+01+4497812.99202968j,-7.40650822e+01+4497812.99202968j, -6.02318851e+01+4497817.94162674j,-1.98390915e+01+4497835.4539936j , 1.93158486e+01+4497855.56826354j,4.37055412e+01+4497871.87009121j, 7.72626261e+01+4497900.35036866j,1.08879867e+02+4497930.96118169j, 1.36226374e+02+4497965.43834138j,1.83914308e+02+4498039.43198652j, 2.58060957e+02+4498182.7842137j ,3.46527521e+02+4498400.20917783j, 4.26706222e+02+4498667.15544146j,4.94661306e+02+4499027.56784064j, 5.43482338e+02+4499582.92538958j,5.37601327e+02+4500375.11759629j, 4.18116316e+02+4501483.68340875j,1.06781854e+02+4502992.29896325j, -5.18346745e+02+4504994.88486696j,-1.49458714e+03+4507337.42385509j, -3.01163886e+03+4510119.3419273j ,-5.32851179e+03+4513546.45481774j, -8.74569640e+03+4517649.58201841j,-1.36711235e+04+4522515.97696859j, -2.06268308e+04+4528145.57335092j,-3.07188747e+04+4534772.43779405j, -4.42705242e+04+4541938.02912512j,-6.14651616e+04+4548954.45228089j, -8.23300421e+04+4555211.22162217j,-1.09421551e+05+4560368.34346543j, -1.43885886e+05+4563628.1865127j ,-1.85808399e+05+4563383.852869j , -2.36208282e+05+4558209.23829535j,-2.94836934e+05+4546270.53281669j, -3.63317854e+05+4525133.07455768j,-4.41779074e+05+4492246.31582297j, -5.28977031e+05+4445197.26263046j,-6.24427353e+05+4380854.18329653j, -7.28570463e+05+4294604.34393273j,-8.41413067e+05+4180725.12037253j, -9.58666802e+05+4036850.21934613j,-1.07489637e+06+3861588.24443417j, -1.18692079e+06+3650150.96222293j,-1.28868132e+06+3402561.33925834j, -1.37503355e+06+3113868.12951949j,-1.44047679e+06+2779413.13521708j, -1.47644078e+06+2402815.35953829j,-1.47522678e+06+1985042.23744602j, -1.42897968e+06+1528424.34271266j,-1.32931255e+06+1034805.30411738j, -1.16912937e+06 +511261.80102318j,-9.43345126e+05 -30406.39494472j, -6.44543913e+05 -585971.64269612j,-2.67898382e+05-1147041.0353738j , 1.87647422e+05-1699739.23544117j,7.19585769e+05-2229855.79356738j, 1.32653137e+06-2725965.80099238j,2.00691053e+06-3178849.17084715j, 2.75728744e+06-3578075.86057957j,3.56230981e+06-3910440.14562456j, 4.40408617e+06-4164575.91355405j,5.28572695e+06-4338227.19020188j, 6.19719564e+06-4426787.10912655j,7.11277008e+06-4425807.66220696j, 8.01692653e+06-4335730.38899002j,8.89765817e+06-4159572.80505286j, 9.74683705e+06-3900763.99853979j,1.05559999e+07-3564480.67012727j, 1.13018718e+07-3165395.29765105j,1.19781005e+07-2712267.95526922j, 1.25833208e+07-2214895.26359232j,1.31112101e+07-1685734.89623327j, 1.35640429e+07-1132761.26804116j,1.39371556e+07 -573495.98893318j, 1.42323033e+07 -19883.35687916j,1.44559502e+07 +521811.95451886j, 1.46134106e+07+1043190.45283868j,1.47105373e+07+1534116.02749795j, 1.47549265e+07+1994083.71851812j,1.47545428e+07+2416602.70892133j, 1.47166958e+07+2794242.30539414j,1.46493955e+07+3129779.93382244j, 1.45593030e+07+3424466.23125072j,1.44539743e+07+3677716.51226699j, 1.43401341e+07+3889644.33404043j,1.42224899e+07+4064982.31004726j, 1.41063737e+07+4205965.72167177j,1.39946111e+07+4317244.42689922j, 1.38886184e+07+4403883.23649077j,1.37894739e+07+4469861.27187975j, 1.36989283e+07+4518194.75268176j,1.36191316e+07+4551305.81768837j, 1.35495619e+07+4572524.22309931j,1.34903101e+07+4584597.89085099j, 1.34406305e+07+4589814.4489974j ,1.33976876e+07+4590220.82697034j, 1.33615022e+07+4587255.76269093j,1.33327026e+07+4582254.09185628j, 1.33096130e+07+4576070.77968165j,1.32911752e+07+4569436.1321998j , 1.32768524e+07+4562928.08977976j,1.32656893e+07+4556810.85976046j, 1.32570926e+07+4551309.42853408j,1.32504722e+07+4546502.73564931j, 1.32453253e+07+4542354.45990368j,1.32414716e+07+4539159.11692844j, 1.32386032e+07+4536873.63706821j,1.32362022e+07+4534949.63932622j, 1.32341515e+07+4533397.43716764j,1.32323621e+07+4532141.64712087j, 1.32307439e+07+4531156.20064611j,1.32292493e+07+4530633.17835778j, 1.32277994e+07+4530492.96280951j,1.32263821e+07+4530446.25647796j, 1.32249901e+07+4530405.83108728j,1.32236081e+07+4530431.11420123j, 1.32222495e+07+4530467.44843446j,1.32208432e+07+4530611.48233323j, 1.32193886e+07+4530847.10244979j,1.32179361e+07+4531084.60180009j, 1.32164993e+07+4531317.55923836j,1.32150516e+07+4531560.32993118j, 1.32135685e+07+4531829.29611484j,1.32120853e+07+4532098.20168656j, 1.32106022e+07+4532367.04664624j,1.32091191e+07+4532635.83099376j, 1.32076359e+07+4532904.55472902j,1.32061675e+07+4533173.93875581j, 1.32046990e+07+4533443.26260922j,1.32032158e+07+4533711.80494598j, 1.32017326e+07+4533980.28666989j,1.32002495e+07+4534248.70778084j, 1.31987663e+07+4534517.06827872j,1.31972831e+07+4534785.36816343j, 1.31957999e+07+4535053.60743485j,1.31943167e+07+4535321.78609287j, 1.31928335e+07+4535589.90413737j,1.31913503e+07+4535857.96156826j, 1.31898671e+07+4536125.95838542j,1.31883839e+07+4536393.89458873j, 1.31869007e+07+4536661.77017809j,1.31854174e+07+4536929.58515338j, 1.31839342e+07+4537197.33951451j,1.31824510e+07+4537465.03326134j, 1.31809677e+07+4537732.66639378j,1.31794845e+07+4538000.23891172j, 1.31780012e+07+4538267.75081504j,1.31765179e+07+4538535.20210364j, 1.31750347e+07+4538802.5927774j ,1.31735514e+07+4539069.92283622j, 1.31720681e+07+4539337.19227997j,1.31705848e+07+4539604.40110857j, 1.31691016e+07+4539871.54932188j,1.31676183e+07+4540138.63691982j, 1.31661350e+07+4540405.66390225j,1.31646517e+07+4540672.63026908j, 1.31631684e+07+4540939.53602019j,1.31616850e+07+4541206.38115549j, 1.31602017e+07+4541473.16567484j,1.31587184e+07+4541739.88957815j, 1.31572351e+07+4542006.55286531j,1.31557517e+07+4542273.1555362j , 1.31542684e+07+4542539.69759073j,1.31527850e+07+4542806.17902876j, 1.31513017e+07+4543072.59985021j,1.31498183e+07+4543338.96005496j, 1.31483350e+07+4543605.2596429j ,1.31468516e+07+4543871.49861392j, 1.31453682e+07+4544137.6769679j ,1.31438848e+07+4544403.79470476j, 1.31424014e+07+4544669.85182436j,1.31409181e+07+4544935.84832662j, 1.31394347e+07+4545201.7842114j ,1.31379513e+07+4545467.65947862j, 1.31364679e+07+4545733.47412815j,1.31349844e+07+4545999.22815989j, 1.31335010e+07+4546264.92157373j,1.31320176e+07+4546530.55436956j, 1.31305342e+07+4546796.12654728j,1.31290507e+07+4547061.63810677j, 1.31275673e+07+4547327.08904792j,1.31260839e+07+4547592.47937064j, 1.31246004e+07+4547857.8090748j ,1.31231170e+07+4548123.0781603j , 1.31216335e+07+4548388.28662704j,1.31201500e+07+4548653.4344749j , 1.31186666e+07+4548918.52170378j,1.31171831e+07+4549183.54831356j, 1.31156996e+07+4549448.51430414j,1.31142161e+07+4549713.41967541j, 1.31127326e+07+4549978.26442727j])/1e6, digit_round) self.assertListEqual(V_sum.tolist(), V_sum_exp.tolist(), msg='In TestCavityFeedback test_Vsum_IQ: total voltage ' +'is different from expected values!')
plt.figure() convtime = np.linspace(-1e-9, -1e-9+len(V_ind_beam.real)* profile.bin_size, len(V_ind_beam.real)) plt.plot(convtime, V_ind_beam.real, 'b--') plt.plot(convtime[:140], V_ind_beam.real[:140], 'b', label='Re(Vind), OTFB') plt.plot(convtime, V_ind_beam.imag, 'r--') plt.plot(convtime[:140], V_ind_beam.imag[:140], 'r', label='Im(Vind), OTFB') plt.plot(convtime[:140], V_ind_beam.real[:140]*np.cos(OTFB_4.omega_c*convtime[:140]) \ + V_ind_beam.imag[:140]*np.sin(OTFB_4.omega_c*convtime[:140]), color='purple', label='Total, OTFB') # Comparison with impedances: FREQUENCY DOMAIN TWC200_4 = TravelingWaveCavity(0.876e6, 200.222e6, 3.899e-6) TWC200_5 = TravelingWaveCavity(1.38e6, 200.222e6, 4.897e-6) indVoltageTWC = InducedVoltageTime(beam, profile, [TWC200_4, TWC200_4, TWC200_5, TWC200_5]) indVoltage = TotalInducedVoltage(beam, profile, [indVoltageTWC]) indVoltage.induced_voltage_sum() plt.plot(indVoltage.time_array, indVoltage.induced_voltage, color='limegreen', label='Time domain w FFT') # Comparison with impedances: TIME DOMAIN TWC200_4.wake_calc(profile.bin_centers - profile.bin_centers[0]) TWC200_5.wake_calc(profile.bin_centers - profile.bin_centers[0]) wake1 = 2*(TWC200_4.wake + TWC200_5.wake) Vind = -profile.Beam.ratio*profile.Beam.Particle.charge*e*\ np.convolve(wake1, profile.n_macroparticles, mode='full')[:140] plt.plot(convtime[:140], Vind, color='teal', label='Time domain w conv') # Wake from impulse response OTFB_4.TWC.impulse_response_gen(omega_c, profile.bin_centers) OTFB_5.TWC.impulse_response_gen(omega_c, profile.bin_centers) OTFB_4.TWC.compute_wakes(profile.bin_centers)
R_shunt = 1e6 f_res = 915e6 Q_factor = 5000 resonator = Resonators(R_shunt, f_res, Q_factor) # Set up of induced voltage # Dictionary for compressed wake calculation compression_dict = {} compression_dict['n_window'] = int(2 * n_slices_per_bucket) compression_dict['n_spacing'] = int(bunch_spacing * n_slices_per_bucket) # Induced voltage with compressed convolution ind_volt_time_compressed = InducedVoltageTime( beam, profile, [resonator], compression_dict=compression_dict) tot_ind_volt_compressed = TotalInducedVoltage(beam, profile, [ind_volt_time_compressed]) profile.track() # Performance test n_test = 50 exec_time_c = np.zeros(n_test) for k in range(n_test): t0 = time.perf_counter() tot_ind_volt_compressed.induced_voltage_sum() t1 = time.perf_counter() exec_time_c[k] = t1 - t0 print( f'Compressed convolution: mean {np.mean(exec_time_c):1.3e} s, std {np.std(exec_time_c):1.3e} s' ) # Induced voltage with full convolution
frequency_R = 2*RF_sct_par.omega_rf[0,0] / 2.0 / np.pi Q = 10000 print('Im Z/n = '+str(R_S / (RF_sct_par.t_rev[0] * frequency_R * Q))) resonator = Resonators(R_S, frequency_R, Q) # INDUCED VOLTAGE FROM IMPEDANCE ---------------------------------------------- imp_list = [resonator] ind_volt_freq = InducedVoltageFreq(beam, slice_beam, imp_list, frequency_resolution=5e4) total_ind_volt = TotalInducedVoltage(beam, slice_beam, [ind_volt_freq]) # BEAM GENERATION ------------------------------------------------------------- n_bunches = 3 bunch_spacing_buckets = 10 intensity_list = [1e11, 1e11, 1e11] minimum_n_macroparticles = [5e5, 5e5, 5e5] distribution_options_list = {'bunch_length': 1e-9, 'type': 'parabolic_amplitude', 'density_variable': 'Hamiltonian'} matched_from_distribution_density_multibunch(beam, general_params, full_tracker, distribution_options_list, n_bunches, bunch_spacing_buckets, intensity_list=intensity_list,
def test_vind(self): # randomly chose omega_c from allowed range np.random.seed(1980) factor = np.random.uniform(0.9, 1.1) # round results to this digits digit_round = 8 # SPS parameters C = 2*np.pi*1100.009 # Ring circumference [m] gamma_t = 18.0 # Gamma at transition alpha = 1/gamma_t**2 # Momentum compaction factor p_s = 25.92e9 # Synchronous momentum at injection [eV] h = 4620 # 200 MHz system harmonic V = 4.5e6 # 200 MHz RF voltage phi = 0. # 200 MHz RF phase # Beam and tracking parameters N_m = 1e5 # Number of macro-particles for tracking N_b = 1.0e11 # Bunch intensity [ppb] N_t = 1 # Number of turns to track ring = Ring(C, alpha, p_s, Proton(), n_turns=N_t) rf = RFStation(ring, h, V, phi) beam = Beam(ring, N_m, N_b) bigaussian(ring, rf, beam, 3.2e-9/4, seed=1234, reinsertion=True) n_shift = 5 # how many rf-buckets to shift beam beam.dt += n_shift * rf.t_rf[0,0] profile = Profile(beam, CutOptions= CutOptions(cut_left=(n_shift-1.5)*rf.t_rf[0,0], cut_right=(n_shift+1.5)*rf.t_rf[0,0], n_slices=140)) profile.track() l_cav = 16.082 v_g = 0.0946 tau = l_cav/(v_g*c)*(1 + v_g) TWC_impedance_source = TravelingWaveCavity(l_cav**2 * 27.1e3 / 8, 200.222e6, 2*np.pi*tau) # Beam loading by convolution of beam and wake from cavity inducedVoltageTWC = InducedVoltageTime(beam, profile, [TWC_impedance_source]) induced_voltage = TotalInducedVoltage(beam, profile, [inducedVoltageTWC]) induced_voltage.induced_voltage_sum() V_ind_impSource = np.around(induced_voltage.induced_voltage, digit_round) # Beam loading via feed-back system OTFB_4 = SPSOneTurnFeedback(rf, beam, profile, 4, n_cavities=1) OTFB_4.counter = 0 # First turn OTFB_4.omega_c = factor * OTFB_4.TWC.omega_r # Compute impulse response OTFB_4.TWC.impulse_response_beam(OTFB_4.omega_c, profile.bin_centers) # Compute induced voltage in (I,Q) coordinates OTFB_4.beam_induced_voltage(lpf=False) # convert back to time V_ind_OTFB \ = OTFB_4.V_fine_ind_beam.real \ * np.cos(OTFB_4.omega_c*profile.bin_centers) \ + OTFB_4.V_fine_ind_beam.imag \ * np.sin(OTFB_4.omega_c*profile.bin_centers) V_ind_OTFB = np.around(V_ind_OTFB, digit_round) self.assertListEqual(V_ind_impSource.tolist(), V_ind_OTFB.tolist(), msg="In TravelingWaveCavity test_vind: induced voltages differ")
# direct space charge dir_space_charge = InductiveImpedance( my_beam, slice_beam, -376.730313462 / (general_params.beta[0] * general_params.gamma[0]**2), RF_sct_par) # INDUCED VOLTAGE FROM IMPEDANCE------------------------------------------------ imp_list = [Ekicker_table, F_C_table] ind_volt_freq = InducedVoltageFreq(my_beam, slice_beam, imp_list, frequency_resolution=2e5) total_induced_voltage = TotalInducedVoltage( my_beam, slice_beam, [ind_volt_freq, steps, dir_space_charge]) # PLOTS format_options = { 'dirname': this_directory + '../output_files/EX_02_fig', 'linestyle': '.' } plots = Plot(general_params, RF_sct_par, my_beam, 1, n_turns, 0, 5.72984173562e-7, -my_beam.sigma_dE * 4.2,
# LOAD IMPEDANCE TABLE-------------------------------------------------------- table = np.loadtxt(this_directory + '../input_files/EX_05_new_HQ_table.dat', comments='!') R_shunt = table[:, 2] * 10**6 f_res = table[:, 0] * 10**9 Q_factor = table[:, 1] resonator = Resonators(R_shunt, f_res, Q_factor) ind_volt_time = InducedVoltageTime(my_beam, slice_beam, [resonator]) ind_volt_freq = InducedVoltageFreq(my_beam_freq, slice_beam_freq, [resonator], 1e5) ind_volt_res = InducedVoltageResonator(my_beam_res, slice_beam_res, resonator) tot_vol = TotalInducedVoltage(my_beam, slice_beam, [ind_volt_time]) tot_vol_freq = TotalInducedVoltage(my_beam_freq, slice_beam_freq, [ind_volt_freq]) tot_vol_res = TotalInducedVoltage(my_beam_res, slice_beam_res, [ind_volt_res]) # Analytic result----------------------------------------------------------- VindGauss = np.zeros(len(slice_beam.bin_centers)) for r in range(len(Q_factor)): # Notice that the time-argument of inducedVoltageGauss is shifted by # mean(my_slices.bin_centers), because the analytical equation assumes the # Gauss to be centered at t=0, but the line density is centered at # mean(my_slices.bin_centers) tmp = analytical_gaussian_resonator(tau_0/4, \ Q_factor[r],R_shunt[r],2*np.pi*f_res[r], \ slice_beam.bin_centers - np.mean(slice_beam.bin_centers), \ my_beam.intensity)
def setUp(self): C = 2*np.pi*1100.009 # Ring circumference [m] gamma_t = 18.0 # Gamma at transition alpha = 1/gamma_t**2 # Momentum compaction factor p_s = 25.92e9 # Synchronous momentum at injection [eV] h = 4620 # 200 MHz system harmonic phi = 0. # 200 MHz RF phase # With this setting, amplitude in the two four-section, five-section # cavities must converge, respectively, to # 2.0 MV = 4.5 MV * 4/18 * 2 # 2.5 MV = 4.5 MV * 5/18 * 2 V = 4.5e6 # 200 MHz RF voltage N_t = 1 # Number of turns to track self.ring = Ring(C, alpha, p_s, Particle=Proton(), n_turns=N_t) self.rf = RFStation(self.ring, h, V, phi) N_m = 1e6 # Number of macro-particles for tracking N_b = 72*1.0e11 # Bunch intensity [ppb] # Gaussian beam profile self.beam = Beam(self.ring, N_m, N_b) sigma = 1.0e-9 bigaussian(self.ring, self.rf, self.beam, sigma, seed=1234, reinsertion=False) n_shift = 1550 # how many rf-buckets to shift beam self.beam.dt += n_shift * self.rf.t_rf[0, 0] self.profile = Profile( self.beam, CutOptions=CutOptions( cut_left=(n_shift-1.5)*self.rf.t_rf[0, 0], cut_right=(n_shift+2.5)*self.rf.t_rf[0, 0], n_slices=4*64)) self.profile.track() # Cavities l_cav = 43*0.374 v_g = 0.0946 tau = l_cav/(v_g*c)*(1 + v_g) f_cav = 200.222e6 n_cav = 2 # factor 2 because of two four/five-sections cavities short_cavity = TravelingWaveCavity(l_cav**2 * n_cav * 27.1e3 / 8, f_cav, 2*np.pi*tau) shortInducedVoltage = InducedVoltageTime(self.beam, self.profile, [short_cavity]) l_cav = 54*0.374 tau = l_cav/(v_g*c)*(1 + v_g) long_cavity = TravelingWaveCavity(l_cav**2 * n_cav * 27.1e3 / 8, f_cav, 2*np.pi*tau) longInducedVoltage = InducedVoltageTime(self.beam, self.profile, [long_cavity]) self.induced_voltage = TotalInducedVoltage( self.beam, self.profile, [shortInducedVoltage, longInducedVoltage]) self.induced_voltage.induced_voltage_sum() self.cavity_tracker = RingAndRFTracker( self.rf, self.beam, Profile=self.profile, interpolation=True, TotalInducedVoltage=self.induced_voltage) self.OTFB = SPSCavityFeedback( self.rf, self.beam, self.profile, G_llrf=5, G_tx=0.5, a_comb=15/16, turns=50, Commissioning=CavityFeedbackCommissioning()) self.OTFB_tracker = RingAndRFTracker(self.rf, self.beam, Profile=self.profile, TotalInducedVoltage=None, CavityFeedback=self.OTFB, interpolation=True)
ind_volt_freq = InducedVoltageFreq(beam, slice_beam, imp_list, RFParams=RF_sct_par, frequency_resolution=1e3, multi_turn_wake=True, mtw_mode='time') ind_volt_time = InducedVoltageTime(beam, slice_beam, imp_list, RFParams=RF_sct_par, wake_length=n_turns*bucket_length, multi_turn_wake=True) ind_volt_freq_periodic = InducedVoltageFreq(beam, slice_beam, imp_list) total_ind_volt_freq = TotalInducedVoltage(beam, slice_beam, [ind_volt_freq]) total_ind_volt_time = TotalInducedVoltage(beam, slice_beam, [ind_volt_time]) total_ind_volt_freq_periodic = TotalInducedVoltage(beam, slice_beam, [ind_volt_freq_periodic]) # ACCELERATION MAP------------------------------------------------------------- map_ = [total_ind_volt_freq] + [total_ind_volt_time] total_ind_volt_freq_periodic.track() # FIRST COMPARISON: CONSTANT REVOLUTION FREQUENCY ----------------------------- for i in range(n_turns): for m in map_: m.track()