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 } } }
void snaprect(bodyptr btab, int nbody) { matrix qmat, tmpm; bodyptr bp; vector frame[3], tmpv; static vector oldframe[3] = { { 1.0, 0.0, 0.0, }, { 0.0, 1.0, 0.0, }, { 0.0, 0.0, 1.0, }, }; int i; snapcenter(btab, nbody, WeightField.offset); CLRM(qmat); for (bp = btab; bp < NthBody(btab, nbody); bp = NextBody(bp)) { OUTVP(tmpm, Pos(bp), Pos(bp)); MULMS(tmpm, tmpm, Weight(bp)); ADDM(qmat, qmat, tmpm); } eigenvect(frame[0], frame[1], frame[2], qmat); if (dotvp(oldframe[0], frame[0]) < 0.0) MULVS(frame[0], frame[0], -1.0); if (dotvp(oldframe[2], frame[2]) < 0.0) MULVS(frame[2], frame[2], -1.0); CROSSVP(frame[1], frame[2], frame[0]); printvect("e_x:", frame[0]); printvect("e_y:", frame[1]); printvect("e_z:", frame[2]); for (bp = btab; bp < NthBody(btab, nbody); bp = NextBody(bp)) { if (PosField.offset != BadOffset) { for (i = 0; i < NDIM; i++) tmpv[i] = dotvp(Pos(bp), frame[i]); SETV(Pos(bp), tmpv); } if (VelField.offset != BadOffset) { for (i = 0; i < NDIM; i++) tmpv[i] = dotvp(Vel(bp), frame[i]); SETV(Vel(bp), tmpv); } if (AccField.offset != BadOffset) { for (i = 0; i < NDIM; i++) tmpv[i] = dotvp(Acc(bp), frame[i]); SETV(Acc(bp), tmpv); } if (AuxVecField.offset != BadOffset) { for (i = 0; i < NDIM; i++) tmpv[i] = dotvp(AuxVec(bp), frame[i]); SETV(AuxVec(bp), tmpv); } } for (i = 0; i < NDIM; i++) SETV(oldframe[i], frame[i]); }