예제 #1
0
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);
  }
}
예제 #2
0
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);
}
예제 #3
0
local void sumcell(cellptr start, cellptr finish, vector pos0,
		   real *phi0, vector acc0)
{
  real eps2, eps2thrd, dr2, dr2i, dr1i, mdr1i, mdr3i, qdr2, dr5i, phi_q;
  vector dr, qdr;
 
  eps2 = eps * eps;				// premultiply softening
  eps2thrd = eps2 / 3.0;			// predivide for soft corr
  for (cellptr p = start; p < finish; p++) {	// loop over node list
    DOTPSUBV(dr2, dr, Pos(p), pos0);		// do mono part of force
    dr2i = ((real) 1.0) / (dr2 + eps2);		// perform only division
    dr1i = rsqrt(dr2i);				// set inverse soft distance
    mdr1i = Mass(p) * dr1i;			// form mono potential
    mdr3i = mdr1i * dr2i;			// get scale factor for dr
    DOTPMULMV(qdr2, qdr, Quad(p), dr);		// do quad part of force
#if defined(SOFTCORR)
    qdr2 -= eps2thrd * Trace(p);		// apply Keigo's correction
#endif
    dr5i = ((real) 3.0) * dr2i * dr2i * dr1i;	// factor 3 saves a multiply
    phi_q = ((real) 0.5) * dr5i * qdr2;		// form quad potential
    mdr3i += ((real) 5.0) * phi_q * dr2i;	// adjust radial term
    *phi0 -= mdr1i + phi_q;			// sum mono and quad pot
    ADDMULVS2(acc0, dr, mdr3i, qdr, - dr5i);	// sum mono and quad acc
  }
}
예제 #4
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
  }
}
예제 #5
0
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 */
    }
}
예제 #6
0
local void sumcell(cellptr start, cellptr finish,
                   vector pos0, real *phi0, vector acc0)
{
    cellptr p;
    real eps2, dr2, drab, phi_p, mr3i, drqdr, dr5i, phi_q;
    vector dr, qdr;
 
    eps2 = eps * eps;
    for (p = start; p < finish; p++) {          /* loop over node list      */
        DOTPSUBV(dr2, dr, Pos(p), pos0);        /* do mono part of force    */
        dr2 += eps2;
        drab = rsqrt(dr2);
        phi_p = Mass(p) / drab;
        mr3i = phi_p / dr2;
        DOTPMULMV(drqdr, qdr, Quad(p), dr);     /* do quad part of force    */
        dr5i = ((real) 1.0) / (dr2 * dr2 * drab);
        phi_q = ((real) 0.5) * dr5i * drqdr;
        *phi0 -= phi_p + phi_q;                 /* add mono and quad pot    */
        mr3i += ((real) 5.0) * phi_q / dr2;
        ADDMULVS2(acc0, dr, mr3i, qdr, -dr5i);  /* add mono and quad acc    */
    }
}