Fermi Acceleration

advertisement
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.
The question to be
solved is whether
the ball can be
accelerated to very
large velocities
u
Top View
V(t)
Some Web links
http://www.dynamical-systems.org/fermi/info.html
and you can see an animation at
http://www.dynamical-systems.org/fermi/index.html
http://books.google.com/books?id=a0AABe1Hve8C&lpg=PA10&dq=velocity%20
of%20ball%20bouncing%20off%20moving%20wall&pg=PA10#v=onepage&q=vel
ocity%20of%20ball%20bouncing%20off%20moving%20wall&f=false
http://en.wikipedia.org/wiki/Fermi_acceleration
http://en.wikipedia.org/wiki/Fermi%E2%80%93Ulam_model
A ball bouncing off a stationary wall
u
?
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)
A ball bouncing off a moving wall
V
u=0
Wall
After
u=?
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?
Use the special theory of relativity
V
Wall
?
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?
Viewed sitting on the wall moving at V
V
?
Wall
 You see the ball
approaching you with
velocity V
 I think we have already
solved this problem. . .
Viewed sitting on the wall moving at V
V
?
Wall
 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!
Viewed sitting on the wall moving at V
V
?
Wall
If the ball is moving towards the wall with
speed u, after the collision it moves right
with speed u + 2V
The ball gains energy because the wall
is moving, and we assumed it was
infinitely massive. Whatever is moving
the wall puts energy into the ball.
 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!
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)
V(t)
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
area of little triangle =
(1/2)*(1/2-{t})*V({t})=
(V/4)[1/2 - {t}]2
V/4
{t}
-V/4
1
t
distance =
area of trapezoid =
area of big triangle area of little triangle =
(V/16) – (V/4)[1/2 - {t}]2
{t=1/2} area = base * height/2 = (1/2)*(1/2)*(V/4) = V/16 = max oscillation
A little calculus...
V(t)
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
area of little triangle =
(1/2)*(1/2-{t})*V({t})=
(V/4)[1/2 - {t}]2
V/4
{t}
-V/4
1
t
For {t} > 1/2, the area under the curve is
the area of the positive triangle – area of
the 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
distance =
area of trapezoid =
area of big triangle area of little triangle =
(V/16) – (V/4)[1/2 - {t}]2
{t=1/2} area = base * height/2 = (1/2)*(1/2)*(V/4) = V/16 = max oscillation
A little calculus...
V(t)
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
area of little triangle =
(1/2)*(1/2-{t})*V({t})=
(V/4)[1/2 - {t}]2
V/4
{t}
-V/4
1
t
For {t} > 1/2, the area under the curve is
the area of the positive triangle – area of
the dotted triangle=
V/16 – (1/2)[{t} – (1/2)]*(V/4)[1 – 2{t}] =
V/16 + (V/4)[{t} - (1/2)]2
distance =
area of trapezoid =
area of big triangle area of little triangle =
(V/16) – (V/4)[1/2 - {t}]2
Sanity check:
d = 0 at {t} = 0, 1
d = V/16 at {t} = ½
It is two parabolas!
{t=1/2} area = base * height/2 = (1/2)*(1/2)*(V/4) = V/16 = max oscillation
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 Vun+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 . . .
PhaseCanvas
TimeCanvas
How do we do this using Java?
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 float
u[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 bounce
while (ft[1] > 1.0f)
// Get its fractional part
ft[1] -= 1.0f; // could use ft[1] - (float)Math.floor((double)ft[1])
// Phase plot
pc.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 iteration
u[0] = u[1];
ft[0] = ft[1];
nstep[0] = nstep[1];
// add a delay so we can watch the plot happening
try { // 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
}
What happens if ft, u change
before they get plotted?
are Swing components and that Swing
is processing many events. It is
a bad idea to call methods in Swing
from outside the EventQueue.
See next slide for the correct way.
Putting events on the EventQueue
Can only pass final variables into
final float u1 = u[1];
invokeLater so that the things we
final float ft1 = ft[1];
pass in do not change
final int i1 = i;
Note that we are defining
// Phase plot
a new anonymous class
EventQueue.invokeLater(new Runnable() { (we never need it's name)
to spawn a Thread that
public void run() {
will sit on the Swing event
pc.symbol(ft1, u1, colors[i1]);
queue until Swing is
} // end of run()
ready to process it.
} ); //end of call
We must implement the
run() method
// 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]);
}
There is also
});
EventQueue.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.
PhaseCanvas
public class PhaseCanvas extends JPanel {
symbol() is called by FermiCalc
public PhaseCanvas() {} // Constructor
@Override
when it has some data to plot.
public void paintComponent(Graphics g) { It puts the data into a DataPoint
super.paintComponent(g);
and adds it to the end of a
// More code to come
Vector
}
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;
<DataPoint> tells the compiler
this.c = c;
that this vector is composed
}
of DataPoints. If you try to add
} // End of DataPoint class
something else, you get a
}
// End of PhaseCanvas class
compiler 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
0, 0
width, 0
1.0, 2M
0.0, 2M
PhaseCanvas
FermiCalc
?
0, height
width,height
0.0, 0.0
1.0, 0.0
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
Affine Transforms
0, 0
1.0, 2M
0.0, 2M
width, 0
PhaseCanvas
FermiCalc
?
0, height
0.0, 0.0
width,height
scale(width/1.0, height/2M)
translate(0.0, height)
0.0, -height
1.0, 0.0
width, -height
0.0, height
width, height
scale(1.0, -1.0)
0.0, 0.0
We do the steps backwards
in the code
width, 0.0
0.0, 0.0
width, 0.0
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
curve() is called from FermiCalc
public void paintComponent(Graphics g) {
when new iteration s are ready
super.paintComponent(g);
to be plotted
// 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;
}
}
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
PhaseCanvas
TimeCanvas
Labels
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.
FermiPlotView code
These are the names you called
public FermiPlotView()
{
the two canvases in the GUI builder
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
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/T
GA/Projects/FermiPlot/dist/ja
vadoc/index.html will show
you documentation for your
Project
•But we did not insert many
JavaDoc comments…
Download