void walksub(nodeptr n, real dsq, long ProcessId) { nodeptr* nn; leafptr l; bodyptr p; long i; if (subdivp(n, dsq, ProcessId)) { if (Type(n) == CELL) { for (nn = Subp(n); nn < Subp(n) + NSUB; nn++) { if (*nn != NULL) { walksub(*nn, dsq / 4.0, ProcessId); } } } else { l = (leafptr) n; for (i = 0; i < l->num_bodies; i++) { p = Bodyp(l)[i]; if (p != Local[ProcessId].pskip) { gravsub(p, ProcessId); } else { Local[ProcessId].skipself = TRUE; } } } } else { gravsub(n, ProcessId); } }
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 walkgrav(nodeptr *aptr, nodeptr *nptr, cellptr cptr, cellptr bptr, nodeptr p, real psize, vector pmid) { nodeptr *np, *ap, q; int actsafe; if (Update(p)) { /* are new forces needed? */ np = nptr; /* start new active list */ actsafe = actlen - NSUB; /* leave room for NSUB more */ for (ap = aptr; ap < nptr; ap++) /* loop over active nodes */ if (Cell(*ap)) { /* is this node a cell? */ if (accept(*ap, psize, pmid)) { /* does it pass the test? */ Mass(cptr) = Mass(*ap); /* copy to interaction list */ SETV(Pos(cptr), Pos(*ap)); SETM(Quad(cptr), Quad(*ap)); cptr++; /* and bump cell array ptr */ } else { /* else it fails the test */ if (np - active >= actsafe) /* check list has room */ error("walkgrav: active list overflow\n"); for (q = More(*ap); q != Next(*ap); q = Next(q)) /* loop over all subcells */ *np++= q; /* put on new active list */ } } else /* else this node is a body */ if (*ap != p) { /* if not self-interaction */ --bptr; /* bump body array ptr */ Mass(bptr) = Mass(*ap); /* and copy data to array */ SETV(Pos(bptr), Pos(*ap)); } actmax = MAX(actmax, np - active); /* keep track of max active */ if (np != nptr) /* if new actives listed */ walksub(nptr, np, cptr, bptr, p, psize, pmid); /* then visit next level */ else { /* else no actives left, so */ if (! Body(p)) /* must have found a body */ error("walkgrav: recursion terminated with cell\n"); gravsum((bodyptr) p, cptr, bptr); /* sum force on the body */ } } }
void hackwalk(long ProcessId) { walksub(Global->G_root, Global->rsize * Global->rsize, ProcessId); }