/*! \brief A ray-rod intersection test. A rod is a cylinder which is not infinite, but of limited length. The cylinder is defined using a single base vertex at the center of the bottom circular face and an axial vector pointing from the base vertex to the top vertex. This test ignores the back face of the rod. It is used to detect when a ray will enter a rod. \param T The origin of the ray relative to the base vertex. \param D The direction/velocity of the ray. \param A The axial vector of the rod. \param r Radius of the rod. \return The time until the intersection, or HUGE_VAL if no intersection. */ inline double ray_rod(math::Vector T, math::Vector D, const math::Vector& A, const double r) { double t = ray_cylinder(T, D, A / A.nrm(), r); double Tproj = ((T + t * D) | A); if ((Tproj < 0) || (Tproj > A.nrm2())) return HUGE_VAL; return t; }
/*! \brief A ray-inverse_rod intersection test. A rod is a cylinder which is not infinite, but of limited length. An inverse rod is used to test when a ray will exit a rod. The cylinder is defined using a single base vertex at the center of the bottom circular face and an axial vector pointing from the base vertex to the top vertex. This test ignores the back face of the rod. \param T The origin of the ray relative to the base vertex. \param D The direction/velocity of the ray. \param A The axial vector of the inverse rod. \param r Radius of the inverse rod. \tparam always_intersect If true, this will ensure that glancing ray's never escape the enclosing sphere by returning the time when the ray is nearest the sphere if the ray does not intersect the sphere. \return The time until the intersection, or HUGE_VAL if no intersection. */ inline double ray_inv_rod(math::Vector T, math::Vector D, const math::Vector& A, const double r) { double t = ray_inv_cylinder(T, D, A / A.nrm(), r); M_throw() << "Confirm that this function is correct"; double Tproj = ((T + t * D) | A); if ((Tproj < 0) || (Tproj > A.nrm2())) return HUGE_VAL; return t; }
OffcentreSpheresOverlapFunction(const math::Vector& rij, const math::Vector& vij, const math::Vector& omegai, const math::Vector& omegaj, const math::Vector& nu1, const math::Vector& nu2, const double diameter1, const double diameter2, const double maxdist, const double t, const double invgamma, const double t_min, const double t_max): w1(omegai), w2(omegaj), u1(nu1), u2(nu2), r12(rij), v12(vij), _diameter1(diameter1), _diameter2(diameter2), _invgamma(invgamma), _t(t), _t_min(t_min), _t_max(t_max) { double Gmax = std::max(1 + t * invgamma, 1 + (t + t_max) * invgamma); const double sigmaij = 0.5 * (_diameter1 + _diameter2); const double sigmaij2 = sigmaij * sigmaij; double magw1 = w1.nrm(), magw2 = w2.nrm(); double rijmax = Gmax * std::max(maxdist, rij.nrm()); #ifdef MAGNET_DEBUG if (rij.nrm() > 1.0001 * maxdist) std::cout << "WARNING!: Particle separation is larger than the maximum specified. " <<rij.nrm() << ">" << maxdist << "\n"; #endif double magu1 = u1.nrm(), magu2 = u2.nrm(); double vijmax = v12.nrm() + Gmax * (magu1 * magw1 + magu2 * magw2) + std::abs(invgamma) * (magu1 + magu2); double aijmax = Gmax * (magu1 * magw1 * magw1 + magu2 * magw2 * magw2) + 2 * std::abs(invgamma) * (magu1 * magw1 + magu2 * magw2); double dotaijmax = Gmax * (magu1 * magw1 * magw1 * magw1 + magu2 * magw2 * magw2 * magw2) + 3 * std::abs(invgamma) * (magu1 * magw1 * magw1 + magu2 * magw2 * magw2); _f1max = 2 * rijmax * vijmax + 2 * Gmax * std::abs(invgamma) * sigmaij2; _f2max = 2 * vijmax * vijmax + 2 * rijmax * aijmax + 2 * invgamma * invgamma * sigmaij2; _f3max = 6 * vijmax * aijmax + 2 * rijmax * dotaijmax; }