def init_all(self): n_slices = 100 z_cut = 2.5e-9 * c self.n_slices = n_slices self.z_cut = z_cut from LHC import LHC self.machine = LHC(machine_configuration='Injection', n_segments=43, D_x=0., RF_at='end_of_transverse') # We suppose that all the object that cannot be slice parallelized are at the end of the ring i_end_parallel = len( self.machine.one_turn_map) - 1 #only RF is not parallelizable # split the machine sharing = shs.ShareSegments(i_end_parallel, self.ring_of_CPUs.N_nodes) myid = self.ring_of_CPUs.myid i_start_part, i_end_part = sharing.my_part(myid) self.mypart = self.machine.one_turn_map[i_start_part:i_end_part] if self.ring_of_CPUs.I_am_a_worker: print 'I am id=%d (worker) and my part is %d long' % ( myid, len(self.mypart)) elif self.ring_of_CPUs.I_am_the_master: self.non_parallel_part = self.machine.one_turn_map[i_end_parallel:] print 'I am id=%d (master) and my part is %d long' % ( myid, len(self.mypart))
def init_all(self): n_slices = 100 z_cut = 2.5e-9*c self.n_slices = n_slices self.z_cut = z_cut from LHC import LHC self.machine = LHC(machine_configuration='Injection', n_segments=43, D_x=0., RF_at='end_of_transverse') # We suppose that all the object that cannot be slice parallelized are at the end of the ring i_end_parallel = len(self.machine.one_turn_map)-1 #only RF is not parallelizable # split the machine sharing = shs.ShareSegments(i_end_parallel, self.ring_of_CPUs.N_nodes) myid = self.ring_of_CPUs.myid i_start_part, i_end_part = sharing.my_part(myid) self.mypart = self.machine.one_turn_map[i_start_part:i_end_part] if self.ring_of_CPUs.I_am_a_worker: print 'I am id=%d (worker) and my part is %d long'%(myid, len(self.mypart)) elif self.ring_of_CPUs.I_am_the_master: self.non_parallel_part = self.machine.one_turn_map[i_end_parallel:] print 'I am id=%d (master) and my part is %d long'%(myid, len(self.mypart))
class Simulation(object): def __init__(self): self.N_turns = 128 self.N_buffer_float_size = 500000 self.N_buffer_int_size = 450 def init_all(self): n_slices = 100 z_cut = 2.5e-9*c self.n_slices = n_slices self.z_cut = z_cut from LHC import LHC self.machine = LHC(machine_configuration='Injection', n_segments=43, D_x=0., RF_at='end_of_transverse') # We suppose that all the object that cannot be slice parallelized are at the end of the ring i_end_parallel = len(self.machine.one_turn_map)-1 #only RF is not parallelizable # split the machine sharing = shs.ShareSegments(i_end_parallel, self.ring_of_CPUs.N_nodes) myid = self.ring_of_CPUs.myid i_start_part, i_end_part = sharing.my_part(myid) self.mypart = self.machine.one_turn_map[i_start_part:i_end_part] if self.ring_of_CPUs.I_am_a_worker: print 'I am id=%d (worker) and my part is %d long'%(myid, len(self.mypart)) elif self.ring_of_CPUs.I_am_the_master: self.non_parallel_part = self.machine.one_turn_map[i_end_parallel:] print 'I am id=%d (master) and my part is %d long'%(myid, len(self.mypart)) def init_master(self): # beam parameters epsn_x = 2.5e-6 epsn_y = 3.5e-6 sigma_z = 0.05 intensity = 1e11 macroparticlenumber_track = 50000 # initialization bunch bunch = self.machine.generate_6D_Gaussian_bunch_matched( macroparticlenumber_track, intensity, epsn_x, epsn_y, sigma_z=sigma_z) print 'Bunch initialized.' # initial slicing from PyHEADTAIL.particles.slicing import UniformBinSlicer self.slicer = UniformBinSlicer(n_slices = self.n_slices, z_cuts=(-self.z_cut, self.z_cut)) #slice for the first turn slice_obj_list = bunch.extract_slices(self.slicer) #prepare to save results self.beam_x, self.beam_y, self.beam_z = [], [], [] self.sx, self.sy, self.sz = [], [], [] self.epsx, self.epsy, self.epsz = [], [], [] pieces_to_be_treated = slice_obj_list return pieces_to_be_treated def init_worker(self): pass def treat_piece(self, piece): for ele in self.mypart: ele.track(piece) def finalize_turn_on_master(self, pieces_treated): # re-merge bunch bunch = sum(pieces_treated) #finalize present turn (with non parallel part, e.g. synchrotron motion) for ele in self.non_parallel_part: ele.track(bunch) #save results self.beam_x.append(bunch.mean_x()) self.beam_y.append(bunch.mean_y()) self.beam_z.append(bunch.mean_z()) self.sx.append(bunch.sigma_x()) self.sy.append(bunch.sigma_y()) self.sz.append(bunch.sigma_z()) self.epsx.append(bunch.epsn_x()*1e6) self.epsy.append(bunch.epsn_y()*1e6) self.epsz.append(bunch.epsn_z()) # prepare next turn (re-slice) new_pieces_to_be_treated = bunch.extract_slices(self.slicer) orders_to_pass = [] return orders_to_pass, new_pieces_to_be_treated def execute_orders_from_master(self, orders_from_master): pass def finalize_simulation(self): # save results import PyPARIS.myfilemanager as mfm mfm.dict_to_h5({\ 'beam_x':self.beam_x, 'beam_y':self.beam_y, 'beam_z':self.beam_z, 'sx':self.sx, 'sy':self.sy, 'sz':self.sz, 'epsx':self.epsx, 'epsy':self.epsy, 'epsz':self.epsz}, 'beam_coord.h5') # output plots if False: beam_x = self.beam_x beam_y = self.beam_y beam_z = self.beam_z sx = self.sx sy = self.sy sz = self.sz epsx = self.epsx epsy = self.epsy epsz = self.epsz import pylab as plt plt.figure(2, figsize=(16, 8), tight_layout=True) plt.subplot(2,3,1) plt.plot(beam_x) plt.ylabel('x [m]');plt.xlabel('Turn') plt.gca().ticklabel_format(style='sci', scilimits=(0,0),axis='y') plt.subplot(2,3,2) plt.plot(beam_y) plt.ylabel('y [m]');plt.xlabel('Turn') plt.gca().ticklabel_format(style='sci', scilimits=(0,0),axis='y') plt.subplot(2,3,3) plt.plot(beam_z) plt.ylabel('z [m]');plt.xlabel('Turn') plt.gca().ticklabel_format(style='sci', scilimits=(0,0),axis='y') plt.subplot(2,3,4) plt.plot(np.fft.rfftfreq(len(beam_x), d=1.), np.abs(np.fft.rfft(beam_x))) plt.ylabel('Amplitude');plt.xlabel('Qx') plt.subplot(2,3,5) plt.plot(np.fft.rfftfreq(len(beam_y), d=1.), np.abs(np.fft.rfft(beam_y))) plt.ylabel('Amplitude');plt.xlabel('Qy') plt.subplot(2,3,6) plt.plot(np.fft.rfftfreq(len(beam_z), d=1.), np.abs(np.fft.rfft(beam_z))) plt.xlim(0, 0.1) plt.ylabel('Amplitude');plt.xlabel('Qz') fig, axes = plt.subplots(3, figsize=(16, 8), tight_layout=True) twax = [plt.twinx(ax) for ax in axes] axes[0].plot(sx) twax[0].plot(epsx, '-g') axes[0].set_xlabel('Turns') axes[0].set_ylabel(r'$\sigma_x$') twax[0].set_ylabel(r'$\varepsilon_y$') axes[1].plot(sy) twax[1].plot(epsy, '-g') axes[1].set_xlabel('Turns') axes[1].set_ylabel(r'$\sigma_x$') twax[1].set_ylabel(r'$\varepsilon_y$') axes[2].plot(sz) twax[2].plot(epsz, '-g') axes[2].set_xlabel('Turns') axes[2].set_ylabel(r'$\sigma_x$') twax[2].set_ylabel(r'$\varepsilon_y$') axes[0].grid() axes[1].grid() axes[2].grid() for ax in list(axes)+list(twax): ax.ticklabel_format(useOffset=False, style='sci', scilimits=(0,0),axis='y') plt.show() def piece_to_buffer(self, piece): buf = ch.beam_2_buffer(piece) return buf def buffer_to_piece(self, buf): piece = ch.buffer_2_beam(buf) return piece
def run(intensity, chroma=0, i_oct=0): '''Arguments: - intensity: integer number of charges in beam - chroma: first-order chromaticity Q'_{x,y}, identical for both transverse planes - i_oct: octupole current in A (positive i_oct means LOF = i_oct > 0 and LOD = -i_oct < 0) ''' # BEAM AND MACHINE PARAMETERS # ============================ from LHC import LHC # energy set above will enter get_nonlinear_params p0 assert machine_configuration == 'LHC-injection' machine = LHC(n_segments=1, machine_configuration=machine_configuration, **get_nonlinear_params(chroma=chroma, i_oct=i_oct, p0=0.45e12 * e / c)) # BEAM # ==== epsn_x = 3.e-6 # normalised horizontal emittance epsn_y = 3.e-6 # normalised vertical emittance sigma_z = 1.2e-9 * machine.beta * c / 4. # RMS bunch length in meters bunch = machine.generate_6D_Gaussian_bunch(n_macroparticles, intensity, epsn_x, epsn_y, sigma_z=sigma_z, matched=True) print("\n--> Bunch length and emittance: {:g} m, {:g} eVs.".format( bunch.sigma_z(), bunch.epsn_z())) # CREATE BEAM SLICERS # =================== slicer_for_slicemonitor = UniformBinSlicer(50, z_cuts=(-3 * sigma_z, 3 * sigma_z)) slicer_for_wakefields = UniformBinSlicer( 50, z_cuts=(-3 * sigma_z, 3 * sigma_z), circumference=machine.circumference, h_bunch=machine.h_bunch) print("Slice") # CREATE WAKES # ============ wake_table1 = WakeTable( wakefile, [ 'time', 'dipole_x', 'dipole_y', # 'quadrupole_x', 'quadrupole_y', 'noquadrupole_x', 'noquadrupole_y', # 'dipole_xy', 'dipole_yx', 'nodipole_xy', 'nodipole_yx', ]) wake_field = WakeField(slicer_for_wakefields, wake_table1, mpi=True) # CREATE DAMPER # ============= dampingtime = 50. gain = 2. / dampingtime damper = IdealBunchFeedback(gain) # CREATE MONITORS # =============== try: bucket = machine.longitudinal_map.get_bucket(bunch) except AttributeError: bucket = machine.rfbucket simulation_parameters_dict = { 'gamma': machine.gamma, 'intensity': intensity, 'Qx': machine.Q_x, 'Qy': machine.Q_y, 'Qs': bucket.Q_s, 'beta_x': bunch.beta_Twiss_x(), 'beta_y': bunch.beta_Twiss_y(), 'beta_z': bucket.beta_z, 'epsn_x': bunch.epsn_x(), 'epsn_y': bunch.epsn_y(), 'sigma_z': bunch.sigma_z(), } bunchmonitor = BunchMonitor( outputpath + '/bunchmonitor_{:04d}_chroma={:g}'.format(it, chroma), n_turns, simulation_parameters_dict, write_buffer_to_file_every=512, buffer_size=4096) slicemonitor = SliceMonitor( outputpath + '/slicemonitor_{:04d}_chroma={:g}'.format(it, chroma), n_turns_slicemon, slicer_for_slicemonitor, simulation_parameters_dict, write_buffer_to_file_every=1, buffer_size=n_turns_slicemon) # TRACKING LOOP # ============= # machine.one_turn_map.append(damper) machine.one_turn_map.append(wake_field) # for slice statistics monitoring: s_cnt = 0 monitorswitch = False print('\n--> Begin tracking...\n') # GO!!! for i in range(n_turns): t0 = time.clock() # track the beam around the machine for one turn: machine.track(bunch) ex, ey, ez = bunch.epsn_x(), bunch.epsn_y(), bunch.epsn_z() mx, my, mz = bunch.mean_x(), bunch.mean_y(), bunch.mean_z() # monitor the bunch statistics (once per turn): bunchmonitor.dump(bunch) # if the centroid becomes unstable (>1cm motion) # then monitor the slice statistics: if not monitorswitch: if mx > 1e-2 or my > 1e-2 or i > n_turns - n_turns_slicemon: print("--> Activate slice monitor") monitorswitch = True else: if s_cnt < n_turns_slicemon: slicemonitor.dump(bunch) s_cnt += 1 # stop the tracking as soon as we have not-a-number values: if not all(np.isfinite(c) for c in [ex, ey, ez, mx, my, mz]): print('*** STOPPING SIMULATION: non-finite bunch stats!') break # print status all 1000 turns: if i % 100 == 0: t1 = time.clock() print('Emittances: ({:.3g}, {:.3g}, {:.3g}) ' '& Centroids: ({:.3g}, {:.3g}, {:.3g})' '@ turn {:d}, {:g} ms, {:s}'.format( ex, ey, ez, mx, my, mz, i, (t1 - t0) * 1e3, time.strftime("%d/%m/%Y %H:%M:%S", time.localtime()))) print('\n*** Successfully completed!')
n_turns = 512 * 4 epsn_x = 2.5e-6 epsn_y = 3.5e-6 sigma_z = 0.05 intensity = 1e11 mode = 'smooth' #mode = 'non-smooth' import pickle from LHC import LHC if mode == 'smooth': machine = LHC(machine_configuration='Injection', n_segments=29, D_x=10) elif mode == 'non-smooth': with open('lhc_2015_80cm_optics.pkl') as fid: optics = pickle.load(fid) optics.pop('circumference') machine = LHC(machine_configuration='Injection', optics_mode='non-smooth', V_RF=10e6, **optics) print('Create bunch for optics...') bunch = machine.generate_6D_Gaussian_bunch_matched(macroparticlenumber_optics, intensity, epsn_x, epsn_y,
p0_GeV = 2000. # LHC machine_configuration = '6.5_TeV_collision_tunes' intensity = 1.2e11 epsn_x = 2.5e-6 epsn_y = 2.5e-6 sigma_z = 7e-2 n_macroparticles = 1000000 sparse_solver = 'PyKLU' machine = LHC(machine_configuration=machine_configuration, optics_mode='smooth', n_segments=1, p0=p0_GeV * 1e9 * e / c) # generate beam bunch = machine.generate_6D_Gaussian_bunch(n_macroparticles=n_macroparticles, intensity=intensity, epsn_x=epsn_x, epsn_y=epsn_y, sigma_z=sigma_z) # Single grid parameters Dh_single = 0.5 * bunch.sigma_x() #.3 # Bassetti-Erskine parameters Dh_BE = 0.3 * bunch.sigma_x()
class Simulation(object): def __init__(self): self.N_turns = 2 def init_all(self): n_slices = 100 z_cut = 2.5e-9 * c self.n_slices = n_slices self.z_cut = z_cut n_segments = 70 from LHC import LHC self.machine = LHC(machine_configuration='Injection', n_segments=n_segments, D_x=0., RF_at='end_of_transverse') # We suppose that all the object that cannot be slice parallelized are at the end of the ring i_end_parallel = len( self.machine.one_turn_map) - 1 #only RF is not parallelizable # split the machine sharing = shs.ShareSegments(i_end_parallel, self.ring_of_CPUs.N_nodes) myid = self.ring_of_CPUs.myid i_start_part, i_end_part = sharing.my_part(myid) self.mypart = self.machine.one_turn_map[i_start_part:i_end_part] if self.ring_of_CPUs.I_am_a_worker: print 'I am id=%d (worker) and my part is %d long' % ( myid, len(self.mypart)) elif self.ring_of_CPUs.I_am_the_master: self.non_parallel_part = self.machine.one_turn_map[i_end_parallel:] print 'I am id=%d (master) and my part is %d long' % ( myid, len(self.mypart)) # config e-cloud chamb_type = 'polyg' x_aper = 2.300000e-02 y_aper = 1.800000e-02 filename_chm = '../pyecloud_config/LHC_chm_ver.mat' B_multip_per_eV = [1.190000e-12] B_multip_per_eV = np.array(B_multip_per_eV) fraction_device = 0.65 intensity = 1.150000e+11 epsn_x = 2.5e-6 epsn_y = 2.5e-6 init_unif_edens_flag = 1 init_unif_edens = 9.000000e+11 N_MP_ele_init = 100000 N_mp_max = N_MP_ele_init * 4. Dh_sc = .2e-3 nel_mp_ref_0 = init_unif_edens * 4 * x_aper * y_aper / N_MP_ele_init import PyECLOUD.PyEC4PyHT as PyEC4PyHT ecloud = PyEC4PyHT.Ecloud( L_ecloud=self.machine.circumference / n_segments, slicer=None, Dt_ref=10e-12, pyecl_input_folder='../pyecloud_config', chamb_type=chamb_type, x_aper=x_aper, y_aper=y_aper, filename_chm=filename_chm, Dh_sc=Dh_sc, init_unif_edens_flag=init_unif_edens_flag, init_unif_edens=init_unif_edens, N_mp_max=N_mp_max, nel_mp_ref_0=nel_mp_ref_0, B_multip=B_multip_per_eV * self.machine.p0 / e * c, slice_by_slice_mode=True) my_new_part = [] self.my_list_eclouds = [] for ele in self.mypart: my_new_part.append(ele) if ele in self.machine.transverse_map: ecloud_new = ecloud.generate_twin_ecloud_with_shared_space_charge( ) my_new_part.append(ecloud_new) self.my_list_eclouds.append(ecloud_new) self.mypart = my_new_part def init_master(self): # beam parameters epsn_x = 2.5e-6 epsn_y = 3.5e-6 sigma_z = 0.05 intensity = 1e11 macroparticlenumber_track = 50000 # initialization bunch bunch = self.machine.generate_6D_Gaussian_bunch_matched( macroparticlenumber_track, intensity, epsn_x, epsn_y, sigma_z=sigma_z) print 'Bunch initialized.' # initial slicing from PyHEADTAIL.particles.slicing import UniformBinSlicer self.slicer = UniformBinSlicer(n_slices=self.n_slices, z_cuts=(-self.z_cut, self.z_cut)) #slice for the first turn slice_obj_list = bunch.extract_slices(self.slicer) #prepare to save results self.beam_x, self.beam_y, self.beam_z = [], [], [] self.sx, self.sy, self.sz = [], [], [] self.epsx, self.epsy, self.epsz = [], [], [] pieces_to_be_treated = slice_obj_list return pieces_to_be_treated def init_worker(self): pass def treat_piece(self, piece): for ele in self.mypart: ele.track(piece) def finalize_turn_on_master(self, pieces_treated): # re-merge bunch bunch = sum(pieces_treated) #finalize present turn (with non parallel part, e.g. synchrotron motion) for ele in self.non_parallel_part: ele.track(bunch) #csave results self.beam_x.append(bunch.mean_x()) self.beam_y.append(bunch.mean_y()) self.beam_z.append(bunch.mean_z()) self.sx.append(bunch.sigma_x()) self.sy.append(bunch.sigma_y()) self.sz.append(bunch.sigma_z()) self.epsx.append(bunch.epsn_x() * 1e6) self.epsy.append(bunch.epsn_y() * 1e6) self.epsz.append(bunch.epsn_z()) # prepare next turn (re-slice) new_pieces_to_be_treated = bunch.extract_slices(self.slicer) orders_to_pass = ['reset_clouds'] return orders_to_pass, new_pieces_to_be_treated def execute_orders_from_master(self, orders_from_master): if 'reset_clouds' in orders_from_master: for ec in self.my_list_eclouds: ec.finalize_and_reinitialize() def finalize_simulation(self): # save results import myfilemanager as mfm mfm.save_dict_to_h5('beam_coord.h5',{\ 'beam_x':self.beam_x, 'beam_y':self.beam_y, 'beam_z':self.beam_z, 'sx':self.sx, 'sy':self.sy, 'sz':self.sz, 'epsx':self.epsx, 'epsy':self.epsy, 'epsz':self.epsz}) # output plots if False: beam_x = self.beam_x beam_y = self.beam_y beam_z = self.beam_z sx = self.sx sy = self.sy sz = self.sz epsx = self.epsx epsy = self.epsy epsz = self.epsz import pylab as plt plt.figure(2, figsize=(16, 8), tight_layout=True) plt.subplot(2, 3, 1) plt.plot(beam_x) plt.ylabel('x [m]') plt.xlabel('Turn') plt.gca().ticklabel_format(style='sci', scilimits=(0, 0), axis='y') plt.subplot(2, 3, 2) plt.plot(beam_y) plt.ylabel('y [m]') plt.xlabel('Turn') plt.gca().ticklabel_format(style='sci', scilimits=(0, 0), axis='y') plt.subplot(2, 3, 3) plt.plot(beam_z) plt.ylabel('z [m]') plt.xlabel('Turn') plt.gca().ticklabel_format(style='sci', scilimits=(0, 0), axis='y') plt.subplot(2, 3, 4) plt.plot(np.fft.rfftfreq(len(beam_x), d=1.), np.abs(np.fft.rfft(beam_x))) plt.ylabel('Amplitude') plt.xlabel('Qx') plt.subplot(2, 3, 5) plt.plot(np.fft.rfftfreq(len(beam_y), d=1.), np.abs(np.fft.rfft(beam_y))) plt.ylabel('Amplitude') plt.xlabel('Qy') plt.subplot(2, 3, 6) plt.plot(np.fft.rfftfreq(len(beam_z), d=1.), np.abs(np.fft.rfft(beam_z))) plt.xlim(0, 0.1) plt.ylabel('Amplitude') plt.xlabel('Qz') fig, axes = plt.subplots(3, figsize=(16, 8), tight_layout=True) twax = [plt.twinx(ax) for ax in axes] axes[0].plot(sx) twax[0].plot(epsx, '-g') axes[0].set_xlabel('Turns') axes[0].set_ylabel(r'$\sigma_x$') twax[0].set_ylabel(r'$\varepsilon_y$') axes[1].plot(sy) twax[1].plot(epsy, '-g') axes[1].set_xlabel('Turns') axes[1].set_ylabel(r'$\sigma_x$') twax[1].set_ylabel(r'$\varepsilon_y$') axes[2].plot(sz) twax[2].plot(epsz, '-g') axes[2].set_xlabel('Turns') axes[2].set_ylabel(r'$\sigma_x$') twax[2].set_ylabel(r'$\varepsilon_y$') axes[0].grid() axes[1].grid() axes[2].grid() for ax in list(axes) + list(twax): ax.ticklabel_format(useOffset=False, style='sci', scilimits=(0, 0), axis='y') plt.show() def piece_to_buffer(self, piece): buf = ch.beam_2_buffer(piece) return buf def buffer_to_piece(self, buf): piece = ch.buffer_2_beam(buf) return piece
def init_all(self): n_slices = 100 z_cut = 2.5e-9 * c self.n_slices = n_slices self.z_cut = z_cut n_segments = 70 from LHC import LHC self.machine = LHC(machine_configuration='Injection', n_segments=n_segments, D_x=0., RF_at='end_of_transverse') # We suppose that all the object that cannot be slice parallelized are at the end of the ring i_end_parallel = len( self.machine.one_turn_map) - 1 #only RF is not parallelizable # split the machine sharing = shs.ShareSegments(i_end_parallel, self.ring_of_CPUs.N_nodes) myid = self.ring_of_CPUs.myid i_start_part, i_end_part = sharing.my_part(myid) self.mypart = self.machine.one_turn_map[i_start_part:i_end_part] if self.ring_of_CPUs.I_am_a_worker: print 'I am id=%d (worker) and my part is %d long' % ( myid, len(self.mypart)) elif self.ring_of_CPUs.I_am_the_master: self.non_parallel_part = self.machine.one_turn_map[i_end_parallel:] print 'I am id=%d (master) and my part is %d long' % ( myid, len(self.mypart)) # config e-cloud chamb_type = 'polyg' x_aper = 2.300000e-02 y_aper = 1.800000e-02 filename_chm = '../pyecloud_config/LHC_chm_ver.mat' B_multip_per_eV = [1.190000e-12] B_multip_per_eV = np.array(B_multip_per_eV) fraction_device = 0.65 intensity = 1.150000e+11 epsn_x = 2.5e-6 epsn_y = 2.5e-6 init_unif_edens_flag = 1 init_unif_edens = 9.000000e+11 N_MP_ele_init = 100000 N_mp_max = N_MP_ele_init * 4. Dh_sc = .2e-3 nel_mp_ref_0 = init_unif_edens * 4 * x_aper * y_aper / N_MP_ele_init import PyECLOUD.PyEC4PyHT as PyEC4PyHT ecloud = PyEC4PyHT.Ecloud( L_ecloud=self.machine.circumference / n_segments, slicer=None, Dt_ref=10e-12, pyecl_input_folder='../pyecloud_config', chamb_type=chamb_type, x_aper=x_aper, y_aper=y_aper, filename_chm=filename_chm, Dh_sc=Dh_sc, init_unif_edens_flag=init_unif_edens_flag, init_unif_edens=init_unif_edens, N_mp_max=N_mp_max, nel_mp_ref_0=nel_mp_ref_0, B_multip=B_multip_per_eV * self.machine.p0 / e * c, slice_by_slice_mode=True) my_new_part = [] self.my_list_eclouds = [] for ele in self.mypart: my_new_part.append(ele) if ele in self.machine.transverse_map: ecloud_new = ecloud.generate_twin_ecloud_with_shared_space_charge( ) my_new_part.append(ecloud_new) self.my_list_eclouds.append(ecloud_new) self.mypart = my_new_part
def run(intensity, chroma=0, i_oct=0): '''Arguments: - intensity: integer number of charges in beam - chroma: first-order chromaticity Q'_{x,y}, identical for both transverse planes - i_oct: octupole current in A (positive i_oct means LOF = i_oct > 0 and LOD = -i_oct < 0) ''' # BEAM AND MACHINE PARAMETERS # ============================ from LHC import LHC # energy set above will enter get_nonlinear_params p0 assert machine_configuration == 'LHC-injection' machine = LHC(n_segments=1, machine_configuration=machine_configuration, **get_nonlinear_params(chroma=chroma, i_oct=i_oct, p0=0.45e12 * e / c)) # BEAM # ==== #print(filling_scheme) epsn_x = 3.e-6 # normalised horizontal emittance epsn_y = 3.e-6 # normalised vertical emittance sigma_z = 1.2e-9 * machine.beta * c / 4. # RMS bunch length in meters beam = machine.generate_6D_Gaussian_bunch(n_macroparticles, intensity, epsn_x, epsn_y, sigma_z=sigma_z, matched=True, filling_scheme=filling_scheme) bunch_list = beam.split_to_views() for b in bunch_list: if b.bucket_id[0] < batch_length: b.x += 1e-3 b.y += 1e-3 bunch = bunch_list[0] print("\n--> Bunch length and emittance: {:g} m, {:g} eVs.".format( bunch.sigma_z(), bunch.epsn_z())) # CREATE BEAM SLICERS # =================== slicer_for_slicemonitor = UniformBinSlicer(50, z_cuts=(-3 * sigma_z, 3 * sigma_z)) slicer_for_wakefields = UniformBinSlicer( 50, z_cuts=(-3 * sigma_z, 3 * sigma_z), circumference=machine.circumference, h_bunch=machine.h_bunch) # CREATE WAKES # ============ wake_table1 = WakeTable( wakefile, [ 'time', 'dipole_x', 'dipole_y', # 'quadrupole_x', 'quadrupole_y', 'noquadrupole_x', 'noquadrupole_y', # 'dipole_xy', 'dipole_yx', 'nodipole_xy', 'nodipole_yx', ]) wake_field = WakeField(slicer_for_wakefields, wake_table1, mpi='linear_mpi_full_ring_fft') # CREATE DAMPER # ============= from PyHEADTAIL_feedback.feedback import OneboxFeedback from PyHEADTAIL_feedback.processors.multiplication import ChargeWeighter from PyHEADTAIL_feedback.processors.register import TurnFIRFilter from PyHEADTAIL_feedback.processors.convolution import Lowpass, FIRFilter from PyHEADTAIL_feedback.processors.resampling import DAC, HarmonicADC, BackToOriginalBins, Upsampler from MD4063_filter_functions import calculate_coefficients_3_tap, calculate_hilbert_notch_coefficients # from PyHEADTAIL_feedback.processors.addition import NoiseGenerator dampingtime = 20. gain = 2. / dampingtime lowpass100kHz = [ 1703, 1169, 1550, 1998, 2517, 3108, 3773, 4513, 5328, 6217, 7174, 8198, 9282, 10417, 11598, 12813, 14052, 15304, 16555, 17793, 19005, 20176, 21294, 22345, 23315, 24193, 24969, 25631, 26171, 26583, 26860, 27000, 27000, 26860, 26583, 26171, 25631, 24969, 24193, 23315, 22345, 21294, 20176, 19005, 17793, 16555, 15304, 14052, 12813, 11598, 10417, 9282, 8198, 7174, 6217, 5328, 4513, 3773, 3108, 2517, 1998, 1550, 1169, 1703 ] lowpassEnhanced = [ 490, 177, -478, -820, -370, 573, 1065, 428, -909, -1632, -799, 1015, 2015, 901, -1592, -3053, -1675, 1642, 3670, 1841, -2828, -6010, -3929, 2459, 7233, 4322, -6384, -17305, -18296, -5077, 16097, 32000, 32000, 16097, -5077, -18296, -17305, -6384, 4322, 7233, 2459, -3929, -6010, -2828, 1841, 3670, 1642, -1675, -3053, -1592, 901, 2015, 1015, -799, -1632, -909, 428, 1065, 573, -370, -820, -478, 177, 490 ] lowpass20MHz = [ 38, 118, 182, 112, -133, -389, -385, -45, 318, 257, -259, -665, -361, 473, 877, 180, -996, -1187, 162, 1670, 1329, -954, -2648, -1219, 2427, 4007, 419, -5623, -6590, 2893, 19575, 32700, 32700, 19575, 2893, -6590, -5623, 419, 4007, 2427, -1219, -2648, -954, 1329, 1670, 162, -1187, -996, 180, 877, 473, -361, -665, -259, 257, 318, -45, -385, -389, -133, 112, 182, 118, 38 ] phaseEqualizer = [ 2, 4, 7, 10, 12, 16, 19, 22, 27, 31, 36, 42, 49, 57, 67, 77, 90, 104, 121, 141, 164, 191, 223, 261, 305, 358, 422, 498, 589, 700, 836, 1004, 1215, 1483, 1832, 2301, 2956, 3944, 5600, 9184, 25000, -16746, -4256, -2056, -1195, -769, -523, -372, -271, -202, -153, -118, -91, -71, -56, -44, -34, -27, -20, -15, -11, -7, -4, -1 ] FIR_phase_filter = np.loadtxt( './injection_error_input_data/FIR_Phase_40MSPS.csv') FIR_phase_filter = np.array(phaseEqualizer) FIR_phase_filter = FIR_phase_filter / float(np.sum(FIR_phase_filter)) FIR_gain_filter = np.array(lowpass20MHz) FIR_gain_filter = FIR_gain_filter / float(np.sum(lowpass20MHz)) # Cut-off frequency of the kicker system fc = 1.0e6 ADC_bits = 16 ADC_range = (-1e-3, 1e-3) # signal processing delay in turns before the first measurements is applied delay = 1 extra_adc_bins = 10 # betatron phase advance between the pickup and the kicker. The value 0.25 # corresponds to the 90 deg phase change from from the pickup measurements # in x-plane to correction kicks in xp-plane. additional_phase = 0.25 # Kicker-to-pickup phase advance 0 deg # additional_phase = 0. # Kicker-to-pickup phase advance 90 deg f_RF = 1. / (machine.circumference / c / (float(machine.h_RF))) # turn_phase_filter_x = calculate_hilbert_notch_coefficients(machine.Q_x, delay, additional_phase) # turn_phase_filter_y = calculate_hilbert_notch_coefficients(machine.Q_y, delay, additional_phase) turn_phase_filter_x = calculate_coefficients_3_tap(machine.Q_x, delay, additional_phase) turn_phase_filter_y = calculate_coefficients_3_tap(machine.Q_y, delay, additional_phase) print('f_RF: ' + str(f_RF)) processors_detailed_x = [ Bypass(), ChargeWeighter(normalization='segment_average'), # NoiseGenerator(RMS_noise_level, debug=False), HarmonicADC(1 * f_RF / 10., ADC_bits, ADC_range, n_extras=extra_adc_bins), TurnFIRFilter(turn_phase_filter_x, machine.Q_x, delay=delay), FIRFilter(FIR_phase_filter, zero_tap=40), Upsampler(3, [1.5, 1.5, 0]), FIRFilter(FIR_gain_filter, zero_tap=34), DAC(ADC_bits, ADC_range), Lowpass(fc, f_cutoff_2nd=10 * fc), BackToOriginalBins(), ] processors_detailed_y = [ Bypass(), ChargeWeighter(normalization='segment_average'), # NoiseGenerator(RMS_noise_level, debug=False), HarmonicADC(1 * f_RF / 10., ADC_bits, ADC_range, n_extras=extra_adc_bins), TurnFIRFilter(turn_phase_filter_y, machine.Q_y, delay=delay), FIRFilter(FIR_phase_filter, zero_tap=40), Upsampler(3, [1.5, 1.5, 0]), FIRFilter(FIR_gain_filter, zero_tap=34), DAC(ADC_bits, ADC_range), Lowpass(fc, f_cutoff_2nd=10 * fc), BackToOriginalBins(), ] # Kicker-to-pickup phase advance 0 deg damper = OneboxFeedback(gain, slicer_for_wakefields, processors_detailed_x, processors_detailed_y, pickup_axis='displacement', kicker_axis='divergence', mpi=True, beta_x=machine.beta_x, beta_y=machine.beta_y) # # Kicker-to-pickup phase advance 90 deg # damper = OneboxFeedback(gain,slicer_for_wakefields, # processors_detailed_x,processors_detailed_y, mpi=True, # pickup_axis='displacement', kicker_axis='displacement') # CREATE MONITORS # =============== try: bucket = machine.longitudinal_map.get_bucket(bunch) except AttributeError: bucket = machine.rfbucket simulation_parameters_dict = { 'gamma': machine.gamma, 'intensity': intensity, 'Qx': machine.Q_x, 'Qy': machine.Q_y, 'Qs': bucket.Q_s, 'beta_x': bunch.beta_Twiss_x(), 'beta_y': bunch.beta_Twiss_y(), 'beta_z': bucket.beta_z, 'epsn_x': bunch.epsn_x(), 'epsn_y': bunch.epsn_y(), 'sigma_z': bunch.sigma_z(), } bunchmonitor = BunchMonitor( outputpath + '/bunchmonitor_{:04d}_chroma={:g}'.format(it, chroma), n_turns, simulation_parameters_dict, write_buffer_to_file_every=512, buffer_size=4096, mpi=True, filling_scheme=filling_scheme) # slicemonitor = SliceMonitor( # outputpath+'/slicemonitor_{:04d}_chroma={:g}_bunch_{:04d}'.format(it, chroma, bunch.bucket_id[0]), # n_turns_slicemon, # slicer_for_slicemonitor, simulation_parameters_dict, # write_buffer_to_file_every=1, buffer_size=n_turns_slicemon) # TRACKING LOOP # ============= machine.one_turn_map.append(damper) machine.one_turn_map.append(wake_field) # for slice statistics monitoring: s_cnt = 0 monitorswitch = False print('\n--> Begin tracking...\n') # GO!!! for i in range(n_turns): t0 = time.clock() # track the beam around the machine for one turn: machine.track(beam) bunch_list = beam.split_to_views() bunch = bunch_list[0] ex, ey, ez = bunch.epsn_x(), bunch.epsn_y(), bunch.epsn_z() mx, my, mz = bunch.mean_x(), bunch.mean_y(), bunch.mean_z() # monitor the bunch statistics (once per turn): bunchmonitor.dump(beam) # if the centroid becomes unstable (>1cm motion) # then monitor the slice statistics: if not monitorswitch: if mx > 1e-2 or my > 1e-2 or i > n_turns - n_turns_slicemon: print("--> Activate slice monitor") monitorswitch = True else: if s_cnt < n_turns_slicemon: # slicemonitor.dump(bunch) s_cnt += 1 # stop the tracking as soon as we have not-a-number values: if not all(np.isfinite(c) for c in [ex, ey, ez, mx, my, mz]): print('*** STOPPING SIMULATION: non-finite bunch stats!') break # print status all 1000 turns: if i % 100 == 0: t1 = time.clock() print('Emittances: ({:.3g}, {:.3g}, {:.3g}) ' '& Centroids: ({:.3g}, {:.3g}, {:.3g})' '@ turn {:d}, {:g} ms, {:s}'.format( ex, ey, ez, mx, my, mz, i, (t1 - t0) * 1e3, time.strftime("%d/%m/%Y %H:%M:%S", time.localtime()))) print('\n*** Successfully completed!')
from LHC import LHC import matplotlib.pyplot as plt import numpy as np import Damper from scipy.constants import e, m_p, c print("Generating machine") machine = LHC(machine_configuration='6.5_TeV_collision_tunes', n_segments=29, D_x=10) print("Machine generated") damper = Damper.Damper(machine) machine.one_turn_map.append(damper.damper) macroparticlenumber_track = 50000 intensity = 1e11 chroma = 0. epsn_x = 2.5e-6 epsn_y = 3.5e-6 sigma_z = 0.05 bunch = machine.generate_6D_Gaussian_bunch_matched(macroparticlenumber_track, intensity, epsn_x, epsn_y, sigma_z=sigma_z) n_turns = 512 beam_x = []
n_turns = 512*4 epsn_x = 2.5e-6 epsn_y = 3.5e-6 sigma_z = 0.05 intensity = 1e11 #mode = 'smooth' mode = 'non-smooth' import pickle from LHC import LHC if mode == 'smooth': machine = LHC(machine_configuration='Injection', n_segments=29, D_x=10) elif mode == 'non-smooth': with open('lhc_2015_80cm_optics.pkl') as fid: optics = pickle.load(fid) optics.pop('circumference') machine = LHC(machine_configuration='Injection', optics_mode = 'non-smooth', V_RF=10e6, **optics) print 'Create bunch for optics...' bunch = machine.generate_6D_Gaussian_bunch_matched( macroparticlenumber_optics, intensity, epsn_x, epsn_y, sigma_z=sigma_z) print 'Done.' bunch.x += 10. bunch.y += 20. bunch.z += .020
if nDvar <= 3: nCons = 1 # Tell DOT how many contraint equations are present else: nCons = 2 # Tell DOT how many contraint equations are present NEWITR = 0 # Set the current iteration to zero JWRITE = 21 # File number to write iteration history to. IWRITE = 20 # File number for printed output FDCH = 0.001 FDCHM = 0.0001 # // Obtain 10 different design points (starting points) from LHC function from LHC import LHC s = 10 #number of different starting points sp, cl, cu = LHC(nDvar, s) # // # ---------------------------------------------------------------------------------------------------------------- # In case more than one algorithm needs to be tested, but the same starting points. Unindent the following lines and # manually add the starting points from the "starting_points.txt" file. This is to be done before the second algorithm # is started. During the first, leave the file as is and for the 2nd, unindent the lines below and follow the steps # set out below. # NB !!!! - Remember to indent lines 173-175 # - Change the algorithm type in line 273 # - In the "graphs.py" file unindent the lines explained there, only just before the second algorithm's # optimisation is started # - Change the lines as explained in "File_paths.py" # sp = nm.empty([10,3])
y_aper = 25e-3 Dh_single = 0.5e-3 #~ # machine parameters optics_mode = 'smooth' n_segments = 1 # beam parameters n_macroparticles = 1000000 #LHC machine_configuration = '6.5_TeV_collision_tunes' intensity = 1.2e11 epsn_x = .5e-6 epsn_y = 3e-6 sigma_z = 7e-2 machine = LHC(machine_configuration=machine_configuration, optics_mode=optics_mode, n_segments=n_segments) # build chamber chamber = ell.ellip_cham_geom_object(x_aper=x_aper, y_aper=y_aper) Vx, Vy = chamber.points_on_boundary(N_points=200) # generate beam for singlegrid bunch = machine.generate_6D_Gaussian_bunch(n_macroparticles=n_macroparticles, intensity=intensity, epsn_x=epsn_x, epsn_y=epsn_y, sigma_z=sigma_z) # generate beam for state1 bunch1 = machine.generate_6D_Gaussian_bunch(n_macroparticles=n_macroparticles,
class Simulation(object): def __init__(self): self.N_turns = 2 def init_all(self): n_slices = 100 z_cut = 2.5e-9*c self.n_slices = n_slices self.z_cut = z_cut n_segments=70 from LHC import LHC self.machine = LHC(machine_configuration='Injection', n_segments=n_segments, D_x=0., RF_at='end_of_transverse') # We suppose that all the object that cannot be slice parallelized are at the end of the ring i_end_parallel = len(self.machine.one_turn_map)-1 #only RF is not parallelizable # split the machine sharing = shs.ShareSegments(i_end_parallel, self.ring_of_CPUs.N_nodes) myid = self.ring_of_CPUs.myid i_start_part, i_end_part = sharing.my_part(myid) self.mypart = self.machine.one_turn_map[i_start_part:i_end_part] if self.ring_of_CPUs.I_am_a_worker: print 'I am id=%d (worker) and my part is %d long'%(myid, len(self.mypart)) elif self.ring_of_CPUs.I_am_the_master: self.non_parallel_part = self.machine.one_turn_map[i_end_parallel:] print 'I am id=%d (master) and my part is %d long'%(myid, len(self.mypart)) # config e-cloud chamb_type = 'polyg' x_aper = 2.300000e-02 y_aper = 1.800000e-02 filename_chm = '../pyecloud_config/LHC_chm_ver.mat' B_multip_per_eV = [1.190000e-12] B_multip_per_eV = np.array(B_multip_per_eV) fraction_device = 0.65 intensity = 1.150000e+11 epsn_x = 2.5e-6 epsn_y = 2.5e-6 init_unif_edens_flag = 1 init_unif_edens = 9.000000e+11 N_MP_ele_init = 100000 N_mp_max = N_MP_ele_init*4. Dh_sc = .2e-3 nel_mp_ref_0 = init_unif_edens*4*x_aper*y_aper/N_MP_ele_init import PyECLOUD.PyEC4PyHT as PyEC4PyHT ecloud = PyEC4PyHT.Ecloud(L_ecloud=self.machine.circumference/n_segments, slicer=None, Dt_ref=10e-12, pyecl_input_folder='../pyecloud_config', chamb_type = chamb_type, x_aper=x_aper, y_aper=y_aper, filename_chm=filename_chm, Dh_sc=Dh_sc, init_unif_edens_flag=init_unif_edens_flag, init_unif_edens=init_unif_edens, N_mp_max=N_mp_max, nel_mp_ref_0=nel_mp_ref_0, B_multip=B_multip_per_eV*self.machine.p0/e*c, slice_by_slice_mode=True) my_new_part = [] self.my_list_eclouds = [] for ele in self.mypart: my_new_part.append(ele) if ele in self.machine.transverse_map: ecloud_new = ecloud.generate_twin_ecloud_with_shared_space_charge() my_new_part.append(ecloud_new) self.my_list_eclouds.append(ecloud_new) self.mypart = my_new_part def init_master(self): # beam parameters epsn_x = 2.5e-6 epsn_y = 3.5e-6 sigma_z = 0.05 intensity = 1e11 macroparticlenumber_track = 50000 # initialization bunch bunch = self.machine.generate_6D_Gaussian_bunch_matched( macroparticlenumber_track, intensity, epsn_x, epsn_y, sigma_z=sigma_z) print 'Bunch initialized.' # initial slicing from PyHEADTAIL.particles.slicing import UniformBinSlicer self.slicer = UniformBinSlicer(n_slices = self.n_slices, z_cuts=(-self.z_cut, self.z_cut)) #slice for the first turn slice_obj_list = bunch.extract_slices(self.slicer) #prepare to save results self.beam_x, self.beam_y, self.beam_z = [], [], [] self.sx, self.sy, self.sz = [], [], [] self.epsx, self.epsy, self.epsz = [], [], [] pieces_to_be_treated = slice_obj_list return pieces_to_be_treated def init_worker(self): pass def treat_piece(self, piece): for ele in self.mypart: ele.track(piece) def finalize_turn_on_master(self, pieces_treated): # re-merge bunch bunch = sum(pieces_treated) #finalize present turn (with non parallel part, e.g. synchrotron motion) for ele in self.non_parallel_part: ele.track(bunch) #csave results self.beam_x.append(bunch.mean_x()) self.beam_y.append(bunch.mean_y()) self.beam_z.append(bunch.mean_z()) self.sx.append(bunch.sigma_x()) self.sy.append(bunch.sigma_y()) self.sz.append(bunch.sigma_z()) self.epsx.append(bunch.epsn_x()*1e6) self.epsy.append(bunch.epsn_y()*1e6) self.epsz.append(bunch.epsn_z()) # prepare next turn (re-slice) new_pieces_to_be_treated = bunch.extract_slices(self.slicer) orders_to_pass = ['reset_clouds'] return orders_to_pass, new_pieces_to_be_treated def execute_orders_from_master(self, orders_from_master): if 'reset_clouds' in orders_from_master: for ec in self.my_list_eclouds: ec.finalize_and_reinitialize() def finalize_simulation(self): # save results import myfilemanager as mfm mfm.save_dict_to_h5('beam_coord.h5',{\ 'beam_x':self.beam_x, 'beam_y':self.beam_y, 'beam_z':self.beam_z, 'sx':self.sx, 'sy':self.sy, 'sz':self.sz, 'epsx':self.epsx, 'epsy':self.epsy, 'epsz':self.epsz}) # output plots if False: beam_x = self.beam_x beam_y = self.beam_y beam_z = self.beam_z sx = self.sx sy = self.sy sz = self.sz epsx = self.epsx epsy = self.epsy epsz = self.epsz import pylab as plt plt.figure(2, figsize=(16, 8), tight_layout=True) plt.subplot(2,3,1) plt.plot(beam_x) plt.ylabel('x [m]');plt.xlabel('Turn') plt.gca().ticklabel_format(style='sci', scilimits=(0,0),axis='y') plt.subplot(2,3,2) plt.plot(beam_y) plt.ylabel('y [m]');plt.xlabel('Turn') plt.gca().ticklabel_format(style='sci', scilimits=(0,0),axis='y') plt.subplot(2,3,3) plt.plot(beam_z) plt.ylabel('z [m]');plt.xlabel('Turn') plt.gca().ticklabel_format(style='sci', scilimits=(0,0),axis='y') plt.subplot(2,3,4) plt.plot(np.fft.rfftfreq(len(beam_x), d=1.), np.abs(np.fft.rfft(beam_x))) plt.ylabel('Amplitude');plt.xlabel('Qx') plt.subplot(2,3,5) plt.plot(np.fft.rfftfreq(len(beam_y), d=1.), np.abs(np.fft.rfft(beam_y))) plt.ylabel('Amplitude');plt.xlabel('Qy') plt.subplot(2,3,6) plt.plot(np.fft.rfftfreq(len(beam_z), d=1.), np.abs(np.fft.rfft(beam_z))) plt.xlim(0, 0.1) plt.ylabel('Amplitude');plt.xlabel('Qz') fig, axes = plt.subplots(3, figsize=(16, 8), tight_layout=True) twax = [plt.twinx(ax) for ax in axes] axes[0].plot(sx) twax[0].plot(epsx, '-g') axes[0].set_xlabel('Turns') axes[0].set_ylabel(r'$\sigma_x$') twax[0].set_ylabel(r'$\varepsilon_y$') axes[1].plot(sy) twax[1].plot(epsy, '-g') axes[1].set_xlabel('Turns') axes[1].set_ylabel(r'$\sigma_x$') twax[1].set_ylabel(r'$\varepsilon_y$') axes[2].plot(sz) twax[2].plot(epsz, '-g') axes[2].set_xlabel('Turns') axes[2].set_ylabel(r'$\sigma_x$') twax[2].set_ylabel(r'$\varepsilon_y$') axes[0].grid() axes[1].grid() axes[2].grid() for ax in list(axes)+list(twax): ax.ticklabel_format(useOffset=False, style='sci', scilimits=(0,0),axis='y') plt.show() def piece_to_buffer(self, piece): buf = ch.beam_2_buffer(piece) return buf def buffer_to_piece(self, buf): piece = ch.buffer_2_beam(buf) return piece
def init_all(self): n_slices = 100 z_cut = 2.5e-9*c self.n_slices = n_slices self.z_cut = z_cut n_segments=70 from LHC import LHC self.machine = LHC(machine_configuration='Injection', n_segments=n_segments, D_x=0., RF_at='end_of_transverse') # We suppose that all the object that cannot be slice parallelized are at the end of the ring i_end_parallel = len(self.machine.one_turn_map)-1 #only RF is not parallelizable # split the machine sharing = shs.ShareSegments(i_end_parallel, self.ring_of_CPUs.N_nodes) myid = self.ring_of_CPUs.myid i_start_part, i_end_part = sharing.my_part(myid) self.mypart = self.machine.one_turn_map[i_start_part:i_end_part] if self.ring_of_CPUs.I_am_a_worker: print 'I am id=%d (worker) and my part is %d long'%(myid, len(self.mypart)) elif self.ring_of_CPUs.I_am_the_master: self.non_parallel_part = self.machine.one_turn_map[i_end_parallel:] print 'I am id=%d (master) and my part is %d long'%(myid, len(self.mypart)) # config e-cloud chamb_type = 'polyg' x_aper = 2.300000e-02 y_aper = 1.800000e-02 filename_chm = '../pyecloud_config/LHC_chm_ver.mat' B_multip_per_eV = [1.190000e-12] B_multip_per_eV = np.array(B_multip_per_eV) fraction_device = 0.65 intensity = 1.150000e+11 epsn_x = 2.5e-6 epsn_y = 2.5e-6 init_unif_edens_flag = 1 init_unif_edens = 9.000000e+11 N_MP_ele_init = 100000 N_mp_max = N_MP_ele_init*4. Dh_sc = .2e-3 nel_mp_ref_0 = init_unif_edens*4*x_aper*y_aper/N_MP_ele_init import PyECLOUD.PyEC4PyHT as PyEC4PyHT ecloud = PyEC4PyHT.Ecloud(L_ecloud=self.machine.circumference/n_segments, slicer=None, Dt_ref=10e-12, pyecl_input_folder='../pyecloud_config', chamb_type = chamb_type, x_aper=x_aper, y_aper=y_aper, filename_chm=filename_chm, Dh_sc=Dh_sc, init_unif_edens_flag=init_unif_edens_flag, init_unif_edens=init_unif_edens, N_mp_max=N_mp_max, nel_mp_ref_0=nel_mp_ref_0, B_multip=B_multip_per_eV*self.machine.p0/e*c, slice_by_slice_mode=True) my_new_part = [] self.my_list_eclouds = [] for ele in self.mypart: my_new_part.append(ele) if ele in self.machine.transverse_map: ecloud_new = ecloud.generate_twin_ecloud_with_shared_space_charge() my_new_part.append(ecloud_new) self.my_list_eclouds.append(ecloud_new) self.mypart = my_new_part
class Simulation(object): def __init__(self): self.N_turns = 128 def init_all(self): n_slices = 100 z_cut = 2.5e-9 * c self.n_slices = n_slices self.z_cut = z_cut from LHC import LHC self.machine = LHC(machine_configuration='Injection', n_segments=43, D_x=0., RF_at='end_of_transverse') # We suppose that all the object that cannot be slice parallelized are at the end of the ring i_end_parallel = len( self.machine.one_turn_map) - 1 #only RF is not parallelizable # split the machine sharing = shs.ShareSegments(i_end_parallel, self.ring_of_CPUs.N_nodes) myid = self.ring_of_CPUs.myid i_start_part, i_end_part = sharing.my_part(myid) self.mypart = self.machine.one_turn_map[i_start_part:i_end_part] if self.ring_of_CPUs.I_am_a_worker: print 'I am id=%d (worker) and my part is %d long' % ( myid, len(self.mypart)) elif self.ring_of_CPUs.I_am_the_master: self.non_parallel_part = self.machine.one_turn_map[i_end_parallel:] print 'I am id=%d (master) and my part is %d long' % ( myid, len(self.mypart)) def init_master(self): # beam parameters epsn_x = 2.5e-6 epsn_y = 3.5e-6 sigma_z = 0.05 intensity = 1e11 macroparticlenumber_track = 50000 # initialization bunch bunch = self.machine.generate_6D_Gaussian_bunch_matched( macroparticlenumber_track, intensity, epsn_x, epsn_y, sigma_z=sigma_z) print 'Bunch initialized.' # initial slicing from PyHEADTAIL.particles.slicing import UniformBinSlicer self.slicer = UniformBinSlicer(n_slices=self.n_slices, z_cuts=(-self.z_cut, self.z_cut)) #slice for the first turn slice_obj_list = bunch.extract_slices(self.slicer) #prepare to save results self.beam_x, self.beam_y, self.beam_z = [], [], [] self.sx, self.sy, self.sz = [], [], [] self.epsx, self.epsy, self.epsz = [], [], [] pieces_to_be_treated = slice_obj_list return pieces_to_be_treated def init_worker(self): pass def treat_piece(self, piece): for ele in self.mypart: ele.track(piece) def finalize_turn_on_master(self, pieces_treated): # re-merge bunch bunch = sum(pieces_treated) #finalize present turn (with non parallel part, e.g. synchrotron motion) for ele in self.non_parallel_part: ele.track(bunch) #save results self.beam_x.append(bunch.mean_x()) self.beam_y.append(bunch.mean_y()) self.beam_z.append(bunch.mean_z()) self.sx.append(bunch.sigma_x()) self.sy.append(bunch.sigma_y()) self.sz.append(bunch.sigma_z()) self.epsx.append(bunch.epsn_x() * 1e6) self.epsy.append(bunch.epsn_y() * 1e6) self.epsz.append(bunch.epsn_z()) # prepare next turn (re-slice) new_pieces_to_be_treated = bunch.extract_slices(self.slicer) orders_to_pass = [] return orders_to_pass, new_pieces_to_be_treated def execute_orders_from_master(self, orders_from_master): pass def finalize_simulation(self): # save results import myfilemanager as mfm mfm.save_dict_to_h5('beam_coord.h5',{\ 'beam_x':self.beam_x, 'beam_y':self.beam_y, 'beam_z':self.beam_z, 'sx':self.sx, 'sy':self.sy, 'sz':self.sz, 'epsx':self.epsx, 'epsy':self.epsy, 'epsz':self.epsz}) # output plots if False: beam_x = self.beam_x beam_y = self.beam_y beam_z = self.beam_z sx = self.sx sy = self.sy sz = self.sz epsx = self.epsx epsy = self.epsy epsz = self.epsz import pylab as plt plt.figure(2, figsize=(16, 8), tight_layout=True) plt.subplot(2, 3, 1) plt.plot(beam_x) plt.ylabel('x [m]') plt.xlabel('Turn') plt.gca().ticklabel_format(style='sci', scilimits=(0, 0), axis='y') plt.subplot(2, 3, 2) plt.plot(beam_y) plt.ylabel('y [m]') plt.xlabel('Turn') plt.gca().ticklabel_format(style='sci', scilimits=(0, 0), axis='y') plt.subplot(2, 3, 3) plt.plot(beam_z) plt.ylabel('z [m]') plt.xlabel('Turn') plt.gca().ticklabel_format(style='sci', scilimits=(0, 0), axis='y') plt.subplot(2, 3, 4) plt.plot(np.fft.rfftfreq(len(beam_x), d=1.), np.abs(np.fft.rfft(beam_x))) plt.ylabel('Amplitude') plt.xlabel('Qx') plt.subplot(2, 3, 5) plt.plot(np.fft.rfftfreq(len(beam_y), d=1.), np.abs(np.fft.rfft(beam_y))) plt.ylabel('Amplitude') plt.xlabel('Qy') plt.subplot(2, 3, 6) plt.plot(np.fft.rfftfreq(len(beam_z), d=1.), np.abs(np.fft.rfft(beam_z))) plt.xlim(0, 0.1) plt.ylabel('Amplitude') plt.xlabel('Qz') fig, axes = plt.subplots(3, figsize=(16, 8), tight_layout=True) twax = [plt.twinx(ax) for ax in axes] axes[0].plot(sx) twax[0].plot(epsx, '-g') axes[0].set_xlabel('Turns') axes[0].set_ylabel(r'$\sigma_x$') twax[0].set_ylabel(r'$\varepsilon_y$') axes[1].plot(sy) twax[1].plot(epsy, '-g') axes[1].set_xlabel('Turns') axes[1].set_ylabel(r'$\sigma_x$') twax[1].set_ylabel(r'$\varepsilon_y$') axes[2].plot(sz) twax[2].plot(epsz, '-g') axes[2].set_xlabel('Turns') axes[2].set_ylabel(r'$\sigma_x$') twax[2].set_ylabel(r'$\varepsilon_y$') axes[0].grid() axes[1].grid() axes[2].grid() for ax in list(axes) + list(twax): ax.ticklabel_format(useOffset=False, style='sci', scilimits=(0, 0), axis='y') plt.show() def piece_to_buffer(self, piece): buf = ch.beam_2_buffer(piece) return buf def buffer_to_piece(self, buf): piece = ch.buffer_2_beam(buf) return piece