Created by Ansh Bhatnagar
Email: ab4616@ic.ac.uk


Cyclotron and the Lorentz Force Law

Learning Objectives

  • To understand the Lorentz Force Law.
  • The roles that the electric field and the magnetic field play in accelerating a particle in a spiral.
  • To understand that the electric field increases the kinetic energy of the particle and the magnetic field does no work.

Table of Contents

  1. Introduction
  2. Code

1. Introduction

These days the major experiments in particle physics involve the use of particle accelerators, such as the Large Hadron Collider at CERN, pictured below.

Particle accelerators started from an amazingly simple physical law - the Lorentz force law, given by $\renewcommand{\vec}[1]{\mathbf{#1}}$

$\vec{F} = q(\vec{E} + \vec{v}\times\vec{B})$

the particle starts at the centre and is accelerated by a uniform electric field, which lies between two dees as shown by the following

This electric field alternates direction each time the particle crosses the gap, continuing to accelerate it in a spiral. The spiral shape is a result of the radius getting bigger as the particle gains kinetic energy due to the electric field - no work is done by the magnetic field, as usual.

In the next section you can create your own cyclotron path by specifying the charge and mass of a particle, and the electric and magnetic field strengths.

2. Code

A particle class, functions for the vector fields and the plotcyclo method is created, which plots the path of the cyclotron.


In [1]:
import plotly.plotly as py
import plotly.figure_factory as ff
import plotly.graph_objs as go
import plotly as plty
from plotly.offline import iplot
import numpy as np
plty.offline.init_notebook_mode()



class particle:
    
    def __init__(self, r, v, charge, mass):
        self.r = r
        self.v = v
        self.q = charge
        self.m = mass
        
    def force(self, E, B):
        F = self.q*(E+np.cross(self.v, B))
        return F
    
    def update(self, E, B, dt):
        self.v = np.add(self.v, dt*self.force(E, B)/self.m)
        self.r = np.add(self.r, dt*self.v)
    

def mag(r, Bmag):
    B = np.array([0,0,5])
        
    return B

def elec(r, orientation, Emag):
    E = np.array([0,0,0])
    
    if abs(r[0]) < 1:
        E = np.array([orientation*Emag, 0, 0])
        
    return E
  
def plotcyclo(q0, m0, Emag, Bmag, totalt):
    r0 = np.array([0, -2, 0])
    v0 = np.array([0, 0, 0])

    p = particle(r0, v0, q0, m0)

    dt = 0.001

    end = totalt/dt


    x=[]
    y=[]


    switch = False


    for t in range(0, int(end)):
        if p.r[0] < -1:
            switch = False
        elif p.r[0] > 1:
            switch = True

        if switch:
            E = elec(p.r, -1, Emag)
        else:
            E = elec(p.r, 1, Emag)

        B = mag(p.r, Bmag)

        p.update(E, B, dt)

        x.append(p.r[0])
        y.append(p.r[1])






    points = go.Scatter(x=x, y=y,
                        mode='markers',
                        marker=dict(size=2),
                        name='points')

    layout = dict(    
        width=800,height=800,    
        showlegend=True,           
        scene = dict(        
            xaxis = dict(range=[-5, 5], autorange=False, zeroline=False),        
            yaxis = dict(range=[-5, 5], autorange=False, zeroline=False),
        ),    
        plot_bgcolor= 'rgb(255, 255, 255)')

    fig = go.Figure(data=[points], layout = layout)

    figure = {'data': [{'x': [0, 1], 'y': [0, 1]}],
                'layout': {'xaxis': {'range': [-5, 5], 'autorange': False},
                         'yaxis': {'range': [-5, 5], 'autorange': False}

                        }}

    iplot(fig)


The next block sets up the variables that define the visualisation. Feel free to alter these!

totalt is the total time, in seconds, that the visualisation shows the path for.


In [2]:
q = 1
m = 1
Emag = 30
Bmag = 5
totalt = 10

Run the next cell to generate a cyclotron path.


In [3]:
plotcyclo(q, m, Emag, Bmag, totalt)


Feel free to go back and alter the code!