/** * Enlarge cubical "box", salvaging existing tree structure. * * @param tree the root of the tree. * @param nsteps the current time step */ public void expandBox (BTree tree, int nsteps) { MathVector rmid = MathVector.makeMathVector (); int k; bool inbox = icTest (tree); while (!inbox) { double rsize = tree.rsize; rmid.addScalar (tree.rmin, 0.5 * rsize); for (k = 0; k < MathVector.NDIM; k++) { if (pos.value (k) < rmid.value (k)) { double rmin = tree.rmin.value (k); tree.rmin.setValue (k, rmin - rsize); } } tree.rsize = 2.0 * rsize; if (tree.root != null) { MathVector ic = tree.intcoord (rmid); k = Node.oldSubindex (ic, Node.IMAX >> 1); Cell newt = Cell.makeCell (); newt.subp [k] = tree.root; tree.root = newt; inbox = icTest (tree); } } }
/** * Descend Tree and insert particle. We're at a cell so * we need to move down the tree. * * @param p the body to insert into the tree * @param xpic * @param l * @param tree the root of the tree * @return the subtree with the new body inserted */ public override Cell loadTree (Body p, MathVector xpic, int l, BTree tree) { // move down one level int si = Node.oldSubindex (xpic, l); Node rt = subp [si]; if (rt != null) subp [si] = rt.loadTree (p, xpic, l >> 1, tree); else subp [si] = p; return this; }
/** * Construct the root of the data structure that represents the N-bodies. */ public static BTree makeTreeX () { BTree t = new BTree (); t.rmin = MathVector.makeMathVector (); t.rsize = -2.0 * -2.0; t.root = null; t.bodyTab = null; t.bodyTabRev = null; t.rmin.setValue (0, -2.0); t.rmin.setValue (1, -2.0); t.rmin.setValue (2, -2.0); return t; }
/** * Check the bounds of the body and return true if it isn't in the * correct bounds. */ public bool icTest (BTree tree) { double pos0 = pos.value (0); double pos1 = pos.value (1); double pos2 = pos.value (2); // by default, it is in bounds bool result = true; double xsc = (pos0 - tree.rmin.value (0)) / tree.rsize; if (!(0.0 < xsc && xsc < 1.0)) result = false; xsc = (pos1 - tree.rmin.value (1)) / tree.rsize; if (!(0.0 < xsc && xsc < 1.0)) result = false; xsc = (pos2 - tree.rmin.value (2)) / tree.rsize; if (!(0.0 < xsc && xsc < 1.0)) result = false; return result; }
public abstract Cell loadTree(Body p, MathVector xpic, int l, BTree root);
/** * Determine which subcell to select. * Combination of intcoord and oldSubindex. * * @param t the root of the tree */ public int subindex (BTree tree, int l) { MathVector xp = MathVector.makeMathVector (); double imxv = (double)Node.IMAX; double xsc = (pos.value (0) - tree.rmin.value (0)) / tree.rsize; xp.setValue (0, Math.Floor (imxv * xsc)); xsc = (pos.value (1) - tree.rmin.value (1)) / tree.rsize; xp.setValue (1, Math.Floor (imxv * xsc)); xsc = (pos.value (2) - tree.rmin.value (2)) / tree.rsize; xp.setValue (2, Math.Floor (imxv * xsc)); int i = 0; for (int k = 0; k < MathVector.NDIM; k++) { if (((int)xp.value (k) & l) != 0) //This used val & 1 != 0 so if there is a problem look here i += Cell.NSUB >> (k + 1); } return i; }
/** * Descend Tree and insert particle. We're at a body so we need to * create a cell and attach this body to the cell. * * @param p the body to insert * @param xpic * @param l * @param tree the root of the data structure * @return the subtree with the new body inserted */ public override Cell loadTree (Body p, MathVector xpic, int l, BTree tree) { // create a Cell Cell retval = Cell.makeCell (); int si = subindex (tree, l); // attach this Body node to the cell retval.subp [si] = this; // move down one level si = Node.oldSubindex (xpic, l); Node rt = retval.subp [si]; if (rt != null) retval.subp [si] = rt.loadTree (p, xpic, l >> 1, tree); else retval.subp [si] = p; return retval; }
public abstract Cell loadTree (Body p, MathVector xpic, int l, BTree root);