def setUp(self): # Bunch parameters # ----------------- N_turn = 200 N_b = 1e9 # Intensity N_p = int(2e6) # Macro-particles # Machine parameters # -------------------- C = 6911.5038 # Machine circumference [m] p = 450e9 # Synchronous momentum [eV/c] gamma_t = 17.95142852 # Transition gamma alpha = 1. / gamma_t**2 # First order mom. comp. factor # Define general parameters # -------------------------- self.general_params = Ring(C, alpha, p, Proton(), N_turn) # Define beam # ------------ self.beam = Beam(self.general_params, N_p, N_b) # Define RF section # ----------------- self.rf_params = RFStation(self.general_params, [4620], [7e6], [0.])
def test_kinetic_energy_positive(self): # Kinetic energy must be greater or equal 0 for all turns ring = Ring(self.C, self.alpha_0, self.momentum, self.particle, self.n_turns, n_sections=self.num_sections) self.assertTrue( (ring.kin_energy >= 0.0).all(), msg='In TestGeneralParameters kinetic energy is ' + 'negative!')
def test_cycle_time_turn1(self): # Cycle_time[0] must be equal to t_rev[0] ring = Ring(self.C, self.alpha_0, self.momentum, self.particle, self.n_turns, n_sections=self.num_sections) self.assertEqual(ring.cycle_time[0], ring.t_rev[0], msg='In TestGeneralParameters cycle_time at first ' + 'turn not equal to revolution time at first turn!')
def test_alpha_shape_exception(self): # Test if 'momentum compaction' RuntimeError gets thrown for wrong # shape of alpha alpha = [[3.21e-4, 2.e-5, 5.e-7]] # only one array! with self.assertRaisesRegex( RuntimeError, "ERROR in Ring: the input data " + "does not match the number of sections", msg='No RuntimeError for wrong shape of alpha!'): Ring(self.C, alpha, self.momentum, self.particle, self.n_turns, n_sections=self.num_sections)
def test_momentum_shape_exception(self): # Test if RuntimeError gets thrown for wrong shape of momentum cycle_time = np.linspace(0, 1, self.n_turns) momentum = [[450e9], [450e9]] # only one momentum! with self.assertRaisesRegex( RuntimeError, "ERROR in Ring: synchronous data " + "does not match the time data", msg='No RuntimeError for wrong shape of momentum!'): Ring(self.C, self.alpha_0, ((cycle_time, momentum[0]), (cycle_time, momentum[1])), self.particle, self.n_turns, n_sections=self.num_sections)
def test_ring_length_exception(self): # Test if 'ring length size' RuntimeError gets thrown for wrong number # of rf sections num_sections = 1 # only one rf-section! with self.assertRaisesRegex( RuntimeError, 'ERROR in Ring: Number of sections and ring ' + 'length size do not match!', msg='No RuntimeError for wrong n_sections!'): Ring(self.C, self.alpha_0, self.momentum, self.particle, self.n_turns, n_sections=num_sections, alpha_1=self.alpha_1, alpha_2=self.alpha_2)
def test_momentum_length_exception(self): # Test if RuntimeError gets thrown for wrong length of momentum # Only n_turns elements per section! momentum = [ np.linspace(450e9, 450e9, self.n_turns), np.linspace(450e9, 450e9, self.n_turns) ] with self.assertRaisesRegex( RuntimeError, "ERROR in Ring: The input data " + "does not match the proper length " + "\(n_turns\+1\)", msg='No RuntimeError for wrong length of momentum array!'): Ring(self.C, self.alpha_0, momentum, self.particle, self.n_turns, n_sections=self.num_sections)
def test_synchronous_data_exception(self): # What to do when user wants momentum programme for multiple sections? # One array of cycle_time? One array per section? # Currently, __init__ checks only if the number of cycle_time arrays is # the same as the number of momentum_arrays, but not if the array # have the correct length. cycle_time = np.linspace(0, 1, self.n_turns) # wrong length with self.assertRaisesRegex( RuntimeError, "ERROR in Ring: synchronous data does " + "not match the time data", msg='No RuntimeError for wrong synchronous_data!'): Ring(self.C, self.alpha_0, ((cycle_time, self.momentum), (cycle_time, self.momentum)), self.particle, self.n_turns, n_sections=self.num_sections)
# ## 1.1 Single parameters # In[2]: # Simplest case: define a synchrotron with constant momentum from blond_common.interfaces.input_parameters.ring import Ring from blond_common.interfaces.beam.beam import Proton ring_length = 6911.5 # m gamma_transition = 17.95 alpha_0 = 1 / gamma_transition**2. momentum = 25.92e9 # eV/c particle = Proton() ring = Ring(ring_length, alpha_0, momentum, particle) # Note that size of programs is (n_sections, n_turns+1) print('Momentum : %.5e eV/c' % (ring.momentum[0, 0])) print('Kinetic energy : %.5e eV' % (ring.kin_energy[0, 0])) print('Total energy : %.5e eV' % (ring.energy[0, 0])) print('beta : %.5f' % (ring.beta[0, 0])) print('gamma : %.5f' % (ring.gamma[0, 0])) print('Revolution period : %.5e s' % (ring.t_rev[0])) # In[3]: # Now we define a synchrotron by giving the kinetic energy from blond_common.interfaces.input_parameters.ring import Ring from blond_common.interfaces.beam.beam import Proton
from blond_common.interfaces.input_parameters.ring import Ring from scipy.constants import u, c, e ring_length = 2 * np.pi * 100 # Machine circumference [m] bending_radius = 70.079 # Bending radius [m] bending_field = 1.136487 # Bending field [T] gamma_transition = 6.1 # Transition gamma alpha_0 = 1 / gamma_transition**2. particle_charge = 39 # Particle charge [e] particle_mass = 128.883 * u * c**2. / e # Particle mass [eV/c2] particle = Particle(particle_mass, particle_charge) ring = Ring(ring_length, alpha_0, bending_field, particle, synchronous_data_type='bending field', bending_radius=bending_radius) from blond_common.interfaces.input_parameters.rf_parameters import RFStation harmonic = [21, 28, 169] #voltage = [80e3, 0, 0] # V, h21 Single RF voltage = [6e3, 20e3, 0] # V, h21->h28 batch compression voltage = [0, 16.1e3, 12.4e3] # V, h28->h169 rebucketting phi_rf = [np.pi, np.pi, np.pi] # rad rf_station = RFStation(ring, harmonic, voltage, phi_rf, n_rf=3) from blond_common.rf_functions.potential import rf_voltage_generation
energy_fin = 27e9 # eV delta_E = 1e6 # eV total_energy = np.array([energy_init, energy_init, energy_fin, energy_fin]) # eV particle = Proton() ring_options = RingOptions(interpolation='linear', flat_bottom=0, flat_top=0, t_start=None, t_end=None) ring = Ring(ring_length, alpha_0, (time_array, total_energy), particle, synchronous_data_type='total energy', RingOptions=ring_options) # In[3]: # Note that size of programs is (n_sections, n_turns+1) plt.figure('Ring Programs') plt.clf() plt.plot(time_array, total_energy, 'ro', label='Input') plt.plot(ring.cycle_time, ring.energy[0, :], '.', label='Output', markersize=0.5) plt.xlabel('Time [s]')
# In[2]: # Defining a constant energy # Based on SPS with p+ at flat bottom with Q26 optics from blond_common.interfaces.beam.beam import Proton from blond_common.interfaces.input_parameters.ring import Ring ring_length = 6911.5038 # Machine circumference [m] momentum = 25.92e9 # Momentum [GeV/c] gamma_transition = 22.77422954 # Transition gamma alpha_0 = 1 / gamma_transition**2. particle = Proton() ring = Ring(ring_length, alpha_0, momentum, particle) # In[3]: # Defining the rf program # The program is based on a batch compression and a rebucketting, the rf voltage at the three stages # can be used for the example from blond_common.interfaces.input_parameters.rf_parameters import RFStation harmonic = [4620] voltage = [0.9e6] # V, h21->h28 batch compression phi_rf = [0] # rad rf_station = RFStation(ring, harmonic, voltage, phi_rf)