42 persistentId = particleIdx;
50 persistentId = *seq.
begin();
68 return idxs.
find(idx) != idxs.
end();
77 if (this->
size() == 1) {
102 if (alpha[persistentId] !=
Vector(0._f)) {
106 alpha[persistentId] =
Vector(0._f);
110 for (
Size i : idxs) {
113 r[i] = r_com + rotationMatrix * (r[i] - r_com);
114 v[i] +=
cross(omega, r[i] - r_com);
123 if (this->
size() == 1) {
134 for (
Size i : idxs) {
135 dv_com += m[i] * dv[i];
136 v_com += m[i] * v[i];
137 r_com += m[i] * r[i];
147 for (
Size i : idxs) {
148 const Vector dr = r[i] - r_com;
149 L += m[i] *
cross(dr, v[i] - v_com);
151 M += m[i] *
cross(dr, dv[i] - dv_com);
177 for (
Size i : idxs) {
184 alpha[persistentId] =
Vector(0._f);
185 dalpha[persistentId] = w[persistentId];
190 const Integrals ag = this->getIntegrals();
193 for (
Size i : idxs) {
194 v[i] = ag.v_com +
cross(ag.omega, r[i] - ag.r_com);
202 for (
Size i : idxs) {
215 for (
Size i : idxs) {
216 v_com += m[i] * v[i];
227 for (
Size i : idxs) {
259 Integrals getIntegrals()
const {
267 for (
Size i : idxs) {
268 v_com += m[i] * v[i];
269 r_com += m[i] * r[i];
277 for (
Size i : idxs) {
278 const Vector dr = r[i] - r_com;
279 L += m[i] *
cross(dr, v[i] - v_com);
293 value.omega =
Vector(0._f);
314 mutable std::mutex mutex;
325 for (
Size i = 0; i < n; ++i) {
338 aggregates[i].
clear();
342 aggregates[idx] =
Aggregate(storage, seq);
344 for (
Size i = 0; i < seq.
size(); ++i) {
357 Aggregate& ag = *particleToAggregate[particleIdx];
364 const Aggregate& ag = *particleToAggregate[particleIdx];
394 this->
merge(ag2, ag1);
400 if (ag2.
size() == 1) {
403 particleToAggregate[id] = &ag1;
416 if (ag.
getId() == idx) {
420 aggregates[idx].add(idx);
421 particleToAggregate[idx] =
addressOf(aggregates[idx]);
431 aggregates[i].add(i);
432 particleToAggregate[i] =
addressOf(aggregates[i]);
461 std::unique_lock<std::mutex> lock(mutex);
471 std::unique_lock<std::mutex> lock(mutex);
504 holder = dynamicCast<AggregateHolder>(storage.
getUserData().
get());
525 v[i] = this->reflect(v[i], v_com, -dr);
526 v[j] = this->reflect(v[j], v_com, dr);
527 v[i][
H] = v[j][
H] = 0._f;
552 holder->
merge(ag_i, ag_j);
569 const Vector v_rel = v - v_com;
571 const Vector v_t = v_rel - proj * dir;
572 const Vector v_n = proj * dir;
575 return restitution.t * v_t - restitution.n * v_n + v_com;
589 : handler(settings) {}
592 holder = dynamicCast<AggregateHolder>(storage.
getUserData().
get());
629 if (dist > r[i][
H] + r[j][
H]) {
636 const Float x1 = (r[i][
H] + r[j][
H] - dist) / (1._f + m1 / m2);
637 const Float x2 = m1 / m2 * x1;
641 handler.
collide(i, j, toRemove);
663 for (
Size i = 0; i < aggregateIds.
size(); ++i) {
684 holder = makeShared<AggregateHolder>(storage, source);
INLINE bool almostEqual(const AffineMatrix &m1, const AffineMatrix &m2, const Float eps=EPS)
NAMESPACE_SPH_BEGIN const Vector MAX_SPIN
Various function for interpretation of the results of a simulation.
INLINE bool isReal(const AntisymmetricTensor &t)
#define SPH_ASSERT(x,...)
#define NOT_IMPLEMENTED
Helper macro marking missing implementation.
INLINE AutoPtr< T > makeAuto(TArgs &&... args)
Helper functions to check the internal consistency of the code.
@ NON_REENRANT
Function can be executed by any thread, but only once at a time.
#define CHECK_FUNCTION(flags)
INLINE bool areParticlesBound(const Float m_sum, const Float h_sum, const Vector &dv, const Float limit)
INLINE T weightedAverage(const T &v1, const Float w1, const T &v2, const Float w2)
@ BOUNCE
Bounce/scatter collision, no merging and no fragmentation.
@ NONE
No collision took place.
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.
Base class for solvers of gravity.
Logging routines of the run.
SPH-specific implementation of particle materials.
constexpr INLINE T clamp(const T &f, const T &f1, const T &f2)
#define INLINE
Macros for conditional compilation based on selected compiler.
#define NAMESPACE_SPH_END
const NothingType NOTHING
@ POSITION
Positions (velocities, accelerations) of particles, always a vector quantity,.
@ AGGREGATE_ID
Index of the aggregate containing this particle.
@ MASS
Paricles masses, always a scalar quantity.
Holder of quantity values and their temporal derivatives.
@ FIRST
Quantity with 1st derivative.
@ ZERO
Quantity without derivatives, or "zero order" of quantity.
INLINE RawPtr< T > addressOf(T &ref)
StaticArray< T0 &, sizeof...(TArgs)+1 > tie(T0 &t0, TArgs &... rest)
Creates a static array from a list of l-value references.
Statistics gathered and periodically displayed during the run.
@ AGGREGATE_COUNT
Number of aggregates in the simulation (single particles are not counted as aggregates).
Container for storing particle quantities and materials.
INLINE SymmetricTensor symmetricOuter(const Vector &v1, const Vector &v2)
SYMMETRIZED outer product of two vectors.
INLINE Tuple< TArgs &... > tieToTuple(TArgs &... args)
Creates a tuple of l-value references. Use IGNORE placeholder to omit one or more parameters.
INLINE Float getLength(const Vector &v)
Returns the length of the vector. Enabled only for vectors of floating-point precision.
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.
BasicVector< Float > Vector
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)
static AffineMatrix identity()
static AffineMatrix rotateAxis(const Vector &axis, const Float angle)
virtual void initialize(Storage &storage) override
AggregateCollisionHandler(const RunSettings &settings)
virtual CollisionResult collide(const Size i, const Size j, FlatSet< Size > &UNUSED(toRemove)) override
Holds a set of aggregates.
void integrate()
Integrates all aggregates.
virtual Size count() const override
Returns the number of aggregates in the storage.
Optional< Size > getAggregateId(const Size particleIdx) const
AggregateHolder(Storage &storage, const AggregateEnum source)
void disband(Aggregate &ag)
void separate(Aggregate &ag, const Size idx)
void merge(Aggregate &ag1, Aggregate &ag2)
Merges two aggregates.
Aggregate & getAggregate(const Size particleIdx)
Returns the aggregate holding the given particle.
const Aggregate & getAggregate(const Size particleIdx) const
Returns the aggregate holding the given particle.
AggregateOverlapHandler(const RunSettings &settings)
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 i, const Size j) const override
Returns true if two particles overlaps.
virtual void integrate(Storage &storage, Statistics &stats) override
Computes derivatives of all time-dependent quantities.
virtual void create(Storage &storage, IMaterial &material) const override
Initializes all quantities needed by the solver in the storage.
void createAggregateData(Storage &storage, const AggregateEnum source)
AggregateSolver(IScheduler &scheduler, const RunSettings &settings)
virtual void collide(Storage &storage, Statistics &stats, const Float dt) override
Checks and resolves particle collisions.
Aggregate of particles, moving as a rigid body according to Euler's equations.
void displace(const Vector &offset)
bool contains(const Size idx) const
void spin()
Modifies velocities according to saved angular frequency.
Aggregate(Storage &storage, IndexSequence seq)
void integrate()
Saves angular frequency, sets velocities to COM movement.
Aggregate()=default
Needed due to resize.
void remove(const Size idx)
Aggregate(Storage &storage, const Size particleIdx)
Single particle.
Object providing safe access to continuous memory of data.
INLINE TCounter size() const
void resize(const TCounter newSize)
Resizes the array to new size.
StorageType & emplaceBack(TArgs &&... args)
Constructs a new element at the end of the array in place, using the provided arguments.
void clear()
Removes all elements from the array, but does NOT release the memory.
bool contains(const T &value)
Iterator< T > erase(Iterator< T > pos)
INLINE bool empty() const
Iterator< T > find(const T &value)
Solver computing gravitational interactions of hard-sphere particles.
virtual void collide(Storage &storage, Statistics &stats, const Float dt) override
Checks and resolves particle collisions.
virtual void integrate(Storage &storage, Statistics &stats) override
Computes derivatives of all time-dependent quantities.
virtual void create(Storage &storage, IMaterial &material) const override
Initializes all quantities needed by the solver in the storage.
Holds aggregate data stored in the storage and used by the solver.
Abstraction of collision outcome.
Material settings and functions specific for one material.
Handles overlaps of particles.
Interface that allows unified implementation of sequential and parallelized versions of algorithms.
INLINE IndexIterator begin() const
Non-owning wrapper of a material and particles with this material.
INLINE IndexSequence sequence()
Returns iterable index sequence.
INLINE Type valueOr(const TOther &other) const
Returns the stored value if the object has been initialized, otherwise returns provided parameter.
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.
INLINE RawPtr< T > get() const
Object holding various statistics about current run.
Statistics & set(const StatisticsId idx, TValue &&value)
Sets new values of a statistic.
Container storing all quantities used within the simulations.
Size getMaterialCnt() const
Return the number of materials in the storage.
Quantity & insert(const QuantityId key, const OrderEnum order, const TValue &defaultValue)
Creates a quantity in the storage, given its key, value type and order.
StaticArray< Array< TValue > &, 3 > getAll(const QuantityId key)
Retrieves quantity buffers from the storage, given its key and value type.
Array< TValue > & getDt(const QuantityId key)
Retrieves a quantity derivative from the storage, given its key and value type.
void setUserData(SharedPtr< IStorageUserData > newData)
Stores new user data into the storage.
Size getParticleCnt() const
Returns the number of particles.
SharedPtr< IStorageUserData > getUserData() const
Returns the stored user data.
MaterialView getMaterial(const Size matIdx) const
Returns an object containing a reference to given material.
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
static INLINE SymmetricTensor identity()
Returns an identity tensor.
static INLINE SymmetricTensor null()
Returns a tensor with all zeros.
INLINE Float determinant() const
Returns the determinant of the tensor.
Creating code components based on values from settings.
@ COLLISION_BOUNCE_MERGE_LIMIT
@ COLLISION_RESTITUTION_TANGENT
@ COLLISION_RESTITUTION_NORMAL
Provides a convenient way to construct objects from settings.
AutoPtr< IGravity > getGravity(const RunSettings &settings)
Object with deleted copy constructor and copy operator.