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);
        }
    }
}
Example #2
0
/* Try to run a potential function and see if it fails. Return TRUE on failure. */
static int nbVerifyPotentialFunction(const NBodyFlags* nbf, const NBodyCtx* ctx, NBodyState* st)
{
    mwvector acc;
    mwvector pos = mw_vec(1.0, 1.0, 0.0);

    if (ctx->potentialType != EXTERNAL_POTENTIAL_CUSTOM_LUA)
    {
        return FALSE;
    }

    /* Try to use it once to make sure it is OK */
    if (nbOpenPotentialEvalStatePerThread(st, nbf))
    {
        return TRUE;
    }

    nbEvalPotentialClosure(st, pos, &acc);
    return st->potentialEvalError;
}
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);
        }
    }
}