コード例 #1
0
ファイル: snapstack.c プロジェクト: jasminegrosso/zeno
void snapstack(bodyptr btab, bodyptr bt1, int nb1, bodyptr bt2, int nb2,
	       string *tags)
{
  vector deltar, deltav;
  bodyptr bp;
  int i;
  
  setvect(deltar, burststring(getparam("deltar"), ", "));
  setvect(deltav, burststring(getparam("deltav"), ", "));
  for (i = 0; i < nb1; i++) {
    bp = NthBody(btab, i);
    memcpy(bp, NthBody(bt1, i), SizeofBody);
    if (set_member(tags, PosTag)) {
      ADDMULVS(Pos(bp), deltar, 0.5);
    }
    if (set_member(tags, VelTag)) {
      ADDMULVS(Vel(bp), deltav, 0.5);
    }
  }
  for (i = 0; i < nb2; i++) {
    bp = NthBody(btab, i + nb1);
    memcpy(bp, NthBody(bt2, i), SizeofBody);
    if (set_member(tags, PosTag)) {
      ADDMULVS(Pos(bp), deltar, -0.5);
    }
    if (set_member(tags, VelTag)) {
      ADDMULVS(Vel(bp), deltav, -0.5);
    }
  }
}
コード例 #2
0
ファイル: treecode.c プロジェクト: petrabarus/nbodyc
void calculateCenterOfMass(cellptr cell)
{
	/* Center of mass position */
	vector cmPos;
	vector tempV;
	nodeptr q;
	int i;
	/* Init the cell's total mass */
	Mass(cell) = 0.0;
	/* Init the cell's center of mass position */
	CLRV(cmPos);
	/* Loop over the subnodes */
	for (i = 0; i < NCHILD; i++) {
		/* Skipping empty child nodes */
		if ((q = Child(cell)[i]) != NULL) {
			/* If node is a cell */
			if (Type(q) == CELL)
				/* Recursively do the same */
				calculateCenterOfMass((cellptr) q);
			/* Accumulate total mass */
			Mass(cell) = Mass(q);
			/* Accumulate center of mass */
			ADDMULVS(cmPos, Pos(q), Mass(q));
		}
	}
	/* Usually, cell has mass */
	if (Mass(cell) > 0.0) {
		/* Find center of mass position */
		DIVVS(cmPos, cmPos, Mass(cell));
	} else { /* If no mass inside */
		SETV(cmPos, Pos(cell));
	}
	SETV(Pos(cell), cmPos);
}
コード例 #3
0
ファイル: testcode.c プロジェクト: jasminegrosso/zeno
local void sumforces(bodyptr btab, int nbody, bodyptr gtab, int ngrav,
		     real eps2)
{
  bodyptr bp, gp;
  double phi0, acc0[NDIM];
  vector pos0, dr;
  real dr2, dr2i, dr1i, mdr1i, mdr3i;

  for (bp = btab; bp < NthBody(btab, nbody); bp = NextBody(bp)) {
    phi0 = 0.0;
    CLRV(acc0);
    SETV(pos0, Pos(bp));
    for (gp = gtab; gp < NthBody(gtab, ngrav); gp = NextBody(gp)) {
      DOTPSUBV(dr2, dr, Pos(gp), pos0);
      dr2i = ((real) 1.0) / (dr2 + eps2);
      dr1i = rsqrt(dr2i);
      mdr1i = Mass(gp) * dr1i;
      mdr3i = mdr1i * dr2i;
      phi0 -= mdr1i;
      ADDMULVS(acc0, dr, mdr3i);
    }
    Phi(bp) = phi0;
    SETV(Acc(bp), acc0);
  }
}
コード例 #4
0
ファイル: treecode.c プロジェクト: jasminegrosso/zeno
local void stepsystem(void) {
  bodyptr p1, p2, p;

  p1 = bodytab + MAX(nstatic, 0);		// set dynamic body range
  p2 = bodytab + nbody + MIN(nstatic, 0);
  for (p = p1; p < p2; p++) {			// loop over body range	
    ADDMULVS(Vel(p), Acc(p), 0.5 * dtime);	// advance v by 1/2 step
    ADDMULVS(Pos(p), Vel(p), dtime);		// advance r by 1 step
  }
  treeforce();
  for (p = p1; p < p2; p++) {			// loop over body range	
    ADDMULVS(Vel(p), Acc(p), 0.5 * dtime);	// advance v by 1/2 step
  }
  nstep++;					// count another time step
  tnow = tnow + dtime;				// finally, advance time
}
コード例 #5
0
ファイル: snapforce.c プロジェクト: jasminegrosso/zeno
local void sum1force(bodyptr btab, int nbody, int i0, real eps2)
{
    bodyptr bp0, bp;
    double phi0, acc0[NDIM];
    vector pos0, dr;
    real dr2, drab, mri, mr3i;
    int j;

    bp0 = NthBody(btab, i0);
    phi0 = 0.0;
    CLRV(acc0);
    SETV(pos0, Pos(bp0));
    for (j = 0; j < nbody; j++)
	if (j != i0) {
	    bp = NthBody(btab, j);
	    DOTPSUBV(dr2, dr, Pos(bp), pos0);
	    dr2 += eps2;
	    drab = rsqrt(dr2);
	    mri = Mass(bp) / drab;
	    phi0 -= mri;
	    mr3i = mri / dr2;
	    ADDMULVS(acc0, dr, mr3i);
	}
    Phi(bp0) = phi0;
    SETV(Acc(bp0), acc0);
}
コード例 #6
0
ファイル: snaptrak.c プロジェクト: jasminegrosso/zeno
void snaptrak(void)
{
  bodyptr bp, gp;
  int nzero;
  
  if (traktab == NULL) {
    ntrak = 0;
    for (bp = bodytab; bp < NthBody(bodytab, nbody); bp = NextBody(bp))
      ntrak = MAX(ntrak, Group(bp));
    eprintf("[%s: allocating %d groups]\n", getprog(), ntrak);
    traktab = (bodyptr) allocate(ntrak * SizeofBody);
  }
  for (gp = traktab; gp < NthBody(traktab, ntrak); gp = NextBody(gp)) {
    Mass(gp) = 0.0;
    CLRV(Pos(gp));
    CLRV(Vel(gp));
    Key(gp) = 0;
  }
  for (bp = bodytab; bp < NthBody(bodytab, nbody); bp = NextBody(bp)) {
    if (Group(bp) > ntrak)
      error("snaptrak: cant expand group array\n");
    if (Group(bp) > 0) {
      gp = NthBody(traktab, Group(bp) - 1);
      Mass(gp) += Mass(bp);
      ADDMULVS(Pos(gp), Pos(bp), Mass(bp));
      ADDMULVS(Vel(gp), Vel(bp), Mass(bp));
      Key(gp)++;
    }
  }
  nzero = 0;
  for (gp = traktab; gp < NthBody(traktab, ntrak); gp = NextBody(gp))
    if (Mass(gp) != 0.0) {
      DIVVS(Pos(gp), Pos(gp), Mass(gp));
      DIVVS(Vel(gp), Vel(gp), Mass(gp));
    } else
      nzero++;
  if (nzero > 0)
    eprintf("[%s: %d groups have zero mass]\n", getprog(), nzero);
}
コード例 #7
0
ファイル: snapcenter.c プロジェクト: jasminegrosso/zeno
void snapcmacc(vector cmacc, bodyptr btab, int nbody, int woff)
{
  double wtot, cmtmp[NDIM];
  bodyptr bp;

  wtot = 0.0;
  CLRV(cmtmp);
  for (bp = btab; bp < NthBody(btab, nbody); bp = NextBody(bp)) {
    wtot = wtot + Weight(bp, woff);
    ADDMULVS(cmtmp, Acc(bp), Weight(bp, woff));
  }
  DIVVS(cmacc, cmtmp, wtot);
}
コード例 #8
0
local void sumnode(cellptr start, cellptr finish,
                   vector pos0, real *phi0, vector acc0)
{
  real eps2, dr2, dr2i, dr1i, mdr1i, mdr3i;
  vector dr;
 
  eps2 = eps * eps;				// premultiply softening
  for (cellptr p = start; p < finish; p++) {	// loop over node list
    DOTPSUBV(dr2, dr, Pos(p), pos0);		// compute sep. vector
						// and square of distance
    dr2i = ((real) 1.0) / (dr2 + eps2);		// perform only division
    dr1i = rsqrt(dr2i);				// set inverse soft distance
    mdr1i = Mass(p) * dr1i;			// form partial potential
    mdr3i = mdr1i * dr2i;			// form scale factor for dr
    *phi0 -= mdr1i;				// sum potential
    ADDMULVS(acc0, dr, mdr3i);			// sum acceleration
  }
}
コード例 #9
0
ファイル: sphgrav.c プロジェクト: jasminegrosso/zeno
local void sumnode(cellptr start, cellptr finish,
                   vector pos0, real *phi0, vector acc0)
{
    cellptr p;
    real eps2, dr2, drab, phi_p, mr3i;
    vector dr;
 
    eps2 = eps * eps;                           /* avoid extra multiplys    */
    for (p = start; p < finish; p++) {          /* loop over node list      */
        DOTPSUBV(dr2, dr, Pos(p), pos0);        /* compute separation       */
                                                /* and distance squared     */
        dr2 += eps2;                            /* add standard softening   */
        drab = rsqrt(dr2);                      /* form scalar "distance"   */
        phi_p = Mass(p) / drab;                 /* get partial potential    */
        *phi0 -= phi_p;                         /* decrement tot potential  */
        mr3i = phi_p / dr2;                     /* form scale factor for dr */
        ADDMULVS(acc0, dr, mr3i);               /* sum partial acceleration */
    }
}
コード例 #10
0
ファイル: treecode.c プロジェクト: jasminegrosso/zeno
//  treeforce: supervise force calculation.
//  _______________________________________
local void treeforce(void) {
  bodyptr p1, p2, p;
  real r, mr3i;

  p1 = bodytab + MAX(nstatic, 0);		// set dynamic body range
  p2 = bodytab + nbody + MIN(nstatic, 0);
  for (p = bodytab; p < bodytab+nbody; p++)	// loop over all bodies
    Update(p) = (testcalc ? p1 <= p && p < p2 : TRUE);
						// flag bodies to update
  maketree(bodytab, nbody);			// construct tree structure
  gravcalc();					// compute current forces
  forcereport();				// print force statistics
#if defined(EXTGRAV)
  for (p = bodytab; p < bodytab+nbody; p++)	// loop over all bodies
    if (Update(p) && gravgsp != NULL) {		// update in extern field?
      r = absv(Pos(p));				// get distance from origin
      mr3i = - mass_gsp(gravgsp, r) / (r*r*r);
      ADDMULVS(Acc(p), Pos(p), mr3i);		// add extern acc and phi
      Phi(p) += phi_gsp(gravgsp, r);
    }
#endif
}
コード例 #11
0
ファイル: testcode.c プロジェクト: jasminegrosso/zeno
int main(int argc, string argv[])
{
  stream istr, ostr, gstr;
  real tnow, tgrav, eps2, tstop, dtime, tout, Mhqm, ahqm, bhqm, tol;
  real decrit, epot0, demin, demax, derms, de2avg, enow, denow;
  int nbody, ngrav;
  bodyptr btab = NULL, gtab = NULL, bp;
  string bdtags[MaxBodyFields], grtags[MaxBodyFields], *optags;
  gsprof *gravgsp = NULL;
  bool decrit_inc = FALSE;

  initparam(argv, defv);
  new_field(&EinitPBF, RealType, EinitTag);	// define initial energy field
  layout_body(bodytags, Precision, NDIM);	// layout necessary fields
  istr = stropen(getparam("in"), "r");
  get_history(istr);
  if (! get_snap(istr, &btab, &nbody, &tnow, bdtags, TRUE))
    error("%s: can't read input snapshot\n", getprog());
  if (! (set_member(bdtags, PosTag) && set_member(bdtags, VelTag)))
    error("%s: required data missing from input snapshot\n", getprog());
#if defined(NBDGRAV)
  gstr = stropen(getparam("grav"), "r");
  get_history(gstr);
  if (! get_snap(gstr, &gtab, &ngrav, &tgrav, grtags, FALSE))
    error("%s: can't read gravity snapshot\n", getprog());
  if (! (set_member(grtags, MassTag) && set_member(grtags, PosTag)))
    error("%s: required data missing from gravity snapshot\n", getprog());
  eps2 = rsqr(getdparam("eps"));
#elif defined(GSPGRAV)
  gstr = stropen(getparam("grav"), "r");
  get_history(gstr);
  gravgsp = get_gsprof(gstr);			// read GSP for grav. field
#elif defined(HQMGRAV)
  Mhqm = getdparam("M");
  ahqm = getdparam("a");
  bhqm = getdparam("b");
  tol = getdparam("tol");
#endif
  ostr = stropen(getparam("out"), "w");
  put_history(ostr);
  tstop = getdparam("tstop");
  dtime = getdparam("dtime");
  decrit = getdparam("decrit");
  optags = burststring(getparam("outputs"), ",");
#if defined(NBDGRAV)
  sumforces(btab, nbody, gtab, ngrav, eps2);	// prime the pump...
#elif defined(GSPGRAV)
  gspforces(btab, nbody, gravgsp);
#elif defined(HQMGRAV)
  hqmforces(btab, nbody, Mhqm, ahqm, bhqm, tol);
#endif

  epot0 = 0.0;					// use as energy scale
  for (bp = btab; bp < NthBody(btab, nbody); bp = NextBody(bp)) {
    epot0 += Phi(bp) / nbody;			// compute avg. potential
    Einit(bp) = Phi(bp) + dotvp(Vel(bp), Vel(bp)) / 2;
  }
  eprintf("[%s: initial average potential = %g]\n", getprog(), epot0);
  put_snap(ostr, &btab, &nbody, &tnow, optags);
  fflush(NULL);
  tout = tnow + getdparam("dtout");
  demin = demax = derms = 0.0;			// track maximum errors
  while (tnow < tstop) {			// enter main loop
    for (bp = btab; bp < NthBody(btab, nbody); bp = NextBody(bp)) {
      ADDMULVS(Vel(bp), Acc(bp), 0.5 * dtime);	// step velocities by dt/2
      ADDMULVS(Pos(bp), Vel(bp), dtime);	// step positions by dt
    }
    tnow = tnow + dtime;			// step time to new value
#if defined(NBDGRAV)
    if (! getbparam("frozen"))
      if (! get_snap(gstr, &gtab, &ngrav, &tgrav, grtags, TRUE))
	error("%s: can't read gravity snapshot\n", getprog());
    sumforces(btab, nbody, gtab, ngrav, eps2);	// get new accelerations
#elif defined(GSPGRAV)
    gspforces(btab, nbody, gravgsp);
#elif defined(HQMGRAV)
    hqmforces(btab, nbody, Mhqm, ahqm, bhqm, tol);
#endif
    de2avg = 0.0;
    for (bp = btab; bp < NthBody(btab, nbody); bp = NextBody(bp)) {
      ADDMULVS(Vel(bp), Acc(bp), 0.5 * dtime);	// step velocities by dt/2
      enow = 0.5 * dotvp(Vel(bp), Vel(bp)) + Phi(bp);
      denow = (enow - Einit(bp)) / ABS(epot0);	// compute rel. energy change
      demin = MIN(demin, denow);
      demax = MAX(demax, denow);
      de2avg += rsqr(denow) / nbody;
    }
    derms = MAX(derms, rsqrt(de2avg));
    if (demin < -decrit || demax > decrit) {
      eprintf("[%s: warning: energy error exceeds %.4e at time = %-12.8f\n"
	      " min,max,rms = %.6g,%.6g,%.6g  threshold now %.4e]\n",
	      getprog(), decrit, tnow,
	      demin, demax, rsqrt(de2avg), decrit * rsqrt(2.0));
      decrit = decrit * rsqrt(2.0);
      decrit_inc = TRUE;
    }
    if (tout <= tnow) {
      put_snap(ostr, &btab, &nbody, &tnow, optags);
      tout = tout + getdparam("dtout");
    }
    fflush(NULL);
  }
  eprintf(decrit_inc ?
	  "[%s: WARNING: energy error: min,max,rms = %.6g,%.6g,%.6g]\n" :
	  "[%s: energy error: min,max,rms = %.6g,%.6g,%.6g]\n",
	  getprog(), demin, demax, derms);
  return (0);
}