/* Advance velocity by half a timestep */
static inline void bodyAdvanceVel(Body* p, const mwvector a, const real dtHalf)
{
    mwvector dv;

    dv = mw_mulvs(a, dtHalf);   /* get velocity increment */
    mw_incaddv(Vel(p), dv);     /* advance v by 1/2 step */
}
/* Advance body position by 1 timestep */
static inline void bodyAdvancePos(Body* p, const real dt)
{
    mwvector dr;

    dr = mw_mulvs(Vel(p), dt);  /* get position increment */
    mw_incaddv(Pos(p), dr);     /* advance r by 1 step */
}
static inline mwvector isotropicBodyPosition(dsfmt_t* dsfmtState, mwvector rshift,  real r)
{
    mwvector pos;

    pos = pickShell(dsfmtState,  r);  /* pick scaled position */
    mw_incaddv(pos, rshift);               /* move the position */

    return pos;
}
Example #4
0
mwvector nbExtAcceleration(const Potential* pot, mwvector pos)
{
    mwvector acc, acctmp;
    const real r = mw_absv(pos);
    /*Calculate the Disk Accelerations*/
    switch (pot->disk.type)
    {
        case ExponentialDisk:
            acc = exponentialDiskAccel(&pot->disk, pos, r);
            break;
        case MiyamotoNagaiDisk:
            acc = miyamotoNagaiDiskAccel(&pot->disk, pos, r);
            break;
        case InvalidDisk:
        default:
            mw_fail("Invalid disk type in external acceleration\n");
    }
    /*Calculate the Halo Accelerations*/
    switch (pot->halo.type)
    {
        case LogarithmicHalo:
            acctmp = logHaloAccel(&pot->halo, pos, r);
            break;
        case NFWHalo:
            acctmp = nfwHaloAccel(&pot->halo, pos, r);
            break;
        case TriaxialHalo:
            acctmp = triaxialHaloAccel(&pot->halo, pos, r);
            break;
        case CausticHalo:
            acctmp = causticHaloAccel(&pot->halo, pos, r);
            break;
        case InvalidHalo:
        default:
            mw_fail("Invalid halo type in external acceleration\n");
    }

    mw_incaddv(acc, acctmp);
    /*Calculate the Bulge Accelerations*/
    acctmp = sphericalAccel(&pot->sphere[0], pos, r);
    mw_incaddv(acc, acctmp);

    return acc;
}
static inline void nbMapForceBody(const NBodyCtx* ctx, NBodyState* st)
{
    int i;
    const int nbody = st->nbody;  /* Prevent reload on each loop */
    mwvector a, externAcc;
    const Body* b;

  #ifdef _OPENMP
    #pragma omp parallel for private(i, b, a, externAcc) schedule(dynamic)
  #endif
    for (i = 0; i < nbody; ++i)      /* get force on each body */
    {
        /* Repeat the base hackGrav part in each case or else GCC's
         * -funswitch-loops doesn't happen. Without that this constant
         * gets checked on every body on every step which is dumb.  */
        switch (ctx->potentialType)
        {
            case EXTERNAL_POTENTIAL_DEFAULT:
                /* Include the external potential */
                b = &st->bodytab[i];
                a = nbGravity(ctx, st, b);

                externAcc = nbExtAcceleration(&ctx->pot, Pos(b));
                mw_incaddv(a, externAcc);
                st->acctab[i] = a;
                break;

            case EXTERNAL_POTENTIAL_NONE:
                st->acctab[i] = nbGravity(ctx, st, &st->bodytab[i]);
                break;

            case EXTERNAL_POTENTIAL_CUSTOM_LUA:
                a = nbGravity(ctx, st, &st->bodytab[i]);
                nbEvalPotentialClosure(st, Pos(&st->bodytab[i]), &externAcc);
                mw_incaddv(a, externAcc)
                st->acctab[i] = a;
                break;

            default:
                mw_fail("Bad external potential type: %d\n", ctx->potentialType);
        }
    }
}
static inline mwvector isotropicBodyVelocity(dsfmt_t* dsfmtState,real r, mwvector vshift, real vsc,  real scaleRad1, real scaleRad2,
					     real Mass1, real Mass2)
{
    mwvector vel;
    real v;

    v = isotropicRandomV(r,scaleRad1,scaleRad2,Mass1,Mass2);
    vel = pickShell(dsfmtState, vsc * v);   /* pick scaled velocity */
    mw_incaddv(vel, vshift);                /* move the velocity */

    return vel;
}
static inline void nbMapForceBody_Exact(const NBodyCtx* ctx, NBodyState* st)
{
    int i;
    const int nbody = st->nbody;  /* Prevent reload on each loop */
    mwvector a, externAcc;
    const Body* b;

  #ifdef _OPENMP
    #pragma omp parallel for private(i, b, a, externAcc) schedule(dynamic)
  #endif
    for (i = 0; i < nbody; ++i)      /* get force on each body */
    {
        switch (ctx->potentialType)
        {
            case EXTERNAL_POTENTIAL_DEFAULT:
                b = &st->bodytab[i];
                a = nbGravity_Exact(ctx, st, b);
                mw_incaddv(a, nbExtAcceleration(&ctx->pot, Pos(b)));
                st->acctab[i] = a;
                break;

            case EXTERNAL_POTENTIAL_NONE:
                st->acctab[i] = nbGravity_Exact(ctx, st, &st->bodytab[i]);
                break;

            case EXTERNAL_POTENTIAL_CUSTOM_LUA:
                a = nbGravity_Exact(ctx, st, &st->bodytab[i]);
                nbEvalPotentialClosure(st, Pos(&st->bodytab[i]), &externAcc);
                mw_incaddv(a, externAcc);
                st->acctab[i] = a;
                break;

            default:
                mw_fail("Bad external potential type: %d\n", ctx->potentialType);
        }
    }
}
mwvector nbodyCenterOfMass(const NBodyState* st)
{
    unsigned int i;
    const Body* b;
    mwvector cm = ZERO_VECTOR;
    mwvector tmp;
    real mass = 0.0;

    for (i = 0; i < st->nbody; ++i)
    {
        b = &st->bodytab[i];

        tmp = mw_mulvs(Pos(b), Mass(b));
        mass += Mass(b);
        mw_incaddv(cm, tmp);
    }

    mw_incdivs(cm, mass);

    return cm;
}
static mwvector nbGravity_Exact(const NBodyCtx* ctx, NBodyState* st, const Body* p)
{
    int i;
    const int nbody = st->nbody;
    mwvector a = ZERO_VECTOR;
    const real eps2 = ctx->eps2;

    for (i = 0; i < nbody; ++i)
    {
        const Body* b = &st->bodytab[i];

        mwvector dr = mw_subv(Pos(b), Pos(p));
        real drSq = mw_sqrv(dr) + eps2;

        real drab = mw_sqrt(drSq);
        real phii = Mass(b) / drab;
        real mor3 = phii / drSq;

        mw_incaddv(a, mw_mulvs(dr, mor3));
    }

    return a;
}