Пример #1
0
    def test_wake(self):

        time = np.linspace(-0.1e-6, 0.7e-6, 1000)

        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)

        TWC_impedance_source.wake_calc(time - time[0])
        wake_impSource = np.around(TWC_impedance_source.wake / 1e12, 12)

        TWC_impulse_response = SPS4Section200MHzTWC()
        # omega_c not need for computation of wake function
        TWC_impulse_response.impulse_response_beam(2 * np.pi * 200.222e6, time)
        TWC_impulse_response.impulse_response_gen(2 * np.pi * 200.222e6, time)
        TWC_impulse_response.compute_wakes(time)
        wake_impResp = np.around(TWC_impulse_response.W_beam / 1e12, 12)

        self.assertListEqual(
            wake_impSource.tolist(),
            wake_impResp.tolist(),
            msg="In TestTravelingWaveCavity test_wake: wake fields differ")
Пример #2
0
    def test_wake(self):

        time = np.linspace(-0.1e-6, 0.7e-6, 1000)

        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)

        TWC_impedance_source.wake_calc(time-time[0])
        wake_impSource = np.around(TWC_impedance_source.wake/1e12, 12)

        TWC_impulse_response = SPS4Section200MHzTWC()
        # omega_c not need for computation of wake function
        TWC_impulse_response.impulse_response_beam(2*np.pi*200.222e6, time)
        TWC_impulse_response.impulse_response_gen(2*np.pi*200.222e6, time)
        TWC_impulse_response.compute_wakes(time)
        wake_impResp = np.around(TWC_impulse_response.W_beam/1e12, 12)

        self.assertListEqual(wake_impSource.tolist(), wake_impResp.tolist(),
            msg="In TestTravelingWaveCavity test_wake: wake fields differ")
Пример #3
0
    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)
Пример #4
0
    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 = 2  # factor 2 because of two cavities are used for tracking
elif cavities == 'future':

    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':
Пример #5
0
    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")
Пример #6
0
def reduce_impedance_feedforward_feedback(
        profile,
        freqres,
        impedanceScenario,
        outdir=None,
        Gfb=10.0,
        gff=0.5):  # Changed default from Gfb = 7.5 to 10. on 05.Aug.2020

    if type(Gfb) is not list:
        if (Gfb == 0.): Gfblist = [None, None]
        else: Gfblist = [Gfb, Gfb]
    else:
        # It comes already in a list form:
        # For past/present imp: [4-sec cavs, 5-sec cavs]
        # For future       imp: [3-sec cavs, 4-sec cavs]
        Gfblist = copy(Gfb)
        pass

    if type(gff) is not list:
        if (gff == 0.): gfflist = [None, None]
        else: gfflist = [gff, gff]
    else:
        # For past/present imp: [4-sec cavs, 5-sec cavs]
        # For future       imp: [3-sec cavs, 4-sec cavs]
        gfflist = copy(gff)
        pass

    ##gfb = # 1/(4.*50)*10. #4.*50. * 0.1
    #gfb = 1e-2 #1.5e-2 #0.86e6/2. # 1e-3 # None #1e-6 # with Zr

    #print(f'impedanceScenario = {impedanceScenario}')
    print(
        f'impedanceScenario.scenarioFileName = {impedanceScenario.scenarioFileName}'
    )

    if ('future' in impedanceScenario.scenarioFileName):
        Gfb3or5sec = Gfblist[0]
        Gfb4sec = Gfblist[1]
        print('* Gfb3sec =', Gfb3or5sec, '(Gfb3or5sec)')
        print('* Gfb4sec =', Gfb4sec)
        gff3or5sec = gfflist[0]
        gff4sec = gfflist[1]
        print('* gff3sec =', gff3or5sec, '(gff3or5sec)')
        print('* gff4sec =', gff4sec)
    else:
        Gfb3or5sec = Gfblist[1]
        Gfb4sec = Gfblist[0]
        print('* Gfb5sec =', Gfb3or5sec, '(Gfb3or5sec)')
        print('* Gfb4sec =', Gfb4sec)
        gff3or5sec = gfflist[1]
        gff4sec = gfflist[0]
        print('* gff5sec =', gff3or5sec, '(gff3or5sec)')
        print('* gff4sec =', gff4sec)
    print('')

    print('Running reduce_impedance_feedforward...\n')

    # Frequency array

    freq_res = freqres / 10  #150e3
    n_fft = int(1. / (profile.bin_size) / freq_res)
    print('n_fft      =', n_fft)

    profile.beam_spectrum_freq_generation(n_fft)
    freq_array = profile.beam_spectrum_freq
    print(
        'freq_array =', freq_array, len(freq_array)
    )  # it will not be exactly equal than the frequency array to be computed in the profile
    print('')
    #quit()

    # Find the index of the main harmonic cavities in the impedance list using their source file names as keys
    # (the necessary attenuations (e.g. from FB) and corrections have already been performed upon loading):

    key3 = 'cavities/200MHz/3sections/TWC200_3sections_dome_MAIN.dat'
    key4 = 'cavities/200MHz/4sections/TWC200_4sections_dome_MAIN.dat'
    key5 = 'cavities/200MHz/5sections/TWC200_5sections_dome_MAIN.dat'

    elID_dict = {
    }  # List of indices of the main cavities to be "erased" and replaced
    for i in range(len(impedanceScenario.SPSimpList)):
        filei = impedanceScenario.SPSimpList[i]['file']
        if (i < 15 or i == len(impedanceScenario.SPSimpList) - 1):
            print(i, filei)
        elif (i == 15):
            print('...')
        if (filei == key3): elID_dict['3sections'] = i  # i = elIDkey3
        if (filei == key4): elID_dict['4sections'] = i  # i = elIDkey4
        if (filei == key5): elID_dict['5sections'] = i  # i = elIDkey5
    print('')
    print('Elements being replaced:')
    print('elID_dict =', elID_dict)
    print('')

    # Parameters for the cavities

    Z_0 = 50  # Characteristic impedance of the RF chain [Ohm]
    oneCellLength = 0.374  # Length of one cell [m] = 0.374 m
    rho = 27.1e3  # Series impedance of the cavity [Ohm/m^2]
    vg = 0.0946 * c  # Group velocity [m/s]

    elID_list = []

    for key in elID_dict.keys():

        elID = elID_dict[key]
        elID_list.append(elID)
        print('elID =', elID, ' | key =', key, '|',
              impedanceScenario.table_impedance[elID]['file'])
        print('')

        if (key == '4sections'):

            nsections = 4
            ncavities = 2
            print('nsections = ', nsections)
            print('ncavities = ', ncavities)
            print('')

            L4sec = oneCellLength * (
                nsections * 11 - 0.5 - 0.5
            )  # Length of the 4-section 200MHz cavities (43 cells) [m]
            print('L4sec =', L4sec)
            print('')

            fr4sec = impedanceScenario.table_impedance[elID]['fr'][
                0, 0]  # Centre frequency of the 4-section 200MHz cavities [Hz]
            Rsh4sec = impedanceScenario.table_impedance[elID]['Rsh'][
                0,
                0] / ncavities  # Shunt impedance [Ohm] # = (rho*L4sec**2)/8., the shunt impedance? [Ohm] -> works
            alpha4sec = impedanceScenario.table_impedance[elID]['alpha'][
                0,
                0]  # Time factor alpha [s] # = L4sec/vg* 0.5*( (1.-vg/c) + (1.+vg/c)) *2*np.pi, the daming time [s] (average of 1.-vg/c and 1.+vg/c):
            rho4sec = 8. * Rsh4sec / L4sec**2
            print('fr4sec      =', fr4sec)
            print('Rsh4sec     =', Rsh4sec / 1e6, 'MOhm')
            print('alpha4sec   =', alpha4sec / 1e-6, 'us')
            print('rho4sec     =', rho4sec / 1e3, 'kOhm/m2')
            print('rho4sec/rho =', rho4sec / rho)
            print('')

            # For comparison: creating TWCs with the parameters derived from the loaded input using BLonD's TWC object:
            twc4sec = TravelingWaveCavity(Rsh4sec, fr4sec, alpha4sec)
            twc4sec.imped_calc(freq_array)
            Ztwc4sec = twc4sec.impedance
            print('Ztwc4sec =', Ztwc4sec)  # ~ Zb4sec
            print('')

            # Creating TWCs, characterised by their impedance (Zb); creating RF impedance (Zrf)

            params0 = [fr4sec, Z_0, rho4sec, L4sec, vg]

            ReZb4sec = ReZb(freq_array, *params0)
            Zb4sec = Zb(freq_array, *params0)
            print('ReZb4sec =', ReZb4sec, '\n', max(np.abs(np.real(ReZb4sec))),
                  max(np.abs(np.imag(ReZb4sec))), max(np.abs(ReZb4sec)))
            print('Zb4sec   =', Zb4sec, '\n', max(np.abs(np.real(Zb4sec))),
                  max(np.abs(np.imag(Zb4sec))), max(np.abs(Zb4sec)))
            print('')
            ReZrf4sec = ReZrf(freq_array, *params0)
            Zrf4sec = Zrf(freq_array, *params0)
            print('ReZrf4sec =', ReZrf4sec, '\n', max(np.abs(ReZrf4sec)))
            print('Zrf4sec   =', Zrf4sec, '\n', max(np.abs(Zrf4sec)))
            print('')

            Zrf4secnew = np.copy(Zb4sec)

            # FF reduction
            if (gff4sec is not None):
                hff4sec = gff4sec / (4. * Z_0)
                ReHff4sec = hff4sec * ReZrf4sec
                ImHff4sec = 0.
                Hff4sec = ReHff4sec + 1j * ImHff4sec
                Zrf4secnew -= Hff4sec * Zrf4sec
                print('gff4sec =', gff4sec)
                print('hff4sec =', hff4sec)
                print('Hff4sec =', Hff4sec)
            else:
                print('No FF')
            print('Zrf4secnew =', Zrf4secnew, '\n',
                  max(np.abs(np.real(Zrf4secnew))),
                  max(np.abs(np.imag(Zrf4secnew))), max(np.abs(Zrf4secnew)))
            print('')

            # FB reduction (acting on top of the FF-reduction, if applicable)
            #if(gfb is not None):
            if (Gfb4sec is not None):
                #    gfb4sec = Gfb4sec * ((rho4sec*L4sec**2)/8.)
                #    hfb4sec = gfb4sec / ((rho4sec*L4sec**2)/8.)
                #    Hfb4sec = hfb4sec * ReZb4sec          # [1]
                #    #gfb4sec = Gfb4sec * (L4sec*np.sqrt(rho4sec*Z_0/2.))
                #    #hfb4sec = gfb4sec / (L4sec*np.sqrt(rho4sec*Z_0/2.))
                #    #Hfb4sec = hfb4sec * ReZrf4sec         # [1]
                #   #Zrf4secnew /= 1.  + Hfb4sec*Zrf4sec
                #   #Zrf4secnew /= Zb4sec + Hfb4sec*Zrf4sec
                #    Hfb4sec = Gfb4sec / (4.*Z_0)
                #    Zrf4secnew /= 1.  + Hfb4sec*Hff4sec*Zrf4sec
                #   #Zrf4secnew /= Zb4sec + Hfb4sec*Hff4sec*Zrf4sec
                #   #Zrf4secnew /= 1.  + Hfb4sec*Zrf4secnew
                #   #Zrf4secnew /= Zb4sec + Hfb4sec*Zrf4secnew
                #    print('Gfb4sec =', Gfb4sec)
                #    print('gfb4sec =', gfb4sec)
                #    print('hfb4sec =', hfb4sec)
                #    print('Hfb4sec =', Hfb4sec)
                Hfb4secZrf = Gfb4sec * ReZb4sec / ((rho4sec * L4sec**2) / 8.)
                Zrf4secnew /= 1. + Hfb4secZrf
                print('Hfb4secZrf =', Hfb4secZrf)
            else:
                print('No FB')
            print('Zrf4secnew =', Zrf4secnew, '\n',
                  max(np.abs(np.real(Zrf4secnew))),
                  max(np.abs(np.imag(Zrf4secnew))), max(np.abs(Zrf4secnew)))
            print('')

        elif (key == '3sections' or key == '5sections'):

            if (key == '3sections'):
                nsections = 3
                ncavities = 4
            elif (key == '5sections'):
                nsections = 5
                ncavities = 2
            print('nsections = ', nsections)
            print('ncavities = ', ncavities)
            print('')

            L3or5sec = oneCellLength * (
                nsections * 11 - 0.5 - 0.5
            )  # Length of the (3/5)-section cavities (32/54 cells) [m]
            print('L3or5sec =', L3or5sec)
            print('')

            fr3or5sec = impedanceScenario.table_impedance[elID]['fr'][
                0, 0]  # Centre frequency of the 200MHz cavities [Hz]
            Rsh3or5sec = impedanceScenario.table_impedance[elID]['Rsh'][
                0,
                0] / ncavities  # Shunt impedance [Ohm] # = (rho*L3or5sec**2)/8., the shunt impedance? [Ohm] -> works
            alpha3or5sec = impedanceScenario.table_impedance[elID]['alpha'][
                0,
                0]  # Time factor alpha [s] # = L3or5sec/vg* 0.5*( (1.-vg/c) + (1.+vg/c)) *2*np.pi, the daming time [s] (average of 1.-vg/c and 1.+vg/c):
            rho3or5sec = 8. * Rsh3or5sec / L3or5sec**2
            print('fr3or5sec      =', fr3or5sec)
            print('Rsh3or5sec     =', Rsh3or5sec / 1e6, 'MOhm')
            print('alpha3or5sec   =', alpha3or5sec / 1e-6, 'us')
            print('rho3or5sec     =', rho3or5sec / 1e3, 'kOhm/m2')
            print('rho3or5sec/rho =', rho3or5sec / rho)
            print('')

            # For comparison: creating TWCs with the parameters derived from the loaded input using BLonD's TWC object:
            twc3or5sec = TravelingWaveCavity(Rsh3or5sec, fr3or5sec,
                                             alpha3or5sec)
            twc3or5sec.imped_calc(freq_array)
            Ztwc3or5sec = twc3or5sec.impedance
            print('Ztwc3or5sec =', Ztwc3or5sec)  # ~ Zb3or5sec
            print('')

            # Creating TWCs, characterised by their impedance (Zb); creating RF impedance (Zrf)

            params1 = [fr3or5sec, Z_0, rho3or5sec, L3or5sec, vg]

            ReZb3or5sec = ReZb(freq_array, *params1)
            Zb3or5sec = Zb(freq_array, *params1)
            print('ReZb3or5sec =', ReZb3or5sec, '\n',
                  max(np.abs(np.real(ReZb3or5sec))),
                  max(np.abs(np.imag(ReZb3or5sec))), max(np.abs(ReZb3or5sec)))
            print('Zb3or5sec   =', Zb3or5sec, '\n',
                  max(np.abs(np.real(Zb3or5sec))),
                  max(np.abs(np.imag(Zb3or5sec))), max(np.abs(Zb3or5sec)))
            print('')
            ReZrf3or5sec = ReZrf(freq_array, *params1)
            Zrf3or5sec = Zrf(freq_array, *params1)
            print('ReZrf3or5sec =', ReZrf3or5sec, '\n',
                  max(np.abs(ReZrf3or5sec)))
            print('Zrf3or5sec   =', Zrf3or5sec, '\n', max(np.abs(Zrf3or5sec)))
            print('')

            Zrf3or5secnew = np.copy(Zb3or5sec)

            # FF reduction
            if (gff3or5sec is not None):
                hff3or5sec = gff3or5sec / (4. * Z_0)
                ReHff3or5sec = hff3or5sec * Zrf3or5sec
                ImHff3or5sec = 0.
                Hff3or5sec = ReHff3or5sec + 1j * ImHff3or5sec
                Zrf3or5secnew -= Hff3or5sec * Zrf3or5sec
                print('gff3or5sec =', gff3or5sec)
                print('hff3or5sec =', hff3or5sec)
                print('Hff3or5sec =', Hff3or5sec)
            else:
                print('No FF')
            print('Zrf3or5secnew =', Zrf3or5secnew, '\n',
                  max(np.abs(np.real(Zrf3or5secnew))),
                  max(np.abs(np.imag(Zrf3or5secnew))),
                  max(np.abs(Zrf3or5secnew)))
            print('')

            # FB reduction (acting on top of the FF-reduction, if applicable)
            #if(gfb is not None):
            if (Gfb3or5sec is not None):
                #    gfb3or5sec = Gfb3or5sec * ((rho3or5sec*L3or5sec**2)/8.)
                #    hfb3or5sec = gfb3or5sec / ((rho3or5sec*L3or5sec**2)/8.)
                #    Hfb3or5sec = hfb3or5sec * ReZb3or5sec          # [1]
                #    #gfb3or5sec = Gfb3or5sec * (L3or5sec*np.sqrt(rho3or5sec*Z_0/2.))
                #    #hfb3or5sec = gfb3or5sec / (L3or5sec*np.sqrt(rho3or5sec*Z_0/2.))
                #    #Hfb3or5sec = hfb3or5sec * ReZrf3or5sec         # [1]
                #   #Zrf3or5secnew /= 1.  + Hfb3or5sec*Zrf3or5sec
                #   #Zrf3or5secnew /= Zb3or5sec + Hfb3or5sec*Zrf3or5sec
                #    Hfb3or5sec = Gfb3or5sec / (4.*Z_0)
                #    Zrf3or5secnew /= 1.  + Hfb3or5sec*Hff3or5sec*Zrf3or5sec
                #   #Zrf3or5secnew /= Zb3or5sec + Hfb3or5sec*Hff3or5sec*Zrf3or5sec
                #   #Zrf3or5secnew /= 1.  + Hfb3or5sec*Zrf3or5secnew
                #   #Zrf3or5secnew /= Zb3or5sec + Hfb3or5sec*Zrf3or5secnew
                #    print('Gfb3or5sec =', Gfb3or5sec)
                #    print('gfb3or5sec =', gfb3or5sec)
                #    print('hfb3or5sec =', hfb3or5sec)
                #    print('Hfb3or5sec =', Hfb3or5sec)
                Hfb3or5secZrf = Gfb3or5sec * ReZb3or5sec / (
                    (rho3or5sec * L3or5sec**2) / 8.)
                Zrf3or5secnew /= 1. + Hfb3or5secZrf
                print('Hfb3or5secZrf =', Hfb3or5secZrf)
            else:
                print('No FB')
            print('Zrf3or5secnew =', Zrf3or5secnew, '\n',
                  max(np.abs(np.real(Zrf3or5secnew))),
                  max(np.abs(np.imag(Zrf3or5secnew))),
                  max(np.abs(Zrf3or5secnew)))
            print('')

    #quit()

    ################################

    # "Erase" the main harmonic already loaded and replace it by the new one.
    # Only the contributions in the range [0, 1 GHz] are set to zero (the frequency
    # as computed above might span higher, e.g 6.41 GHz if using the usual 44 kHz
    # from SPS input as frequency resolution

    for i in elID_list:
        impedanceScenario.damp_R_resonatorOrTWC(i, [
            0, 1e9
        ], R_factor=0.)  # Deletes elIDkey4 and elIDkey5 if 'present' or 'past'
        # or      elIDkey3 and elIDkey4 if 'future'
    print('')

    ## Replace them with the a new object that is the sum of the new cavities:
    #if('present' in impedanceScenario.scenarioFileName or 'past' in impedanceScenario.scenarioFileName): # 'past' is similar to present with attenuations of -20.0/-20.0 instead of -15.0/None for the 200MHz/800MHz systems (if applicable)
    #    impedanceScenario.importInputTableFromList([freq_array,
    #                                                np.real(2*Zrfnew4 + 2*Zrfnew5),
    #                                                np.imag(2*Zrfnew4 + 2*Zrfnew5)],
    #                                                'cavities/totalReducedByFeedbackFeedforward')
    #elif('future' in impedanceScenario.scenarioFileName):
    #    impedanceScenario.importInputTableFromList([freq_array,
    #                                                np.real(2*Zrfnew4 + 4*Zrfnew3),
    #                                                np.imag(2*Zrfnew4 + 4*Zrfnew3)],
    #                                                'cavities/totalReducedByFeedbackFeedforward')
    #else:
    #    raise RuntimeError('You must use MODEL= \'present\' or \'future\' to use the reducesImpedanceFeedbackFeedforward function')

    if outdir is not None:

        impedanceScenario.importInputTableFromList([
            freq_array,
            np.real(2 * Zrf4secnew + ncavities * Zrf3or5secnew),
            np.imag(2 * Zrf4secnew + ncavities * Zrf3or5secnew)
        ], 'cavities/200MHz_total_reducedFF')

        # plot
        myncols = 3
        mynrows = 3
        fig, ax = plt.subplots(
            nrows=mynrows,
            ncols=myncols)  #, sharex=True,sharey=True) #) #2) #,sharex=True)
        fig.set_size_inches(1.5 * 4.0 * myncols, 1.5 * 2.0 * mynrows)

        for nrow in [0, 1]:

            if ('3sections' in elID_dict.keys()): nsec = '3'
            elif ('5sections' in elID_dict.keys()): nsec = '5'

            #print('nrow =', nrow)

            if (nrow == 0):
                ZbA = Zb4sec
                #ZtwcA   = Zb4sec
                ZrfA = Zrf4sec
                ZrfnewA = Zrf4secnew
                nsecA = '4'

            elif (nrow == 1):
                ZbA = Zb3or5sec
                #ZtwcA   = Zb3or5sec
                ZrfA = Zrf3or5sec
                ZrfnewA = Zrf3or5secnew
                nsecA = nsec

            print('ZbA =', ZbA, max(np.abs(ZbA)))
            print('ZrfA =', ZrfA, max(np.abs(ZrfA)))
            print('ZrfnewA =', ZrfnewA, max(np.abs(ZrfnewA)))
            print('')

            #ax[nrow][0].plot(freq_array/1e6, np.real(ZtwcA)/1e6, '-y', label=r'Re($Z_{twc,'+nsecA+r'}$)', alpha=0.5)
            #ax[nrow][1].plot(freq_array/1e6, np.imag(ZtwcA)/1e6, '-y', label=r'Im($Z_{twc,'+nsecA+r'}$)', alpha=0.5)
            #ax[nrow][2].plot(freq_array/1e6, np.abs( ZtwcA)/1e6, '-y', label=r'|$Z_{twc,'+nsecA+r'}$|'  , alpha=0.5)

            ax[nrow][0].plot(freq_array / 1e6,
                             np.real(ZbA) / 1e6,
                             '--r',
                             label=r'Re($Z_{b,' + nsecA + r'}$)',
                             alpha=0.5)  # = ReZb
            ax[nrow][1].plot(freq_array / 1e6,
                             np.imag(ZbA) / 1e6,
                             '--r',
                             label=r'Im($Z_{b,' + nsecA + r'}$)',
                             alpha=0.5)  # = ImZb
            ax[nrow][2].plot(freq_array / 1e6,
                             np.abs(ZbA) / 1e6,
                             '--r',
                             label=r'|$Z_{b,' + nsecA + r'}$|',
                             alpha=0.5)  # = |Zb|

            ax[nrow][0].plot(freq_array / 1e6,
                             np.real(ZrfA) / 1e6,
                             '-b',
                             label=r'Re($Z_{rf,' + nsecA + r'}$)',
                             alpha=0.8)  # = ReZrf = Zrf
            ax[nrow][1].plot(freq_array / 1e6,
                             np.imag(ZrfA) / 1e6,
                             '-b',
                             label=r'Im($Z_{rf,' + nsecA + r'}$)',
                             alpha=0.8)  # = zero by definition
            ax[nrow][2].plot(freq_array / 1e6,
                             np.abs(ZrfA) / 1e6,
                             '-b',
                             label=r'|$Z_{rf,' + nsecA + r'}$|',
                             alpha=0.8)  # = |Zrf|

            ax[nrow][0].plot(freq_array / 1e6,
                             np.real(ZrfnewA) / 1e6,
                             ':k',
                             label=r'Re($Z_{rf,' + nsecA + r'}^{new}$)',
                             alpha=1.0)
            ax[nrow][1].plot(freq_array / 1e6,
                             np.imag(ZrfnewA) / 1e6,
                             ':k',
                             label=r'Im($Z_{rf,' + nsecA + r'}^{new}$)',
                             alpha=1.0)
            ax[nrow][2].plot(freq_array / 1e6,
                             np.abs(ZrfnewA) / 1e6,
                             ':k',
                             label=r'|$Z_{rf,' + nsecA + r'}^{new}$|',
                             alpha=1.0)

            #ax[nrow][2].plot(freq_array/1e6, 20*np.log10( np.abs(ZrfnewA)/np.abs(ZbA) )/100., '-g', label=r'20 log( |$Z_{rf,'+nsecA+r'}^{new}|/|Z_{b,'+nsecA+r'}$| ) /100'+f'\n(min = {min(20*np.log10( np.abs(ZrfnewA)/np.abs(ZbA) )):.4f})', alpha=1.0)
            ##ax[nrow][2].plot(freq_array/1e6, -0.3*np.ones(len(freq_array)), ':', color='#888888')

        for nrow in [2]:

            ZbA = Zb4sec
            #ZtwcA   = Zb4sec
            ZrfA = Zrf4sec
            ZrfnewA = Zrf4secnew
            nsecA = '4'

            ZbB = Zb3or5sec
            #ZtwcB   = Zb3or5sec
            ZrfB = Zrf3or5sec
            ZrfnewB = Zrf3or5secnew
            nsecB = nsec

            #ax[nrow][0].plot(freq_array/1e6, np.real(2*ZtwcA+ncavities*ZtwcB)/1e6, '-y', label=r'Re($2 Z_{twc,'+nsecB+r'} + '+str(ncavities)+r' Z_{twc,'+nsecB+r'}$)', alpha=0.5) # = ReZtwc
            #ax[nrow][1].plot(freq_array/1e6, np.imag(2*ZtwcA+ncavities*ZtwcB)/1e6, '-y', label=r'Im($2 Z_{twc,'+nsecB+r'} + '+str(ncavities)+r' Z_{twc,'+nsecB+r'}$)', alpha=0.5) # = ImZtwc
            #ax[nrow][2].plot(freq_array/1e6, np.abs( 2*ZtwcA+ncavities*ZtwcB)/1e6, '-y', label=r'|$2 Z_{twc,'+nsecB+r'} + '+str(ncavities)+r' Z_{twc,'+nsecB+r'}$|'  , alpha=0.5) # = |Ztwc|

            ax[nrow][0].plot(freq_array / 1e6,
                             np.real(2 * ZbA + ncavities * ZbB) / 1e6,
                             '--r',
                             label=r'Re($2 Z_{b,' + nsecA + r'} + ' +
                             str(ncavities) + r' Z_{b,' + nsecB + r'}$)',
                             alpha=0.5)  # = ReZb
            ax[nrow][1].plot(freq_array / 1e6,
                             np.imag(2 * ZbA + ncavities * ZbB) / 1e6,
                             '--r',
                             label=r'Im($2 Z_{b,' + nsecA + r'} + ' +
                             str(ncavities) + r' Z_{b,' + nsecB + r'}$)',
                             alpha=0.5)  # = ImZb
            ax[nrow][2].plot(freq_array / 1e6,
                             np.abs(2 * ZbA + ncavities * ZbB) / 1e6,
                             '--r',
                             label=r'|$2 Z_{b,' + nsecA + r'} + ' +
                             str(ncavities) + r' Z_{b,' + nsecB + r'}$|',
                             alpha=0.5)  # = |Zb|

            ax[nrow][0].plot(freq_array / 1e6,
                             np.real(2 * ZrfA + ncavities * ZrfB) / 1e6,
                             '-b',
                             label=r'Re($2 Z_{rf,' + nsecA + r'} + ' +
                             str(ncavities) + r' Z_{rf,' + nsecB + r'}$)',
                             alpha=0.8)  # = ReZrf = Zrf
            ax[nrow][1].plot(freq_array / 1e6,
                             np.imag(2 * ZrfA + ncavities * ZrfB) / 1e6,
                             '-b',
                             label=r'Im($2 Z_{rf,' + nsecA + r'} + ' +
                             str(ncavities) + r' Z_{rf,' + nsecB + r'}$)',
                             alpha=0.8)  # = zero by definition
            ax[nrow][2].plot(freq_array / 1e6,
                             np.abs(2 * ZrfA + ncavities * ZrfB) / 1e6,
                             '-b',
                             label=r'|$2 Z_{rf,' + nsecA + r'} + ' +
                             str(ncavities) + r' Z_{rf,' + nsecB + r'}$|',
                             alpha=0.8)  # = |Zrf|

            ax[nrow][0].plot(freq_array / 1e6,
                             np.real(2 * ZrfnewA + ncavities * ZrfnewB) / 1e6,
                             ':k',
                             label=r'Re($2 Z_{rf,' + nsecA + r'}^{new} + ' +
                             str(ncavities) + r' Z_{rf,' + nsecB +
                             r'}^{new}$)',
                             alpha=1.0)
            ax[nrow][1].plot(freq_array / 1e6,
                             np.imag(2 * ZrfnewA + ncavities * ZrfnewB) / 1e6,
                             ':k',
                             label=r'Im($2 Z_{rf,' + nsecA + r'}^{new} + ' +
                             str(ncavities) + r' Z_{rf,' + nsecB +
                             r'}^{new}$)',
                             alpha=1.0)
            ax[nrow][2].plot(freq_array / 1e6,
                             np.abs(2 * ZrfnewA + ncavities * ZrfnewB) / 1e6,
                             ':k',
                             label=r'|$2 Z_{rf,' + nsecA + r'}^{new} + ' +
                             str(ncavities) + r' Z_{rf,' + nsecB +
                             r'}^{new}$|',
                             alpha=1.0)

            ##ax[nrow][2].plot(freq_array/1e6, 10*np.log10(np.abs(2*ZrfnewA + ncavities*ZrfnewB)/np.abs(2*ZbA+ncavities*ZbB))/100., '-g', label=r'log|$2 Z_{rf,'+nsecB+r'}^{new} + '+str(ncavities)+r' Z_{rf,'+nsecB+r'}^{new}$|/|$2 Z_{b,'+nsecB+r'} + '+str(ncavities)+r' Z_{b,'+nsecB+r'}$|/10'  , alpha=1.0)
            ##ax[nrow][2].plot(freq_array/1e6, -0.3*np.ones(len(freq_array)), ':', color='#888888')

        for i in range(mynrows):
            ax[i][0].set_ylabel('Impedance (M$\Omega$)')
            for j in range(myncols):
                if (i == 0):
                    ax[mynrows - 1][j].set_xlabel('f (MHz)')
                    #if(j==2-1):
                ax[i][j].legend(frameon=False, loc='upper left')  # loc='best')
                ax[i][j].set_xlim(180, 220)
                ax[i][j].grid()

        fig.tight_layout()
        fig.savefig(outdir + '/plot_reduce_impedance_feedforward_feedback.pdf')
        print('Saving',
              outdir + '/plot_reduce_impedance_feedforward_feedback.pdf ...\n')
        fig.clf()
Пример #7
0
    ax8.set_ylabel("RF current [A]")
    ax8.legend()
    logging.info("Peak beam current, meas %.10f A" %(peak_rf_current))
    logging.info("Peak beam current, theor %.4f A" %(2*N_b*e/bunch_spacing))


if IMP_RESP == True:

    # Impulse response of beam- and generator-induced voltage for TWC
    # Comparison of wake and impulse resonse
    time = np.linspace(-1e-6, 4.e-6, 10000)
    TWC_v1 = SPS4Section200MHzTWC()
    TWC_v1.impulse_response_beam(2*np.pi*f_rf, time)
    TWC_v1.impulse_response_gen(2*np.pi*f_rf, time)
    TWC_v1.compute_wakes(time)
    TWC_v2 = TravelingWaveCavity(0.876e6, f_rf, 2*np.pi*6.207e-7)
    TWC_v2.wake_calc(time - time[0])
    t_beam = time - time[0]
    t_gen = time - time[0] - 0.5*TWC_v1.tau

    plt.figure()
    plt.plot(TWC_v2.time_array, TWC_v2.wake, 'b', marker='.', label='wake, impedances')
    plt.plot(t_beam, TWC_v1.W_beam, 'r', marker='.', label='cav wake, OTFB')
    plt.plot(t_beam, TWC_v1.h_beam.real, 'g', marker='.', label='hs_cav, OTFB')
    plt.plot(t_gen, TWC_v1.W_gen, 'orange', marker='.', label='gen wake, OTFB')
    plt.plot(t_gen, TWC_v1.h_gen.real, 'purple', marker='.', label='hs_gen, OTFB')
    plt.xlabel("Time [s]")
    plt.ylabel("Wake/impulse response [Ohms/s]")
    plt.legend()

Пример #8
0
    ax8.set_ylabel("RF current [A]")
    ax8.legend()
    logging.info("Peak beam current, meas %.10f A" %(peak_rf_current))
    logging.info("Peak beam current, theor %.4f A" %(2*N_b*e/bunch_spacing))


if IMP_RESP == True:

    # Impulse response of beam- and generator-induced voltage for TWC
    # Comparison of wake and impulse resonse
    time = np.linspace(-1e-6, 4.e-6, 10000)
    TWC_v1 = SPS4Section200MHzTWC()
    TWC_v1.impulse_response_beam(2*np.pi*f_rf, time)
    TWC_v1.impulse_response_gen(2*np.pi*f_rf, time)
    TWC_v1.compute_wakes(time)
    TWC_v2 = TravelingWaveCavity(0.876e6, f_rf, 2*np.pi*6.207e-7) # From impedance sources, params: R_S, frequency_R, a_factor
    TWC_v2.wake_calc(time - time[0])
    t_beam = time - time[0]
    t_gen = time - time[0] - 0.5*TWC_v1.tau

    plt.figure()
    plt.plot(TWC_v2.time_array, TWC_v2.wake, 'b', marker='.', label='wake, impedances')
    plt.plot(t_beam, TWC_v1.W_beam, 'r', marker='.', label='beam wake, OTFB')
    plt.plot(t_beam, TWC_v1.h_beam.real, 'g', marker='.', label='hs_beam, OTFB')
    plt.plot(t_gen, TWC_v1.W_gen, 'orange', marker='.', label='gen wake, OTFB')
    plt.plot(t_gen, TWC_v1.h_gen.real, 'purple', marker='.', label='hs_gen, OTFB')
    plt.xlabel("Time [s]")
    plt.ylabel("Wake/impulse response [Ohms/s]")
    plt.legend()