/** * 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); } } }
static private void vp(List <Body> bv, int nstep) { MathVector dacc = MathVector.makeMathVector(); MathVector dvel = MathVector.makeMathVector(); double dthf = 0.5 * BH.DTIME; for (int i = 0; i < bv.Count; ++i) { Body b = bv[i]; MathVector acc1 = b.newAcc.cloneMathVector(); if (nstep > 0) { dacc.subtraction2(acc1, b.acc); dvel.multScalar2(dacc, dthf); dvel.addition(b.vel); b.vel = dvel.cloneMathVector(); } b.acc = acc1.cloneMathVector(); dvel.multScalar2(b.acc, dthf); MathVector vel1 = b.vel.cloneMathVector(); vel1.addition(dvel); MathVector dpos = vel1.cloneMathVector(); dpos.multScalar1(BH.DTIME); dpos.addition(b.pos); b.pos = dpos.cloneMathVector(); vel1.addition(dvel); b.vel = vel1.cloneMathVector(); } }
/** * 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); }
/** * Create a HG object. * * @param b the body object * @param p a vector that represents the body */ public static HG makeHG(Body b, MathVector p) { HG hg = new HG(); hg.pskip = b; hg.pos0 = p.cloneMathVector(); hg.phi0 = 0.0; hg.acc0 = MathVector.makeMathVector(); return(hg); }
/** * Decide if the cell is too close to accept as a single term. * * @return true if the cell is too close. */ public bool subdivp(double dsq, HG hg) { MathVector dr = MathVector.makeMathVector(); dr.subtraction2(pos, hg.pos0); double drsq = dr.dotProduct(); // in the original olden version drsp is multiplied by 1.0 return(drsq < dsq); }
//private Body next; //private Body procNext; /** * Create an empty body. */ public static Body makeBody() { Body b = new Body(); b.initNode(); b.vel = MathVector.makeMathVector(); b.acc = MathVector.makeMathVector(); b.newAcc = MathVector.makeMathVector(); b.phi = 0.0; return(b); }
/** * 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); }
/** * Compute a single body-body or body-cell interaction */ public HG gravSub(HG hg) { MathVector dr = MathVector.makeMathVector(); dr.subtraction2(pos, hg.pos0); double drsq = dr.dotProduct() + (EPS * EPS); double drabs = Math.Sqrt(drsq); double phii = mass / drabs; hg.phi0 -= phii; double mor3 = phii / drsq; dr.multScalar1(mor3); hg.acc0.addition(dr); return(hg); }
/** * Compute integerized coordinates. * * @return the coordinates or null if rp is out of bounds */ public MathVector intcoord(MathVector vp) { MathVector xp = MathVector.makeMathVector(); double imxv = (double)Node.IMAX; double xsc = (vp.value(0) - rmin.value(0)) / rsize; if (0.0 <= xsc && xsc < 1.0) { xp.setValue(0, Math.Floor(imxv * xsc)); } else { return(null); } xsc = (vp.value(1) - rmin.value(1)) / rsize; if (0.0 <= xsc && xsc < 1.0) { xp.setValue(1, Math.Floor(imxv * xsc)); } else { return(null); } xsc = (vp.value(2) - rmin.value(2)) / rsize; if (0.0 <= xsc && xsc < 1.0) { xp.setValue(2, Math.Floor(imxv * xsc)); } else { return(null); } return(xp); }
/** * Descend tree finding center of mass coordinates * * @return the mass of this node */ public override double hackcofm() { double mq = 0.0; MathVector tmpPos = MathVector.makeMathVector(); MathVector tmpv = MathVector.makeMathVector(); for (int i = 0; i < NSUB; i++) { Node r = this.subp[i]; if (r != null) { double mr = r.hackcofm(); mq = mr + mq; tmpv.multScalar2(r.pos, mr); tmpPos.addition(tmpv); } } mass = mq; pos = tmpPos; pos.divScalar(mass); return(mq); }
/** * Create the testdata used in the benchmark. * * @param nbody the number of bodies to create */ public void createTestData(int nbody) { MathVector cmr = MathVector.makeMathVector(); MathVector cmv = MathVector.makeMathVector(); bodyTab = new List <Body>(); double rsc = 3.0 * 3.1415 / 16.0; double vsc = Math.Sqrt(1.0 / rsc); double seed = 123.0; int k; for (int i = 0; i < nbody; i++) { Body p = Body.makeBody(); bodyTab.Add(p); p.mass = 1.0 / (double)nbody; seed = BH.myRand(seed); double t1 = BH.xRand(0.0, 0.999, seed); t1 = Math.Pow(t1, (-2.0 / 3.0)) - 1.0; double r = 1.0 / Math.Sqrt(t1); double coeff = 4.0; for (k = 0; k < MathVector.NDIM; k++) { seed = BH.myRand(seed); r = BH.xRand(0.0, 0.999, seed); p.pos.setValue(k, coeff * r); } cmr.addition(p.pos); double x = 0.0; double y = 0.0; do { seed = BH.myRand(seed); x = BH.xRand(0.0, 1.0, seed); seed = BH.myRand(seed); y = BH.xRand(0.0, 0.1, seed); } while(y > x * x * Math.Pow(1.0 - x * x, 3.5)); double v = Math.Sqrt(2.0) * x / Math.Pow(1.0 + r * r, 0.25); double rad = vsc * v; double rsq = 0.0; do { for (k = 0; k < MathVector.NDIM; k++) { seed = BH.myRand(seed); p.vel.setValue(k, BH.xRand(-1.0, 1.0, seed)); } rsq = p.vel.dotProduct(); } while(rsq > 1.0); double rsc1 = rad / Math.Sqrt(rsq); p.vel.multScalar1(rsc1); cmv.addition(p.vel); } cmr.divScalar((double)nbody); cmv.divScalar((double)nbody); this.bodyTabRev = new List <Body>(); for (int j = 0; j < this.bodyTab.Count; ++j) { Body b = this.bodyTab[j]; b.pos.subtraction1(cmr); b.vel.subtraction1(cmv); this.bodyTabRev.Add(b); } }
/** * Construct an empty node */ public void initNode() { mass = 0.0; pos = MathVector.makeMathVector(); }