import java.applet.Applet; import java.awt.*; import java.awt.event.*; import java.io.*; // here comes the Ode integrator class Parameter { double x0,y0,v_x0,v_y0; double gradB_0, B_0; double q; double xb,xe,yb,ye; double dt; double dtout; public Parameter() { x0 = 0; y0 = 0; v_x0 = 1; v_y0 = 0; xb = -20; yb = -15; xe = 20; ye = 15; q = -1; gradB_0 = 0; B_0 = 0; dt = 0.01; dtout = 3*dt; } } class Ode extends Parameter { double time; double x,y,v_x,v_y; int ic_out; int ic_dtout; public Ode() { time = 0; x = x0; y = y0; v_x = v_x0; v_y = v_y0; ic_out = 1; ic_dtout = (int)(dtout/dt+0.5); } void integrate() { while (true) { singlestep(); if (ic_out >= ic_dtout) { ic_out = 1; break; } else { ic_out++; } } } void singlestep() { // rk2 // d_t x = v_x; d_t y = v_y // d_t v_x = q v_y (B_z + y gradB_0) // d_t v_y = - q v_x (B_z + y gradB_0) double x1, x2, y1, y2, v_x1, v_x2, v_y1, v_y2; x1 = dt*v_x; y1 = dt*v_y; v_x1 = dt*q*v_y*(B_0 + y*gradB_0); v_y1 = -dt*q*v_x*(B_0 + y*gradB_0); x2 = dt*(v_x+0.5*v_x1); y2 = dt*(v_y+0.5*v_y1); v_x2 = dt*q*(v_y+0.5*v_y1)*(B_0 + y*gradB_0); v_y2 = -dt*q*(v_x+0.5*v_x1)*(B_0 + y*gradB_0); x += x2; y += y2; v_x += v_x2; v_y += v_y2; time += dt; if (x > xe) x -= (xe-xb); if (x < xb) x += (xe-xb); if (y > ye) y -= (ye-yb); if (y < yb) y += (ye-yb); } } // here comes the graphics class driftCanvas extends Container { public int x,y; boolean reset_flag=true; public synchronized void reset() { reset_flag=true; } public synchronized void paint(Graphics g) { if (reset_flag) { Dimension size = getSize(); g.setColor(Color.yellow); g.fillRect(0,0,size.width,size.height); reset_flag=false; } g.setColor(Color.blue); g.drawLine(x,y,x,y); } } public class Drift extends Applet implements Runnable, AdjustmentListener, ItemListener, MouseListener { Ode drift; Thread killme = null; Choice charge; Scrollbar bfield; Scrollbar gradBfield; driftCanvas canvas; public synchronized void init() { drift=new Ode(); GridBagLayout gridbag = new GridBagLayout(); GridBagConstraints c = new GridBagConstraints(); setLayout(gridbag); c.weightx = 0.5; c.fill = GridBagConstraints.HORIZONTAL; charge = new Choice(); charge.addItemListener(this); charge.addItem("Electron"); charge.addItem("Ion"); gridbag.setConstraints(charge, c); add(charge); c.weightx = 1; add(new Label(" magnetic Field")); bfield=new Scrollbar(Scrollbar.HORIZONTAL, 128, 1, 0, 255); bfield.addAdjustmentListener(this); gridbag.setConstraints(bfield, c); add(bfield); add(new Label(" gradient B ")); gradBfield=new Scrollbar(Scrollbar.HORIZONTAL, 128, 1, 0, 255); gradBfield.addAdjustmentListener(this); c.gridwidth = GridBagConstraints.REMAINDER; //end row gridbag.setConstraints(gradBfield, c); add(gradBfield); canvas = new driftCanvas(); canvas.addMouseListener(this); c.fill = GridBagConstraints.BOTH; c.weighty = 1.0; gridbag.setConstraints(canvas, c); add(canvas); canvas.reset(); } public void start() { if(killme == null) { killme = new Thread(this); killme.start(); } } public void stop() { killme = null; } public void run() { while (killme != null) { try { drift.integrate(); Dimension size; size = canvas.getSize(); canvas.x = (int)((drift.x-drift.xb)*size.width/(drift.xe-drift.xb)); canvas.y = (int)((drift.y-drift.yb)*size.height/(drift.ye-drift.yb)); Thread.sleep(10); } catch (InterruptedException e){} repaint(); } killme = null; } public void update(Graphics g) { paint(g); } public void itemStateChanged(ItemEvent evt) { if (charge.getSelectedItem().equals("Electron")) { drift.q = -1; } else if (charge.getSelectedItem().equals("Ion")) { drift.q = 0.5; } } public void adjustmentValueChanged(AdjustmentEvent evt) { if (evt.getSource() == gradBfield) { drift.gradB_0 = (gradBfield.getValue()-128)*1./128; } if (evt.getSource() == bfield) { drift.B_0 = (bfield.getValue()-128)*5./128; } } public void mouseClicked(MouseEvent evt) { canvas.reset(); } public void mousePressed(MouseEvent evt) { } public void mouseReleased(MouseEvent evt) { } public void mouseEntered(MouseEvent evt) { } public void mouseExited(MouseEvent evt) { } }