3 //import java.util.Enumeration;
6 * A class that represents the root of the data structure used
7 * to represent the N-bodies in the Barnes-Hut algorithm.
16 * A reference to the root node.
20 * The complete list of bodies that have been created.
24 * The complete list of bodies that have been created - in reverse.
26 public Body bodyTabRev;
29 * Construct the root of the data structure that represents the N-bodies.
31 public Tree(double DTIME)
33 rmin = new MathVector();
47 * Return an enumeration of the bodies.
48 * @return an enumeration of the bodies.
50 /*final Enumeration bodies()
52 return bodyTab.elements();
56 * Return an enumeration of the bodies - in reverse.
57 * @return an enumeration of the bodies - in reverse.
59 /*final Enumeration bodiesRev()
61 return bodyTabRev.elementsRev();
65 * Random number generator used by the orignal BH benchmark.
66 * @param seed the seed to the generator
67 * @return a random number
69 public double myRand(double seed)
71 double t = 16807.0*seed + 1;
73 double iseed = t - (2147483647.0 * Math.floor(t / 2147483647.0f));
78 * Generate a doubleing point random number. Used by
79 * the original BH benchmark.
81 * @param xl lower bound
82 * @param xh upper bound
84 * @return a doubleing point randon number
86 public double xRand(double xl, double xh, double r)
88 double res = xl + (xh-xl)*r/2147483647.0;
93 * Create the testdata used in the benchmark.
94 * @param nbody the number of bodies to create
96 public void createTestData(int nbody)
98 MathVector cmr = new MathVector();
99 MathVector cmv = new MathVector();
101 Body head = new Body();
104 double rsc = 3.0 * Math.PI() / 16.0;
105 double vsc = Math.sqrt(1.0 / rsc);
107 //Random rand = new Random((long)seed);
108 //int max_int = ~(int)0x1+1;
110 for (int i = 0; i < nbody; i++) {
118 //seed = Math.abs((double)rand.nextInt()/max_int);
119 double t1 = xRand(0.0, 0.999, seed);
120 t1 = Math.pow(t1, (-2.0/3.0)) - 1.0;
121 double r = 1.0 / Math.sqrt(t1);
124 for (int k = 0; k < cmr.NDIM; k++) {
126 //seed = Math.abs((double)rand.nextInt()/max_int);
127 r = xRand(0.0, 0.999, seed);
128 p.pos.value(k, coeff*r);
136 //seed = Math.abs((double)rand.nextInt()/max_int);
137 x = xRand(0.0, 1.0, seed);
139 //seed = Math.abs((double)rand.nextInt()/max_int);
140 y = xRand(0.0, 0.1, seed);
141 } while (y > (x*x * Math.pow((1.0f - x*x), 3.5)));
143 double v = Math.sqrt(2.0) * x / Math.pow(1 + r*r, 0.25);
145 double rad = vsc * v;
148 for (int k = 0; k < cmr.NDIM; k++) {
150 //seed = Math.abs((double)rand.nextInt()/max_int);
151 p.vel.value(k, xRand(-1.0, 1.0, seed));
153 rsq = p.vel.dotProduct();
155 double rsc1 = rad / Math.sqrt(rsq);
156 p.vel.multScalar(rsc1);
162 // toss the dummy node at the beginning and set a reference to the first element
163 bodyTab = head.getNext();
165 cmr.divScalar(nbody);
166 cmv.divScalar(nbody);
169 Body b = this.bodyTab;
171 b.pos.subtraction(cmr);
172 b.vel.subtraction(cmv);
177 // set the reference to the last element
183 * Advance the N-body system one time-step.
184 * @param nstep the current time step
186 public void stepSystem(int nstep)
194 Body b = this.bodyTabRev;
196 b.hackGravity(this.rsize, this.root);
200 vp(this.bodyTabRev, nstep);
205 * Initialize the tree structure for hack force calculation.
206 * @param nsteps the current time step
208 public void makeTree(int nstep)
210 Body q = this.bodyTabRev;
213 q.expandBox(this, nstep);
214 MathVector xqic = intcoord(q.pos);
215 if (this.root == null) {
218 if(root instanceof Body) {
219 Body rootb = (Body) root;
220 this.root = rootb.loadTree(q, xqic, 1073741824/*Node.IMAX*/ >> 1, this);
221 } else if(root instanceof Cell) {
222 Cell rootc = (Cell)root;
223 this.root = rootc.loadTree(q, xqic, 1073741824/*Node.IMAX*/ >> 1, this);
229 if(root instanceof Body) {
230 Body rootb = (Body)root;
232 } else if(root instanceof Cell) {
233 Cell rootc = (Cell)root;
239 * Compute integerized coordinates.
240 * @return the coordinates or null if rp is out of bounds
242 public MathVector intcoord(MathVector vp)
244 MathVector xp = new MathVector();
246 double xsc = (vp.value(0) - rmin.value(0)) / rsize;
247 if (0.0 <= xsc && xsc < 1.0) {
248 xp.value(0, Math.floor(1073741824/*Node.IMAX*/ * xsc));
253 xsc = (vp.value(1) - rmin.value(1)) / rsize;
254 if (0.0 <= xsc && xsc < 1.0) {
255 xp.value(1, Math.floor(1073741824/*Node.IMAX*/ * xsc));
260 xsc = (vp.value(2) - rmin.value(2)) / rsize;
261 if (0.0 <= xsc && xsc < 1.0) {
262 xp.value(2, Math.floor(1073741824/*Node.IMAX*/ * xsc));
269 public void vp(Body p, int nstep)
271 MathVector dacc = new MathVector();
272 MathVector dvel = new MathVector();
273 double dthf = 0.5 * this.DTIME;
277 MathVector acc1 = (MathVector)b.newAcc.clone();
279 dacc.subtraction(acc1, b.acc);
280 dvel.multScalar(dacc, dthf);
281 dvel.addition(b.vel);
282 b.vel = (MathVector)dvel.clone();
284 b.acc = (MathVector)acc1.clone();
285 dvel.multScalar(b.acc, dthf);
287 MathVector vel1 = (MathVector)b.vel.clone();
289 MathVector dpos = (MathVector)vel1.clone();
290 dpos.multScalar(this.DTIME);
291 dpos.addition(b.pos);
292 b.pos = (MathVector)dpos.clone();
294 b.vel = (MathVector)vel1.clone();