예제 #1
0
파일: grav.c 프로젝트: amiralish/csolve-bak
local bool subdivp(nodeptr n)
{
  cellptr SAFE q = TC(n);
    SUBV(dr, PosC(q), pos0);			/* compute displacement     */
    DOTVP(drsq, dr, dr);			/* and find dist squared    */
    qmem = q;					/* remember we know them    */
    return (drsq < Rcrit2(q));			/* apply standard rule      */
}
예제 #2
0
char* showCell(const NBodyCell* c)
{
    char* buf;
    char* posBuf;

    if (!c)
        return NULL;


    posBuf = showVector(Pos(c));

    if (0 > asprintf(&buf,
                     "NBodyCell = {\n"
                     "  cellnode = {\n"
                     "    pos  = %s\n"
                     "    next = %p\n"
                     "    mass = %f\n"
                     "    type = %d\n"
                     "  }\n"
                     "  rcrit2   = %f\n"
                     "  more     = %p\n"
                     "  stuff    = {\n"
                     "    .quad = {\n"
                     "      .xx = %f, .xy = %f, .xz = %f,\n"
                     "      .yy = %f, .yz = %f,\n"
                     "      .zz = %f\n"
                     "    },\n"
                     "\n"
                     "    .subp = {\n"
                     "      %p, %p, %p, %p,\n"
                     "      %p, %p, %p, %p\n"
                     "    }\n"
                     "  }\n"
                     "}\n",
                     posBuf,
                     (void*) Next(c),
                     Mass(c),
                     Type(c),

                     Rcrit2(c),
                     (void*) More(c),

                     Quad(c).xx, Quad(c).xy, Quad(c).xz,
                     Quad(c).yy, Quad(c).yz,
                     Quad(c).zz,

                     (void*) Subp(c)[0], (void*) Subp(c)[1], (void*) Subp(c)[2], (void*) Subp(c)[3],
                     (void*) Subp(c)[5], (void*) Subp(c)[5], (void*) Subp(c)[6], (void*) Subp(c)[7]
            ))
    {
        mw_fail("asprintf() failed\n");
    }

    free(posBuf);

    return buf;
}
예제 #3
0
local bool accept(nodeptr c, real psize, vector pmid)
{
    real dmax, dsq, dk;
    int k;
 
    dmax = psize;                               /* init maximum distance    */
    dsq = 0.0;                                  /* and squared min distance */
    for (k = 0; k < NDIM; k++) {                /* loop over space dims     */
        dk = Pos(c)[k] - pmid[k];               /* form distance to midpnt  */
        if (dk < 0)                             /* and get absolute value   */
            dk = - dk;
        if (dk > dmax)                          /* keep track of max value  */
            dmax = dk;
        dk -= ((real) 0.5) * psize;             /* allow for size of cell   */
        if (dk > 0)
            dsq += dk * dk;                     /* sum min dist to cell ^2  */
    }
    return (dsq > Rcrit2(c) &&                  /* test angular criterion   */
              dmax > ((real) 1.5) * psize);     /* and adjacency criterion  */
}
예제 #4
0
local bool accept(nodeptr c, real psize, vector pmid)
{
  real dmax, dsq, dk;
  int k;
 
  dmax = psize;                                 // init maximum distance
  dsq = 0.0;                                    // and squared min distance
  for (k = 0; k < NDIM; k++) {                  // loop over space dims
    dk = Pos(c)[k] - pmid[k];                   // form distance to midpnt
    if (dk < 0)                                 // and get absolute value
      dk = - dk;
    if (dk > dmax)                              // keep track of max value
      dmax = dk;
    dk -= ((real) 0.5) * psize;                 // allow for size of cell
    if (dk > 0)
      dsq += dk * dk;                           // sum (min dist to cell)^2
  }
  return (dsq > Rcrit2(c) &&                    // test angular criterion
	  dmax > ((real) 1.5) * psize);         // and adjacency criterion
}
예제 #5
0
/*
 * nbodyGravity: Walk the tree starting at the root to do force
 * calculations.
 *
 *
 * Random notes:
 *   - Not inlined without inline from multiple calls in
 *     mapForceBody(). Measurably better with the inline, but only
 *     slightly.
 */
static inline mwvector nbGravity(const NBodyCtx* ctx, NBodyState* st, const Body* p)
{
    mwbool skipSelf = FALSE;

    mwvector pos0 = Pos(p);
    mwvector acc0 = ZERO_VECTOR;

    const NBodyNode* q = (const NBodyNode*) st->tree.root; /* Start at the root */

    while (q != NULL)               /* while not at end of scan */
    {
        mwvector dr = mw_subv(Pos(q), pos0);   /* Then compute distance */
        real drSq = mw_sqrv(dr);               /* and distance squared */

        if (isBody(q) || (drSq >= Rcrit2(q)))      /* If is a body or far enough away to approximate */
        {
            if (mw_likely((const Body*) q != p))   /* self-interaction? */
            {
                real drab, phii, mor3;

                /* Compute gravity */

                drSq += ctx->eps2;   /* use standard softening */
                drab = mw_sqrt(drSq);
                phii = Mass(q) / drab;
                mor3 = phii / drSq;

                acc0.x += mor3 * dr.x;
                acc0.y += mor3 * dr.y;
                acc0.z += mor3 * dr.z;

                if (ctx->useQuad && isCell(q))          /* if cell, add quad term */
                {
                    real dr5inv, drQdr, phiQ;
                    mwvector Qdr;

                    /* form Q * dr */
                    Qdr.x = Quad(q).xx * dr.x + Quad(q).xy * dr.y + Quad(q).xz * dr.z;
                    Qdr.y = Quad(q).xy * dr.x + Quad(q).yy * dr.y + Quad(q).yz * dr.z;
                    Qdr.z = Quad(q).xz * dr.x + Quad(q).yz * dr.y + Quad(q).zz * dr.z;


                    /* form dr * Q * dr */
                    drQdr = Qdr.x * dr.x + Qdr.y * dr.y + Qdr.z * dr.z;

                    dr5inv = 1.0 / (sqr(drSq) * drab);  /* form dr^-5 */

                    /* get quad. part of phi */
                    phiQ = 2.5 * (dr5inv * drQdr) / drSq;

                    acc0.x += phiQ * dr.x;
                    acc0.y += phiQ * dr.y;
                    acc0.z += phiQ * dr.z;

                    /* acceleration */
                    acc0.x -= dr5inv * Qdr.x;
                    acc0.y -= dr5inv * Qdr.y;
                    acc0.z -= dr5inv * Qdr.z;
                }
            }
            else
            {
                skipSelf = TRUE;   /* Encountered self */
            }

            q = Next(q);  /* Follow next link */
        }
        else
        {
             q = More(q); /* Follow to the next level if need to go deeper */
        }
    }

    if (!skipSelf)
    {
        /* If a body does not encounter itself in its traversal of the
         * tree, it is "tree incest" */

        nbReportTreeIncest(ctx, st);
    }

    return acc0;
}