SPH
Collision.h
Go to the documentation of this file.
1 #pragma once
2 
7 
9 #include "physics/Functions.h"
10 #include "quantities/Storage.h"
11 #include "system/Settings.h"
12 
14 
15 enum class CollisionResult {
16  NONE,
17  BOUNCE,
19  MERGER,
20  EVAPORATION,
21 };
22 
30 public:
31  virtual void initialize(Storage& storage) = 0;
32 
46  virtual CollisionResult collide(const Size i, const Size j, FlatSet<Size>& toRemove) = 0;
47 };
48 
54 class IOverlapHandler : public Polymorphic {
55 public:
56  virtual void initialize(Storage& storage) = 0;
57 
62  virtual bool overlaps(const Size i, const Size j) const = 0;
63 
68  virtual void handle(const Size i, const Size j, FlatSet<Size>& toRemove) = 0;
69 };
70 
72 template <typename T>
73 Tuple<T, T> minMax(const T& t1, const T& t2) {
74  if (t1 < t2) {
75  return { t1, t2 };
76  } else {
77  return { t2, t1 };
78  }
79 }
80 
81 template <typename T>
82 INLINE T weightedAverage(const T& v1, const Float w1, const T& v2, const Float w2) {
83  SPH_ASSERT(w1 + w2 > 0._f, w1, w2);
84  return (v1 * w1 + v2 * w2) / (w1 + w2);
85 }
86 
87 INLINE bool areParticlesBound(const Float m_sum, const Float h_sum, const Vector& dv, const Float limit) {
88  const Float vEscSqr = 2._f * Constants::gravity * m_sum / h_sum;
89  const Float vRelSqr = getSqrLength(dv);
90  return vRelSqr * limit < vEscSqr;
91 }
92 
93 // ----------------------------------------------------------------------------------------------------------
94 // Collision Handlers
95 // ----------------------------------------------------------------------------------------------------------
96 
102 public:
103  virtual void initialize(Storage& UNUSED(storage)) override {}
104 
105  virtual CollisionResult collide(const Size UNUSED(i),
106  const Size UNUSED(j),
107  FlatSet<Size>& UNUSED(toRemove)) override {
108  return CollisionResult::NONE;
109  }
110 };
111 
118 private:
119  ArrayView<Vector> r, v;
122  ArrayView<Vector> omega;
125 
127 
128  Float bounceLimit;
129  Float rotationLimit;
130 
131 public:
132  explicit MergingCollisionHandler(const RunSettings& settings) {
133  bounceLimit = settings.get<Float>(RunSettingsId::COLLISION_BOUNCE_MERGE_LIMIT);
134  rotationLimit = settings.get<Float>(RunSettingsId::COLLISION_ROTATION_MERGE_LIMIT);
135  }
136 
137  explicit MergingCollisionHandler(const Float bounceLimit, const Float rotationLimit)
138  : bounceLimit(bounceLimit)
139  , rotationLimit(rotationLimit) {}
140 
141  virtual void initialize(Storage& storage) override {
143  tie(r, v, dv) = storage.getAll<Vector>(QuantityId::POSITION);
144  m = storage.getValue<Float>(QuantityId::MASS);
146 
147  if (storage.has(QuantityId::MOMENT_OF_INERTIA)) {
151  }
152  }
153 
154  virtual CollisionResult collide(const Size i, const Size j, FlatSet<Size>& toRemove) override {
155  // set radius of the merger so that the volume is conserved
156  const Float h_merger = root<3>(pow<3>(r[i][H]) + pow<3>(r[j][H]));
157 
158  // conserve total mass
159  const Float m_merger = m[i] + m[j];
160 
161  // merge so that the center of mass remains unchanged
162  const Vector r_merger = weightedAverage(r[i], m[i], r[j], m[j]);
163 
164  // converve momentum
165  const Vector v_merger = weightedAverage(v[i], m[i], v[j], m[j]);
166 
167  Vector omega_merger;
168  SymmetricTensor I_merger;
169  Vector L_merger;
170  Tensor E_merger = Tensor::identity();
171 
172  // Never modify particle values below UNTIL we know the collision is accepted; save the preliminary
173  // values to _merger variables!
174 
175  if (I) {
176  // So far this is just an experimental branch, not intended to be used for "serious" simulations.
177  // This assert is just a check that it does not get enabled by accident.
179 
180  // compute inertia tensors in inertial frame
181  const SymmetricTensor I1 = transform(I[i], convert<AffineMatrix>(E[i]));
182  const SymmetricTensor I2 = transform(I[j], convert<AffineMatrix>(E[j]));
183 
184  // sum up the inertia tensors, but first move them to new origin
185  I_merger = Rigid::parallelAxisTheorem(I1, m[i], r_merger - r[i]) +
186  Rigid::parallelAxisTheorem(I2, m[j], r_merger - r[j]);
187 
188  // compute the total angular momentum - has to be conserved
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) + //
191  L[i] + L[j];
192  // L = I*omega => omega = I^-1 * L
193  omega_merger = I_merger.inverse() * L_merger;
194 
195  // compute the new local frame of the merger and inertia tensor in this frame
196  Eigen eigen = eigenDecomposition(I_merger);
197  I_merger = SymmetricTensor(eigen.values, Vector(0._f));
198  SPH_ASSERT(isReal(I_merger));
199 
200  E_merger = convert<Tensor>(eigen.vectors);
201  SPH_ASSERT(isReal(E_merger));
202 
203  SPH_ASSERT(isReal(L_merger) && isReal(omega_merger), L_merger, omega_merger);
205  SPH_ASSERT(almostEqual(getSqrLength(E_merger.row(0)), 1._f, 1.e-6_f));
206  SPH_ASSERT(almostEqual(getSqrLength(E_merger.row(1)), 1._f, 1.e-6_f));
207  SPH_ASSERT(almostEqual(getSqrLength(E_merger.row(2)), 1._f, 1.e-6_f));
208 
209  } else {
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) + //
212  Rigid::sphereInertia(m[i], r[i][H]) * omega[i] + //
213  Rigid::sphereInertia(m[j], r[j][H]) * omega[j];
214  omega_merger = Rigid::sphereInertia(m_merger, h_merger).inverse() * L_merger;
215  }
216 
217  if (!this->acceptMerge(i, j, h_merger, omega_merger)) {
218  return CollisionResult::NONE;
219  }
220 
221  // NOW we can save the values
222 
223  m[i] = m_merger;
224  r[i] = r_merger;
225  r[i][H] = h_merger;
226  v[i] = v_merger;
227  v[i][H] = 0._f;
228  omega[i] = omega_merger;
229 
230  if (I) {
231  I[i] = I_merger;
232  L[i] = L_merger;
233  E[i] = E_merger;
234  }
235 
236  SPH_ASSERT(isReal(v[i]) && isReal(r[i]));
237  toRemove.insert(j);
239  }
240 
241 private:
249  INLINE bool acceptMerge(const Size i, const Size j, const Float h, const Vector& omega) const {
250  if (!areParticlesBound(m[i] + m[j], r[i][H] + r[j][H], v[i] - v[j], bounceLimit)) {
251  // moving too fast, reject the merge
253  return false;
254  }
255  const Float omegaCritSqr = Constants::gravity * (m[i] + m[j]) / pow<3>(h);
256  const Float omegaSqr = getSqrLength(omega);
257  if (omegaSqr * rotationLimit > omegaCritSqr) {
258  // rotates too fast, reject the merge
259  return false;
260  }
261  return true;
262  }
263 };
264 
270 protected:
273 
275  struct {
278 
281 
283 
284 public:
285  explicit ElasticBounceHandler(const RunSettings& settings) {
288  }
289 
291  restitution.n = n;
292  restitution.t = t;
293  }
294 
295  virtual void initialize(Storage& storage) override {
297  tie(r, v, dv) = storage.getAll<Vector>(QuantityId::POSITION);
298  m = storage.getValue<Float>(QuantityId::MASS);
299  }
300 
301  virtual CollisionResult collide(const Size i, const Size j, FlatSet<Size>& UNUSED(toRemove)) override {
302  const Vector dr = getNormalized(r[i] - r[j]);
303  const Vector v_com = weightedAverage(v[i], m[i], v[j], m[j]);
304  v[i] = this->reflect(v[i], v_com, -dr);
305  v[j] = this->reflect(v[j], v_com, dr);
306 
307  // no change of radius
308  v[i][H] = 0._f;
309  v[j][H] = 0._f;
310 
311  SPH_ASSERT(isReal(v[i]) && isReal(v[j]));
313  }
314 
315 private:
316  INLINE Vector reflect(const Vector& v, const Vector& v_com, const Vector& dir) {
317  SPH_ASSERT(almostEqual(getSqrLength(dir), 1._f), dir);
318  const Vector v_rel = v - v_com;
319  const Float proj = dot(v_rel, dir);
320  const Vector v_t = v_rel - proj * dir;
321  const Vector v_n = proj * dir;
322 
323  // flip the orientation of normal component (bounce) and apply coefficients of restitution
324  return restitution.t * v_t - restitution.n * v_n + v_com;
325  }
326 };
327 
330 template <typename TPrimary, typename TFallback>
332 private:
333  TPrimary primary;
334  TFallback fallback;
335 
336 public:
337  FallbackHandler(const RunSettings& settings)
338  : primary(settings)
339  , fallback(settings) {}
340 
341  virtual void initialize(Storage& storage) override {
342  primary.initialize(storage);
343  fallback.initialize(storage);
344  }
345 
346  virtual CollisionResult collide(const Size i, const Size j, FlatSet<Size>& toRemove) override {
347  CollisionResult result = primary.collide(i, j, toRemove);
348  if (result == CollisionResult::NONE) {
349  return fallback.collide(i, j, toRemove);
350  } else {
351  return result;
352  }
353  }
354 };
355 
357 public:
358  // ParametricRelations, directionality of fragments
359 
360  virtual CollisionResult collide(const Size i, const Size j, FlatSet<Size>& UNUSED(toRemove)) override {
361  (void)i;
362  (void)j;
366  }
367 };
368 
369 
370 // ----------------------------------------------------------------------------------------------------------
371 // Overlap Handlers
372 // ----------------------------------------------------------------------------------------------------------
373 
376 public:
377  virtual void initialize(Storage& UNUSED(storage)) override {}
378 
379  virtual bool overlaps(const Size UNUSED(i), const Size UNUSED(j)) const override {
380  return false;
381  }
382 
383  virtual void handle(const Size UNUSED(i),
384  const Size UNUSED(j),
385  FlatSet<Size>& UNUSED(toRemove)) override {}
386 };
387 
393 private:
394  MergingCollisionHandler handler;
395 
396 public:
398  : handler(0._f, 0._f) {}
399 
400  virtual void initialize(Storage& storage) override {
401  handler.initialize(storage);
402  }
403 
404  virtual bool overlaps(const Size UNUSED(i), const Size UNUSED(j)) const override {
405  return true;
406  }
407 
408  virtual void handle(const Size i, const Size j, FlatSet<Size>& toRemove) override {
409  handler.collide(i, j, toRemove);
410  }
411 };
412 
419 template <typename TFollowupHandler>
421 private:
422  TFollowupHandler handler;
423 
424  ArrayView<Vector> r, v;
426 
427 public:
428  explicit RepelHandler(const RunSettings& settings)
429  : handler(settings) {}
430 
431  virtual void initialize(Storage& storage) override {
433  tie(r, v, dv) = storage.getAll<Vector>(QuantityId::POSITION);
434  m = storage.getValue<Float>(QuantityId::MASS);
435 
436  handler.initialize(storage);
437  }
438 
439  virtual bool overlaps(const Size UNUSED(i), const Size UNUSED(j)) const override {
440  // this function is called only if the spheres intersect, which is the only condition for this handler
441  return true;
442  }
443 
444  virtual void handle(const Size i, const Size j, FlatSet<Size>& toRemove) override {
445  Vector dir;
446  Float dist;
447  tieToTuple(dir, dist) = getNormalizedWithLength(r[i] - r[j]);
448  dir[H] = 0._f; // don't mess up radii
449  // can be only used for overlapping particles
450  SPH_ASSERT(dist < r[i][H] + r[j][H], dist, r[i][H] + r[i][H]);
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;
453  r[i] += dir * x1;
454  r[j] -= dir * x2;
455  SPH_ASSERT(almostEqual(getSqrLength(r[i] - r[j]), sqr(r[i][H] + r[j][H])),
456  getSqrLength(r[i] - r[j]),
457  sqr(r[i][H] + r[j][H]));
458 
459  SPH_ASSERT(isReal(v[i]) && isReal(v[j]));
460  SPH_ASSERT(isReal(r[i]) && isReal(r[j]));
461 
462  // Now when the two particles are touching, handle the collision using the followup handler.
463  handler.collide(i, j, toRemove);
464  }
465 };
466 
473 private:
474  ElasticBounceHandler handler;
475 
476  ArrayView<Vector> r, v;
477 
478 public:
479  explicit InternalBounceHandler(const RunSettings& settings)
480  : handler(settings) {
481  // this handler allows overlaps of particles, so it should never be used with point particles, as we
482  // could potentially get infinite accelerations
485  }
486 
487  virtual void initialize(Storage& storage) override {
489  tie(r, v, dv) = storage.getAll<Vector>(QuantityId::POSITION);
490 
491  handler.initialize(storage);
492  }
493 
494  virtual bool overlaps(const Size i, const Size j) const override {
495  // overlap needs to be handled only if the particles are moving towards each other
496  const Vector dr = r[i] - r[j];
497  const Vector dv = v[i] - v[j];
498  return dot(dr, dv) < 0._f;
499  }
500 
501  virtual void handle(const Size i, const Size j, FlatSet<Size>& toRemove) override {
502  handler.collide(i, j, toRemove);
503  }
504 };
505 
511 private:
512  MergingCollisionHandler handler;
513 
514 public:
517 
520 
521 public:
522  explicit MergeBoundHandler(const RunSettings& settings)
523  : handler(settings) {
526  }
527 
528  virtual void initialize(Storage& storage) override {
530  tie(r, v, dv) = storage.getAll<Vector>(QuantityId::POSITION);
532  m = storage.getValue<Float>(QuantityId::MASS);
533 
534  handler.initialize(storage);
535  }
536 
537  virtual bool overlaps(const Size i, const Size j) const override {
538  const Float m_merger = m[i] + m[j];
539  if (!areParticlesBound(m_merger, r[i][H] + r[j][H], v[i] - v[j], bounceLimit)) {
540  // moving too fast, reject the merge
542  return false;
543  }
544 
545  const Float h_merger = root<3>(pow<3>(r[i][H]) + pow<3>(r[j][H]));
546  const Float omegaCritSqr = Constants::gravity * (m[i] + m[j]) / pow<3>(h_merger);
547 
548  const Vector r_merger = weightedAverage(r[i], m[i], r[j], m[j]);
549  const Vector v_merger = weightedAverage(v[i], m[i], v[j], 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) + //
552  Rigid::sphereInertia(m[i], r[i][H]) * omega[i] + //
553  Rigid::sphereInertia(m[j], r[j][H]) * omega[j];
554  const Vector omega_merger = Rigid::sphereInertia(m_merger, h_merger).inverse() * L_merger;
555  const Float omegaSqr = getSqrLength(omega_merger);
556  if (omegaSqr * rotationLimit > omegaCritSqr) {
557  // rotates too fast, reject the merge
558  return false;
559  }
560 
561  return true;
562  }
563 
564  virtual void handle(const Size i, const Size j, FlatSet<Size>& toRemove) override {
565  handler.collide(i, j, toRemove);
566  }
567 };
568 
INLINE bool almostEqual(const AffineMatrix &m1, const AffineMatrix &m2, const Float eps=EPS)
Definition: AffineMatrix.h:278
INLINE bool isReal(const AntisymmetricTensor &t)
#define SPH_ASSERT(x,...)
Definition: Assert.h:94
#define NOT_IMPLEMENTED
Helper macro marking missing implementation.
Definition: Assert.h:100
NAMESPACE_SPH_BEGIN
Definition: BarnesHut.cpp:13
INLINE bool areParticlesBound(const Float m_sum, const Float h_sum, const Vector &dv, const Float limit)
Definition: Collision.h:87
Tuple< T, T > minMax(const T &t1, const T &t2)
Helper function sorting two values.
Definition: Collision.h:73
INLINE T weightedAverage(const T &v1, const Float w1, const T &v2, const Float w2)
Definition: Collision.h:82
CollisionResult
Definition: Collision.h:15
@ 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).
Definition: Globals.h:16
double Float
Precision used withing the code. Use Float instead of float or double where precision is important.
Definition: Globals.h:13
constexpr INLINE T sqr(const T &f) noexcept
Return a squared value.
Definition: MathUtils.h:67
constexpr INLINE Float pow< 3 >(const Float v)
Definition: MathUtils.h:132
INLINE Float root< 3 >(const Float f)
Definition: MathUtils.h:105
constexpr Float E
Definition: MathUtils.h:365
#define INLINE
Macros for conditional compilation based on selected compiler.
Definition: Object.h:31
#define UNUSED(x)
Definition: Object.h:37
#define NAMESPACE_SPH_END
Definition: Object.h:12
@ 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.
Definition: StaticArray.h:281
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.
Definition: Tuple.h:304
INLINE Tuple< Vector, Float > getNormalizedWithLength(const Vector &v)
Returns normalized vector and length of the input vector as tuple.
Definition: Vector.h:597
INLINE Float getSqrLength(const Vector &v)
Definition: Vector.h:574
INLINE BasicVector< float > cross(const BasicVector< float > &v1, const BasicVector< float > &v2)
Cross product between two vectors.
Definition: Vector.h:559
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...
Definition: Vector.h:548
INLINE Vector getNormalized(const Vector &v)
Definition: Vector.h:590
@ H
Definition: Vector.h:25
Object providing safe access to continuous memory of data.
Definition: ArrayView.h:17
Handler for bounce on collision.
Definition: Collision.h:269
ArrayView< Float > m
Definition: Collision.h:272
ElasticBounceHandler(const RunSettings &settings)
Definition: Collision.h:285
virtual CollisionResult collide(const Size i, const Size j, FlatSet< Size > &UNUSED(toRemove)) override
Definition: Collision.h:301
Float t
Tangential.
Definition: Collision.h:280
ArrayView< Vector > r
Definition: Collision.h:271
virtual void initialize(Storage &storage) override
Definition: Collision.h:295
struct ElasticBounceHandler::@3 restitution
Coefficients of restitution.
ArrayView< Vector > v
Definition: Collision.h:271
Float n
Normal;.
Definition: Collision.h:277
ElasticBounceHandler(const Float n, const Float t)
Definition: Collision.h:290
Composite handler, choosing another collision handler if the primary handler rejects the collision by...
Definition: Collision.h:331
FallbackHandler(const RunSettings &settings)
Definition: Collision.h:337
virtual void initialize(Storage &storage) override
Definition: Collision.h:341
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.
Definition: Collision.h:346
bool insert(U &&value)
Definition: FlatSet.h:45
virtual CollisionResult collide(const Size i, const Size j, FlatSet< Size > &UNUSED(toRemove)) override
Definition: Collision.h:360
Abstraction of collision outcome.
Definition: Collision.h:29
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.
Definition: Collision.h:54
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.
Definition: Collision.h:472
virtual bool overlaps(const Size i, const Size j) const override
Returns true if two particles overlaps.
Definition: Collision.h:494
virtual void initialize(Storage &storage) override
Definition: Collision.h:487
virtual void handle(const Size i, const Size j, FlatSet< Size > &toRemove) override
Handles the overlap of two particles.
Definition: Collision.h:501
InternalBounceHandler(const RunSettings &settings)
Definition: Collision.h:479
Handler merging overlapping particles if their relative velocity is lower than the escape velocity.
Definition: Collision.h:510
ArrayView< Vector > v
Definition: Collision.h:515
MergeBoundHandler(const RunSettings &settings)
Definition: Collision.h:522
ArrayView< Vector > r
Definition: Collision.h:515
virtual void handle(const Size i, const Size j, FlatSet< Size > &toRemove) override
Handles the overlap of two particles.
Definition: Collision.h:564
virtual bool overlaps(const Size i, const Size j) const override
Returns true if two particles overlaps.
Definition: Collision.h:537
ArrayView< Vector > omega
Definition: Collision.h:515
ArrayView< Float > m
Definition: Collision.h:516
virtual void initialize(Storage &storage) override
Definition: Collision.h:528
Handler unconditionally merging the overlapping particles.
Definition: Collision.h:392
virtual bool overlaps(const Size UNUSED(i), const Size UNUSED(j)) const override
Definition: Collision.h:404
virtual void initialize(Storage &storage) override
Definition: Collision.h:400
virtual void handle(const Size i, const Size j, FlatSet< Size > &toRemove) override
Handles the overlap of two particles.
Definition: Collision.h:408
Handler merging particles into a single, larger particles.
Definition: Collision.h:117
virtual void initialize(Storage &storage) override
Definition: Collision.h:141
MergingCollisionHandler(const Float bounceLimit, const Float rotationLimit)
Definition: Collision.h:137
MergingCollisionHandler(const RunSettings &settings)
Definition: Collision.h:132
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.
Definition: Collision.h:154
Helper handler always returning CollisionResult::NONE.
Definition: Collision.h:101
virtual void initialize(Storage &UNUSED(storage)) override
Definition: Collision.h:103
virtual CollisionResult collide(const Size UNUSED(i), const Size UNUSED(j), FlatSet< Size > &UNUSED(toRemove)) override
Definition: Collision.h:105
Handler simply ignoring overlaps.
Definition: Collision.h:375
virtual void initialize(Storage &UNUSED(storage)) override
Definition: Collision.h:377
virtual bool overlaps(const Size UNUSED(i), const Size UNUSED(j)) const override
Definition: Collision.h:379
virtual void handle(const Size UNUSED(i), const Size UNUSED(j), FlatSet< Size > &UNUSED(toRemove)) override
Definition: Collision.h:383
Handler displacing the overlapping particles so that they just touch.
Definition: Collision.h:420
virtual void initialize(Storage &storage) override
Definition: Collision.h:431
virtual void handle(const Size i, const Size j, FlatSet< Size > &toRemove) override
Handles the overlap of two particles.
Definition: Collision.h:444
virtual bool overlaps(const Size UNUSED(i), const Size UNUSED(j)) const override
Definition: Collision.h:439
RepelHandler(const RunSettings &settings)
Definition: Collision.h:428
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.
Definition: Settings.h:326
Container storing all quantities used within the simulations.
Definition: Storage.h:230
StaticArray< Array< TValue > &, 3 > getAll(const QuantityId key)
Retrieves quantity buffers from the storage, given its key and value type.
Definition: Storage.cpp:163
bool has(const QuantityId key) const
Checks if the storage contains quantity with given key.
Definition: Storage.cpp:130
Array< TValue > & getValue(const QuantityId key)
Retrieves a quantity values from the storage, given its key and value type.
Definition: Storage.cpp:191
Symmetric tensor of 2nd order.
INLINE SymmetricTensor inverse() const
Generic 2nd-order tensor with 9 independent components.
Definition: Tensor.h:13
INLINE Vector row(const Size idx) const
Definition: Tensor.h:44
static Tensor identity()
Definition: Tensor.h:81
Heterogeneous container capable of storing a fixed number of values.
Definition: Tuple.h:146
Generic storage and input/output routines of settings.
GravityKernelEnum
Definition: Settings.h:796
@ 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)
Definition: Constants.h:29
INLINE SymmetricTensor sphereInertia(const Float m, const Float r)
Computes the inertia tensor of a homogeneous sphere.
Definition: Functions.h:61
INLINE SymmetricTensor parallelAxisTheorem(const SymmetricTensor &I, const Float m, const Vector &a)
Computes the inertia tensor with respect to given point.
Definition: Functions.h:70
static bool isTest
Definition: Assert.h:15
AffineMatrix vectors
Matrix of eigenvectors, stored as rows.
Vector values
Eigenvalues.
Base class for all polymorphic objects.
Definition: Object.h:88