예제 #1
0
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);
   }
}
예제 #2
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
    }
  }
}
예제 #3
0
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    */
	}
    }
}
예제 #4
0
void hackwalk(long ProcessId)
{
    walksub(Global->G_root, Global->rsize * Global->rsize, ProcessId);
}