6dea99a84878f2d6a6e6e293aa0cf6a808e08144
[IRC.git] / Robust / src / Benchmarks / Scheduling / GC / NON_BAMBOO / bh / Tree.java
1
2 //import java.util.Enumeration;
3
4 /**
5  * A class that represents the root of the data structure used
6  * to represent the N-bodies in the Barnes-Hut algorithm.
7  **/
8 class Tree
9 {
10   public double DTIME; 
11   
12   MathVector rmin;
13   public double     rsize;
14   /**
15    * A reference to the root node.
16    **/
17   public Node       root;
18   /**
19    * The complete list of bodies that have been created.
20    **/
21   public  Body       bodyTab;
22   /**
23    * The complete list of bodies that have been created - in reverse.
24    **/
25   public  Body       bodyTabRev;
26
27   /**
28    * Construct the root of the data structure that represents the N-bodies.
29    **/
30   public Tree(double DTIME)
31   {
32     rmin       = new MathVector();
33     rsize      = -2.0 * -2.0;
34     root       = null;
35     bodyTab    = null;
36     bodyTabRev = null;
37
38     rmin.value(0, -2.0);
39     rmin.value(1, -2.0);
40     rmin.value(2, -2.0);
41     
42     this.DTIME = DTIME;
43   }
44
45   /**
46    * Return an enumeration of the bodies.
47    * @return an enumeration of the bodies.
48    **/
49   /*final Enumeration bodies()
50   {
51     return bodyTab.elements();
52   }*/
53
54   /**
55    * Return an enumeration of the bodies - in reverse.
56    * @return an enumeration of the bodies - in reverse.
57    **/
58   /*final Enumeration bodiesRev()
59   {
60     return bodyTabRev.elementsRev();
61   }*/
62
63   /**
64    * Random number generator used by the orignal BH benchmark.
65    * @param seed the seed to the generator
66    * @return a random number
67    **/
68   public double myRand(double seed)
69   {
70     double t = 16807.0*seed + 1;
71
72     double iseed = t - (2147483647.0 * Math.floor(t / 2147483647.0f));
73     return iseed;
74   }
75
76   /**
77    * Generate a doubleing point random number.  Used by
78    * the original BH benchmark.
79    *
80    * @param xl lower bound
81    * @param xh upper bound
82    * @param r seed
83    * @return a doubleing point randon number
84    **/
85   public double xRand(double xl, double xh, double r)
86   {
87     double res = xl + (xh-xl)*r/2147483647.0;
88     return res;
89   }
90   
91   /**
92    * Create the testdata used in the benchmark.
93    * @param nbody the number of bodies to create
94    **/
95   public  void createTestData(int nbody)
96   {
97     MathVector cmr = new MathVector();
98     MathVector cmv = new MathVector();
99
100     Body head = new Body();
101     Body prev = head;
102
103     double rsc  = 3.0 * Math.PI() / 16.0;
104     double vsc  = Math.sqrt(1.0 / rsc);
105     double seed = 123.0;
106     //Random rand = new Random((long)seed);
107     //int max_int = ~(int)0x1+1;
108
109     for (int i = 0; i < nbody; i++) {
110       Body p = new Body();
111
112       prev.setNext(p);
113       prev = p;
114       p.mass = 1.0/nbody;
115
116       seed      = myRand(seed);
117       //seed = Math.abs((double)rand.nextInt()/max_int);
118       double t1 = xRand(0.0, 0.999, seed);
119       t1        = Math.pow(t1, (-2.0/3.0)) - 1.0;
120       double r  = 1.0 / Math.sqrt(t1);
121
122       double coeff = 4.0;
123       for (int k = 0; k < cmr.NDIM; k++) {
124         seed = myRand(seed);
125         //seed = Math.abs((double)rand.nextInt()/max_int);
126         r = xRand(0.0, 0.999, seed);
127         p.pos.value(k, coeff*r);
128       }
129
130       cmr.addition(p.pos);
131
132       double x, y;
133       do {
134         seed = myRand(seed);
135         //seed = Math.abs((double)rand.nextInt()/max_int);
136         x    = xRand(0.0, 1.0, seed);
137         seed = myRand(seed);
138         //seed = Math.abs((double)rand.nextInt()/max_int);
139         y    = xRand(0.0, 0.1, seed);
140       } while (y > (x*x * Math.pow((1.0f - x*x), 3.5)));
141
142       double v = Math.sqrt(2.0) * x / Math.pow(1 + r*r, 0.25);
143
144       double rad = vsc * v;
145       double rsq;
146       do {
147         for (int k = 0; k < cmr.NDIM; k++) {
148           seed     = myRand(seed);
149           //seed = Math.abs((double)rand.nextInt()/max_int);
150           p.vel.value(k, xRand(-1.0, 1.0, seed));
151         }
152         rsq = p.vel.dotProduct();
153       } while (rsq > 1.0);
154       double rsc1 = rad / Math.sqrt(rsq);
155       p.vel.multScalar(rsc1);
156       cmv.addition(p.vel);
157     }
158
159     // mark end of list
160     prev.setNext(null);
161     // toss the dummy node at the beginning and set a reference to the first element
162     bodyTab = head.getNext();
163
164     cmr.divScalar(nbody);
165     cmv.divScalar(nbody);
166
167     prev = null;
168     Body b = this.bodyTab;
169     do {
170       b.pos.subtraction(cmr);
171       b.vel.subtraction(cmv);
172       b.setProcNext(prev);
173       prev = b;
174       b = b.getNext();
175     } while(b != null);
176     // set the reference to the last element
177     bodyTabRev = prev;
178   }
179
180
181   /**
182    * Advance the N-body system one time-step.
183    * @param nstep the current time step
184    **/
185   public void stepSystem(int nstep)
186   {
187     // free the tree
188     this.root = null;
189
190     makeTree(nstep);
191     
192     Body next = null;
193     Body b = this.bodyTabRev;
194     do {
195       b.hackGravity(this.rsize, this.root);
196       b = b.getProcNext();
197     } while(b != null);
198
199     vp(this.bodyTabRev, nstep);
200
201   }
202
203   /**
204    * Initialize the tree structure for hack force calculation.
205    * @param nsteps the current time step
206    **/
207   public  void makeTree(int nstep)
208   {
209     Body q = this.bodyTabRev;
210     do {
211       if (q.mass != 0.0) {
212         q.expandBox(this, nstep);
213         MathVector xqic = intcoord(q.pos);
214         if (this.root == null) {
215           this.root = q;
216         } else {
217           if(root instanceof Body) {
218             Body rootb = (Body) root;
219             this.root = rootb.loadTree(q, xqic, 1073741824/*Node.IMAX*/ >> 1, this);
220           } else if(root instanceof Cell) {
221             Cell rootc = (Cell)root;
222             this.root = rootc.loadTree(q, xqic, 1073741824/*Node.IMAX*/ >> 1, this);
223           }
224         }
225       }
226       q = q.getProcNext();
227     } while(q != null);
228     if(root instanceof Body) {
229       Body rootb = (Body)root;
230       rootb.hackcofm();
231     } else if(root instanceof Cell) {
232       Cell rootc = (Cell)root;
233       rootc.hackcofm();
234     }
235   }
236
237   /**
238    * Compute integerized coordinates.
239    * @return the coordinates or null if rp is out of bounds
240    **/
241   public  MathVector intcoord(MathVector vp)
242   {
243     MathVector xp = new MathVector();
244
245     double xsc = (vp.value(0) - rmin.value(0)) / rsize;
246     if (0.0 <= xsc && xsc < 1.0) {
247       xp.value(0, Math.floor(1073741824/*Node.IMAX*/ * xsc));
248     } else {
249       return null;
250     }
251
252     xsc = (vp.value(1) - rmin.value(1)) / rsize;
253     if (0.0 <= xsc && xsc < 1.0) {
254       xp.value(1, Math.floor(1073741824/*Node.IMAX*/ * xsc));
255     } else {
256       return null;
257     }
258
259     xsc = (vp.value(2) - rmin.value(2)) / rsize;
260     if (0.0 <= xsc && xsc < 1.0) {
261       xp.value(2, Math.floor(1073741824/*Node.IMAX*/ * xsc));
262     } else {
263       return null;
264     }
265     return xp;
266   }
267
268   public  void vp(Body p, int nstep)
269   {
270     MathVector dacc = new MathVector();
271     MathVector dvel = new MathVector();
272     double dthf = 0.5 * this.DTIME;
273     
274     Body b = p;
275     do {
276       MathVector acc1 = (MathVector)b.newAcc.clone();
277       if (nstep > 0) {
278         dacc.subtraction(acc1, b.acc);
279         dvel.multScalar(dacc, dthf);
280         dvel.addition(b.vel);
281         b.vel = (MathVector)dvel.clone();
282       }
283       b.acc = (MathVector)acc1.clone();
284       dvel.multScalar(b.acc, dthf);
285
286       MathVector vel1 = (MathVector)b.vel.clone();
287       vel1.addition(dvel);
288       MathVector dpos = (MathVector)vel1.clone();
289       dpos.multScalar(this.DTIME);
290       dpos.addition(b.pos);
291       b.pos = (MathVector)dpos.clone();
292       vel1.addition(dvel);
293       b.vel = (MathVector)vel1.clone();
294       
295       b = b.getProcNext();
296     } while(b != null);
297   }
298 }