def getLattice(lattice_length,n_parts,spaceChargeCalculator2p5D): elem = teapot.DriftTEAPOT("my_drift") elem.setLength(lattice_length) elem.setnParts(n_parts) teapot_lattice = teapot.TEAPOT_Lattice("teapot_lattice") teapot_lattice.addNode(elem) teapot_lattice.initialize() # we will put SC nodes as frequently as possible. # In this case one for each part of the Drift node sc_path_length_min = 0.00000001 scLatticeModifications.setSC2p5DAccNodes(teapot_lattice, sc_path_length_min,spaceChargeCalculator2p5D) return teapot_lattice
def getLattice(lattice_length, n_parts, spaceChargeCalculator2p5D): elem = teapot.DriftTEAPOT("my_drift") elem.setLength(lattice_length) elem.setnParts(n_parts) teapot_lattice = teapot.TEAPOT_Lattice("teapot_lattice") teapot_lattice.addNode(elem) teapot_lattice.initialize() # we will put SC nodes as frequently as possible. # In this case one for each part of the Drift node sc_path_length_min = 0.00000001 scLatticeModifications.setSC2p5DAccNodes(teapot_lattice, sc_path_length_min, spaceChargeCalculator2p5D) return teapot_lattice
tunes = TeapotTuneAnalysisNode("tune_analysis") tunes.assignTwiss(TwissDataX0[2][0][1], TwissDataX0[1][0][1], 0.0, 0.0, TwissDataY0[2][0][1], TwissDataY0[1][0][1]) addTeapotDiagnosticsNode(lattice, 0, tunes) print("Tune analysis node added") #----------------------------Add Space Charge nodes---------------------------------------------------- sc_path_length_min = 0.000001 sizeX = 32 #number of grid points in horizontal direction sizeY = 32 #number of grid points in vertical direction sizeZ = 16 #number of longitudinal slices calc2p5d = SpaceChargeForceCalc2p5D(sizeX, sizeY, sizeZ) scLatticeModifications.setSC2p5DAccNodes(lattice, sc_path_length_min, calc2p5d) print "SC nodes appied to the lattice" #--------------------------------Tracking----------------------------------------- print("tracking") x_space0 = [(b.x(i), b.px(i)) for i in range(n_particles)] bunchtwissanalysis = BunchTwissAnalysis() bunchtwissanalysis.analyzeBunch(b) Ex = bunchtwissanalysis.getEmittance(0) Ey = bunchtwissanalysis.getEmittance(1) x = bunchtwissanalysis.getCorrelation(0, 0) y = bunchtwissanalysis.getCorrelation(2, 2)
#---------------------------------------------- #make 2.5D space charge calculator #---------------------------------------------- #set boundary nboundarypoints = 128 n_freespacemodes = 32 r_boundary = 0.110 boundary = Boundary2D(nboundarypoints, n_freespacemodes, "Circle", r_boundary, r_boundary) sizeX = 64 #number of grid points in horizontal direction sizeY = 64 #number of grid points in vertical direction sizeZ = 1 #number of longitudinal slices in the 2.5D space charge solver calc2p5d = SpaceChargeCalc2p5D(sizeX, sizeY, sizeZ) sc_path_length_min = 0.00000001 scLatticeModifications.setSC2p5DAccNodes(teapot_latt, sc_path_length_min, calc2p5d, boundary) #----------------------------------------------- # Add longitudinal space charge node with Imped #----------------------------------------------- b_a = 10.0 / 3.0 length = lattlength nMacrosMin = 1000 useSpaceCharge = 1 nBins = 128 #number of longitudinal slices in the 1D space charge solver position = 64.0 #SNS Longitudinal Impedance tables. EKicker impedance from private communication # with J.G. Wang. Seems to be for 7 of the 14 kickers (not sure why). # Impedance in Ohms/n. Kicker and RF impedances are inductive with real part positive and imaginary is negative by Chao definition.
paramsDict["lostbunch"]=lostbunch paramsDict["bunch"]= bunch #############################-------------------######################## ############################# SPACE CHARGE ######################## #############################-------------------######################## # Add space charge nodes #---------------------------------------------------- if s['Space_Charge']: print '\n\t\tAdding slice-by-slice space charge nodes on MPI process: ', rank # Make a SC solver calcsbs = SpaceChargeCalcSliceBySlice2D(s['GridSizeX'], s['GridSizeY'], s['GridSizeZ'], useLongitudinalKick=True) sc_path_length_min = 1E-8 # Add the space charge solver to the lattice as child nodes sc_nodes = scLatticeModifications.setSC2p5DAccNodes(Lattice, sc_path_length_min, calcsbs) print '\n\t\tInstalled', len(sc_nodes), 'space charge nodes ...' # Add tune analysis child node #----------------------------------------------------- parentnode_number = 97 parentnode = Lattice.getNodes()[parentnode_number] Twiss_at_parentnode_entrance = Lattice.getNodes()[parentnode_number-1].getParamsDict() tunes = TeapotTuneAnalysisNode("tune_analysis") tunes.assignTwiss(*[Twiss_at_parentnode_entrance[k] for k in ['betax','alphax','etax','etapx','betay','alphay','etay','etapy']]) tunes.assignClosedOrbit(*[Twiss_at_parentnode_entrance[k] for k in ['orbitx','orbitpx','orbity','orbitpy']]) addTeapotDiagnosticsNodeAsChild(Lattice, parentnode, tunes) # Define twiss analysis and output dictionary
#---------------------------------------------- #make 2.5D space charge calculator #---------------------------------------------- #set boundary nboundarypoints = 128 n_freespacemodes = 32 r_boundary = 0.220 boundary = Boundary2D(nboundarypoints,n_freespacemodes,"Circle",r_boundary,r_boundary) sizeX = 64 #number of grid points in horizontal direction sizeY = 64 #number of grid points in vertical direction sizeZ = 1 #number of longitudinal slices in the 2.5D space charge solver calc2p5d = SpaceChargeCalc2p5D(sizeX,sizeY,sizeZ) sc_path_length_min = 0.00000001 scLatticeModifications.setSC2p5DAccNodes(teapot_latt, sc_path_length_min,calc2p5d, boundary) #----------------------------------------------- # Add longitudinal space charge node with Imped #----------------------------------------------- b_a = 10.0/3.0 length = lattlength nMacrosMin = 1000 useSpaceCharge = 1 nBins= 128 #number of longitudinal slices in the 1D space charge solver position = 64.0 #SNS Longitudinal Impedance tables. EKicker impedance from private communication # with J.G. Wang. Seems to be for 7 of the 14 kickers (not sure why). # Impedance in Ohms/n. Kicker and RF impedances are inductive with real part positive and imaginary is negative by Chao definition.
boundary.setBoundaryPoint(i,x,y) boundary.initialize() #------------------------------------------------------------------------- """ For the Boundary2D class it is possible to have the predefined shapes Circle - the last parameter will be the diameter of the circle Ellipse - there will be two parameters at the end - 2*a and 2*b where a,b are semi-axises Rectangle - there will be two parameters at the end - horizontal and vertical sizes """ #------------------------------------------------------------------------- #boundary = Boundary2D(nBoundaryPoints,N_FreeSpaceModes,"Circle",2*R_Boundary) sc_path_length_min = 0.05 scNode_arr = scLatticeModifications.setSC2p5DAccNodes(teapot_lattice, sc_path_length_min, calc2p5d) #scNode_arr = scLatticeModifications.setSC2p5DAccNodes(teapot_lattice, sc_path_length_min, calc2p5d, boundary) #track lattice #teapot_lattice.trackBunch(b) slice_length=0.1 calc2p5d.trackBunch(b,slice_length) #------------------------------------- # momentum change # coeff is: 2*r0*L*lambda/e*(gamma^3*beta^2) # r/a^2 and grad/macrosize #------------------------------------- xyp_coeff = 2*b.classicalRadius()*b.charge()**2*0.1/(b.getSyncParticle().gamma()**3*b.getSyncParticle().beta()**2) for ip in range(10): x = b.x(ip)
#make 2.5D space charge calculator sizeX = 128 sizeY = 128 sizeZ = 32 xy_ratio = 10.0 calc2p5d = SpaceChargeCalc2p5D(sizeX, sizeY, sizeZ, xy_ratio) # boundary nBoundaryPoints = 128 N_FreeSpaceModes = 32 boundary_radius = 0.11 boundary = Boundary2D(nBoundaryPoints, N_FreeSpaceModes, "Circle", 2 * boundary_radius) #=====track bunch through SC Node============ sc_path_length_min = 0.05 scNode_arr = scLatticeModifications.setSC2p5DAccNodes(lattice, sc_path_length_min, calc2p5d, boundary) ACC_TURNS = 1 print("Tracking.") for i in range(ACC_TURNS): lattice.trackBunch(b) print "Turn ", i # dump ORBIT_MPI bunch to compare results bunch_pyorbit_to_orbit(lattice.getLength(), b, runName + "_pyorbit_output.dat") print("STOP.")
#make 2.5D space charge calculator sizeX = 256 sizeY = sizeX sizeZ = 1 xy_ratio = 1.0 calc2p5d = SpaceChargeCalc2p5D(sizeX,sizeY,sizeZ,xy_ratio) # boundary nBoundaryPoints = 32 N_FreeSpaceModes = 10 boundary_radius = 0.11 boundary = Boundary2D(nBoundaryPoints,N_FreeSpaceModes,"Circle",2.0*boundary_radius) #=====track bunch through SC Node============ sc_path_length_min = 0.05 scNode_arr = [] scNode_arr = scLatticeModifications.setSC2p5DAccNodes(lattice,sc_path_length_min,calc2p5d,boundary) #scNode_arr = scLatticeModifications.setSC2p5DAccNodes(lattice,sc_path_length_min,calc2p5d) print "number of SC nodes =",len(scNode_arr) TURNS = 100 print("Tracking.") for i in range(TURNS): lattice.trackBunch(b) print "Turn ",i # dump ORBIT_MPI bunch to compare results bunch_pyorbit_to_orbit(lattice.getLength(), b, "pyorbit_final.dat") print("STOP.")
tunes = TeapotTuneAnalysisNode("tune_analysis") tunes.assignTwiss(10.207, 0.0469, -0.05, 0.0061, 10.639, 0.056) addTeapotDiagnosticsNode(lattice, 0, tunes) #----------------------------------- # Add Space Charge nodes #----------------------------------- nMacrosMin = 1 sc_path_length_min = 0.00000001 sizeX = 32 #number of grid points in horizontal direction sizeY = 32 #number of grid points in vertical direction sizeZ = 16 #number of longitudinal slices calc2p5d = SpaceChargeCalc2p5D(sizeX,sizeY,sizeZ) scLatticeModifications.setSC2p5DAccNodes(lattice, sc_path_length_min, calc2p5d) #----------------------------------- # Tracking #----------------------------------- paramsDict = {} paramsDict["bunch"]= b n_turns = 2 for i in range(n_turns): lattice.trackBunch(b, paramsDict) b.dumpBunch("bunch_2p5D_turn" + str(n_turns) + ".dat") print "Stop."