def setUp(self): self.general_params = Ring(np.ones(self.n_sections) * self.C/self.n_sections, np.tile(self.momentum_compaction, (1, self.n_sections)).T, np.tile(self.sync_momentum, (self.n_sections, self.n_turns+1)), self.particle_type, self.n_turns, n_sections=self.n_sections) self.RF_sct_par = [] self.RF_sct_par_cpp = [] for i in np.arange(self.n_sections)+1: self.RF_sct_par.append(RFStation(self.general_params, [self.harmonic_numbers], [ self.voltage_program/self.n_sections], [self.phi_offset], self.n_rf_systems, section_index=i)) self.RF_sct_par_cpp.append(RFStation(self.general_params, [self.harmonic_numbers], [ self.voltage_program/self.n_sections], [self.phi_offset], self.n_rf_systems, section_index=i)) # DEFINE BEAM------------------------------------------------------------------ self.beam = Beam(self.general_params, self.n_macroparticles, self.n_particles) self.beam_cpp = Beam(self.general_params, self.n_macroparticles, self.n_particles) # DEFINE SLICES---------------------------------------------------------------- number_slices = 500 cut_options = CutOptions( cut_left=0., cut_right=self.bucket_length, n_slices=number_slices) self.slice_beam = Profile(self.beam, CutOptions=cut_options) self.slice_beam_cpp = Profile(self.beam_cpp, CutOptions=cut_options) # DEFINE TRACKER--------------------------------------------------------------- self.longitudinal_tracker = [] self.longitudinal_tracker_cpp = [] for i in range(self.n_sections): self.longitudinal_tracker.append(RingAndRFTracker( self.RF_sct_par[i], self.beam, Profile=self.slice_beam)) self.longitudinal_tracker_cpp.append(RingAndRFTracker( self.RF_sct_par_cpp[i], self.beam_cpp, Profile=self.slice_beam_cpp)) full_tracker = FullRingAndRF(self.longitudinal_tracker) full_tracker_cpp = FullRingAndRF(self.longitudinal_tracker_cpp) # BEAM GENERATION-------------------------------------------------------------- matched_from_distribution_function(self.beam, full_tracker, emittance=self.emittance, distribution_type=self.distribution_type, distribution_variable=self.distribution_variable, seed=1000) matched_from_distribution_function(self.beam_cpp, full_tracker_cpp, emittance=self.emittance, distribution_type=self.distribution_type, distribution_variable=self.distribution_variable, seed=1000) self.slice_beam.track() self.slice_beam_cpp.track()
def test_losses_energy_cut(self): longitudinal_tracker = RingAndRFTracker(self.rf_params, self.beam) full_tracker = FullRingAndRF([longitudinal_tracker]) try: matched_from_distribution_function(self.beam, full_tracker, distribution_exponent=1.5, distribution_type='binomial', bunch_length=1.65e-9, bunch_length_fit='fwhm', distribution_variable='Hamiltonian') except TypeError as te: self.skipTest("Skipped because of known bug in deepcopy. Exception message %s" % str(te)) self.beam.losses_energy_cut(-3e8, 3e8) self.assertEqual(len(self.beam.id[self.beam.id == 0]), 0, msg='Beam: Failed losses_energy_cut, first') self.beam.dE += 10e8 self.beam.losses_energy_cut(-3e8, 3e8) self.assertEqual(len(self.beam.id[self.beam.id == 0]), self.beam.n_macroparticles, msg='Beam: Failed losses_energy_cut, second')
full_tracker = FullRingAndRF([longitudinal_tracker]) # DEFINE SLICES---------------------------------------------------------------- n_slices = 500 n_bunches = 80 bunch_spacing = 1600 # buckets filling_pattern = np.zeros(bunch_spacing * n_bunches) filling_pattern[::bunch_spacing] = 1 # BEAM GENERATION-------------------------------------------------------------- matched_from_distribution_function(beam, full_tracker, emittance=emittance, distribution_type=distribution_type, distribution_variable=distribution_variable, seed=134253) indexes = np.arange(n_macroparticles) for i in range(int(np.sum(filling_pattern))): beam.dt[indexes[int(i * len(beam.dt) // np.sum(filling_pattern))]:indexes[int( (i + 1) * len(beam.dt) // np.sum(filling_pattern) - 1)]] += (bucket_length * np.where(filling_pattern)[0][i]) import time slice_beam = SparseSlices(RF_sct_par, beam, n_slices, filling_pattern)
} phase_loop = BeamFeedback(general_params, rf_params, slices_ring, configuration) #Long tracker long_tracker = RingAndRFTracker(rf_params, my_beam, BeamFeedback=phase_loop) full_ring = FullRingAndRF([long_tracker]) distribution_type = 'gaussian' bunch_length = 200.0e-9 distribution_variable = 'Action' matched_from_distribution_function(my_beam, full_ring, bunch_length=bunch_length, distribution_type=distribution_type, distribution_variable=distribution_variable, seed=1223) slices_ring.track() # Accelerator map map_ = [long_tracker] + [slices_ring] if worker.isMaster: #Monitor bunch_monitor = BunchMonitor(general_params, rf_params, my_beam, this_directory + '../mpi_output_files/EX_09_output_data',
interpolation=True) fulltracker = FullRingAndRF([tracker]) mpiprint('Creating SPS bunch from PS bunch') # create 72 bunches from PS bunch beginIndex = 0 endIndex = 0 PS_beam = Beam(ring, n_particles, 0.0) PS_n_bunches = 1 for copy in range(n_bunches): # create binomial distribution; # use different seed for different bunches to avoid cloned bunches matched_from_distribution_function(PS_beam, fulltracker, seed=seed + copy, distribution_type='binomial', distribution_exponent=0.7, emittance=0.35) endIndex = beginIndex + n_particles # now place PS bunch at correct position beam.dt[beginIndex:endIndex] \ = PS_beam.dt + copy * t_rf * PS_n_bunches * bunch_spacing beam.dE[beginIndex:endIndex] = PS_beam.dE beginIndex = endIndex mpiprint('dE mean: ', np.mean(beam.dE)) mpiprint('dE std: ', np.std(beam.dE)) # profile.track()
# DEFINE TRACKER--------------------------------------------------------------- longitudinal_tracker = RingAndRFTracker(RF_sct_par,beam) full_tracker = FullRingAndRF([longitudinal_tracker]) # DEFINE SLICES---------------------------------------------------------------- number_slices = 500 cut_options = CutOptions(cut_left= 0, cut_right=bucket_length, n_slices=number_slices) slice_beam = Profile(beam, cut_options) # Single RF ------------------------------------------------------------------- matched_from_distribution_function(beam, full_tracker, emittance=emittance, distribution_type=distribution_type, distribution_variable=distribution_variable, main_harmonic_option='lowest_freq', seed=1256) slice_beam.track() [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) # Plot of the synchrotron frequency distribution plt.figure('fs_distribution') plt.plot(delta_time_left, sync_freq_distribution_left, lw=2, label='Left') plt.plot(delta_time_right, sync_freq_distribution_right, 'r--', lw=2, label='Right')
imp_list = [resonator] ind_volt_freq = InducedVoltageFreq(beam, slice_beam, imp_list, frequency_resolution=5e5) total_ind_volt = TotalInducedVoltage(beam, slice_beam, [ind_volt_freq]) # BEAM GENERATION ------------------------------------------------------------- matched_from_distribution_function(beam, full_tracker, distribution_type=distribution_type, distribution_exponent=distribution_exponent, bunch_length=bunch_length, bunch_length_fit=bunch_length_fit, distribution_variable='Action', seed=18) plt.figure() slice_beam.track() plt.plot(slice_beam.bin_centers, slice_beam.n_macroparticles, lw=2, label='from distribution function') matched_from_line_density(beam, full_tracker, bunch_length=bunch_length, line_density_type=distribution_type,
phase_loop = BeamFeedback(general_params, rf_params, slices_ring, configuration) #Long tracker long_tracker = RingAndRFTracker(rf_params, my_beam, periodicity='Off', BeamFeedback=phase_loop) full_ring = FullRingAndRF([long_tracker]) distribution_type = 'gaussian' bunch_length = 200.0e-9 distribution_variable = 'Action' matched_from_distribution_function(my_beam, full_ring, bunch_length=bunch_length, distribution_type=distribution_type, distribution_variable=distribution_variable, seed=1222) my_beam.dE += 90.0e3 slices_ring.track() #Monitor bunch_monitor = BunchMonitor(general_params, rf_params, my_beam, this_directory + '../output_files/EX_08_output_data', Profile=slices_ring, PhaseLoop=phase_loop) #Plots format_options = {'dirname': this_directory + '../output_files/EX_08_fig'} plots = Plot(general_params, rf_params, my_beam, 50, n_turns, 0.0, 2*np.pi, -1e6, 1e6, xunit='rad', separatrix_plot=True, Profile=slices_ring,
# INDUCED VOLTAGE FROM IMPEDANCE ---------------------------------------------- imp_list = [resonator] ind_volt_freq = InducedVoltageFreq(beam, slice_beam, imp_list, frequency_resolution=5e5) total_ind_volt = TotalInducedVoltage(beam, slice_beam, [ind_volt_freq]) # BEAM GENERATION ------------------------------------------------------------- matched_from_distribution_function(beam, full_tracker, distribution_type=distribution_type, distribution_exponent=distribution_exponent, bunch_length=bunch_length, bunch_length_fit=bunch_length_fit, distribution_variable='Action', seed=18) plt.figure() slice_beam.track() plt.plot(slice_beam.bin_centers, slice_beam.n_macroparticles, lw=2, label='from distribution function') matched_from_line_density(beam, full_tracker, bunch_length=bunch_length, line_density_type=distribution_type, line_density_exponent=distribution_exponent, seed=90) slice_beam.track() plt.plot(slice_beam.bin_centers, slice_beam.n_macroparticles, lw=2, label='from line density')
tInd = map_[2] indFreq = tInd.induced_voltage_list[1] notchResons.frequency_R = notchHarmonics*ring.f_rev[turn] notchResons.R_S = (1/63-1)*np.interp(notchHarmonics*ring.f_rev[turn], finemet1Cell[0], finemet1Cell[1]*36) prof.beam_spectrum_freq_generation(indFreq.n_fft) indFreq.freq = prof.beam_spectrum_freq indFreq.sum_impedances(indFreq.freq) #%% matchedBeam = distBeam.matched_from_distribution_function(my_beam, full_ring, distribution_type = 'parabolic_amplitude', emittance = 1.8) #%% map_ = [full_ring, profile, totalInduced] # tIt = trackIt.TrackIteration(map_) # tIt.add_function(update_impedance, 1) #%% intensity_ramp = np.linspace(0, targetIntensity, 5000) mpiprint('dE mean: ', np.mean(my_beam.dE)) mpiprint('dE std: ', np.std(my_beam.dE))
plt.plot([f_rf * 1e-6 - fs * 1e-6] * 2, plt.ylim(), 'k--', lw=2) plt.xlim(1.74, 1.76) plt.legend(('Impedance', 'RF frequency', 'Synchrotron sidebands'), loc=0, fontsize='medium') plt.xlabel('Frequency [MHz]') plt.ylabel(r'Impedance [$\Omega$]') plt.savefig(this_directory + '../mpi_output_files/EX_18_fig/impedance.png') plt.close() # BEAM GENERATION ------------------------------------------------------------- matched_from_distribution_function(beam, full_tracker, distribution_type=distribution_type, bunch_length=bunch_length, n_iterations=20, TotalInducedVoltage=total_ind_volt, seed=10) # ACCELERATION MAP ------------------------------------------------------------ map_ = [slice_beam] + [total_ind_volt] + [ring_RF_section] import time t0 = time.time() bunch_center = np.zeros(n_turns) bunch_std = np.zeros(n_turns) beam.split()
# DEFINE SLICES---------------------------------------------------------------- n_slices = 500 n_bunches = 80 bunch_spacing = 1600 # buckets filling_pattern = np.zeros(bunch_spacing*n_bunches) filling_pattern[::bunch_spacing] = 1 # BEAM GENERATION-------------------------------------------------------------- matched_from_distribution_function(beam, full_tracker, emittance=emittance, distribution_type=distribution_type, distribution_variable=distribution_variable , seed=134253) indexes = np.arange(n_macroparticles) for i in range(int(np.sum(filling_pattern))): beam.dt[indexes[int(i*len(beam.dt)//np.sum(filling_pattern))]: indexes[int((i+1)*len(beam.dt)//np.sum(filling_pattern)-1)]] += ( bucket_length * np.where(filling_pattern)[0][i]) import time slice_beam = SparseSlices(RF_sct_par, beam, n_slices, filling_pattern) t0 = time.time()