28 for (
Size i = 0; i < r.
size(); ++i) {
29 counts[i] = finder->
findAll(i, r[i][
H] * particleRadius, neighs);
49 indices.
fill(unassigned);
50 Size componentIdx = 0;
60 for (
Size i = 0; i < r.
size(); ++i) {
61 if (indices[i] == unassigned) {
62 indices[i] = componentIdx;
65 while (!stack.
empty()) {
68 for (
auto& n : neighs) {
69 if (!checker.
belong(index, n.index)) {
73 if (indices[n.index] == unassigned) {
74 indices[n.index] = componentIdx;
94 if (flags.
has(ComponentFlag::SEPARATE_BY_FLAG)) {
99 explicit FlagComponentChecker(
const Storage& storage) {
103 return flag[i] == flag[j];
106 checker = makeAuto<FlagComponentChecker>(storage);
110 Size componentCnt = findComponentsImpl(*checker, r,
radius, indices);
112 if (flags.
has(ComponentFlag::ESCAPE_VELOCITY)) {
129 for (
Size i = 0; i < r.
size(); ++i) {
130 masses[indices[i]] += m[i];
131 positions[indices[i]] += m[i] * r[i];
132 velocities[indices[i]] += m[i] * v[i];
133 volumes[indices[i]] +=
pow<3>(r[i][
H]);
135 for (
Size k = 0; k < componentCnt; ++k) {
137 positions[k] /= masses[k];
138 positions[k][
H] =
cbrt(3._f * volumes[k] / (4._f *
PI));
139 velocities[k] /= masses[k];
152 const Float m_tot = m[i] + m[j];
157 EscapeVelocityComponentChecker velocityChecker;
158 velocityChecker.r = positions;
159 velocityChecker.v = velocities;
160 velocityChecker.m = masses;
161 velocityChecker.radius =
radius;
165 componentCnt = findComponentsImpl(velocityChecker, positions, 50._f, velocityIndices);
175 for (
Size i = 0; i < r.
size(); ++i) {
176 indices[i] = velocityIndices[indices[i]];
181 std::set<Size> uniqueIndices;
182 for (
Size i : indices) {
185 SPH_ASSERT(uniqueIndices.size() == componentCnt);
187 for (
Size i : uniqueIndices) {
194 if (flags.
has(ComponentFlag::SORT_BY_MASS)) {
196 componentMass.
fill(0._f);
198 for (
Size i = 0; i < indices.
size(); ++i) {
199 componentMass[indices[i]] += m[i];
201 Order mapping(componentCnt);
202 mapping.
shuffle([&componentMass](
Size i,
Size j) {
return componentMass[i] > componentMass[j]; });
206 for (
Size i = 0; i < indices.
size(); ++i) {
207 realIndices[i] = mapping[indices[i]];
217 const Float particleRadius,
220 Post::findComponents(storage, particleRadius, flags | ComponentFlag::SORT_BY_MASS, componentIdxs);
224 for (
Size i = 0; i < componentIdxs.
size(); ++i) {
225 if (componentIdxs[i] == 0) {
370 const auto largestIter = std::max_element(m.
begin(), m.
end());
371 const Float largestM = *largestIter;
378 statuses[largestIdx] = MoonEnum::LARGEST_FRAGMENT;
383 for (
Size i = 0; i < m.
size(); ++i) {
384 if (i == largestIdx) {
389 if (r[i][
H] < limit * r[largestIdx][
H]) {
390 statuses[i] = MoonEnum::UNOBSERVABLE;
396 m[i] + largestM, m[i] * largestM / (m[i] + largestM), r[i] - r[largestIdx], v[i] - v[largestIdx]);
400 statuses[i] = MoonEnum::RUNAWAY;
403 if (elements->pericenterDist() <
radius * (r[i][
H] + r[largestIdx][
H])) {
404 statuses[i] = MoonEnum::IMPACTOR;
407 statuses[i] = MoonEnum::MOON;
425 for (
Size j = i + 1; j < r.
size(); ++j) {
426 if (m[j] < limit * m[i]) {
431 m[i] + m[j], m[i] * m[j] / (m[i] + m[j]), r[i] - r[j], v[i] - v[j]);
433 if (elements && elements->pericenterDist() >
radius * (r[i][
H] + r[j][
H])) {
446 for (
Size i = 0; i < omega.
size(); ++i) {
447 const Vector L = I[i] * omega[i];
448 if (omega[i] ==
Vector(0._f)) {
452 SPH_ASSERT(cosBeta >= -1._f && cosBeta <= 1._f);
466 auto functor = [&m_tot, &r_com, m, r](
Size i) {
467 r_com += m[i] * r[i];
471 for (
Size i : idxs) {
475 for (
Size i = 0; i < r.
size(); ++i) {
490 auto functor = [&I, r, m, &r0](
Size i) {
491 const Vector dr = r[i] - r0;
495 for (
Size i : idxs) {
499 for (
Size i = 0; i < r.
size(); ++i) {
522 auto functor = [&L, m, r, v, &r0, &v0](
const Size i) {
523 L += m[i] *
cross(r[i] - r0, v[i] - v0);
527 for (
Size i : idxs) {
531 for (
Size i = 0; i < r.
size(); ++i) {
557 for (
const Triangle& triangle : mesh) {
558 area += triangle.area();
564 MeshDomain domain(scheduler, std::move(mesh), params);
569 return pow(
PI *
sqr(6._f * volume), 1._f / 3._f) / area;
577 template <
typename TValueFunctor>
580 const TValueFunctor& functor) {
600 filtered.
push(functor(i));
614 return processParticleCutoffs(storage, params, [r](
Size i) {
return r[i][
H]; });
618 return processParticleCutoffs(storage, params, [m, ¶ms](
Size i) {
624 return processParticleCutoffs(storage, params, [v](
Size i) {
return getLength(v[i]); });
631 return processParticleCutoffs(storage, params, [omega](
Size i) {
637 return 2._f *
PI / (3600._f * w);
646 return processParticleCutoffs(storage, params, [omega](
Size i) {
648 return 3600._f * 24._f * w / (2._f *
PI);
656 return processParticleCutoffs(storage, params, [omega](
Size i) {
661 return acos(omega[i][
Z] / w);
670 return processParticleCutoffs(storage, params, [&values](
Size i) {
return values[i]; });
677 const Size numComponents,
683 velocities.fill(
Vector(0._f));
686 for (
Size i = 0; i < m.
size(); ++i) {
687 velocities[components[i]] += m[i] * v[i];
688 masses[components[i]] += m[i];
692 for (
Size idx = 0; idx < numComponents; ++idx) {
694 velocities[idx] /= masses[idx];
714 virtual const char*
what() const noexcept
override {
715 return message.c_str();
725 const Size numComponents =
728 Array<Size> toRemove = processComponentCutoffs(storage, components, numComponents, params);
746 for (
Size i = 0; i < m.
size(); ++i) {
754 values[components[i]] += m[i] / density;
762 for (
Size i = 0; i < values.
size(); ++i) {
763 radii[i] =
root<3>(3._f * values[i] / (4._f *
PI));
776 for (
Size i = 0; i < m.
size(); ++i) {
777 const Size componentIdx = components[i];
778 sumV[componentIdx] += m[i] * v[i];
779 weights[componentIdx] += m[i];
783 sumV.remove(toRemove);
784 weights.remove(toRemove);
787 for (
Size i = 0; i < sumV.size(); ++i) {
789 velocities[i] =
getLength(sumV[i] / weights[i]);
805 values = getParticleValues(storage, params,
id);
808 values = getComponentValues(storage, params,
id);
819 Array<Float> values = getValues(storage,
id, source, params);
820 if (values.
empty()) {
823 std::sort(values.
begin(), values.
end());
827 for (
Size i = 0; i < values.
size(); ++i) {
838 for (
int i = values.
size() - 1; i >= 0; --i) {
839 if (values[i] < lastR) {
857 Array<Float> values = getValues(storage,
id, source, params);
866 for (
Size i = 0; i < values.
size(); ++i) {
885 const bool singular = range.
size() == 0;
886 for (
Size i = 0; i < values.
size(); ++i) {
892 const Float floatIdx = binCnt * (values[i] - range.
lower()) / range.
size();
893 if (floatIdx >= 0._f && floatIdx < binCnt) {
894 binIdx =
Size(floatIdx);
906 for (
Size i = 0; i < binCnt; ++i) {
908 histogram[i] = { range.
lower() + (centerIdx * range.
size()) / binCnt, sfd[i] };
916 Float x = 0._f, x2 = 0._f;
917 Float y = 0._f, y2 = 0._f;
928 const Float denom = n * x2 -
sqr(x);
930 const Float b = (y * x2 - x * xy) / denom;
931 const Float a = (n * xy - x * y) / denom;
939 for (
Size k = 0; k < xs.
size(); ++k) {
940 xs[k] =
Vector(1._f, points[k].x,
sqr(points[k].x));
946 for (
Size k = 0; k < xs.
size(); ++k) {
947 for (
Size i = 0; i < 3; ++i) {
948 for (
Size j = 0; j < 3; ++j) {
949 xTx(i, j) += xs[k][j] * xs[k][i];
951 xTy[i] += xs[k][i] * ys[k];
Various function for interpretation of the results of a simulation.
INLINE bool isReal(const AntisymmetricTensor &t)
INLINE CopyableArray< T, TAllocator, TCounter > copyable(const Array< T, TAllocator, TCounter > &array)
#define SPH_ASSERT(x,...)
#define NOT_IMPLEMENTED
Helper macro marking missing implementation.
Object representing a three-dimensional axis-aligned box.
Object finding nearest neighbours by evaluating all partice pairs.
Object for printing quantity values into output.
INLINE Float maxElement(const T &value)
Returns maximum element, simply the value iself by default.
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.
Helper objects allowing to iterate in reverse, iterate over multiple containeres, etc.
Logging routines of the run.
Array< Triangle > getSurfaceMesh(IScheduler &scheduler, const Storage &storage, const McConfig &config)
Returns the triangle mesh of the body surface (or surfaces of bodies).
constexpr INLINE T sqr(const T &f) noexcept
Return a squared value.
INLINE Float cbrt(const Float f)
Returns a cubed root of a value.
INLINE T sqrt(const T f)
Return a squared root of a value.
constexpr INLINE Float pow< 3 >(const Float v)
constexpr INLINE Float pow(const Float v)
Power for floats.
INLINE Float root< 3 >(const Float f)
constexpr Float PI
Mathematical constants.
Domain represented by triangular mesh.
#define NAMESPACE_SPH_END
Saving and loading particle data.
QuantityMetadata getMetadata(const QuantityId key)
Returns the quantity information using quantity ID.
QuantityId
Unique IDs of basic quantities of SPH particles.
@ FLAG
ID of original body, used to implement discontinuities between bodies in SPH.
@ MOMENT_OF_INERTIA
Moment of inertia of particles, analogy of particle masses for rotation.
@ POSITION
Positions (velocities, accelerations) of particles, always a vector quantity,.
@ DENSITY
Density, always a scalar quantity.
@ MASS
Paricles masses, always a scalar quantity.
SequentialScheduler SEQUENTIAL
Global instance of the sequential scheduler.
Interface for executing tasks (potentially) asynchronously.
Box getBoundingBox(const Storage &storage, const Float radius)
Convenience function to get the bounding box of all particles.
Container for storing particle quantities and materials.
INLINE SymmetricTensor symmetricOuter(const Vector &v1, const Vector &v2)
SYMMETRIZED outer product of two vectors.
INLINE Float getLength(const Vector &v)
Returns the length of the vector. Enabled only for vectors of floating-point precision.
INLINE Float distance(const Vector &r, const Vector &axis)
Returns the distance of vector from given axis. The axis is assumed to be normalized.
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 Float determinant() const
Computes determinant of the matrix.
static AffineMatrix null()
AffineMatrix inverse() const
Object providing safe access to continuous memory of data.
INLINE TCounter size() const
INLINE Iterator< StorageType > begin()
INLINE Iterator< StorageType > end()
void resize(const TCounter newSize)
Resizes the array to new size.
INLINE Iterator< StorageType > end() noexcept
INLINE void push(U &&u)
Adds new element to the end of the array, resizing the array if necessary.
void remove(const TCounter idx)
Removes an element with given index from the array.
void fill(const T &t)
Sets all elements of the array to given value.
void insert(const TCounter position, U &&value)
Inserts a new element to given position in the array.
INLINE T pop()
Removes the last element from the array and return its value.
INLINE TCounter size() const noexcept
INLINE bool empty() const noexcept
INLINE Iterator< StorageType > begin() noexcept
Helper object defining three-dimensional interval (box).
INLINE Vector size() const
Returns box dimensions.
Wrapper of an integral value providing functions for reading and modifying individual bits.
constexpr INLINE bool has(const TEnum flag) const
Checks if the object has a given flag.
void build(IScheduler &scheduler, ArrayView< const Vector > points)
Constructs the struct with an array of vectors.
virtual Size findAll(const Size index, const Float radius, Array< NeighbourRecord > &neighbours) const =0
Finds all neighbours within given radius from the point given by index.
Interface that allows unified implementation of sequential and parallelized versions of algorithms.
Object representing a 1D interval of real numbers.
INLINE Float lower() const
Returns lower bound of the interval.
INLINE void extend(const Float &value)
Extends the interval to contain given value.
INLINE Float upper() const
Returns upper bound of the interval.
INLINE Float size() const
Returns the size of the interval.
INLINE bool contains(const Float &value) const
Checks whether value is inside the interval.
INLINE bool empty() const
Returns true if the interval is empty (default constructed).
Domain represented by triangular mesh.
virtual Float getVolume() const override
Returns the total volume of the domain.
Wrapper of type value of which may or may not be present.
Permutation, i.e. (discrete) invertible function int->int.
void shuffle(TBinaryPredicate &&predicate)
Shuffles the order using a binary predicate.
Order getInverted() const
Returns the inverted order.
Class representing an ordinary 1D linear function.
static const Settings & getDefaults()
\brief Returns a reference to object containing default values of all settings.
Container storing all quantities used within the simulations.
Array< TValue > & getDt(const QuantityId key)
Retrieves a quantity derivative from the storage, given its key and value type.
Size getParticleCnt() const
Returns the number of particles.
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
static INLINE SymmetricTensor identity()
Returns an identity tensor.
static INLINE SymmetricTensor null()
Returns a tensor with all zeros.
2D point and other primitives for 2D geometry
Creating code components based on values from settings.
constexpr Float gravity
Gravitational constant (CODATA 2014)
AutoPtr< ISymmetricFinder > getFinder(const RunSettings &settings)
Optional< Elements > computeOrbitalElements(const Float M, const Float mu, const Vector &r, const Vector &v)
Computes the orbital elements, given position and velocity of a body.
Array< MoonEnum > findMoons(const Storage &storage, const Float radius=1._f, const Float limit=0._f)
Find a potential satellites of the largest body.
Array< HistPoint > getDifferentialHistogram(ArrayView< const Float > values, const HistogramParams ¶ms)
Computes the differential histogram from given values.
Array< Size > findNeighbourCounts(const Storage &storage, const Float particleRadius)
Finds the number of neighbours of each particle.
HistogramSource
Source data used to construct the histogram.
@ PARTICLES
Radii of individual particles, considering particles as spheres (N-body framework)
LinearFunction getLinearFit(ArrayView< const PlotPoint > points)
Finds a linear fit to a set of points.
QuadraticFunction getQuadraticFit(ArrayView< const PlotPoint > points)
Array< Size > findLargestComponent(const Storage &storage, const Float particleRadius, const Flags< ComponentFlag > flags)
Returns the indices of particles belonging to the largest remnant.
Vector getAngularFrequency(ArrayView< const Float > m, ArrayView< const Vector > r, ArrayView< const Vector > v, const Vector &r0, const Vector &v0, ArrayView< const Size > idxs=nullptr)
Computes the immediate vector of angular frequency of a rigid body.
Size findComponents(const Storage &storage, const Float particleRadius, const Flags< ComponentFlag > flags, Array< Size > &indices)
Finds and marks connected components (a.k.a. separated bodies) in the array of vertices.
Vector getCenterOfMass(ArrayView< const Float > m, ArrayView< const Vector > r, ArrayView< const Size > idxs=nullptr)
Computes the center of mass.
Array< Tumbler > findTumblers(const Storage &storage, const Float limit)
Find all tumbling asteroids.
SymmetricTensor getInertiaTensor(ArrayView< const Float > m, ArrayView< const Vector > r, const Vector &r0, ArrayView< const Size > idxs=nullptr)
Computes the total inertia tensor of particles with respect to given center.
MoonEnum
Potential relationship of the body with a respect to the largest remnant (fragment).
Array< HistPoint > getCumulativeHistogram(const Storage &storage, const ExtHistogramId id, const HistogramSource source, const HistogramParams ¶ms)
Computes cumulative (integral) histogram of particles in the storage.
HistogramId
Quantity from which the histogram is constructed.
@ VELOCITIES
Particle velocities.
@ ROTATIONAL_AXIS
Distribution of axis directions, from -pi to pi.
@ ROTATIONAL_FREQUENCY
Rotational frequency in revs/day.
@ RADII
Particle radii or equivalent radii of components.
Float getSphericity(IScheduler &scheduler, const Storage &strorage, const Float resolution=0.05_f)
Computes the sphericity coefficient of a body.
Size findMoonCount(ArrayView< const Float > m, ArrayView< const Vector > r, ArrayView< const Vector > v, const Size i, const Float radius=1._f, const Float limit=0._f)
Find the number of moons of given body.
virtual bool belong(const Size UNUSED(i), const Size UNUSED(j))
Float gridResolution
Absolute size of each produced triangle.
bool precomputeInside
If true, cached volume is created to allow fast calls of contains.
MissingQuantityException(const QuantityId id)
virtual const char * what() const noexcept override
Base class for all polymorphic objects.
Size count
Number of particles/components.
Float value
Value of the quantity.
bool operator==(const HistPoint &other) const
Float radius
Radius of particles in units of their smoothing lengths.
Flags< Post::ComponentFlag > flags
Determines how the particles are clustered into the components.
Parameters of the histogram.
Float velocityCutoff
Cutoff value (upper bound) of particle velocity for inclusion in the histogram.
Float referenceDensity
Reference density, used when computing particle radii from their masses.
Function< bool(Size index)> validator
Function used for inclusiong/exclusion of values in the histogram.
Float massCutoff
Cutoff value (lower bound) of particle mass for inclusion in the histogram.
Interval range
Range of values from which the histogram is constructed.
struct Post::HistogramParams::ComponentParams components
Size binCnt
Number of histogram bins.