Example #1
0
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
    }
  }
}
Example #2
0
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]);
}