def getAvgGapPhase(self): """ Returns average phase for all RF gaps in the cavity """ avg_phase = 0. phase = 0. if (len(self.__rfGaps) > 0): phase = phaseNearTargetPhase(self.__rfGaps[0].getGapPhase(), 0.) for rfGap in self.__rfGaps: phase_new = phaseNearTargetPhase(rfGap.getGapPhase(), phase) avg_phase += phase_new phase = phase_new if (len(self.__rfGaps) > 0): avg_phase /= len(self.__rfGaps) return avg_phase
def reverseOrder(self): """ Reverse order of RF gaps in the cavity. The first gap should become the last and vice versa. """ n_gaps = len(self.__rfGaps) if (n_gaps == 0): return self.__rfGaps.reverse() self.__rfGaps[0].setAsFirstRFGap(True) for ind in range(1, n_gaps): self.__rfGaps[ind].setAsFirstRFGap(False) for rfGap in self.__rfGaps: gap_phase = rfGap.getGapPhase() gap_phase = gap_phase + rfGap.getParam("mode") * math.pi gap_phase = -gap_phase + math.pi gap_phase = phaseNearTargetPhase(gap_phase, 0.) rfGap.setGapPhase(gap_phase) self.setPhase(self.__rfGaps[0].getGapPhase()) self.setDesignSetUp(False)
def trackDesign(self, paramsDict): """ The method is tracking the design synchronous particle through the RF Gap. If the gap is a first gap in the cavity we put the arrival time as a cavity parameter. The pair of the cavity design phase and this arrival time at the first gap are used during the real bunch tracking. """ nParts = self.getnParts() index = self.getActivePartIndex() part_length = self.getLength(index) bunch = paramsDict["bunch"] syncPart = bunch.getSyncParticle() eKin_in = syncPart.kinEnergy() #---- parameter E0L is in GeV, but cppGapModel = RfGapThreePointTTF() uses fields in V/m E0L = 1.0e+9*self.getParam("E0L") modePhase = self.baserf_gap.getParam("mode")*math.pi rfCavity = self.getRF_Cavity() rf_ampl = rfCavity.getDesignAmp() arrival_time = syncPart.time() frequency = rfCavity.getFrequency() phase = rfCavity.getFirstGapEtnrancePhase() #---- calculate the entance phase if(self.isFirstRFGap() and index == 0): rfCavity.setDesignArrivalTime(arrival_time) phase = self.__calculate_first_part_phase(bunch) rfCavity.setFirstGapEtnrancePhase(phase) rfCavity.setFirstGapEtnranceDesignPhase(phase) rfCavity.setDesignSetUp(True) rfCavity._setDesignPhase(rfCavity.getPhase()) rfCavity._setDesignAmp(rfCavity.getAmp()) #print "debug firs gap first part phase=",phase*180./math.pi," arr time=",arrival_time else: first_gap_arr_time = rfCavity.getDesignArrivalTime() #print "debug name=",self.getName()," delta_phase=",frequency*(arrival_time - first_gap_arr_time)*360.0," phase=",phase*180/math.pi phase = math.fmod(frequency*(arrival_time - first_gap_arr_time)*2.0*math.pi+phase,2.0*math.pi) if(index == 0): self.part_pos = self.z_min self.gap_phase_vs_z_arr = [[self.part_pos,phase],] #print "debug design name=",self.getName()," index=",index," pos=",self.part_pos," arr_time=",arrival_time," phase=",phase*180./math.pi," freq=",frequency zm = self.part_pos z0 = zm + part_length/2 zp = z0 + part_length/2 Em = E0L*rf_ampl*self.axis_field_func.getY(zm) E0 = E0L*rf_ampl*self.axis_field_func.getY(z0) Ep = E0L*rf_ampl*self.axis_field_func.getY(zp) #---- advance the particle position self.tracking_module.drift(bunch,part_length/2) self.part_pos += part_length/2 #call rf gap model to track the bunch time_middle_gap = syncPart.time() - arrival_time delta_phase = math.fmod(2*math.pi*time_middle_gap*frequency,2.0*math.pi) self.gap_phase_vs_z_arr.append([self.part_pos,phase+delta_phase]) #---- this part is the debugging ---START--- #eKin_out = syncPart.kinEnergy() #s = "debug pos[mm]= %7.2f "%(self.part_pos*1000.) #s += " ekin= %9.6f"%(syncPart.kinEnergy()*1000.) #s += " phase = %9.2f "%(phaseNearTargetPhaseDeg((phase+delta_phase)*180./math.pi,0.)) #s += " dE= %9.6f "%((eKin_out-eKin_in)*1000.) #print s #---- this part is the debugging ---STOP--- self.cppGapModel.trackBunch(bunch,part_length/2,Em,E0,Ep,frequency,phase+delta_phase+modePhase) self.tracking_module.drift(bunch,part_length/2) #---- advance the particle position self.part_pos += part_length/2 time_middle_gap = syncPart.time() - arrival_time delta_phase = math.fmod(2*math.pi*time_middle_gap*frequency,2.0*math.pi) self.gap_phase_vs_z_arr.append([self.part_pos,phase+delta_phase]) #---- this part is the debugging ---START--- #eKin_out = syncPart.kinEnergy() #s = "debug pos[mm]= %7.2f "%(self.part_pos*1000.) #s += " ekin= %9.6f"%(syncPart.kinEnergy()*1000.) #s += " phase = %9.2f "%(phaseNearTargetPhaseDeg((phase+delta_phase)*180./math.pi,0.)) #s += " dE= %9.6f "%((eKin_out-eKin_in)*1000.) #print s #---- this part is the debugging ---STOP--- #---- Calculate the phase at the center if(index == (nParts - 1)): pos_old = self.gap_phase_vs_z_arr[0][0] phase_gap = self.gap_phase_vs_z_arr[0][1] ind_min = -1 for ind in range(1,len(self.gap_phase_vs_z_arr)): [pos,phase_gap] = self.gap_phase_vs_z_arr[ind] if(math.fabs(pos) >= math.fabs(pos_old)): ind_min = ind -1 phase_gap = self.gap_phase_vs_z_arr[ind_min][1] phase_gap = phaseNearTargetPhase(phase_gap,0.) self.gap_phase_vs_z_arr[ind_min][1] = phase_gap break pos_old = pos self.setGapPhase(phase_gap) #---- wrap all gap part's phases around the central one if(ind_min > 0): for ind in range(ind_min-1,-1,-1): [pos,phase_gap] = self.gap_phase_vs_z_arr[ind] [pos,phase_gap1] = self.gap_phase_vs_z_arr[ind+1] self.gap_phase_vs_z_arr[ind][1] = phaseNearTargetPhase(phase_gap,phase_gap1) for ind in range(ind_min+1,len(self.gap_phase_vs_z_arr)): [pos,phase_gap] = self.gap_phase_vs_z_arr[ind] [pos,phase_gap1] = self.gap_phase_vs_z_arr[ind-1] self.gap_phase_vs_z_arr[ind][1] = phaseNearTargetPhase(phase_gap,phase_gap1)
def __calculate_first_part_phase(self,bunch_in): rfCavity = self.getRF_Cavity() #---- the design phase at the center of the RF gap #---- (this is from a thin gap approach) frequency = rfCavity.getFrequency() modePhase = self.baserf_gap.getParam("mode")*math.pi phase_cavity = rfCavity.getPhase() #---- parameter E0L is in GeV, but cppGapModel = RfGapThreePointTTF() uses fields in V/m E0L_local = 1.0e+9*rfCavity.getAmp()*self.getParam("E0L") #---- we have to find the phase_start #---- which is the phase at the distance z_min before the gap center #---- z_min by defenition is negative bunch = AxisFieldRF_Gap.static_test_bunch bunch_in.copyEmptyBunchTo(bunch) syncPart = bunch.getSyncParticle() syncPart.time(0.) eKin_init = syncPart.kinEnergy() #print "debug eKin[MeV]= %9.5f"%(syncPart.kinEnergy()*1000.) beta = syncPart.beta() phase_adv = 2.0*math.pi*frequency*math.fabs(self.z_min)/(beta*speed_of_light) #print "debug phase diff at start=",phase_adv*180./math.pi phase_start = phaseNearTargetPhase(phase_cavity - phase_adv,0.) #print "debug phase at start=",phase_start*180./math.pi phase_cavity_new = phase_cavity + 10*self.phase_tolerance while(math.fabs(phase_cavity_new-phase_cavity) > self.phase_tolerance*math.pi/180.): bunch_in.copyEmptyBunchTo(bunch) syncPart.time(0.) syncPart.kinEnergy(eKin_init) z_old = self.z_min z = self.z_min + self.z_step while(z < 0.): if((z+ self.z_step) > 0.): z = 0. if(math.fabs(z - z_old) < self.z_tolerance): break half_step = (z - z_old)/2 zm = z_old z0 = zm + half_step zp = z0 + half_step self.tracking_module.drift(bunch,half_step) time_gap = syncPart.time() delta_phase = 2*math.pi*time_gap*frequency Em = E0L_local*self.axis_field_func.getY(zm) E0 = E0L_local*self.axis_field_func.getY(z0) Ep = E0L_local*self.axis_field_func.getY(zp) #s = "debug z[mm]= %7.2f "%(z0*1000.) #s += " ekin= %9.5f"%(syncPart.kinEnergy()*1000.) #s += " phase = %9.2f "%(phaseNearTargetPhaseDeg((phase_start+delta_phase+modePhase)*180./math.pi,0.)) #print s self.cppGapModel.trackBunch(bunch,half_step,Em,E0,Ep,frequency,phase_start+delta_phase+modePhase) self.tracking_module.drift(bunch,half_step) #time_gap = syncPart.time() #delta_phase = 2*math.pi*time_gap*frequency #s = "debug z[mm]= %7.2f "%(zp*1000.) #s += " ekin= %9.5f"%(syncPart.kinEnergy()*1000.) #s += " phase = %9.2f "%(phaseNearTargetPhaseDeg((phase_start+delta_phase+modePhase)*180./math.pi,0.)) #print s z_old = z z = z_old + self.z_step time_gap = syncPart.time() delta_phase =2*math.pi*time_gap*frequency phase_cavity_new = phaseNearTargetPhase(phase_start+delta_phase,0.) #s = " phase_diff = %8.4f "%(delta_phase*180./math.pi) #s += " phase_cavity = %8.4f "%(phase_cavity*180./math.pi) #s += " new = %8.4f "%(phase_cavity_new *180./math.pi) #s += " phase_start = %8.4f "%(phase_start*180./math.pi) #s += " eKin[MeV]= %9.5f "%(syncPart.kinEnergy()*1000.) #s += " dE[MeV]= %9.6f "%(syncPart.kinEnergy()*1000. - 2.5) #print "debug "+s phase_start -= 0.8*(phase_cavity_new - phase_cavity) #---- undo the last change in the while loop phase_start += 0.8*(phase_cavity_new - phase_cavity) #print "debug phase_start=",phase_start*180./math.pi return phase_start
def track(self, paramsDict): """ The AxisFieldRF_Gap class implementation of the AccNode class track(probe) method. User have to track the design bunch first to setup all gaps arrival time. """ rfCavity = self.getRF_Cavity() if(not rfCavity.isDesignSetUp()): sequence = self.getSequence() accLattice = sequence.getLinacAccLattice() msg = "The AxisFieldRF_Gap class. " msg += "You have to run trackDesign on the LinacAccLattice" msg += "first to initialize all RF Cavities' phases!" msg += os.linesep if(accLattice != None): msg = msg + "Lattice =" + accLattice.getName() msg = msg + os.linesep if(sequence != None): msg = msg + "Sequence =" + sequence.getName() msg = msg + os.linesep msg = msg + "RF Cavity =" + rfCavity.getName() msg = msg + os.linesep msg = msg + "Name of element=" + self.getName() msg = msg + os.linesep msg = msg + "Type of element=" + self.getType() msg = msg + os.linesep orbitFinalize(msg) #----------------------------------------- nParts = self.getnParts() index = self.getActivePartIndex() part_length = self.getLength(index) bunch = paramsDict["bunch"] syncPart = bunch.getSyncParticle() eKin_in = syncPart.kinEnergy() E0L = 1.0e+9*self.getParam("E0L") modePhase = self.baserf_gap.getParam("mode")*math.pi frequency = rfCavity.getFrequency() rf_ampl = rfCavity.getAmp() arrival_time = syncPart.time() designArrivalTime = rfCavity.getDesignArrivalTime() phase_shift = rfCavity.getPhase() - rfCavity.getDesignPhase() phase = rfCavity.getFirstGapEtnrancePhase() + phase_shift #---------------------------------------- phase = math.fmod(frequency*(arrival_time - designArrivalTime)*2.0*math.pi + phase,2.0*math.pi) if(index == 0): self.part_pos = self.z_min self.gap_phase_vs_z_arr = [[self.part_pos,phase],] zm = self.part_pos z0 = zm + part_length/2 zp = z0 + part_length/2 Em = E0L*rf_ampl*self.axis_field_func.getY(zm) E0 = E0L*rf_ampl*self.axis_field_func.getY(z0) Ep = E0L*rf_ampl*self.axis_field_func.getY(zp) #---- advance the particle position self.tracking_module.drift(bunch,part_length/2) self.part_pos += part_length/2 #call rf gap model to track the bunch time_middle_gap = syncPart.time() - arrival_time delta_phase = math.fmod(2*math.pi*time_middle_gap*frequency,2.0*math.pi) self.gap_phase_vs_z_arr.append([self.part_pos,phase+delta_phase]) #---- this part is the debugging ---START--- #eKin_out = syncPart.kinEnergy() #s = "debug pos[mm]= %7.2f "%(self.part_pos*1000.) #s += " ekin= %9.6f"%(syncPart.kinEnergy()*1000.) #s += " phase = %9.2f "%(phaseNearTargetPhaseDeg((phase+delta_phase)*180./math.pi,0.)) #s += " dE= %9.6f "%((eKin_out-eKin_in)*1000.) #print s #---- this part is the debugging ---STOP--- self.cppGapModel.trackBunch(bunch,part_length/2,Em,E0,Ep,frequency,phase+delta_phase+modePhase) self.tracking_module.drift(bunch,part_length/2) #---- advance the particle position self.part_pos += part_length/2 time_middle_gap = syncPart.time() - arrival_time delta_phase = math.fmod(2*math.pi*time_middle_gap*frequency,2.0*math.pi) self.gap_phase_vs_z_arr.append([self.part_pos,phase+delta_phase]) #---- this part is the debugging ---START--- #eKin_out = syncPart.kinEnergy() #s = "debug pos[mm]= %7.2f "%(self.part_pos*1000.) #s += " ekin= %9.6f"%(syncPart.kinEnergy()*1000.) #s += " phase = %9.2f "%(phaseNearTargetPhaseDeg((phase+delta_phase)*180./math.pi,0.)) #s += " dE= %9.6f "%((eKin_out-eKin_in)*1000.) #print s #---- this part is the debugging ---STOP--- #---- Calculate the phase at the center if(index == (nParts - 1)): pos_old = self.gap_phase_vs_z_arr[0][0] phase_gap = self.gap_phase_vs_z_arr[0][1] ind_min = -1 for ind in range(1,len(self.gap_phase_vs_z_arr)): [pos,phase_gap] = self.gap_phase_vs_z_arr[ind] if(math.fabs(pos) >= math.fabs(pos_old)): ind_min = ind -1 phase_gap = self.gap_phase_vs_z_arr[ind_min][1] phase_gap = phaseNearTargetPhase(phase_gap,0.) self.gap_phase_vs_z_arr[ind_min][1] = phase_gap break pos_old = pos self.setGapPhase(phase_gap) #---- wrap all gap part's phases around the central one if(ind_min > 0): for ind in range(ind_min-1,-1,-1): [pos,phase_gap] = self.gap_phase_vs_z_arr[ind] [pos,phase_gap1] = self.gap_phase_vs_z_arr[ind+1] self.gap_phase_vs_z_arr[ind][1] = phaseNearTargetPhase(phase_gap,phase_gap1) for ind in range(ind_min+1,len(self.gap_phase_vs_z_arr)): [pos,phase_gap] = self.gap_phase_vs_z_arr[ind] [pos,phase_gap1] = self.gap_phase_vs_z_arr[ind-1] self.gap_phase_vs_z_arr[ind][1] = phaseNearTargetPhase(phase_gap,phase_gap1)