def generate_Injector_Lattice(injectorFactor, rpInjectorFactor, parallel=False) -> ParticleTracerLattice: assert type(parallel) == bool if is_Valid_Injector_Phase(injectorFactor, rpInjectorFactor) == False: return None LInjector = injectorFactor * .15 rpInjector = rpInjectorFactor * .02 fringeFrac = 1.5 LMagnet = LInjector - 2 * fringeFrac * rpInjector if LMagnet < 1e-9: # minimum fringe length must be respected. return None PTL_Injector = ParticleTracerLattice(200.0, latticeType='injector', parallel=parallel) PTL_Injector.add_Drift(.1, ap=.025) try: PTL_Injector.add_Halbach_Lens_Sim(rpInjector, LInjector, apFrac=.9) except: print(LInjector, rpInjector) PTL_Injector.add_Drift(.2, ap=.01) # PTL_Injector.add_Combiner_Sim('combinerV3.txt') PTL_Injector.add_Combiner_Sim_Lens(.2, .02) PTL_Injector.end_Lattice(constrain=False, enforceClosedLattice=False) return PTL_Injector
def make_Test_Swarm_And_Lattice(numParticles=100, totalTime=.1 ) -> (Swarm, ParticleTracerLattice): PTL = ParticleTracerLattice(200.0) PTL.add_Lens_Ideal(.4, 1.0, .025) PTL.add_Drift(.1) PTL.add_Lens_Ideal(.4, 1.0, .025) # PTL.add_Bender_Ideal_Segmented_With_Cap(200,.01,.1,1.0,.01,1.0,.001,1e-6) PTL.add_Bender_Ideal(np.pi, 1.0, 1.0, .025) PTL.add_Drift(.2) PTL.add_Lens_Ideal(.2, 1.0, .025) PTL.add_Drift(.1) PTL.add_Lens_Ideal(.2, 1.0, .025) PTL.add_Drift(.2) PTL.add_Bender_Ideal(np.pi, 1.0, 1.0, .025) PTL.end_Lattice() swarmTracer = SwarmTracer(PTL) swarm = swarmTracer.initalize_PseudoRandom_Swarm_In_Phase_Space( 5e-3, 5.0, 1e-5, numParticles) swarm = swarmTracer.trace_Swarm_Through_Lattice(swarm, 5e-6, totalTime, fastMode=False, parallel=True) # file=open('swarmFile','wb') # dill.dump(swarm,file) # file=open('swarmFile','rb') # swarm=dill.load(file) print('swarm and lattice done') return swarm, PTL
def generate_Injector_Lattice_Double_Lens(X) -> ParticleTracerLattice: L_InjectorMagnet1, rpInjectorMagnet1,L_InjectorMagnet2, rpInjectorMagnet2, \ LmCombiner, rpCombiner,loadBeamDiam,L1,L2,L3=X fringeFrac = 1.5 apFrac = .98 LMagnet1 = L_InjectorMagnet1 - 2 * fringeFrac * rpInjectorMagnet1 LMagnet2 = L_InjectorMagnet2 - 2 * fringeFrac * rpInjectorMagnet2 aspect1, aspect2 = LMagnet1 / rpInjectorMagnet1, LMagnet2 / rpInjectorMagnet2 if aspect1 < 1.0 or aspect2 < 1.0: return None if LMagnet1 < 1e-9 or LMagnet2 < 1e-9: # minimum fringe length must be respected. return None if loadBeamDiam > apFrac * rpCombiner: #silly if load beam doens't fit in half of magnet return None PTL_Injector = ParticleTracerLattice(V0, latticeType='injector', parallel=False) PTL_Injector.add_Drift(L1, ap=apFrac * rpInjectorMagnet1) PTL_Injector.add_Halbach_Lens_Sim(rpInjectorMagnet1, L_InjectorMagnet1, apFrac=apFrac) PTL_Injector.add_Drift(L2, ap=apFrac * max([rpInjectorMagnet1, rpInjectorMagnet2])) PTL_Injector.add_Halbach_Lens_Sim(rpInjectorMagnet2, L_InjectorMagnet2, apFrac=apFrac) PTL_Injector.add_Drift(L3, ap=apFrac * rpInjectorMagnet2) PTL_Injector.add_Combiner_Sim_Lens(LmCombiner, rpCombiner, loadBeamDiam=loadBeamDiam) PTL_Injector.end_Lattice(constrain=False, enforceClosedLattice=False) return PTL_Injector
def generate_Injector_Lattice(L_Injector, rpInjector, LmCombiner, rpCombiner,loadBeamDiam,L1,L2)->ParticleTracerLattice: fringeFrac=1.5 apFrac=.95 L_InjectorMagnet=L_Injector-2*fringeFrac*rpInjector if L_InjectorMagnet<1e-9: # minimum fringe length must be respected. return None if loadBeamDiam>rpCombiner: #don't waste time exploring silly configurations return None PTL_Injector=ParticleTracerLattice(V0,latticeType='injector') PTL_Injector.add_Drift(L1,ap=rpInjector) PTL_Injector.add_Halbach_Lens_Sim(rpInjector,L_Injector,apFrac=apFrac) PTL_Injector.add_Drift(L2,ap=apFrac*rpInjector) PTL_Injector.add_Combiner_Sim_Lens(LmCombiner,rpCombiner,loadBeamDiam=loadBeamDiam) PTL_Injector.end_Lattice(constrain=False,enforceClosedLattice=False) return PTL_Injector
def generate_Ring_Surrogate_Lattice(X) -> ParticleTracerLattice: jeremyGap = 5e-2 rpLensLast = .02 rplensFirst = .02 lastGap = 5e-2 L_InjectorMagnet1, rpInjectorMagnet1, L_InjectorMagnet2, rpInjectorMagnet2, \ LmCombiner, rpCombiner, loadBeamDiam, L1, L2, L3 = X PTL_Ring = ParticleTracerLattice(V0, latticeType='storageRing', parallel=False) PTL_Ring.add_Drift(rpLensLast) #models the size of the lengs PTL_Ring.add_Drift(lastGap) PTL_Ring.add_Combiner_Sim_Lens(LmCombiner, rpCombiner, loadBeamDiam=loadBeamDiam) PTL_Ring.add_Drift(jeremyGap) PTL_Ring.add_Halbach_Lens_Sim(rplensFirst, .2) PTL_Ring.end_Lattice(enforceClosedLattice=False, constrain=False, surpressWarning=True) # 17.8 % of time here return PTL_Ring
def generate_Ring_Lattice(rpBend, rpLens, rpLensFirst, Lm, LLens, parallel=False) -> ParticleTracerLattice: tunableDriftGap = 2.54e-2 assert type(parallel) == bool fringeFrac = 1.5 if LLens - 2 * rpLens * fringeFrac < 0 or LLens - 2 * rpLensFirst * fringeFrac < 0: # minimum fringe length must be respected return None PTL_Ring = ParticleTracerLattice(200.0, latticeType='storageRing', parallel=parallel) rOffsetFact = PTL_Ring.find_Optimal_Offset_Factor( rpBend, 1.0, Lm, parallel=parallel) # 25% of time here, 1.0138513851385138 if rOffsetFact is None: return None PTL_Ring.add_Drift(tunableDriftGap / 2, ap=rpLens) PTL_Ring.add_Halbach_Lens_Sim(rpLens, LLens) PTL_Ring.add_Drift(tunableDriftGap / 2, ap=rpLens) PTL_Ring.add_Halbach_Lens_Sim(rpLens, LLens) PTL_Ring.add_Combiner_Sim_Lens(.2, .02) PTL_Ring.add_Halbach_Lens_Sim(rpLensFirst, LLens) PTL_Ring.add_Drift(tunableDriftGap / 2) PTL_Ring.add_Halbach_Lens_Sim(rpLens, LLens) PTL_Ring.add_Drift(tunableDriftGap / 2) PTL_Ring.add_Halbach_Bender_Sim_Segmented_With_End_Cap( Lm, rpBend, None, 1.0, rOffsetFact=rOffsetFact) # PTL_Ring.add_Halbach_Lens_Sim(rpLens,None,constrain=True) # PTL_Ring.add_Drift(probeSpace) PTL_Ring.add_Halbach_Lens_Sim(rpLens, None, constrain=True) PTL_Ring.add_Halbach_Bender_Sim_Segmented_With_End_Cap( Lm, rpBend, None, 1.0, rOffsetFact=rOffsetFact) PTL_Ring.end_Lattice(enforceClosedLattice=True, constrain=True) # 17.8 % of time here return PTL_Ring
def generate_Injector_Lattice_Double_Magnet(L_InjectorMagnet1, rpInjectorMagnet1, L_InjectorMagnet2, rpInjectorMagnet2, LmCombiner, rpCombiner, loadBeamDiam, L1, L2, L3)->ParticleTracerLattice: fringeFrac = 1.5 apFrac = .95 LMagnet1 = L_InjectorMagnet1 - 2 * fringeFrac * rpInjectorMagnet1 LMagnet2 = L_InjectorMagnet2 - 2 * fringeFrac * rpInjectorMagnet2 if LMagnet1 < 1e-9 or LMagnet2 < 1e-9: # minimum fringe length must be respected. return None if loadBeamDiam > apFrac * rpCombiner: # silly if load beam doens't fit in half of magnet return None PTL_Injector = ParticleTracerLattice(V0, latticeType='injector', parallel=False) PTL_Injector.add_Drift(L1, ap=apFrac * rpInjectorMagnet1) PTL_Injector.add_Halbach_Lens_Sim(rpInjectorMagnet1, L_InjectorMagnet1, apFrac=apFrac) PTL_Injector.add_Drift(L2, ap=apFrac * max([rpInjectorMagnet1, rpInjectorMagnet2])) PTL_Injector.add_Halbach_Lens_Sim(rpInjectorMagnet2, L_InjectorMagnet2, apFrac=apFrac) PTL_Injector.add_Drift(L3, ap=apFrac * rpInjectorMagnet2) try: # even with guards it can still derp out PTL_Injector.add_Combiner_Sim_Lens(LmCombiner, rpCombiner, loadBeamDiam=loadBeamDiam) except: return None PTL_Injector.end_Lattice(constrain=False, enforceClosedLattice=False) return PTL_Injector
def generate_Ring_Lattice(rpLens,rpLensFirst,rpLensLast,rpBend,L_Lens, LmCombiner, rpCombiner,loadBeamDiam,tuning)->ParticleTracerLattice: tunableDriftGap=2.54e-2 jeremyGap=.05 Lm=.0254/2.0 lastGap=5e-2 fringeFrac=1.5 if L_Lens-2*rpLens*fringeFrac<0 or L_Lens-2*rpLensFirst*fringeFrac<0 or L_Lens-2*rpLensLast*fringeFrac<0: # minimum fringe length must be respected return None PTL_Ring=ParticleTracerLattice(V0,latticeType='storageRing') if abs(rpBend-1e-2)<SMALL_NUMBER and abs(Lm-.0254/2.0)<SMALL_NUMBER: rOffsetFact = 1.0106 else: # rOffsetFact=PTL_Ring.find_Optimal_Offset_Factor(rpBend,1.0,Lm) raise ValueError if rOffsetFact is None: return None if tuning=='spacing': PTL_Ring.add_Drift(tunableDriftGap/2) PTL_Ring.add_Halbach_Lens_Sim(rpLens,L_Lens) PTL_Ring.add_Drift(tunableDriftGap/2) PTL_Ring.add_Halbach_Lens_Sim(rpLensLast,L_Lens) PTL_Ring.add_Drift(lastGap) PTL_Ring.add_Combiner_Sim_Lens(LmCombiner,rpCombiner,loadBeamDiam=loadBeamDiam) PTL_Ring.add_Drift(jeremyGap) PTL_Ring.add_Halbach_Lens_Sim(rpLensFirst,L_Lens) if tuning=='spacing': PTL_Ring.add_Drift(tunableDriftGap/2) PTL_Ring.add_Halbach_Lens_Sim(rpLens,L_Lens) PTL_Ring.add_Drift(tunableDriftGap/2) PTL_Ring.add_Halbach_Bender_Sim_Segmented_With_End_Cap(Lm,rpBend,None,1.0,rOffsetFact=rOffsetFact) PTL_Ring.add_Halbach_Lens_Sim(rpLens,None,constrain=True) PTL_Ring.add_Halbach_Bender_Sim_Segmented_With_End_Cap(Lm,rpBend,None,1.0,rOffsetFact=rOffsetFact) PTL_Ring.end_Lattice(enforceClosedLattice=True,constrain=True) # 17.8 % of time here return PTL_Ring
class helper: def __init__(self, lens, apMin): self.lens = lens if apMin is None: self.apMin = self.lens.minimum_Radius() * .95 else: self.apMin = apMin self.L_Object = .72 self.L_Image = .8 self.fringeFrac = 4.0 self.PTL = None def make_Lattice(self): self.PTL = ParticleTracerLattice(v0Nominal=210.0, latticeType='injector', parallel=True) self.PTL.add_Drift(self.L_Object - self.fringeFrac * self.lens.maximum_Radius(), ap=.07) self.PTL.add_Genetic_lens(self.lens, self.apMin) self.PTL.add_Drift( 1.5 * (self.L_Image - self.fringeFrac * self.lens.maximum_Radius()), ap=.07) self.PTL.end_Lattice() assert self.PTL.elList[ 1].fringeFracOuter == self.fringeFrac and self.PTL.elList[ 1].rp == self.lens.maximum_Radius() assert abs( abs(self.PTL.elList[1].r2[0]) - (self.L_Object + self.lens.length + self.fringeFrac * self.lens.maximum_Radius())) < 1e-12 def make_Interp_Function(self): swarmTracer = SwarmTracer(self.PTL) angle = .9 * self.lens.minimum_Radius() / (self.L_Object + self.lens.length / 2) v0 = self.PTL.v0Nominal swarm = swarmTracer.initalize_PseudoRandom_Swarm_In_Phase_Space( 1e-6, angle * v0, 1e-6, 500, sameSeed=True) h = 1e-5 fastMode = True swarmTraced = swarmTracer.trace_Swarm_Through_Lattice( swarm, h, 1.0, fastMode=fastMode, jetCollision=False) # for particle in swarmTraced: # particle.plot_Energies() if fastMode == False: self.PTL.show_Lattice(swarm=swarmTraced, trueAspectRatio=False, showTraceLines=True, traceLineAlpha=.1) interpFunc = Interpolater(swarmTraced, self.PTL) return interpFunc def atom_Beam_Intensity(self, x, interpFunc): I = self.beam_Characterization(x, interpFunc)[0] return I def beam_Characterization(self, x, interpFunc): yArr, zArr, pArr = interpFunc(x, returnP=True) rArr = np.sqrt(yArr**2 + zArr**2) beamAreaRMS = np.std(yArr) * np.std(zArr) beamAreaD90 = np.sort(np.sqrt(yArr**2 + zArr**2))[int(len(yArr) * .9)] radiusRMS = np.sqrt(np.mean(rArr**2)) I = len(yArr) / (np.pi * radiusRMS**2) numD90 = int(len(yArr) * .9) return I, beamAreaRMS, beamAreaD90, numD90, radiusRMS def get_Magnification(self, xFocus): L_Focus = xFocus - (abs(self.PTL.elList[1].r2[0]) - self.fringeFrac * self.PTL.elList[1].rp) return L_Focus / self.L_Object def IPeak_And_Magnification_From_Lens(self, rejectOutOfRange): results = self.characterize_Focus(rejectOutOfRange) if results is None: return None else: return results['I'], results['m'] def characterize_Focus(self, rejectOutOfRange=True): self.make_Lattice() interpFunc = self.make_Interp_Function() xArr = np.linspace(-self.PTL.elList[-1].r1[0] + 2e-3, -self.PTL.elList[-1].r2[0] - 2e-3, 50) IArr = np.asarray( [self.atom_Beam_Intensity(x, interpFunc) for x in xArr]) xi = xArr[np.argmax(IArr)] wrapper = lambda x: 1 / self.atom_Beam_Intensity(x[0], interpFunc) sol = spo.minimize(wrapper, xi, bounds=[(xArr.min(), xArr.max())], options={'gtol': 1e-10}) xFocus = sol.x[0] if abs(xFocus - xArr.max()) < .1 or abs( xFocus - xArr.min() ) < .1 and rejectOutOfRange == True: #if peak is too close, answer is invalid return None # plt.plot(xArr,IArr) # plt.show() IPeak, beamAreaRMS, beamAreaD90, numD90, radiusRMS = self.beam_Characterization( xFocus, interpFunc) m = self.get_Magnification(xFocus) results = { 'I': IPeak, 'm': m, 'beamAreaRMS': beamAreaRMS, 'beamAreaD90': beamAreaD90, 'particles in D90': numD90, 'radius RMS': radiusRMS, 'L_Image': m * self.L_Object } return results
def generate_Lattice(configuration): #a variety of lattice configurations are tested if configuration == '1': PTL = ParticleTracerLattice(200.0, latticeType='storageRing') PTL.add_Drift(.25) PTL.add_Halbach_Bender_Sim_Segmented_With_End_Cap(.0254, .01, 150, 1.0, 0.0, rOffsetFact=1.015) PTL.add_Lens_Ideal(1.0, 1.0, .01) PTL.add_Halbach_Lens_Sim(.01, 1.0) PTL.add_Drift(.1) PTL.end_Lattice(constrain=False, surpressWarning=True, enforceClosedLattice=False) elif configuration in ('2', '5'): PTL = ParticleTracerLattice(200.0, latticeType='injector') PTL.add_Drift(.25) PTL.add_Halbach_Lens_Sim(.01, .5) PTL.add_Drift(.1) if configuration == '2': PTL.add_Combiner_Sim('combinerV3.txt') else: PTL.add_Combiner_Sim_Lens(.1, .02) PTL.add_Halbach_Lens_Sim(.01, .5) PTL.end_Lattice() elif configuration == '3': PTL = ParticleTracerLattice(200.0, latticeType='storageRing') PTL.add_Lens_Ideal(1.0, 1.0, .01) PTL.add_Bender_Ideal(np.pi, 1.0, 1.0, .01) PTL.add_Lens_Ideal(1.0, 1.0, .01) PTL.add_Bender_Ideal(np.pi, 1.0, 1.0, .01) PTL.end_Lattice() elif configuration in ('4', '6'): PTL = ParticleTracerLattice(200.0, latticeType='storageRing') PTL.add_Halbach_Lens_Sim(.01, .5) if configuration == '4': PTL.add_Combiner_Sim('combinerV3.txt') else: PTL.add_Combiner_Sim_Lens(.1, .02) PTL.add_Halbach_Lens_Sim(.01, .5) PTL.add_Halbach_Bender_Sim_Segmented_With_End_Cap(.0254 / 2, .01, None, 1.0, 0.0, rOffsetFact=1.015) PTL.add_Halbach_Lens_Sim(.01, None, constrain=True) PTL.add_Halbach_Bender_Sim_Segmented_With_End_Cap(.0254 / 2, .01, None, 1.0, 0.0, rOffsetFact=1.015) PTL.end_Lattice(enforceClosedLattice=True, constrain=True) PTL.elList[0].fieldFact = .3 PTL.elList[2].fieldFact = .3 else: raise Exception('no proper configuration name provided') return PTL