84 return (v1 * w1 + v2 * w2) / (w1 + w2);
90 return vRelSqr * limit < vEscSqr;
138 : bounceLimit(bounceLimit)
139 , rotationLimit(rotationLimit) {}
159 const Float m_merger = m[i] + m[j];
189 L_merger = m[i] *
cross(r[i] - r_merger, v[i] - v_merger) +
190 m[j] *
cross(r[j] - r_merger, v[j] - v_merger) +
193 omega_merger = I_merger.
inverse() * L_merger;
200 E_merger = convert<Tensor>(eigen.
vectors);
210 L_merger = m[i] *
cross(r[i] - r_merger, v[i] - v_merger) +
211 m[j] *
cross(r[j] - r_merger, v[j] - v_merger) +
217 if (!this->acceptMerge(i, j, h_merger, omega_merger)) {
228 omega[i] = omega_merger;
257 if (omegaSqr * rotationLimit > omegaCritSqr) {
304 v[i] = this->reflect(
v[i], v_com, -dr);
305 v[j] = this->reflect(
v[j], v_com, dr);
318 const Vector v_rel =
v - v_com;
320 const Vector v_t = v_rel - proj * dir;
321 const Vector v_n = proj * dir;
330 template <
typename TPrimary,
typename TFallback>
339 , fallback(settings) {}
342 primary.initialize(storage);
343 fallback.initialize(storage);
349 return fallback.collide(i, j, toRemove);
398 : handler(0._f, 0._f) {}
409 handler.
collide(i, j, toRemove);
419 template <
typename TFollowupHandler>
422 TFollowupHandler handler;
429 : handler(settings) {}
436 handler.initialize(storage);
451 const Float x1 = (r[i][
H] + r[j][
H] - dist) / (1._f + m[i] / m[j]);
452 const Float x2 = m[i] / m[j] * x1;
457 sqr(r[i][
H] + r[j][
H]));
463 handler.collide(i, j, toRemove);
480 : handler(settings) {
496 const Vector dr = r[i] - r[j];
497 const Vector dv = v[i] - v[j];
498 return dot(dr, dv) < 0._f;
502 handler.
collide(i, j, toRemove);
523 : handler(settings) {
538 const Float m_merger =
m[i] +
m[j];
550 const Vector L_merger =
m[i] *
cross(
r[i] - r_merger,
v[i] - v_merger) +
551 m[j] *
cross(
r[j] - r_merger,
v[j] - v_merger) +
565 handler.
collide(i, j, toRemove);
INLINE bool almostEqual(const AffineMatrix &m1, const AffineMatrix &m2, const Float eps=EPS)
INLINE bool isReal(const AntisymmetricTensor &t)
#define SPH_ASSERT(x,...)
#define NOT_IMPLEMENTED
Helper macro marking missing implementation.
INLINE bool areParticlesBound(const Float m_sum, const Float h_sum, const Vector &dv, const Float limit)
Tuple< T, T > minMax(const T &t1, const T &t2)
Helper function sorting two values.
INLINE T weightedAverage(const T &v1, const Float w1, const T &v2, const Float w2)
@ FRAGMENTATION
Target was disrupted, creating largest remnant and fragments.
@ BOUNCE
Bounce/scatter collision, no merging and no fragmentation.
@ MERGER
Particles merged together.
@ NONE
No collision took place.
@ EVAPORATION
No asteroids survived the collision.
Container storing sorted unique values.
uint32_t Size
Integral type used to index arrays (by default).
double Float
Precision used withing the code. Use Float instead of float or double where precision is important.
constexpr INLINE T sqr(const T &f) noexcept
Return a squared value.
constexpr INLINE Float pow< 3 >(const Float v)
INLINE Float root< 3 >(const Float f)
#define INLINE
Macros for conditional compilation based on selected compiler.
#define NAMESPACE_SPH_END
@ LOCAL_FRAME
Local coordinates of a particle; moment of inertia is typically expressed in these coordinates.
@ MOMENT_OF_INERTIA
Moment of inertia of particles, analogy of particle masses for rotation.
@ POSITION
Positions (velocities, accelerations) of particles, always a vector quantity,.
@ MASS
Paricles masses, always a scalar quantity.
StaticArray< T0 &, sizeof...(TArgs)+1 > tie(T0 &t0, TArgs &... rest)
Creates a static array from a list of l-value references.
Container for storing particle quantities and materials.
Eigen eigenDecomposition(const SymmetricTensor &t)
Computes eigenvectors and corresponding eigenvalues of symmetric matrix.
INLINE SymmetricTensor transform(const SymmetricTensor &t, const AffineMatrix &transform)
INLINE Tuple< TArgs &... > tieToTuple(TArgs &... args)
Creates a tuple of l-value references. Use IGNORE placeholder to omit one or more parameters.
INLINE Tuple< Vector, Float > getNormalizedWithLength(const Vector &v)
Returns normalized vector and length of the input vector as tuple.
INLINE Float getSqrLength(const Vector &v)
INLINE BasicVector< float > cross(const BasicVector< float > &v1, const BasicVector< float > &v2)
Cross product between two vectors.
INLINE float dot(const BasicVector< float > &v1, const BasicVector< float > &v2)
Make sure the vector is trivially constructible and destructible, needed for fast initialization of a...
INLINE Vector getNormalized(const Vector &v)
Object providing safe access to continuous memory of data.
Handler for bounce on collision.
ElasticBounceHandler(const RunSettings &settings)
virtual CollisionResult collide(const Size i, const Size j, FlatSet< Size > &UNUSED(toRemove)) override
virtual void initialize(Storage &storage) override
struct ElasticBounceHandler::@3 restitution
Coefficients of restitution.
ElasticBounceHandler(const Float n, const Float t)
Composite handler, choosing another collision handler if the primary handler rejects the collision by...
FallbackHandler(const RunSettings &settings)
virtual void initialize(Storage &storage) override
virtual CollisionResult collide(const Size i, const Size j, FlatSet< Size > &toRemove) override
Computes the outcome of collision between i-th and j-th particle.
virtual CollisionResult collide(const Size i, const Size j, FlatSet< Size > &UNUSED(toRemove)) override
Abstraction of collision outcome.
virtual void initialize(Storage &storage)=0
virtual CollisionResult collide(const Size i, const Size j, FlatSet< Size > &toRemove)=0
Computes the outcome of collision between i-th and j-th particle.
Handles overlaps of particles.
virtual bool overlaps(const Size i, const Size j) const =0
Returns true if two particles overlaps.
virtual void handle(const Size i, const Size j, FlatSet< Size > &toRemove)=0
Handles the overlap of two particles.
virtual void initialize(Storage &storage)=0
Overlap handler performing a bounce of particles.
virtual bool overlaps(const Size i, const Size j) const override
Returns true if two particles overlaps.
virtual void initialize(Storage &storage) override
virtual void handle(const Size i, const Size j, FlatSet< Size > &toRemove) override
Handles the overlap of two particles.
InternalBounceHandler(const RunSettings &settings)
Handler merging overlapping particles if their relative velocity is lower than the escape velocity.
MergeBoundHandler(const RunSettings &settings)
virtual void handle(const Size i, const Size j, FlatSet< Size > &toRemove) override
Handles the overlap of two particles.
virtual bool overlaps(const Size i, const Size j) const override
Returns true if two particles overlaps.
ArrayView< Vector > omega
virtual void initialize(Storage &storage) override
Handler unconditionally merging the overlapping particles.
virtual bool overlaps(const Size UNUSED(i), const Size UNUSED(j)) const override
virtual void initialize(Storage &storage) override
virtual void handle(const Size i, const Size j, FlatSet< Size > &toRemove) override
Handles the overlap of two particles.
Handler merging particles into a single, larger particles.
virtual void initialize(Storage &storage) override
MergingCollisionHandler(const Float bounceLimit, const Float rotationLimit)
MergingCollisionHandler(const RunSettings &settings)
virtual CollisionResult collide(const Size i, const Size j, FlatSet< Size > &toRemove) override
Computes the outcome of collision between i-th and j-th particle.
Helper handler always returning CollisionResult::NONE.
virtual void initialize(Storage &UNUSED(storage)) override
virtual CollisionResult collide(const Size UNUSED(i), const Size UNUSED(j), FlatSet< Size > &UNUSED(toRemove)) override
Handler simply ignoring overlaps.
virtual void initialize(Storage &UNUSED(storage)) override
virtual bool overlaps(const Size UNUSED(i), const Size UNUSED(j)) const override
virtual void handle(const Size UNUSED(i), const Size UNUSED(j), FlatSet< Size > &UNUSED(toRemove)) override
Handler displacing the overlapping particles so that they just touch.
virtual void initialize(Storage &storage) override
virtual void handle(const Size i, const Size j, FlatSet< Size > &toRemove) override
Handles the overlap of two particles.
virtual bool overlaps(const Size UNUSED(i), const Size UNUSED(j)) const override
RepelHandler(const RunSettings &settings)
TValue get(const TEnum idx, std::enable_if_t<!std::is_enum< std::decay_t< TValue >>::value, int >=0) const
Returns a value of given type from the settings.
Container storing all quantities used within the simulations.
StaticArray< Array< TValue > &, 3 > getAll(const QuantityId key)
Retrieves quantity buffers from the storage, given its key and value type.
bool has(const QuantityId key) const
Checks if the storage contains quantity with given key.
Array< TValue > & getValue(const QuantityId key)
Retrieves a quantity values from the storage, given its key and value type.
Symmetric tensor of 2nd order.
INLINE SymmetricTensor inverse() const
Generic 2nd-order tensor with 9 independent components.
INLINE Vector row(const Size idx) const
Heterogeneous container capable of storing a fixed number of values.
Generic storage and input/output routines of settings.
@ POINT_PARTICLES
Point-like particles with zero radius.
@ COLLISION_BOUNCE_MERGE_LIMIT
@ COLLISION_RESTITUTION_TANGENT
@ COLLISION_ROTATION_MERGE_LIMIT
@ GRAVITY_KERNEL
Gravity smoothing kernel.
@ COLLISION_RESTITUTION_NORMAL
constexpr Float gravity
Gravitational constant (CODATA 2014)
INLINE SymmetricTensor sphereInertia(const Float m, const Float r)
Computes the inertia tensor of a homogeneous sphere.
INLINE SymmetricTensor parallelAxisTheorem(const SymmetricTensor &I, const Float m, const Vector &a)
Computes the inertia tensor with respect to given point.
AffineMatrix vectors
Matrix of eigenvectors, stored as rows.
Vector values
Eigenvalues.
Base class for all polymorphic objects.