/* 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; }
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; }