SPH
ScriptUtils.cpp
Go to the documentation of this file.
1 #include "run/ScriptUtils.h"
2 
4 
5 #ifdef SPH_USE_CHAISCRIPT
6 
7 Chai::Particles::Particles(const Size particleCnt) {
8  Array<Vector> r(particleCnt);
9  r.fill(Vector(0._f, 0._f, 0._f, EPS));
10  storage = alignedNew<Storage>();
11  storage->insert<Vector>(QuantityId::POSITION, OrderEnum::SECOND, std::move(r));
12  owns = true;
13 
14  this->resize(particleCnt);
15 }
16 
17 Chai::Particles::~Particles() {
18  if (owns) {
19  alignedDelete(storage);
20  }
21 }
22 
23 void Chai::Particles::bindToStorage(Storage& input) {
24  if (owns) {
25  alignedDelete(storage);
26  }
27  storage = &input;
28  owns = false;
29  this->resize(storage->getParticleCnt());
30 
32  if (storage->has(QuantityId::POSITION)) {
33  ArrayView<const Vector> r, v, dv;
34  tie(r, v, dv) = storage->getAll<Vector>(QuantityId::POSITION);
35  std::copy(r.begin(), r.end(), positions.begin());
36  std::copy(v.begin(), v.end(), velocities.begin());
37  std::copy(dv.begin(), dv.end(), accelerations.begin());
38  for (Size i = 0; i < r.size(); ++i) {
39  radii[i] = r[i][H];
40  }
41  }
42 
43  if (storage->has(QuantityId::MASS)) {
44  ArrayView<const Float> m = storage->getValue<Float>(QuantityId::MASS);
45  std::copy(m.begin(), m.end(), masses.begin());
46  }
47 
48  if (storage->has(QuantityId::ENERGY)) {
49  ArrayView<const Float> u = storage->getValue<Float>(QuantityId::ENERGY);
50  std::copy(u.begin(), u.end(), energies.begin());
51  }
52 
53  if (storage->has(QuantityId::DENSITY)) {
54  ArrayView<const Float> rho = storage->getValue<Float>(QuantityId::DENSITY);
55  std::copy(rho.begin(), rho.end(), densities.begin());
56  }
57 }
58 
59 const Storage& Chai::Particles::store() const {
60  const Size N = positions.size();
61  Array<Vector> r(N), v(N), dv(N);
62  Array<Float> m(N), u(N), rho(N);
63  for (Size i = 0; i < N; ++i) {
64  r[i] = positions[i];
65  r[i][H] = radii[i];
66  v[i] = velocities[i];
67  dv[i] = accelerations[i];
68  m[i] = masses[i];
69  u[i] = energies[i];
70  rho[i] = densities[i];
71  }
72  storage->insert<Vector>(QuantityId::POSITION, OrderEnum::SECOND, std::move(r));
73  storage->getDt<Vector>(QuantityId::POSITION) = std::move(v);
74  storage->getD2t<Vector>(QuantityId::POSITION) = std::move(dv);
75  storage->insert<Float>(QuantityId::MASS, OrderEnum::ZERO, std::move(m));
76  storage->insert<Float>(QuantityId::ENERGY, OrderEnum::FIRST, std::move(u));
77  storage->insert<Float>(QuantityId::DENSITY, OrderEnum::FIRST, std::move(rho));
78  return *storage;
79 }
80 
81 Size Chai::Particles::getParticleCnt() const {
82  return storage->getParticleCnt();
83 }
84 
85 void Chai::Particles::resize(const Size particleCnt) {
86  positions.resize(particleCnt);
87  velocities.resize(particleCnt);
88  accelerations.resize(particleCnt);
89  masses.resize(particleCnt);
90  energies.resize(particleCnt);
91  densities.resize(particleCnt);
92  radii.resize(particleCnt);
93 }
94 
95 std::vector<Float>& Chai::Particles::getMasses() {
97  return masses;
98 }
99 
100 std::vector<Float>& Chai::Particles::getEnergies() {
102  return energies;
103 }
104 
105 std::vector<Float>& Chai::Particles::getDensities() {
107  return densities;
108 }
109 
110 std::vector<Float>& Chai::Particles::getRadii() {
111  return radii;
112 }
113 
114 std::vector<Chai::Vec3>& Chai::Particles::getPositions() {
115  return positions;
116 }
117 
118 std::vector<Chai::Vec3>& Chai::Particles::getVelocities() {
119  return velocities;
120 }
121 
122 std::vector<Chai::Vec3>& Chai::Particles::getAccelerations() {
123  return accelerations;
124 }
125 
126 Chai::Box3 Chai::Particles::getBoundingBox() const {
127  Box3 box;
128  for (Size i = 0; i < positions.size(); ++i) {
129  box.extend(positions[i]);
130  }
131  return box;
132 }
133 
134 Float Chai::Particles::getTotalMass() const {
135  return std::accumulate(masses.begin(), masses.end(), 0._f);
136 }
137 
138 Chai::Vec3 Chai::Particles::getCenterOfMass() const {
139  Vec3 r_com(0, 0, 0);
140  Float m = 0._f;
141  for (Size i = 0; i < positions.size(); ++i) {
142  r_com += positions[i] * masses[i];
143  m += masses[i];
144  }
145  return r_com / m;
146 }
147 
148 Chai::Vec3 Chai::Particles::getTotalMomentum() const {
149  Vec3 p(0, 0, 0);
150  for (Size i = 0; i < velocities.size(); ++i) {
151  p += velocities[i] * masses[i];
152  }
153  return p;
154 }
155 
156 Chai::Vec3 Chai::Particles::getTotalAngularMomentum() const {
157  const Vec3 r0 = this->getCenterOfMass();
158  Vec3 L(0, 0, 0);
159  for (Size i = 0; i < velocities.size(); ++i) {
160  L += cross(positions[i] - r0, velocities[i]) * masses[i];
161  }
162  return L;
163 }
164 
165 Chai::Vec3 Chai::Particles::getAngularFrequency() const {
166  Array<Vector> r(positions.size()), v(positions.size());
167  for (Size i = 0; i < r.size(); ++i) {
168  r[i] = positions[i];
169  v[i] = velocities[i];
170  }
171  return Post::getAngularFrequency(ArrayView<const Float>(masses.data(), masses.size()), r, v);
172 }
173 
174 void Chai::Particles::merge(Particles& other) {
175  storage->merge(std::move(*other.storage));
176 
177  positions.insert(positions.end(), other.positions.begin(), other.positions.end());
178  velocities.insert(velocities.end(), other.velocities.begin(), other.velocities.end());
179  masses.insert(masses.end(), other.masses.begin(), other.masses.end());
180  energies.insert(energies.end(), other.energies.begin(), other.energies.end());
181  densities.insert(densities.end(), other.densities.begin(), other.densities.end());
182  radii.insert(radii.end(), other.radii.begin(), other.radii.end());
183 }
184 
185 void Chai::registerBindings(chaiscript::ChaiScript& chai) {
186  // math functions
187  chai.add(chaiscript::fun(&Sph::sqr<double>), "sqr");
188  chai.add(chaiscript::fun(&Sph::sqrt<double>), "sqrt");
189  chai.add(chaiscript::fun(&Sph::cos<double>), "cos");
190  chai.add(chaiscript::fun(&Sph::sin<double>), "sin");
191  chai.add(chaiscript::fun(&Sph::lerp<double, double>), "lerp");
192  chai.add(chaiscript::fun(&Sph::abs<double>), "abs");
193  chai.add(chaiscript::fun(&Sph::pow<double>), "pow");
194 
195  // vector utils
196  chai.add(chaiscript::user_type<Vec3>(), "Vec3");
197  chai.add(chaiscript::constructor<Vec3()>(), "Vec3");
198  chai.add(chaiscript::constructor<Vec3(const Vec3&)>(), "Vec3");
199  chai.add(chaiscript::constructor<Vec3(Float, Float, Float)>(), "Vec3");
200  chai.add(chaiscript::fun(&Vec3::x), "x");
201  chai.add(chaiscript::fun(&Vec3::y), "y");
202  chai.add(chaiscript::fun(&Vec3::z), "z");
203  chai.add(chaiscript::fun(&Vec3::operator+), "+");
204  chai.add(chaiscript::fun(&Vec3::operator-), "-");
205  chai.add(chaiscript::fun(&Vec3::operator*), "*");
206  chai.add(chaiscript::fun(&Vec3::operator/), "/");
207  chai.add(chaiscript::fun(&Vec3::operator=), "=");
208  chai.add(chaiscript::fun(&Vec3::operator+=), "+=");
209  chai.add(chaiscript::fun(&dot), "dotProd");
210  chai.add(chaiscript::fun(&cross), "crossProd");
211  chai.add(chaiscript::fun(&length), "length");
212  chai.add(chaiscript::fun(&max), "max");
213  chai.add(chaiscript::fun(&min), "min");
214  chai.add(chaiscript::fun(&normalized), "normalized");
215 
216  // box utils
217  chai.add(chaiscript::user_type<Box3>(), "Box3");
218  chai.add(chaiscript::constructor<Box3()>(), "Box3");
219  chai.add(chaiscript::constructor<Box3(const Box3&)>(), "Box3");
220  chai.add(chaiscript::constructor<Box3(const Vec3&, const Vec3&)>(), "Box3");
221  chai.add(chaiscript::fun(&Box3::operator=), "=");
222  chai.add(chaiscript::fun(&Box3::size), "size");
223  chai.add(chaiscript::fun(&Box3::extend), "extend");
224 
225  // particle quantities
226  chai.add(chaiscript::user_type<Particles>(), "Particles");
227  chai.add(chaiscript::constructor<Particles(Size)>(), "Particles");
228  chai.add(chaiscript::fun(&Particles::getParticleCnt), "getParticleCnt");
229  chai.add(chaiscript::fun(&Particles::getMasses), "getMasses");
230  chai.add(chaiscript::fun(&Particles::getEnergies), "getEnergies");
231  chai.add(chaiscript::fun(&Particles::getDensities), "getDensities");
232  chai.add(chaiscript::fun(&Particles::getPositions), "getPositions");
233  chai.add(chaiscript::fun(&Particles::getVelocities), "getVelocities");
234  chai.add(chaiscript::fun(&Particles::getAccelerations), "getAccelerations");
235  chai.add(chaiscript::fun(&Particles::getRadii), "getRadii");
236  chai.add(chaiscript::fun(&Particles::merge), "merge");
237  chai.add(chaiscript::fun(&Particles::getBoundingBox), "getBoundingBox");
238  chai.add(chaiscript::fun(&Particles::getCenterOfMass), "getCenterOfMass");
239  chai.add(chaiscript::fun(&Particles::getTotalMass), "getTotalMass");
240  chai.add(chaiscript::fun(&Particles::getTotalMomentum), "getTotalMomentum");
241  chai.add(chaiscript::fun(&Particles::getTotalAngularMomentum), "getTotalAngularMomentum");
242  chai.add(chaiscript::fun(&Particles::getAngularFrequency), "getAngularFrequency");
243 
244  // allow using float and vector std::vector's
245  chai.add(chaiscript::bootstrap::standard_library::vector_type<std::vector<Float>>("VectorFloat"));
246  chai.add(chaiscript::bootstrap::standard_library::vector_type<std::vector<Vec3>>("VectorVec3"));
247 
248  // auxiliary constants
249  chai.add_global_const(chaiscript::const_var(DEG_TO_RAD), "DEG_TO_RAD");
250  chai.add_global_const(chaiscript::const_var(RAD_TO_DEG), "RAD_TO_DEG");
251  chai.add_global_const(chaiscript::const_var(Constants::M_earth), "M_earth");
252  chai.add_global_const(chaiscript::const_var(Constants::M_sun), "M_sun");
253  chai.add_global_const(chaiscript::const_var(Constants::gravity), "G");
254 }
255 
256 #endif
257 
INLINE void alignedDelete(T *ptr)
Deletes an object previously allocated using alignedNew.
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
constexpr INLINE T max(const T &f1, const T &f2)
Definition: MathBasic.h:20
NAMESPACE_SPH_BEGIN constexpr INLINE T min(const T &f1, const T &f2)
Minimum & Maximum value.
Definition: MathBasic.h:15
constexpr Float EPS
Definition: MathUtils.h:30
constexpr Float DEG_TO_RAD
Definition: MathUtils.h:369
constexpr Float RAD_TO_DEG
Definition: MathUtils.h:371
#define NAMESPACE_SPH_END
Definition: Object.h:12
@ POSITION
Positions (velocities, accelerations) of particles, always a vector quantity,.
@ ENERGY
Specific internal energy, always a scalar quantity.
@ DENSITY
Density, always a scalar quantity.
@ MASS
Paricles masses, always a scalar quantity.
@ SECOND
Quantity with 1st and 2nd derivative.
@ FIRST
Quantity with 1st derivative.
@ ZERO
Quantity without derivatives, or "zero order" of quantity.
Utility functions and classes exposed to the embedded scripting language.
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
Box getBoundingBox(const Storage &storage, const Float radius)
Convenience function to get the bounding box of all particles.
Definition: Storage.cpp:832
constexpr int N
INLINE BasicVector< float > cross(const BasicVector< float > &v1, const BasicVector< float > &v2)
Cross product between two vectors.
Definition: Vector.h:559
BasicVector< Float > Vector
Definition: Vector.h:539
@ H
Definition: Vector.h:25
Object providing safe access to continuous memory of data.
Definition: ArrayView.h:17
INLINE TCounter size() const
Definition: ArrayView.h:101
INLINE Iterator< StorageType > begin()
Definition: ArrayView.h:55
INLINE Iterator< StorageType > end()
Definition: ArrayView.h:63
Generic dynamically allocated resizable storage.
Definition: Array.h:43
INLINE void extend(const Vector &v)
Enlarges the box to contain the vector.
Definition: Box.h:49
Container storing all quantities used within the simulations.
Definition: Storage.h:230
constexpr Float gravity
Gravitational constant (CODATA 2014)
Definition: Constants.h:29
constexpr Float M_earth
Earth mass.
Definition: Constants.h:54
constexpr Float M_sun
Definition: Constants.h:51
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.
Definition: Analysis.cpp:514
Vector getCenterOfMass(ArrayView< const Float > m, ArrayView< const Vector > r, ArrayView< const Size > idxs=nullptr)
Computes the center of mass.
Definition: Analysis.cpp:461