Beispiel #1
0
def run():
    def track_n_save(bunch, map_):
        mean_x = np.empty(n_turns)
        mean_y = np.empty(n_turns)
        sigma_z = np.empty(n_turns)

        for i in xrange(n_turns):
            mean_x[i] = bunch.mean_x()
            mean_y[i] = bunch.mean_y()
            sigma_z[i] = bunch.sigma_z()

            for m_ in map_:
                m_.track(bunch)

        return mean_x, mean_y, sigma_z

    def my_fft(data):
        t = np.arange(len(data))
        fft = np.fft.rfft(data)
        fft_freq = np.fft.rfftfreq(t.shape[-1])

        return fft_freq, np.abs(fft.real)

    def generate_bunch(n_macroparticles, alpha_x, alpha_y, beta_x, beta_y,
                       linear_map):

        intensity = 1.05e11
        sigma_z = 0.059958
        gamma = 3730.26
        p0 = np.sqrt(gamma**2 - 1) * m_p * c

        beta_z = (linear_map.eta(dp=0, gamma=gamma) *
                  linear_map.circumference / (2 * np.pi * linear_map.Q_s))

        epsn_x = 3.75e-6  # [m rad]
        epsn_y = 3.75e-6  # [m rad]
        epsn_z = 4 * np.pi * sigma_z**2 * p0 / (beta_z * e)

        bunch = generators.generate_Gaussian6DTwiss(
            macroparticlenumber=n_macroparticles,
            intensity=intensity,
            charge=e,
            gamma=gamma,
            mass=m_p,
            circumference=C,
            alpha_x=alpha_x,
            beta_x=beta_x,
            epsn_x=epsn_x,
            alpha_y=alpha_y,
            beta_y=beta_y,
            epsn_y=epsn_y,
            beta_z=beta_z,
            epsn_z=epsn_z)
        # print ('bunch sigma_z=' + bunch.sigma_z())

        return bunch

    def track_n_show(bunch, slicer, map_woWakes, wake_field):
        fig, ((ax1, ax2)) = plt.subplots(2, 1, figsize=(16, 16))

        xp_diff = np.zeros(n_macroparticles)

        for i in xrange(n_turns):
            for m_ in map_woWakes:
                m_.track(bunch)

            # Dipole X kick.
            if i == (n_turns - 1):
                xp_old = bunch.xp.copy()
            wake_field.track(bunch)

            if i == (n_turns - 1):
                xp_diff[:] = bunch.xp[:] - xp_old[:]

        # Plot bunch.z vs. slice index of particle. Mark particles within
        # z cuts in green.
        nsigmaz_lbl = ' (nsigmaz =' + str(n_sigma_z) + ')'

        slice_set = bunch.get_slices(slicer)
        pidx = slice_set.particles_within_cuts
        slidx = slice_set.slice_index_of_particle

        z_cut_tail, z_cut_head = slice_set.z_cut_tail, slice_set.z_cut_head

    # In[4]:
    # Basic parameters.
    n_turns = 10
    n_segments = 1
    n_macroparticles = 50

    Q_x = 64.28
    Q_y = 59.31
    Q_s = 0.0020443

    C = 26658.883
    R = C / (2. * np.pi)

    alpha_x_inj = 0.
    alpha_y_inj = 0.
    beta_x_inj = 66.0064
    beta_y_inj = 71.5376
    alpha_0 = [0.0003225]

    #waketable filename
    fn = os.path.join(os.path.dirname(__file__), 'wake_table.dat')
    # In[5]:

    # Parameters for transverse map.
    s = np.arange(0, n_segments + 1) * C / n_segments

    alpha_x = alpha_x_inj * np.ones(n_segments)
    beta_x = beta_x_inj * np.ones(n_segments)
    D_x = np.zeros(n_segments)

    alpha_y = alpha_y_inj * np.ones(n_segments)
    beta_y = beta_y_inj * np.ones(n_segments)
    D_y = np.zeros(n_segments)

    # In[6]:

    # In[7]:

    # In[8]:

    # CASE TEST SETUP
    trans_map = TransverseMap(s, alpha_x, beta_x, D_x, alpha_y, beta_y, D_y,
                              Q_x, Q_y)
    long_map = LinearMap(alpha_0, C, Q_s)

    bunch = generate_bunch(n_macroparticles, alpha_x_inj, alpha_y_inj,
                           beta_x_inj, beta_y_inj, long_map)

    # In[9]:

    # CASE I
    # Transverse and long. tracking (linear), and wakes from WakeTable source.
    # DIPOLE X, UniformBinSlicer

    n_sigma_z = 2
    n_slices = 15
    uniform_bin_slicer = UniformBinSlicer(n_slices=n_slices,
                                          n_sigma_z=n_sigma_z)

    # Definition of WakeField as a composition of different sources.
    wake_file_columns = [
        'time', 'dipole_x', 'no_dipole_y', 'no_quadrupole_x',
        'no_quadrupole_y', 'no_dipole_xy', 'no_dipole_yx'
    ]
    table = WakeTable(fn,
                      wake_file_columns,
                      printer=SilentPrinter(),
                      warningprinter=SilentPrinter())
    wake_field = WakeField(uniform_bin_slicer, table)

    trans_map = [m for m in trans_map]
    map_woWakes = trans_map + [long_map]

    track_n_save(bunch, map_woWakes)

    # In[10]:

    # CASE II
    # Transverse and long. tracking (linear), and wakes from WakeTable source.
    # DIPOLE X, UniformChargeSlicer

    n_sigma_z = 2
    n_slices = 15
    uniform_charge_slicer = UniformChargeSlicer(n_slices=n_slices,
                                                n_sigma_z=n_sigma_z)

    # Definition of WakeField as a composition of different sources.
    wake_file_columns = [
        'time', 'dipole_x', 'no_dipole_y', 'no_quadrupole_x',
        'no_quadrupole_y', 'no_dipole_xy', 'no_dipole_yx'
    ]
    table = WakeTable(fn,
                      wake_file_columns,
                      printer=SilentPrinter(),
                      warningprinter=SilentPrinter())
    wake_field = WakeField(uniform_charge_slicer, table)

    trans_map = [m for m in trans_map]
    map_woWakes = trans_map + [long_map]

    track_n_save(bunch, map_woWakes)

    # In[11]:

    # CASE III
    # Transverse and long. tracking (linear), and wakes from WakeTable source.
    # Quadrupole X, UniformChargeSlicer

    n_sigma_z = 2
    n_slices = 15
    uniform_charge_slicer = UniformChargeSlicer(n_slices=n_slices,
                                                n_sigma_z=n_sigma_z)

    # Definition of WakeField as a composition of different sources.
    wake_file_columns = [
        'time', 'no_dipole_x', 'no_dipole_y', 'quadrupole_x',
        'no_quadrupole_y', 'no_dipole_xy', 'no_dipole_yx'
    ]
    table = WakeTable(fn,
                      wake_file_columns,
                      printer=SilentPrinter(),
                      warningprinter=SilentPrinter())
    wake_field = WakeField(uniform_charge_slicer, table)

    trans_map = [m for m in trans_map]
    map_woWakes = trans_map + [long_map]

    track_n_save(bunch, map_woWakes)

    # In[12]:

    # CASE IV
    # Transverse and long. tracking (linear), and wakes from WakeTable source.
    # Quadrupole X, UniformBinSlicer

    n_sigma_z = 2
    n_slices = 15
    uniform_bin_slicer = UniformBinSlicer(n_slices=n_slices,
                                          n_sigma_z=n_sigma_z)

    # Definition of WakeField as a composition of different sources.
    wake_file_columns = [
        'time', 'no_dipole_x', 'no_dipole_y', 'quadrupole_x',
        'no_quadrupole_y', 'no_dipole_xy', 'no_dipole_yx'
    ]
    table = WakeTable(fn,
                      wake_file_columns,
                      printer=SilentPrinter(),
                      warningprinter=SilentPrinter())
    wake_field = WakeField(uniform_bin_slicer, table)

    trans_map = [m for m in trans_map]
    map_woWakes = trans_map + [long_map]

    track_n_save(bunch, map_woWakes)

    # In[15]:

    # CASE V
    # Transverse and long. tracking (linear),
    # Resonator circular

    n_sigma_z = 2
    n_slices = 15
    uniform_bin_slicer = UniformBinSlicer(n_slices=n_slices,
                                          n_sigma_z=n_sigma_z)

    # Definition of WakeField as a composition of different sources.
    reson_circ = CircularResonator(R_shunt=1e6, frequency=1e8, Q=1)
    wake_field = WakeField(uniform_bin_slicer, reson_circ)

    trans_map = [m for m in trans_map]
    map_woWakes = trans_map + [long_map]

    track_n_save(bunch, map_woWakes)

    # In[16]:

    # CASE V b.
    # Transverse and long. tracking (linear),
    # Several Resonators circular

    n_sigma_z = 2
    n_slices = 15
    uniform_bin_slicer = UniformBinSlicer(n_slices=n_slices,
                                          n_sigma_z=n_sigma_z)

    # Definition of WakeField as a composition of different sources.
    reson_circ = CircularResonator(R_shunt=1e6, frequency=1e8, Q=1)
    reson_circ2 = CircularResonator(R_shunt=1e6, frequency=1e9, Q=0.8)
    reson_circ3 = CircularResonator(R_shunt=5e6, frequency=1e6, Q=0.2)

    wake_field = WakeField(uniform_bin_slicer, reson_circ, reson_circ2,
                           reson_circ3)

    trans_map = [m for m in trans_map]
    map_woWakes = trans_map + [long_map]

    track_n_save(bunch, map_woWakes)

    # In[17]:

    # CASE V c.
    # Transverse and long. tracking (linear),
    # Resonator parallel_plates

    n_sigma_z = 2
    n_slices = 15
    uniform_bin_slicer = UniformBinSlicer(n_slices=n_slices,
                                          n_sigma_z=n_sigma_z)

    # Definition of WakeField as a composition of different sources.
    reson_para = ParallelPlatesResonator(R_shunt=1e6, frequency=1e8, Q=1)
    wake_field = WakeField(uniform_bin_slicer, reson_para)

    trans_map = [m for m in trans_map]
    map_woWakes = trans_map + [long_map]

    track_n_save(bunch, map_woWakes)

    # In[18]:

    # CASE V d.
    # Transverse and long. tracking (linear),
    # Resonator w. longitudinal wake

    n_sigma_z = 2
    n_slices = 15
    uniform_bin_slicer = UniformBinSlicer(n_slices=n_slices,
                                          n_sigma_z=n_sigma_z)

    # Definition of WakeField as a composition of different sources.
    reson = Resonator(R_shunt=1e6,
                      frequency=1e8,
                      Q=1,
                      Yokoya_X1=1,
                      Yokoya_X2=1,
                      Yokoya_Y1=1,
                      Yokoya_Y2=1,
                      switch_Z=True)
    wake_field = WakeField(uniform_bin_slicer, reson)

    trans_map = [m for m in trans_map]
    map_woWakes = trans_map + [long_map]

    track_n_save(bunch, map_woWakes)

    # In[19]:

    # CASE VI
    # Transverse and long. tracking (linear),
    # ResistiveWall circular

    n_sigma_z = 2
    n_slices = 15
    uniform_bin_slicer = UniformBinSlicer(n_slices=n_slices,
                                          n_sigma_z=n_sigma_z)

    # Definition of WakeField as a composition of different sources.
    resis_circ = CircularResistiveWall(pipe_radius=5e-2,
                                       resistive_wall_length=C,
                                       conductivity=1e6,
                                       dt_min=1e-3)
    wake_field = WakeField(uniform_bin_slicer, resis_circ)

    trans_map = [m for m in trans_map]
    map_woWakes = trans_map + [long_map]

    track_n_save(bunch, map_woWakes)

    # In[20]:

    # CASE VI b.
    # Transverse and long. tracking (linear),
    # ResistiveWall parallel_plates

    n_sigma_z = 2
    n_slices = 15
    uniform_bin_slicer = UniformBinSlicer(n_slices=n_slices,
                                          n_sigma_z=n_sigma_z)

    # Definition of WakeField as a composition of different sources.
    resis_para = ParallelPlatesResistiveWall(pipe_radius=5e-2,
                                             resistive_wall_length=C,
                                             conductivity=1e6,
                                             dt_min=1e-3)
    wake_field = WakeField(uniform_bin_slicer, resis_para)

    trans_map = [m for m in trans_map]
    map_woWakes = trans_map + [long_map]

    track_n_save(bunch, map_woWakes)

    # In[21]:

    # CASE VII.
    # Transverse and long. tracking (linear),
    # Pass mixture of WakeSources to define WakeField.

    n_sigma_z = 2
    n_slices = 15
    uniform_bin_slicer = UniformBinSlicer(n_slices=n_slices,
                                          n_sigma_z=n_sigma_z)

    # Definition of WakeField as a composition of different sources.
    resis_circ = CircularResistiveWall(pipe_radius=5e-2,
                                       resistive_wall_length=C,
                                       conductivity=1e6,
                                       dt_min=1e-3)
    reson_para = ParallelPlatesResonator(R_shunt=1e6, frequency=1e8, Q=1)
    wake_file_columns = [
        'time', 'dipole_x', 'dipole_y', 'quadrupole_x', 'quadrupole_y',
        'dipole_xy', 'dipole_yx'
    ]
    table = WakeTable(fn,
                      wake_file_columns,
                      printer=SilentPrinter(),
                      warningprinter=SilentPrinter())

    wake_field = WakeField(uniform_bin_slicer, resis_circ, reson_para, table)

    trans_map = [m for m in trans_map]
    map_woWakes = trans_map + [long_map]

    track_n_save(bunch, map_woWakes)
Beispiel #2
0
def run(job_id, accQ_y):
    it = job_id

    # SIMULATION PARAMETERS
    # =====================

    # Simulation parameters
    n_turns = 10000
    n_macroparticles = 100000  # per bunch

    # MACHINE PARAMETERS
    # ==================

    intensity = 1e13  # protons
    #    intensity = 2*4e12 # protons
    E0 = 71e6  # Kinetic energy [eV]
    p0 = np.sqrt((m_p_MeV + E0)**2 - m_p_MeV**2) * e / c

    print('Beam kinetic energy: ' + str(E0 * 1e-6) + ' MeV')
    print('Beam momentum: ' + str(p0 * 1e-6 * c / e) + ' MeV/c')

    accQ_x = 4.31  # Horizontal tune
    #    accQ_y = 3.80 # Vertical tune is an input argument

    chroma = -1.4  # Chromaticity

    alpha = 5.034**-2  # momentum compaction factor

    circumference = 160.  # [meters]

    # Approximated average beta functions (lumped wake normalizations)
    beta_x = circumference / (2. * np.pi * accQ_x)
    beta_y = circumference / (2. * np.pi * accQ_y)

    # Harmonic number for RF
    h_RF = [2]  # a list of harmonic number for RF
    V_RF = [5e3 * 2]  # a list of RF voltages
    p_increment = 0.
    dphi_RF = [np.pi]  # a list of RF phases
    #    dphi_RF = 0.

    # non-linear longitudinal mode includes RF, otherwise linear needs synhotron tune Q_s
    longitudinal_mode = 'non-linear'
    #    Q_s=0.02 # Longitudinal tune

    optics_mode = 'smooth'
    n_segments = 1
    s = None
    alpha_x = None
    alpha_y = None
    D_x = 0
    D_y = 0
    charge = e
    mass = m_p
    name = None
    app_x = 0
    app_y = 0
    app_xy = 0

    # Creates PyHEADTAIL object for the synchotron
    machine = Synchrotron(optics_mode=optics_mode,
                          circumference=circumference,
                          n_segments=n_segments,
                          s=s,
                          name=name,
                          alpha_x=alpha_x,
                          beta_x=beta_x,
                          D_x=D_x,
                          alpha_y=alpha_y,
                          beta_y=beta_y,
                          D_y=D_y,
                          accQ_x=accQ_x,
                          accQ_y=accQ_y,
                          Qp_x=chroma,
                          Qp_y=chroma,
                          app_x=app_x,
                          app_y=app_y,
                          app_xy=app_xy,
                          alpha_mom_compaction=alpha,
                          longitudinal_mode=longitudinal_mode,
                          h_RF=np.atleast_1d(h_RF),
                          V_RF=np.atleast_1d(V_RF),
                          dphi_RF=np.atleast_1d(dphi_RF),
                          p0=p0,
                          p_increment=p_increment,
                          charge=charge,
                          mass=mass)

    print('')
    print('machine.beta: ')
    print(machine.beta)
    print('')

    print('')
    print('machine.gamma: ')
    print(machine.gamma)
    print('')

    epsn_x = 300e-6
    epsn_y = 300e-6
    sigma_z = 15  # bunch length in meters to be matched to the bucket

    # Creates transverse macroparticle distribution
    allbunches = machine.generate_6D_Gaussian_bunch(n_macroparticles,
                                                    intensity, epsn_x, epsn_y,
                                                    sigma_z)

    # Creates longitudinal macroparticle distribution
    rfb = RFBucket(circumference, machine.gamma, m_p, e, [alpha], 0., h_RF,
                   V_RF, dphi_RF)
    rfb_matcher = RFBucketMatcher(rfb, WaterbagDistribution, sigma_z=sigma_z)

    rfb_matcher.integrationmethod = 'cumtrapz'

    z, dp, _, _ = rfb_matcher.generate(n_macroparticles)
    np.copyto(allbunches.z, z)
    np.copyto(allbunches.dp, dp)

    # Slicer object, which used for wakefields and slice monitors
    slicer = UniformBinSlicer(75, z_cuts=(-2. * sigma_z, 2. * sigma_z))

    # WAKE FIELDS
    # ===========

    # Length of the wake function in turns, wake
    n_turns_wake = 150

    # Parameters for a resonator
    # frequency is in the units of (mode-Q_frac), where
    #       mode: integer number of coupled bunch mode (1 matches to the observations)
    #       Q_frac: resonance fractional tune

    f_r = (1 - 0.83) * 1. / (circumference / (c * machine.beta))
    Q = 15
    R = 1.0e6

    # Renator wake object, which is added to the one turn map
    wakes = CircularResonator(R, f_r, Q, n_turns_wake=n_turns_wake)
    wake_field = WakeField(slicer, wakes)
    machine.one_turn_map.append(wake_field)

    # CREATE MONITORS
    # ===============
    simulation_parameters_dict = {'gamma'           : machine.gamma,\
                                  'intensity'       : intensity,\
                                  'Qx'              : accQ_x,\
                                  'Qy'              : accQ_y,\
#                                  'Qs'              : Q_s,\
                                  'beta_x'          : beta_x,\
                                  'beta_y'          : beta_y,\
    #                               'beta_z'          : bucket.beta_z,\
                                  'epsn_x'          : epsn_x,\
                                  'epsn_y'          : epsn_y,\
                                  'sigma_z'         : sigma_z,\
                                 }
    # Bunch monitor strores bunch average positions for all the bunches
    bunchmonitor = BunchMonitor(outputpath + '/bunchmonitor_{:04d}'.format(it),
                                n_turns,
                                simulation_parameters_dict,
                                write_buffer_every=32,
                                buffer_size=32)

    # Slice monitors saves slice-by-slice data for each bunch
    slicemonitor = SliceMonitor(outputpath +
                                '/slicemonitor_{:01d}_{:04d}'.format(0, it),
                                60,
                                slicer,
                                simulation_parameters_dict,
                                write_buffer_every=60,
                                buffer_size=60)

    # Counter for a number of turns stored to slice monitors
    s_cnt = 0

    # TRACKING LOOP
    # =============
    monitor_active = False
    print('\n--> Begin tracking...\n')

    for i in range(n_turns):
        t0 = time.clock()

        # Tracks beam through the one turn map simulation map
        machine.track(allbunches)

        # Stores bunch mean coordinate values
        bunchmonitor.dump(allbunches)

        # If the total oscillation amplitude of bunches exceeds the threshold
        # or the simulation is running on the last turns, triggers the slice
        # monitors for headtail motion data
        if (allbunches.mean_x() > 1e-1 or allbunches.mean_y() > 1e-1 or i >
            (n_turns - 64)):
            monitor_active = True

        # saves slice monitor data if monitors are activated and less than
        # 64 turns have been stored
        if monitor_active and s_cnt < 64:
            slicemonitor.dump(allbunches)
            s_cnt += 1
        elif s_cnt == 64:
            break

        # If this script is runnin on the first processor, prints the current
        # bunch coordinates and emittances
        if (i % 100 == 0):
            print(
                '{:4d} \t {:+3e} \t {:+3e} \t {:+3e} \t {:3e} \t {:3e} \t {:3f} \t {:3f} \t {:3f} \t {:3s}'
                .format(i, allbunches.mean_x(), allbunches.mean_y(),
                        allbunches.mean_z(), allbunches.epsn_x(),
                        allbunches.epsn_y(), allbunches.epsn_z(),
                        allbunches.sigma_z(), allbunches.sigma_dp(),
                        str(time.clock() - t0)))
ww1 = WakeTable(wakefile1, ['time', 'dipole_x', 'dipole_y', 'quadrupole_x', 'quadrupole_y'], n_turns_wake=n_turns_wake)

# only dipolar kick- uncomment the following 3 lines
#my_length = len(ww1.wake_table['quadrupole_x'])
#ww1.wake_table['quadrupole_x'] = np.zeros(my_length)
#ww1.wake_table['quadrupole_y'] = np.zeros(my_length)

# only quadrupolar kick, uncomment the following 3 lines
#my_length = len(ww1.wake_table['dipole_x'])
#ww1.wake_table['dipole_x'] = np.zeros(my_length)
#ww1.wake_table['dipole_y'] = np.zeros(my_length)

wake_field_complete_sps = WakeField(slicer_for_wakefields, ww1)#, beta_x=beta_x, beta_y=beta_y)

# 2) Definition of wakefield of a circular resonator
reson_circ = CircularResonator(R_shunt=2.2e6, frequency=1.92e9, Q=59000) # assuming here that Q is the quality factor in 1e4
wake_field_reson_circ = WakeField(slicer_for_wakefields, reson_circ)



# CREATE TRANSVERSE AND LONGITUDINAL MAPS
# =======================================
scale_factor = 2*bunch.p0  # scale the detuning coefficients in pyheadtail units
transverse_map = TransverseMap(s, alpha_x, beta_x, D_x, alpha_y, beta_y, D_y, Q_x, Q_y,
    [Chromaticity(Qp_x, Qp_y),
    AmplitudeDetuning(app_x*scale_factor, app_y*scale_factor, app_xy*scale_factor)])

longitudinal_map = LinearMap([alpha], circumference, Q_s)