Fermi Acceleration--A real scientific problem
James A. Rome
Tennessee Governor's Academy
August 2010
The problem
Enrico Fermi postulated an acceleration method for cosmic rays that has a simple physical model. Imagine a ball bouncing between two massive walls, one of which oscillates back and forth.
u
V(t)
The question to besolved is whetherthe ball can beaccelerated to verylarge velocities
Top View
Some Web links
http://www.dynamical-systems.org/fermi/info.htmland you can see an animation athttp://www.dynamical-systems.org/fermi/index.html
http://books.google.com/books?id=a0AABe1Hve8C&lpg=PA10&dq=velocity%20of%20ball%20bouncing%20off%20moving%20wall&pg=PA10#v=onepage&q=velocity%20of%20ball%20bouncing%20off%20moving%20wall&f=false
http://en.wikipedia.org/wiki/Fermi_accelerationhttp://en.wikipedia.org/wiki/Fermi%E2%80%93Ulam_model
A ball bouncing off a stationary wall
Assumptions: The ball is a point located at its center The ball is perfectly elastic (think
superball) The Wall is infinitely massive and
absorbs no energy in the collision The collision is instantaneous
If energy (mv2/2) is conserved, and if the wall does not move, the speed after the collision must equal the speed before the collision, but the direction is reversed. The ball bounces off the wall with
velocity = -u This is in accord with your experiences. Between collisions, the ball moves at a
constant velocity (with no external forces)
Wall
u?
A ball bouncing off a moving wall
How do you solve this problem? First suppose the ball is
sitting still, and it is hit by the wall that moves at V towards the ball
If you ever played ping pong or tennis, you will know that the ball goes to the right—but how fast?
Wall
Vu = 0
Afteru = ?
Use the special theory of relativity
Einstein said that physics must be the same when viewed from any system moving at a constant velocity. Example: You sit in your moving
car and toss a ball up. To you it looks just like it would if you were not in the car. The ball goes straight up and straight down.
But to someone on the ground, the ball will move in a parabola.
So what do you see if you sit on the wall and solve this problem?
Wall
V ?
Viewed sitting on the wall moving at V
You see the ball approaching you with velocity V
I think we have already solved this problem. . .
Wall
V?
Viewed sitting on the wall moving at V
You see the ball approaching you with velocity V
I think we have already solved this problem. . . The ball bounces off the
wall with velocity V in the opposite direction
But the wall is already moving to the right at V
So in the Lab frame, the ball goes to the right at 2V
That is why Fermi thought you could make it get faster!
Wall
V?
Viewed sitting on the wall moving at V
You see the ball approaching you with velocity V
I think we have already solved this problem. . . The ball bounces off the
wall with velocity V in the opposite direction
But the wall is already moving to the right at V
So in the Lab frame, the ball goes to the right at 2V
That is why Fermi thought you could make it get faster!
Wall
V?
If the ball is moving towards the wall withspeed u, after the collision it moves rightwith speed u + 2VThe ball gains energy because the wallis moving, and we assumed it wasinfinitely massive. Whatever is movingthe wall puts energy into the ball.
Velocity of the wall
A light ball bounces in one dimension between two massive walls. One wall oscillates with a velocity given by V(t) = (V/4)[1 - 2{t}]where {t} is the fractional part of t (denoted by ft in the code). V(t) | | V/4|\ |\ |\ |\ |\ |\ | \ | \ | \ | \ | \ | \ | --|--\--|--\--|--\--|--\--|--\--|--\--|- t |0 \ |1 \ |2 \ |3 \ |4 \ |5 \ |6 | \| \| \| \| \| \| |
A little calculus... (plane geometry)
The velocity is the time rate of change of the distance (m/s) which means the velocity is the slope of the position of the wall.The position is the area under the velocity curve up to time t
t
V(t)
1
V/4
-V/4
{t=1/2} area = base * height/2 = (1/2)*(1/2)*(V/4) = V/16 = max oscillation
{t}
area of little triangle =(1/2)*(1/2-{t})*V({t})=
(V/4)[1/2 - {t}]2
distance =area of trapezoid =area of big triangle -area of little triangle =(V/16) – (V/4)[1/2 - {t}]2
A little calculus...
The velocity is the time rate of change of the distance (m/s) which means the velocity is the slope of the position of the wall.The position is the area under the velocity curve up to time t
t
V(t)
1
V/4
-V/4
{t=1/2} area = base * height/2 = (1/2)*(1/2)*(V/4) = V/16 = max oscillation
{t}
area of little triangle =(1/2)*(1/2-{t})*V({t})=
(V/4)[1/2 - {t}]2
distance =area of trapezoid =area of big triangle -area of little triangle =(V/16) – (V/4)[1/2 - {t}]2
For {t} > 1/2, the area under the curve isthe area of the positive triangle – area ofthe dotted triangle (note that V < 0) =V/16 + (1/2)[{t} – (1/2)]*(V/4)[1 – 2{t}] =V/16 - (V/4)[{t} - (1/2)]2
A little calculus...
The velocity is the time rate of change of the distance (m/s) which means the velocity is the slope of the position of the wall.The position is the area under the velocity curve up to time t
t
V(t)
1
V/4
-V/4
{t=1/2} area = base * height/2 = (1/2)*(1/2)*(V/4) = V/16 = max oscillation
{t}
area of little triangle =(1/2)*(1/2-{t})*V({t})=
(V/4)[1/2 - {t}]2
distance =area of trapezoid =area of big triangle -area of little triangle =(V/16) – (V/4)[1/2 - {t}]2
For {t} > 1/2, the area under the curve isthe area of the positive triangle – area ofthe dotted triangle=V/16 – (1/2)[{t} – (1/2)]*(V/4)[1 – 2{t}] =V/16 + (V/4)[{t} - (1/2)]2
Sanity check:d = 0 at {t} = 0, 1d = V/16 at {t} = ½It is two parabolas!
When do we need to “solve” this?
Most of the time, the ball is bouncing from the bouncing wall to the fixed wall and back again. It will maintain its speed during this process The speed changes only when it hits the
bouncing wall.The velocity of the ball just before the nth collision with the oscillating wall is (un = vball/V)The ball leaves the collision with its initial velocity (-un) + 2*Vwall({t})/V
and remember that Vwall(t) = (V/4)[1 - 2{t}]
speed = |un + 2*(1/4)[2{tn} – 1]| =>
un+1 = |un + {tn} – 1/2|
How long between bounces?
If we assume the distance between the walls (d) is much greater than the amplitude of the oscillation (V/16), the ball goes a distance 2d between bounces with the moving wall. distance = speed * time, so, remembering that Vu
n+1 i the speed just before the n+1 collision,
tn+1 = tn + 2d/(Vun+1) = tn + M/un+1
where M = 2d/V, and
{tn+1}= {{tn} + M/un+1} So, what do we need to plot?
u vs {t} u vs iteration
Can we predict the output? It is chaotic, so NO
The GUI . . .
How do we do this using Java?
PhaseCanvas TimeCanvas
Make a new Project• Make a New Java Desktop Application• Call it FermiPlot• As before, remove the status panel, the progress
bar, the code after initComponents(), and the variables for the progress bar at the end of the code.
• You can change the name of the project and the other information in the resources.
• Save the project.
Start with the physics calculation
Make a new Class called FermiCalc Need calculations in separate thread to keep the GUI
responsive
public class FermiCalc extends Thread // Run in a separate thread{ PhaseCanvas pc; // The left plot area TimeCanvas tc; // The right plot area private static final int NCURVE = 7; private float M = 10.0f; private static final Color[] colors = {Color.black, Color.blue, Color.cyan, Color.red, Color.green, Color.magenta, Color.orange}; // The constructor to instantiate the class instance public FermiCalc(PhaseCanvas pc, TimeCanvas tc) { // Get and store the two drawing canvases this.pc = pc; this.tc = tc; } // Other methods go here}
FermiCalc
A Thread must have a run() method that does the work public void run(){ float u[] = new float[2]; // Relative velocity before/after collision float ft[] = new float[2]; // Fractional parts of t float nstep[] = new float[2]; // Steps (need float for the plot)/* Pick interesting starting points (NCURVE=7 of them) */ double[] ustart = {M, M, .4*Math.sqrt((double)M),
1.45*M,1.5*M, 2.0*M, M}; double[] tstart = {.1, .4, .5, .5, 0.0, .5, 0.0}; int[] stepmax = {500, 500, 4000, 2000, 4000, 4000,4000, 4000}; for (int i = 0; i < NCURVE; i++) // For each curve { u[0] = (float)ustart[i]; ft[0] = (float)tstart[i]; nstep[0] = 0.0f; for (int n = 1; n < stepmax[i]; n++) // Iterate for each bounce {
. . .// THE CODE THAT DOES THE WORK GOES HERE (next slide) } } }
FermiCalc (continued)
nstep[1] = (float)n; // The iteration number. Cast to floatu[1] = Math.abs(u[0] + ft[0] - .5f); // u_n+1 = |u_n + {t_n} - 1/2|ft[1] = ft[0] + (M/u[1]); // The time of the bouncewhile (ft[1] > 1.0f) // Get its fractional part ft[1] -= 1.0f; // could use ft[1] - (float)Math.floor((double)ft[1])// Phase plotpc.symbol(ft[1], u[1], colors[i]); // Plot a symbol at the new point// Time plot tc.curve(nstep, u,colors[i]); // Plot line between the points
// Prepare for the next iterationu[0] = u[1];ft[0] = ft[1];nstep[0] = nstep[1];
// add a delay so we can watch the plot happeningtry { // This is new. Some methods throw an exception if a problem Thread.sleep(5); // In this case, sleep throws one when its over // 5 millisecs}catch(InterruptedException ex) {} Remember that the two canvases
are Swing components and that Swingis processing many events. It is a bad idea to call methods in Swingfrom outside the EventQueue.See next slide for the correct way.
What happens if ft, u changebefore they get plotted?
Putting events on the EventQueue final float u1 = u[1]; final float ft1 = ft[1]; final int i1 = i;// Phase plot EventQueue.invokeLater(new Runnable() { public void run() { pc.symbol(ft1, u1, colors[i1]); } // end of run() } ); //end of call
// Time plot final float uf[] = {u[0], u[1]}; final float nstepf[] = {nstep[0], nstep[1]}; EventQueue.invokeLater(new Runnable() { public void run() { tc.curve(nstepf, uf,colors[i1]); } });
Can only pass final variables intoinvokeLater so that the things wepass in do not change
Note that we are defininga new anonymous class(we never need it's name)to spawn a Thread thatwill sit on the Swing eventqueue until Swing isready to process it.We must implement therun() method
There is alsoEventQueue.invokeAndWait(new Runnable()…)for when we want our call processed before continuing
PhaseCanvas
The strategy is to make a class that extends JPanel (one of the Java containers). It is a rectangle that we can draw in.
We will add PhaseCanvas to the Swing Component palate and then we can add to to our GUI. We can do this because all Swing components are Java Beans.
All we have to do is to override the paintComponent() method of the JPanel to make our plot.
PhaseCanvaspublic class PhaseCanvas extends JPanel { public PhaseCanvas() {} // Constructor @Override public void paintComponent(Graphics g) { super.paintComponent(g); // More code to come } public void symbol(float x, float y, Color c ){ pts.add(new DataPoint(x, y, c)); this.repaint(); // Force JPanel to be redrawn with this point in it } private float M = 10.0f; // Data members of PhaseCanvas class private Vector<DataPoint> pts = new Vector<DataPoint>(); private int npts = 0; // Define a new internal class to hold the data of one point private class DataPoint { protected float x; // protected variables can be accessed protected float y; // by classes in this package protected Color c; private DataPoint(float x, float y, Color c) { this.x = x; this.y = y; this.c = c; } } // End of DataPoint class } // End of PhaseCanvas class
symbol() is called by FermiCalcwhen it has some data to plot.It puts the data into a DataPointand adds it to the end of aVector
<DataPoint> tells the compilerthat this vector is composedof DataPoints. If you try to addsomething else, you get acompiler error.
PhaseCanvas.paintComponent()
@Override public void paintComponent(Graphics g) {
super.paintComponent(g); Graphics2D g2d = (Graphics2D)g; // cast to Graphics2D which has int width = this.getWidth(); // many drawing methods int height = this.getHeight(); // Get the JPanel dimensions g2d.drawRect(0,0,width-1,height-1); // Outline the panel AffineTransform t = new AffineTransform(); // Next Slide t.translate(0, (double) height); t.scale(1.0, -1.0); t.scale((double)width, (double)height/(2.0*M)); for(int i = 0; i < pts.size(); i++) { // Draw all the points DataPoint dp = (DataPoint)pts.elementAt(i); g2d.setColor(dp.c); // We need to draw in pixel space, so must use the transform Point2D.Float inPt = new Point2D.Float(dp.x, dp.y); Point2D.Float outPt = new Point2D.Float(); t.transform(inPt, outPt); g2d.drawRect((int)outPt.x -1, (int)outPt.y -1, 1, 1); } }
Affine Transforms
FermiCalc calculated u in units of M , and {t} goes from 0 to 1. How do we plot this in pixel space? We use an affine transform which is some fancy
matrix algebra (good reason to do more math!) But I can never remember how it works, so I
always draw some pictures to help me break it down into easy-to-understand steps
PhaseCanvas0, 0
width,height
width, 0
0, height
0.0, 2M
1.0, 0.00.0, 0.0
FermiCalc
?
1.0, 2M
Affine Transforms
PhaseCanvas0, 0
width,height
width, 0
0, height
0.0, 2M
1.0, 0.0
width, height
0.0, 0.0
FermiCalc
?
0.0, height
width, 0.00.0, 0.0
1.0, 2M
width, -height0.0, -height
width, 0.00.0, 0.0
scale(1.0, -1.0)
scale(width/1.0, height/2M)translate(0.0, height)
We do the steps backwardsin the code
t.translate(0, (double) height);t.scale(1.0, -1.0); t.scale((double)width, (double)height/(2.0*M));
TimeCanvas is very similar
public class TimeCanvas extends JPanel { public TimeCanvas() { } @Override public void paintComponent(Graphics g) { super.paintComponent(g); // More code to come . . . } public void curve(float x[], float y[], Color c) { linesegs.add(new Lines(x, y, c)); this.repaint(); // Repaint TimeCanvas to display new curve } private float M = 10.0f; Vector<Lines> linesegs = new Vector<Lines>()
// Define a private class to store the plot vectors private class Lines { protected Point2D.Float[] p2d = new Point2D.Float[2]; protected Color c; protected Lines(float x[], float y[], Color c) { p2d[0] = new Point2D.Float(x[0], y[0]); p2d[1] = new Point2D.Float(x[1], y[1]); this.c = c; } }}
curve() is called from FermiCalcwhen new iteration s are readyto be plotted
TimeCanvas.paintComponent()
@Override public void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2d = (Graphics2D)g; // cast to Graphics2D int width = this.getWidth(); int height = this.getHeight(); g2d.drawRect(0,0,width-1,height-1); // Draw a box around the plot AffineTransform t = new AffineTransform(); t.translate(0, (double) height); t.scale(1.0, -1.0); t.scale((double)width/4000.0, (double)height/(2.0*M)); for(int i = 0; i < linesegs.size(); i++) { Lines lns = (Lines)linesegs.elementAt(i); g2d.setColor(lns.c); // We need to draw in pixel space, so must use the transform Point2D.Float[] inPts = lns.p2d; Point2D.Float[] outPts = new Point2D.Float[2]; t.transform(inPts, 0, outPts, 0, 2); // Note that we have to draw in integer coordinates (pixels) g2d.drawLine((int)outPts[0].x, (int)outPts[0].y, (int)outPts[1].x, (int)outPts[1].y); } }
Add the canvases to your Palette
•First, right-click the FermiPlot project and pick Clean and build (otherwise this will not work) - The palette components are taken from the compiled canvases (in the jar file in the dist directory) •Click Tools, Palette, Swing/AWT Components
Add components from your project
Add to Palette (pick the project)
Add to Palette
Your components are now available
In design view, Add the two canvases and all the labels.• Make sure that the labels are pinned to their canvases, and that the canvases are pinned to the sides and bottom of the mainPanel.• I used copy and paste to replicate the identical labels• Save, clean and build, and run your project. Make sure that the labels and windows behave properly when you resize things.
PhaseCanvas TimeCanvas
Labels
FermiPlotView code
public FermiPlotView() { initComponents(); // NetBeans code // instantiate the calculation FermiCalc fc = new FermiCalc(phaseCanvas, timeCanvas); fc.setM(10.0f); // I left these out before, setting M=10 in the code phaseCanvas.setM(10.0f); timeCanvas.setM(10.0f); disableDoubleBuffering(phaseCanvas); // So you can watch the plot disableDoubleBuffering(timeCanvas); // Otherwise it happens off screen // start the calculation fc.start(); // this starts FermiCalc in its thread by calling fc.run() } /** * * @param c - the component to have double buffering disabled */ private void disableDoubleBuffering( Component c ) { RepaintManager currentManager = RepaintManager.currentManager(c); currentManager.setDoubleBufferingEnabled(false); }// . . . the rest of the code
These are the names you calledthe two canvases in the GUI builder
Optionally, change the Information
This will change the title of the Application window
The Answer . . .
Documentation: JavaDocs
•Click on the FermiPlot Source Packages•Run/Generate JavaDoc•file:///Users/jar/Documents/TGA/Projects/FermiPlot/dist/javadoc/index.html will show you documentation for your Project•But we did not insert many JavaDoc comments…