inline real get_r2(const vec3 &pos) { #ifndef _CYLINDER_ return pos.norm2(); #else return sqr(pos.x) + sqr(pos.y); #endif }
const std::pair<vec3, real> gacc(const vec3 &pos) { const real ds2 = pos.norm2(); const real ds = std::sqrt(ds2); const real ids = (ds > 0.0) ? 1.0/ds : 0.0; const real ids2 = ids*ids; const real gravity_mass = GM; const real gravity_eps = GM_EPS; assert(gravity_eps > 0.0); const real h = gravity_eps; const real q = ds/h; const real q2 = q*q; const real q3 = q2*q; const real q4 = q2*q2; const real q5 = q3*q2; real pot; real acc; if (q < 1) { acc = -1.0/sqr(h) * (4.0/3*q - 6.0/5*q3 + 0.5f*q4); pot = +1.0/ h * (2.0/3*q2 - 0.3f *q4 + 0.1f*q5 - 7.0/5); } else if (q < 2) { acc = -1.0/sqr(h) * (8.0/3*q - 3.0*q2 + 6.0/5*q3 - 1.0/6*q4 - 1.0/15/q2); pot = +1.0/ h * (4.0/3*q2 - q3 + 0.3*q4 - 1.0/30*q5 - 8.0/5 + 1.0/15/q); } else { acc = -ids2; pot = -ids; } acc *= gravity_mass*ids; pot *= gravity_mass; return std::make_pair(acc * pos, pot); }
const vec3 project(const vec3 &r, const vec3 &v) { return (v - r*((r*v)/r.norm2())); }