SPH
Integrals.cpp
Go to the documentation of this file.
1 #include "physics/Integrals.h"
2 #include "post/Analysis.h"
3 #include "quantities/Storage.h"
4 #include "system/Factory.h"
5 
7 
8 
9 Float TotalMass::evaluate(const Storage& storage) const {
10  Float total(0._f);
12  SPH_ASSERT(!m.empty());
13  for (Size i = 0; i < m.size(); ++i) {
14  total += m[i];
15  }
16  SPH_ASSERT(isReal(total));
17  return total;
18 }
19 
21  : omega(0._f, 0._f, omega) {}
22 
23 
24 Vector TotalMomentum::evaluate(const Storage& storage) const {
25  BasicVector<double> total(0.); // compute in double precision to avoid round-off error during accumulation
26  ArrayView<const Vector> r, v, dv;
27  tie(r, v, dv) = storage.getAll<Vector>(QuantityId::POSITION);
29  SPH_ASSERT(!v.empty());
30  for (Size i = 0; i < v.size(); ++i) {
31  total += vectorCast<double>(m[i] * (v[i] + cross(omega, r[i])));
32  }
33  SPH_ASSERT(isReal(total));
34  return vectorCast<Float>(total);
35 }
36 
38  : frameFrequency(0._f, 0._f, omega) {}
39 
41  BasicVector<double> total(0.);
42  ArrayView<const Vector> r, v, dv;
43  tie(r, v, dv) = storage.getAll<Vector>(QuantityId::POSITION);
45 
46  // angular momentum with respect to origin
47  SPH_ASSERT(!v.empty());
48  for (Size i = 0; i < v.size(); ++i) {
49  total += vectorCast<double>(m[i] * cross(r[i], (v[i] + cross(frameFrequency, r[i]))));
50  }
51 
52  // local angular momentum
54  /*if (storage.has(QuantityId::ANGULAR_VELOCITY)) {
55  ArrayView<const Vector> omega = storage.getValue<Vector>(QuantityId::ANGULAR_VELOCITY);
56  ArrayView<const SymmetricTensor> I = storage.getValue<SymmetricTensor>(QuantityId::MOMENT_OF_INERTIA);
57  for (Size i = 0; i < v.size(); ++i) {
58  total += I[i] * omega[i];
59  }
60  }*/
61 
62  SPH_ASSERT(isReal(total));
63  return vectorCast<Float>(total);
64 }
65 
67  : omega(0._f, 0._f, omega) {}
68 
69 Float TotalEnergy::evaluate(const Storage& storage) const {
70  double total = 0.;
71  // add kinetic energy
72  ArrayView<const Vector> r, v, dv;
73  tie(r, v, dv) = storage.getAll<Vector>(QuantityId::POSITION);
75  for (Size i = 0; i < v.size(); ++i) {
76  SPH_ASSERT(!v.empty());
77  total += 0.5 * m[i] * getSqrLength(v[i]);
78  }
79 
80  if (storage.has(QuantityId::ENERGY)) {
81  // add internal energy
83  for (Size i = 0; i < v.size(); ++i) {
84  SPH_ASSERT(!v.empty());
85  total += m[i] * u[i];
86  }
87  }
88 
89  SPH_ASSERT(isReal(total));
90  return Float(total);
91 }
92 
94  : omega(0._f, 0._f, omega) {}
95 
97  double total = 0.;
98  ArrayView<const Vector> r, v, dv;
99  tie(r, v, dv) = storage.getAll<Vector>(QuantityId::POSITION);
101  for (Size i = 0; i < v.size(); ++i) {
102  SPH_ASSERT(!v.empty());
103  total += 0.5 * m[i] * getSqrLength(v[i]);
104  }
105  SPH_ASSERT(isReal(total));
106  return Float(total);
107 }
108 
110  double total = 0.;
111  if (!storage.has(QuantityId::ENERGY)) {
112  return total;
113  }
116  SPH_ASSERT(!m.empty());
117  for (Size i = 0; i < m.size(); ++i) {
118  total += double(m[i] * u[i]);
119  }
120  SPH_ASSERT(isReal(total));
121  return Float(total);
122 }
123 
125  : bodyId(bodyId) {}
126 
127 Vector CenterOfMass::evaluate(const Storage& storage) const {
128  Vector com(0._f);
129  Float totalMass = 0._f;
132  auto accumulate = [&](const Size i) {
133  totalMass += m[i];
134  com += m[i] * r[i];
135  };
136 
137  if (bodyId) {
139  for (Size i = 0; i < r.size(); ++i) {
140  if (ids[i] == bodyId.value()) {
141  accumulate(i);
142  }
143  }
144  } else {
145  for (Size i = 0; i < r.size(); ++i) {
146  accumulate(i);
147  }
148  }
149  return com / totalMass;
150 }
151 
153  : quantity(id)
154  , bodyId(bodyId) {}
155 
157  : quantity(std::move(func))
158  , bodyId(bodyId) {}
159 
161  MinMaxMean means;
162  auto accumulate = [&](const auto& getter) {
163  const Size size = storage.getParticleCnt();
164  if (bodyId) {
166  for (Size i = 0; i < size; ++i) {
167  if (ids[i] == bodyId.value()) {
168  means.accumulate(getter(i));
169  }
170  }
171  } else {
172  for (Size i = 0; i < size; ++i) {
173  means.accumulate(getter(i));
174  }
175  }
176  };
177  if (quantity.getTypeIdx() == 0) {
178  const QuantityId id = quantity.get<QuantityId>();
179  SPH_ASSERT(storage.has(id));
180  ArrayView<const Float> q = storage.getValue<Float>(id);
181  accumulate([&](const Size i) { return q[i]; });
182  } else {
183  SPH_ASSERT(quantity.getTypeIdx() == 1);
184  const AutoPtr<IUserQuantity>& func = quantity;
185  func->initialize(storage);
186  accumulate([&](const Size i) { return func->evaluate(i); });
187  }
188  return means;
189 }
190 
191 QuantityValue::QuantityValue(const QuantityId id, const Size particleIdx)
192  : id(id)
193  , idx(particleIdx) {}
194 
195 Float QuantityValue::evaluate(const Storage& storage) const {
196  ArrayView<const Float> values = storage.getValue<Float>(id);
197  return values[idx];
198 }
199 
Various function for interpretation of the results of a simulation.
INLINE bool isReal(const AntisymmetricTensor &t)
#define SPH_ASSERT(x,...)
Definition: Assert.h:94
NAMESPACE_SPH_BEGIN
Definition: BarnesHut.cpp:13
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
Integrals of motion and other integral quantities.
#define NAMESPACE_SPH_END
Definition: Object.h:12
QuantityId
Unique IDs of basic quantities of SPH particles.
Definition: QuantityIds.h:19
@ FLAG
ID of original body, used to implement discontinuities between bodies in SPH.
@ POSITION
Positions (velocities, accelerations) of particles, always a vector quantity,.
@ ENERGY
Specific internal energy, always a scalar 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.
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 bool empty() const
Definition: ArrayView.h:105
INLINE TCounter size() const
Definition: ArrayView.h:101
Wrapper of pointer that deletes the resource from destructor.
Definition: AutoPtr.h:15
specialization for doubles or units of double precision
Definition: Vector.h:371
virtual Vector evaluate(const Storage &storage) const override
Computes the integral quantity using particles in the storage.
Definition: Integrals.cpp:127
CenterOfMass(const Optional< Size > bodyId=NOTHING)
Definition: Integrals.cpp:124
Helper class for statistics, accumulating minimal, maximal and mean value of a set of numbers.
Definition: Means.h:172
INLINE void accumulate(const Float value)
Definition: Means.h:180
INLINE Type & value()
Returns the reference to the stored value.
Definition: Optional.h:172
QuantityMeans(const QuantityId id, const Optional< Size > bodyId=NOTHING)
Computes mean of quantity values.
Definition: Integrals.cpp:152
virtual MinMaxMean evaluate(const Storage &storage) const override
Computes the integral quantity using particles in the storage.
Definition: Integrals.cpp:160
QuantityValue(const QuantityId id, const Size particleIdx)
Definition: Integrals.cpp:191
virtual Float evaluate(const Storage &storage) const override
Computes the integral quantity using particles in the storage.
Definition: Integrals.cpp:195
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
Size getParticleCnt() const
Returns the number of particles.
Definition: Storage.cpp:445
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
virtual Vector evaluate(const Storage &storage) const override
Computes the integral quantity using particles in the storage.
Definition: Integrals.cpp:40
TotalAngularMomentum(const Float frameFrequency=0._f)
Definition: Integrals.cpp:37
virtual Float evaluate(const Storage &storage) const override
Computes the integral quantity using particles in the storage.
Definition: Integrals.cpp:69
TotalEnergy(const Float omega=0._f)
Definition: Integrals.cpp:66
virtual Float evaluate(const Storage &storage) const override
Computes the integral quantity using particles in the storage.
Definition: Integrals.cpp:109
virtual Float evaluate(const Storage &storage) const override
Computes the integral quantity using particles in the storage.
Definition: Integrals.cpp:96
TotalKineticEnergy(const Float omega=0._f)
Definition: Integrals.cpp:93
virtual Float evaluate(const Storage &storage) const override
Computes the integral quantity using particles in the storage.
Definition: Integrals.cpp:9
virtual Vector evaluate(const Storage &storage) const override
Computes the integral quantity using particles in the storage.
Definition: Integrals.cpp:24
TotalMomentum(const Float omega=0._f)
Definition: Integrals.cpp:20
INLINE Size getTypeIdx() const
Returns index of type currently stored in variant.
Definition: Variant.h:310
INLINE T & get()
Returns the stored value.
Definition: Variant.h:335
Creating code components based on values from settings.
Overload of std::swap for Sph::Array.
Definition: Array.h:578