8
8
import info .monitorenter .gui .chart .ZoomableChart ;
9
9
import info .monitorenter .gui .chart .traces .Trace2DLtd ;
10
10
import info .monitorenter .gui .chart .views .ChartPanel ;
11
+ import java .awt .Dimension ;
12
+ import java .io .BufferedOutputStream ;
11
13
import java .io .File ;
12
14
import java .io .FileNotFoundException ;
15
+ import java .io .FileOutputStream ;
13
16
import java .io .IOException ;
14
17
import java .io .PrintStream ;
15
18
import java .util .Scanner ;
@@ -68,17 +71,15 @@ public void loadField(
68
71
}
69
72
}
70
73
71
- private static double h = 1.0e-3 ;
72
-
73
74
// ix < dimX - 1, etc.
74
75
private double dx (int ix , int iy , int iz ) {
75
- return (potential [ix + 1 ][iy ][iz ] - potential [ix ][iy ][iz ]) / h ;
76
+ return (potential [ix + 1 ][iy ][iz ] - potential [ix ][iy ][iz ]);
76
77
}
77
78
private double dy (int ix , int iy , int iz ) {
78
- return (potential [ix ][iy + 1 ][iz ] - potential [ix ][iy ][iz ]) / h ;
79
+ return (potential [ix ][iy + 1 ][iz ] - potential [ix ][iy ][iz ]);
79
80
}
80
81
private double dz (int ix , int iy , int iz ) {
81
- return (potential [ix ][iy ][iz + 1 ] - potential [ix ][iy ][iz ]) / h ;
82
+ return (potential [ix ][iy ][iz + 1 ] - potential [ix ][iy ][iz ]);
82
83
}
83
84
84
85
@ Command
@@ -163,10 +164,38 @@ private static final double interpolate(double[][][] v, double x, double y, doub
163
164
}
164
165
165
166
@ Command
166
- public double getPotential (double x , double y , double z ) {
167
+ public final double getPotential (double x , double y , double z ) {
167
168
return interpolate (potential , x , y , z );
168
169
}
169
170
171
+ private final double getEnergy (double e , double m ,
172
+ double x , double y , double z ,
173
+ double vx , double vy , double vz ) {
174
+ return -e * getPotential (x , y , z ) + m * (vx *vx + vy *vy + vz *vz ) / (2 * K );
175
+ }
176
+
177
+ /**
178
+ * On the unit system
179
+ *
180
+ * The user specifies quantities in following units:
181
+ * e |e| units
182
+ * E eV
183
+ * m amu
184
+ * V V
185
+ * x arb.u.
186
+ * t arb.u.
187
+ * Where arbitrary units for x and t are in agreement:
188
+ * if x is in mm, then t in ms, x in um, then t in us, etc.
189
+ *
190
+ * The Newton's equation is
191
+ * e/m dV/dx = d2x/dt2, quantities in SI.
192
+ * Transforming the eq. to our unit system:
193
+ * K e/m dV/dx = d2x/dt2, where K = |elemCharge|/1amu = |elemCharge|*NAvogadro*1000/1kg
194
+ * The same K appears in v(E): v = sqrt(2E/m) SI => v = sqrt(2E/m K),
195
+ * Ekinetic = mv2/2K for the same reason.
196
+ */
197
+ private static final double K = 9.648534147e6 ;
198
+
170
199
public void solve (double dt , double m , double e ,
171
200
double x0 , double y0 , double z0 ,
172
201
double kineticE , double dirX , double dirY , double dirZ ,
@@ -179,7 +208,7 @@ public void solve(double dt, double m, double e,
179
208
180
209
Vector dir = new Vector (dirX , dirY , dirZ );
181
210
dir .normalizeIt ();
182
- Vector v0 = dir .multiply (Math .sqrt (kineticE * 2 / m ));
211
+ Vector v0 = dir .multiply (Math .sqrt (kineticE * 2 / m * K ));
183
212
184
213
int steps = 0 ;
185
214
double t = 0 ;
@@ -191,15 +220,17 @@ public void solve(double dt, double m, double e,
191
220
x >= 0 && x <= dimX &&
192
221
y >= 0 && y <= dimY &&
193
222
z >= 0 && z <= dimZ ) {
223
+ steps ++;
224
+
194
225
es = getIntensity (x , y , z );
195
226
if (es == null ) {
196
227
break ;
197
228
}
198
229
t += dt ;
199
230
200
- vx += dt * es [X ] * e / m ;
201
- vy += dt * es [Y ] * e / m ;
202
- vz += dt * es [Z ] * e / m ;
231
+ vx += dt * es [X ] * e / m * K ;
232
+ vy += dt * es [Y ] * e / m * K ;
233
+ vz += dt * es [Z ] * e / m * K ;
203
234
204
235
x += dt * vx ;
205
236
y += dt * vy ;
@@ -209,6 +240,9 @@ public void solve(double dt, double m, double e,
209
240
c .point (t , x , y , z , vx , vy , vz );
210
241
}
211
242
}
243
+ for (Callback c : callbacks ) {
244
+ c .close ();
245
+ }
212
246
}
213
247
214
248
private JFrame chartFrame = null ;
@@ -217,33 +251,70 @@ public void solve(double dt, double m, double e,
217
251
public void showGraph () {
218
252
if (chartFrame == null ) {
219
253
JFrame frame = new JFrame ("Graph" );
254
+ frame .setSize (new Dimension (600 , 400 ));
220
255
ZoomableChart chart = new ZoomableChart ();
221
256
chart .addTrace (energyTrace );
222
- frame .getRootPane ().add (new ChartPanel (chart ));
257
+ chart .addTrace (xCoordTrace );
258
+ chart .addTrace (yCoordTrace );
259
+ chart .addTrace (zCoordTrace );
260
+ frame .getContentPane ().add (new ChartPanel (chart ));
223
261
chartFrame = frame ;
224
262
}
225
263
chartFrame .setVisible (true );
226
264
}
227
265
228
- private ITrace2D energyTrace = new Trace2DLtd (10000 , "energy" );
229
- private Callback energyPlottingCallback = new EnergyPllottingCallback ();
266
+ private static final int TRACE_SIZE_LIMIT = 10000 ;
267
+
268
+ private ITrace2D energyTrace = new Trace2DLtd (TRACE_SIZE_LIMIT , "energy" );
269
+ private Callback energyPlottingCallback = new EnergyPlottingCallback ();
230
270
231
- private class EnergyPllottingCallback implements Callback {
271
+ private ITrace2D xCoordTrace = new Trace2DLtd (TRACE_SIZE_LIMIT , "x" );
272
+ private ITrace2D yCoordTrace = new Trace2DLtd (TRACE_SIZE_LIMIT , "y" );
273
+ private ITrace2D zCoordTrace = new Trace2DLtd (TRACE_SIZE_LIMIT , "z" );
274
+ private Callback coordPlottingCallback = new XYZPlottingCallback ();
232
275
233
- private double m ;
234
- private double e ;
276
+ private abstract class PlottingCallback implements Callback {
277
+
278
+ protected double m ;
279
+ protected double e ;
280
+
281
+ protected abstract void clearTraces ();
235
282
236
283
public void params (double dt , double m , double e , double x0 , double y0 , double z0 , double kineticE , double dirX , double dirY , double dirZ ) {
284
+ clearTraces ();
237
285
this .m = m ;
238
286
this .e = e ;
239
287
}
240
288
289
+ public abstract void point (double t , double x , double y , double z , double vx , double vy , double vz );
290
+
291
+ public void close () {}
292
+ }
293
+
294
+ private class EnergyPlottingCallback extends PlottingCallback {
295
+
296
+ protected void clearTraces () {
297
+ energyTrace .removeAllPoints ();
298
+ }
299
+
241
300
public void point (double t , double x , double y , double z , double vx , double vy , double vz ) {
242
- final double fullE = e * getPotential (x , y , z ) + (vx *vx + vy *vy + vz *vz ) * m / 2 ;
243
- energyTrace .addPoint (t , fullE );
301
+ energyTrace .addPoint (t , getEnergy (e , m , x , y , z , vx , vy , vz ));
302
+ }
303
+ }
304
+
305
+ private class XYZPlottingCallback extends PlottingCallback {
306
+
307
+ protected void clearTraces () {
308
+ xCoordTrace .removeAllPoints ();
309
+ yCoordTrace .removeAllPoints ();
310
+ zCoordTrace .removeAllPoints ();
244
311
}
245
312
246
- public void close () {}
313
+ public void point (double t , double x , double y , double z , double vx , double vy , double vz ) {
314
+ xCoordTrace .addPoint (t , x );
315
+ yCoordTrace .addPoint (t , y );
316
+ zCoordTrace .addPoint (t , z );
317
+ }
247
318
}
248
319
249
320
private class OutputCallback implements Callback {
@@ -316,14 +387,21 @@ public void setR0(double x, double y, double z) {
316
387
317
388
@ Command
318
389
public void fly (String outFileBase ) throws FileNotFoundException {
319
- final Callback writer = new OutputCallback (new PrintStream (outFileBase + ".txt" ));
390
+ final Callback writer = new OutputCallback (new PrintStream (
391
+ new BufferedOutputStream (new FileOutputStream (outFileBase + ".txt" ))));
320
392
solve (dt , mass , charge ,
321
393
r0 .getX (), r0 .getY (), r0 .getZ (),
322
394
k0 , dirV0 .getX (), dirV0 .getY (), dirV0 .getZ (),
323
395
maxSteps ,
324
- energyPlottingCallback , writer );
396
+ energyPlottingCallback ,
397
+ // coordPlottingCallback,
398
+ writer );
325
399
}
326
400
401
+ @ Command
402
+ public void exit () {
403
+ System .exit (0 );
404
+ }
327
405
328
406
/**
329
407
* @param args the command line arguments
0 commit comments