#Simple Cyclotron model
#Author: Manuel Jose Paez
#Instituto de Fisica
#Universidad de Antioquia
#Medellin, Colombia
#mpaez@fisica.udea.edu.co
#To run this program install Python and Vpython
#see: http://vpython.org/
#for Windows download and install Python and Vpython from:
# http://vpython.org/contents/download_windows.html
#Copy this program and paste it in IDLE (for example), save it as
# Cyclotron.py and run it.
'''
These are the equations and the selected values for variables
mv*v/r=qvB =>r=mv/qB, with: m=1,B=1,|q|=1 =>r=v
In gap with these units: qE=ma, => a=E
Vf*Vf=Vo*Vo+2ae, with e=20, and Vo=r, => Vf=sqrt(r*r+2*20*E), E=11
E points in opposite direction of motion in gap (to accelerate the electron)
'''
from visual.graph import * #graphics and math classes
scene=display(x=0,y=0,width=600,height=600,range=200,
title='Cyclotron. B: cyan arrows, E: electric field white arrows',forward=(1,-1,-1))
pole1=ring(pos=(0,40,15),axis=(0,1,0),radius=140,thickness=1,shaftwidth=0.1)
pole2=ring(pos=(0,-40,15),axis=(0,1,0),radius=140,thickness=1)
d=frame() #for yellow plate and blackbox
cylinder(frame=d,pos=(0,0,15),radius=130,axis=(0,1,0),color=color.yellow)
blackbox=box(frame=d,pos=(0,0,15),length=20,height=4,width=260,color=color.black)
ball=sphere(pos=(0,0,0),radius=5,color=color.green) #the electron
ball.trail=curve(color=color.red,radius=1) #trail left by electron
arrow1=arrow() #arrows for electric field
arrow2=arrow() #In this way, arrows will be erased
arrow3=arrow()
arrow4=arrow()
arrow5=arrow()
scene.lights=[vector(0.4,0.4,0.8),vector(-0.3,-0.5,-0.2)] #two lights
def Bfield(): #plots magnetic field lines as blue arrows
for z in range(-50,75,25):
for x in range(-50,75,25):
f=frame() #to make cilinder with cone one unit
cylinder(frame=f,pos=(x,0,z),radius=1,axis=(0,-80,0),color=color.cyan)
cone(frame=f,pos=(x,-75,z),radius=3,axis=(0,-10,0),color=color.cyan)
cone(frame=f,pos=(x,-30,z),radius=3,axis=(0,-10,0),color=color.cyan)
f.pos=vector(x,40,z+15)
def trajectory(r,sign,offset): #to plot semicurcular trajectories
th=math.pi/20.0
for i in range(0,21):
rate(20)
if sign==-1:
arrsize=20*math.cos(th*i)
if arrsize>=0:
arrow1.pos=(-10,5,-90+15)
arrow1.axis=(arrsize,0,0)
arrow2.pos=(-10,5,-45+15)
arrow2.axis=(arrsize,0,0)
arrow3.pos=(-10,5,15)
arrow3.axis=(arrsize,0,0)
arrow4.pos=(-10,5,60)
arrow4.axis=(arrsize,0,0)
arrow5.pos=(-10,5,105)
arrow5.axis=(arrsize,0,0)
if arrsize<0:
arrow1.pos=(10,5,-90+15)
arrow1.axis=(arrsize,0,0)
arrow2.pos=(10,5,-45+15)
arrow2.axis=(arrsize,0,0)
arrow3.pos=(10,5,15)
arrow3.axis=(arrsize,0,0)
arrow4.pos=(10,5,60)
arrow4.axis=(arrsize,0,0)
arrow5.pos=(10,5,105)
arrow5.axis=(arrsize,0,0)
z=r*math.cos(th*i)+offset #offset to shift z position
x=-r*math.sin(th*i)+10*sign #10*sign makes the jump in the gap
else:
arrsize=20*math.cos(th*i)
if arrsize>=0:
arrow1.pos=(10,5,-90+15)
arrow1.axis=(-arrsize,0,0)
arrow2.pos=(10,5,-45+15)
arrow2.axis=(-arrsize,0,0)
arrow3.pos=(10,5,15)
arrow3.axis=(-arrsize,0,0)
arrow4.pos=(10,5,60)
arrow4.axis=(-arrsize,0,0)
arrow5.pos=(10,5,105)
arrow5.axis=(-arrsize,0,0)
if arrsize<0:
arrow1.pos=(-10,5,-90+15)
arrow1.axis=(-arrsize,0,0)
arrow2.pos=(-10,5,-45+15)
arrow2.axis=(-arrsize,0,0)
arrow3.pos=(-10,5,15)
arrow3.axis=(-arrsize,0,0)
arrow4.pos=(-10,5,60)
arrow4.axis=(-arrsize,0,0)
arrow5.pos=(-10,5,105)
arrow5.axis=(-arrsize,0,0)
z=-r*math.cos(th*i)+offset
x=r*math.sin(th*i)+10*sign
ball.pos=vector(x,5,z) #electron's position
ball.trail.append(pos=(x,5,z)) #append the trail left by electron
def gap(sign,r): #plots the arrows in gap and computes new radius
rf=math.sqrt(440.0+r*r) #E=11,electric field, new radius due E
return rf
def automatic():
Bfield()
r=20 #initial trajectory radius
sign=1.0 #for direction of E field in gap
offset=r
trajectory(r,sign,offset) #plot first trajectory
rf=gap(sign,r) #electron finds gap
sign=-1.0 #change direction of E field
offset=2*r-rf #to match new radius and old trail
for i in range(1,28): #rest of the trajectories
if sign==-1:
trajectory(rf,sign,offset)
offset=rf-offset
rf=gap(sign,rf)
offset=rf-offset
sign =1
else:
trajectory(rf,sign,offset)
offset=rf+offset
rf=gap(sign,rf)
offset=offset-rf
sign =-1
if i==27: #electron is expelled
for j in range(1,8):
rate(8)
ball.pos=vector(30*j, 5,-rf+16)
ball.trail.append(pos=(30*j,5,-rf+16))
automatic()