local void walktree(nodeptr *aptr, nodeptr *nptr, cellptr cptr, cellptr bptr, nodeptr p, real psize, vector pmid) { nodeptr *np, *ap, q; int actsafe; matrix trQM; if (Update(p)) { // new forces needed in node? np = nptr; // start new active list actsafe = actmax - NSUB; // leave room for NSUB more for (ap = aptr; ap < nptr; ap++) { // loop over active nodes if (Type(*ap) == CELL) { // is this node a cell? if (accept(*ap, psize, pmid)) { // does it pass the test? if (Mass(*ap) > 0.0) { // and contribute to field? Mass(cptr) = Mass(*ap); // copy to interaction list SETV(Pos(cptr), Pos(*ap)); #if defined(SOFTCORR) TRACEM(Trace(cptr), Quad(*ap)); // save trace in copy SETMI(trQM); MULMS(trQM, trQM, Trace(cptr)/3); SUBM(Quad(cptr), Quad(*ap), trQM); // store traceless moment #else SETM(Quad(cptr), Quad(*ap)); // copy traceless moment #endif cptr++; // and bump cell array ptr } } else { // this cell fails the test if (np - active >= actsafe) // make sure list has room fatal("%s.walktree: active list overflow\n", getprog()); for (q = More(*ap); q != Next(*ap); q = Next(q)) // loop over all subcells *np++= q; // put them on active list } } else // else this node is a body if (*ap != p && Mass(*ap) > 0.0) { // not self-interaction? --bptr; // bump body array ptr Mass(bptr) = Mass(*ap); // and copy data to array SETV(Pos(bptr), Pos(*ap)); } } acttot = MAX(acttot, np - active); // keep track of max active if (np != nptr) { // if new actives were added walksub(nptr, np, cptr, bptr, p, psize, pmid); // then visit next level } else { // else no actives left if (Type(p) != BODY) // make sure we got a body fatal("%s.walktree: recursion terminated with cell\n" " p = 0x%x psize = %.8f Mass(p) = %g\n" " pmid = (%.8f,%.8f,%.8f)\n Pos(p) = (%.8f,%.8f,%.8f)\n", getprog(), (int) p, psize, Mass(p), pmid[0], pmid[1], pmid[2], Pos(p)[0], Pos(p)[1], Pos(p)[2]); gravsum((bodyptr) p, cptr, bptr); // sum force on this body } } }
local void diagnostics() { bodyptr p; real velsq, phi0; vector tmpv; matrix tmpt; int ndim=NDIM; mtot = 0.0; /* zero total mass */ etot[1] = etot[2] = 0.0; /* zero total KE and PE */ CLRM(keten); /* zero ke tensor */ CLRM(peten); /* zero pe tensor */ CLRM(amten); /* zero am tensor */ CLRV(cmphase[0]); /* zero c. of m. position */ CLRV(cmphase[1]); /* zero c. of m. velocity */ for (p = bodytab; p < bodytab+nbody; p++) { /* loop over all particles */ mtot += Mass(p); /* sum particle masses */ DOTVP(velsq, Vel(p), Vel(p)); /* square vel vector */ if (extpot) { /* external potential corr. */ (*extpot)(&ndim,Pos(p),tmpv,&phi0,&tnow); phi0 = Phi(p) + phi0; /* extre correction */ } else phi0 = Phi(p); etot[1] += 0.5 * Mass(p) * velsq; /* sum current KE */ etot[2] += 0.5 * Mass(p) * phi0; /* and current PE */ MULVS(tmpv, Vel(p), 0.5 * Mass(p)); /* sum 0.5 m v_i v_j */ OUTVP(tmpt, tmpv, Vel(p)); ADDM(keten, keten, tmpt); MULVS(tmpv, Pos(p), Mass(p)); /* sum m r_i a_j */ OUTVP(tmpt, tmpv, Acc(p)); ADDM(peten, peten, tmpt); OUTVP(tmpt, tmpv, Vel(p)); /* sum m r_i v_j */ ADDM(amten, amten, tmpt); MULVS(tmpv, Pos(p), Mass(p)); /* sum cm position */ ADDV(cmphase[0], cmphase[0], tmpv); MULVS(tmpv, Vel(p), Mass(p)); /* sum cm momentum */ ADDV(cmphase[1], cmphase[1], tmpv); } etot[0] = etot[1] + etot[2]; /* sum KE and PE */ TRANM(tmpt, amten); /* anti-sym. AM tensor */ SUBM(amten, amten, tmpt); DIVVS(cmphase[0], cmphase[0], mtot); /* normalize cm coords */ DIVVS(cmphase[1], cmphase[1], mtot); }
local void diagnostics() { int i; Body *p; real velsq; vector tmpv; matrix tmpt; mtot = 0.0; /* zero total mass */ etot[1] = etot[2] = 0.0; /* zero total KE and PE */ CLRM(keten); /* zero KE tensor */ CLRM(peten); /* zero PE tensor */ CLRM(amten); /* zero AM tensor */ CLRV(cmphase[0]); /* zero c. of m. position */ CLRV(cmphase[1]); /* zero c. of m. velocity */ for (p = bodytab; p < bodytab+nbody; p++) { /* loop over all bodies */ mtot += Mass(p); /* sum body masses */ DOTVP(velsq, Vel(p), Vel(p)); /* square vel vector */ etot[1] += 0.5 * Mass(p) * velsq; /* sum current KE */ etot[2] += 0.5 * Mass(p) * Phi(p); /* and current PE */ MULVS(tmpv, Vel(p), 0.5 * Mass(p)); /* sum 0.5 m v_i v_j */ OUTVP(tmpt, tmpv, Vel(p)); ADDM(keten, keten, tmpt); MULVS(tmpv, Pos(p), Mass(p)); /* sum m r_i a_j */ OUTVP(tmpt, tmpv, Acc(p)); ADDM(peten, peten, tmpt); OUTVP(tmpt, tmpv, Vel(p)); /* sum m r_i v_j */ ADDM(amten, amten, tmpt); MULVS(tmpv, Pos(p), Mass(p)); /* sum cm position */ ADDV(cmphase[0], cmphase[0], tmpv); MULVS(tmpv, Vel(p), Mass(p)); /* sum cm momentum */ ADDV(cmphase[1], cmphase[1], tmpv); } etot[0] = etot[1] + etot[2]; /* sum KE and PE */ TRANM(tmpt, amten); /* antisymmetrize AM tensor */ SUBM(amten, amten, tmpt); DIVVS(cmphase[0], cmphase[0], mtot); /* normalize cm coords */ DIVVS(cmphase[1], cmphase[1], mtot); }