SPH
Boundary.cpp
Go to the documentation of this file.
5 #include "quantities/IMaterial.h"
6 #include "quantities/Iterate.h"
8 #include "sph/kernel/Kernel.h"
9 #include "system/Factory.h"
10 #include "thread/Scheduler.h"
11 #include "timestepping/ISolver.h"
12 
14 
15 //-----------------------------------------------------------------------------------------------------------
16 // GhostParticles implementation
17 //-----------------------------------------------------------------------------------------------------------
18 
19 GhostParticles::GhostParticles(SharedPtr<IDomain> domain, const Float searchRadius, const Float minimalDist)
20  : domain(std::move(domain)) {
21  SPH_ASSERT(this->domain);
22  params.searchRadius = searchRadius;
23  params.minimalDist = minimalDist;
24 }
25 
27  : domain(std::move(domain)) {
28  SPH_ASSERT(this->domain);
29  params.searchRadius = Factory::getKernel<3>(settings).radius();
30  params.minimalDist = settings.get<Float>(RunSettingsId::DOMAIN_GHOST_MIN_DIST);
31 }
32 
34  // note that there is no need to also add particles to dependent storages as we remove ghosts in
35  // finalization; however, it might cause problems when there is another BC or equation that DOES need to
36  // propagate to dependents. So far no such thing is used, but it would have to be done carefully in case
37  // multiple objects add or remove particles from the storage.
38 
39  storage.setUserData(nullptr); // clear previous data
40 
41  SPH_ASSERT(ghosts.empty() && ghostIdxs.empty());
42 
43  // project particles outside of the domain on the boundary
45  domain->project(r);
46 
47  // find particles close to boundary and create necessary ghosts
48  domain->addGhosts(r, ghosts, params.searchRadius, params.minimalDist);
49 
50  // extract the indices for duplication
51  Array<Size> idxs;
52  for (Ghost& g : ghosts) {
53  idxs.push(g.index);
54  }
55  // duplicate all particles that create ghosts to make sure we have correct materials in the storage
56  ghostIdxs = storage.duplicate(idxs);
57 
58  // set correct positions of ghosts
59  SPH_ASSERT(ghostIdxs.size() == ghosts.size());
60  for (Size i = 0; i < ghosts.size(); ++i) {
61  const Size ghostIdx = ghostIdxs[i];
62  r[ghostIdx] = ghosts[i].position;
63  }
64 
65  // reflect velocities (only if we have velocities, GP are also used in Diehl's distribution, for example)
68  for (Size i = 0; i < ghosts.size(); ++i) {
69  const Size ghostIdx = ghostIdxs[i];
70  // offset between particle and its ghost
71  const Vector deltaR = r[ghosts[i].index] - ghosts[i].position;
72  SPH_ASSERT(getLength(deltaR) > 0._f);
73  const Vector normal = getNormalized(deltaR);
74  const Float perp = dot(normal, v[ghosts[i].index]);
75  // mirror vector by copying parallel component and inverting perpendicular component
76  const Vector v0 = v[ghostIdx] - 2._f * normal * perp;
77  if (ghostVelocity) {
78  v[ghostIdx] = ghostVelocity(ghosts[i].position).valueOr(v0);
79  } else {
80  v[ghostIdx] = v0;
81  }
82  SPH_ASSERT(getLength(v[ghostIdx]) < 1.e50_f);
83  }
84  }
85 
86  // set flag to some special value to separate the bodies
87  if (storage.has(QuantityId::FLAG)) {
89  for (Size i = 0; i < ghosts.size(); ++i) {
90  const Size ghostIdx = ghostIdxs[i];
91  flag[ghostIdx] = FLAG;
92  }
93  }
94 
95  SPH_ASSERT(storage.isValid());
96 
97  particleCnt = storage.getParticleCnt();
98 }
99 
101  ghostVelocity = newGhostVelocity;
102 }
103 
105  SPH_ASSERT(storage.getParticleCnt() == particleCnt,
106  "Solver changed the number of particles. This is currently not consistent with the implementation of "
107  "GhostParticles");
108 
109  // remove ghosts by indices
110  storage.remove(ghostIdxs);
111  ghostIdxs.clear();
112 
113  storage.setUserData(makeShared<GhostParticlesData>(std::move(ghosts)));
114 }
115 
116 //-----------------------------------------------------------------------------------------------------------
117 // FixedParticles implementation
118 //-----------------------------------------------------------------------------------------------------------
119 
121  : fixedParticles(std::move(params.material)) {
122  SPH_ASSERT(isReal(params.thickness));
123  Box box = params.domain->getBoundingBox();
124  box.extend(box.lower() - Vector(params.thickness));
125  box.extend(box.upper() + Vector(params.thickness));
126 
127  // We need to fill a layer close to the boundary with dummy particles. IDomain interface does not provide
128  // a way to construct enlarged domain, so we need a more general approach - construct a block domain using
129  // the bounding box, fill it with particles, and then remove all particles that are inside the original
130  // domain or too far from the boundary. This may be inefficient for some obscure domain, but otherwise it
131  // works fine.
132  BlockDomain boundingDomain(box.center(), box.size());
134  const Size n = Size(box.volume() / pow<3>(0.5_f * params.thickness));
135  Array<Vector> dummies = params.distribution->generate(SEQUENTIAL, n, boundingDomain);
136  // remove all particles inside the actual domain or too far away
137  /*Array<Float> distances;
138  params.domain->getDistanceToBoundary(dummies, distances);*/
139  for (Size i = 0; i < dummies.size();) {
140  if (params.domain->contains(dummies[i])) {
141  // if (distances[i] >= 0._f || distances[i] < -params.thickness) {
142  dummies.remove(i);
143  } else {
144  ++i;
145  }
146  }
147  // although we never use the derivatives, the second order is needed to properly merge the storages
148  fixedParticles.insert<Vector>(QuantityId::POSITION, OrderEnum::SECOND, std::move(dummies));
149 
150  // create all quantities
151  MaterialView mat = fixedParticles.getMaterial(0);
152  const Float rho0 = mat->getParam<Float>(BodySettingsId::DENSITY);
153  const Float m0 = rho0 * box.volume() / fixedParticles.getParticleCnt();
154  fixedParticles.insert<Float>(QuantityId::MASS, OrderEnum::ZERO, m0);
155  // use negative flag to separate the dummy particles from the real ones
156  fixedParticles.insert<Size>(QuantityId::FLAG, OrderEnum::ZERO, Size(-1));
157 
158  AutoPtr<ISolver> solver = Factory::getSolver(SEQUENTIAL, settings);
159  solver->create(fixedParticles, mat);
160  MaterialInitialContext context(settings);
161  mat->create(fixedParticles, context);
162 }
163 
165  // add all fixed particles into the storage
166  storage.merge(fixedParticles.clone(VisitorEnum::ALL_BUFFERS));
167  SPH_ASSERT(storage.isValid());
169  storage.getValue<Vector>(QuantityId::POSITION).size());
170 }
171 
173  // remove all fixed particles (particles with flag -1) from the storage
175  Array<Size> toRemove;
176  for (Size i = 0; i < flag.size(); ++i) {
177  if (flag[i] == Size(-1)) {
178  toRemove.push(i);
179  }
180  }
181 
182  storage.remove(toRemove, Storage::IndicesFlag::INDICES_SORTED);
183  SPH_ASSERT(storage.isValid());
184 }
185 
186 //-----------------------------------------------------------------------------------------------------------
187 // FrozenParticles implementation
188 //-----------------------------------------------------------------------------------------------------------
189 
191 
193 
195  : domain(std::move(domain))
196  , radius(radius) {}
197 
199 void FrozenParticles::freeze(const Size flag) {
200  frozen.insert(flag);
201 }
202 
204 void FrozenParticles::thaw(const Size flag) {
205  frozen.erase(flag);
206 }
207 
209  ArrayView<Vector> r, v, dv;
210  tie(r, v, dv) = storage.getAll<Vector>(QuantityId::POSITION);
211 
212  idxs.clear();
213  if (domain) {
214  // project particles outside of the domain onto the boundary
216  domain->project(r, idxs.view());
217 
218  // freeze particles close to the boundary
220  for (Size i = 0; i < r.size(); ++i) {
221  SPH_ASSERT(distances[i] >= -EPS);
222  if (distances[i] < radius * r[i][H]) {
223  idxs.push(i);
224  }
225  }
226  }
227 
228  if (!frozen.empty()) {
229  // find all frozen particles by their body flag
230  ArrayView<Size> flags = storage.getValue<Size>(QuantityId::FLAG);
231  for (Size i = 0; i < r.size(); ++i) {
232  if (frozen.find(flags[i]) != frozen.end()) {
233  idxs.push(i); // this might add particles already frozen by boundary, but it doesn't matter
234  }
235  }
236  }
237 
238  // set all highest derivatives of flagged particles to zero
239  iterate<VisitorEnum::HIGHEST_DERIVATIVES>(storage, [this](QuantityId, auto& d2f) {
240  using T = typename std::decay_t<decltype(d2f)>::Type;
241  for (Size i : idxs) {
242  d2f[i] = T(0._f);
243  }
244  });
245 }
246 
247 //-----------------------------------------------------------------------------------------------------------
248 // WindTunnel implementation
249 //-----------------------------------------------------------------------------------------------------------
250 
252  : FrozenParticles(std::move(domain), radius) {}
253 
255  // clear derivatives of particles close to boundary
256  FrozenParticles::finalize(storage);
257 
258  // remove particles outside of the domain
259  Array<Size> toRemove;
261  for (Size i = 0; i < r.size(); ++i) {
262  if (!this->domain->contains(r[i])) {
263  toRemove.push(i);
264  }
265  }
266  iterate<VisitorEnum::ALL_BUFFERS>(storage, [&toRemove](auto& v) { v.remove(toRemove); });
267 
268  // find z positions of upper two layers of particles
269  /* Float z1 = -INFTY, z2 = -INFTY;
270  for (Size i = 0; i < r.size(); ++i) {
271  if (r[i][Z] > z1) {
272  z2 = z1;
273  z1 = r[i][Z];
274  }
275  }
276  SPH_ASSERT(z2 > -INFTY && z1 > z2 + 0.1_f * r[0][H]);
277  const Float dz = z1 - z2;
278  if (z1 + 2._f * dz < this->domain->getBoundingBox().upper()[Z]) {
279  // find indices of upper two layers
280  Array<Size> idxs;
281  const Size size = r.size();
282  for (Size i = 0; i < size; ++i) {
283  if (r[i][Z] >= z2) {
284  idxs.push(i);
285  }
286  }
287  SPH_ASSERT(!idxs.empty());
288  // copy all quantities
289  iterate<VisitorEnum::ALL_BUFFERS>(storage, [&idxs](auto& v) {
290  for (Size i : idxs) {
291  auto cloned = v[i];
292  v.push(cloned);
293  }
294  });
295  // move created particles by 2dz
296  const Vector offset(0._f, 0._f, 2._f * dz);
297  for (Size i = size; i < r.size(); ++i) {
298  r[i] += offset;
299  }
300  }*/
301  SPH_ASSERT(storage.isValid());
302 }
303 
304 //-----------------------------------------------------------------------------------------------------------
305 // PeriodicBoundary implementation
306 //-----------------------------------------------------------------------------------------------------------
307 
309  : domain(domain) {}
310 
311 static const StaticArray<Vector, 3> UNIT = {
312  Vector(1._f, 0._f, 0._f),
313  Vector(0._f, 1._f, 0._f),
314  Vector(0._f, 0._f, 1._f),
315 };
316 
318  storage.setUserData(nullptr); // clear previous data
319  SPH_ASSERT(ghostIdxs.empty() && ghosts.empty());
320 
321  Array<Size> duplIdxs;
323  const Float radius = 2._f;
324 
325  for (Size i = 0; i < r.size(); ++i) {
326  // move particles outside of the domain to the other side
327  const Vector lowerFlags(int(r[i][X] < domain.lower()[X]),
328  int(r[i][Y] < domain.lower()[Y]),
329  int(r[i][Z] < domain.lower()[Z]));
330  const Vector upperFlags(int(r[i][X] > domain.upper()[X]),
331  int(r[i][Y] > domain.upper()[Y]),
332  int(r[i][Z] > domain.upper()[Z]));
333 
334  const Float h = r[i][H]; // backup for safety
335  r[i] += domain.size() * (lowerFlags - upperFlags);
336  r[i][H] = h;
337 
338  // for particles close to the boundary, add ghosts
339  for (Size j = 0; j < 3; ++j) {
340  if (r[i][j] < domain.lower()[j] + radius * r[i][H]) {
341  duplIdxs.push(i);
342  ghosts.push(Ghost{ r[i] + domain.size()[j] * UNIT[j], i });
343  }
344  if (r[i][j] > domain.upper()[j] - radius * r[i][H]) {
345  duplIdxs.push(i);
346  ghosts.push(Ghost{ r[i] - domain.size()[j] * UNIT[j], i });
347  }
348  }
349  }
350 
351  ghostIdxs = storage.duplicate(duplIdxs);
352  SPH_ASSERT(ghostIdxs.size() == duplIdxs.size());
353 
354  for (Size i = 0; i < ghostIdxs.size(); ++i) {
355  r[ghostIdxs[i]] = ghosts[i].position;
356  r[ghostIdxs[i]][H] = r[ghosts[i].index][H];
357  }
358 
359  // set flag to some special value to separate the bodies
360  if (storage.has(QuantityId::FLAG)) {
362  for (Size i = 0; i < ghosts.size(); ++i) {
363  flag[ghostIdxs[i]] = Size(-1);
364  }
365  }
366 }
367 
369  storage.remove(ghostIdxs);
370  ghostIdxs.clear();
371 
372  storage.setUserData(makeShared<GhostParticlesData>(std::move(ghosts)));
373 }
374 
375 //-----------------------------------------------------------------------------------------------------------
376 // SymmetricBoundary implementation
377 //-----------------------------------------------------------------------------------------------------------
378 
380  storage.setUserData(nullptr); // clear previous data
381  SPH_ASSERT(ghostIdxs.empty() && ghosts.empty());
382 
383  Array<Size> duplIdxs;
385  const Float radius = 2._f;
386 
387  for (Size i = 0; i < r.size(); ++i) {
388  if (r[i][Z] < 0._f) {
389  r[i][Z] = 0.1_f * r[i][H];
390  }
391 
392  // for particles close to the boundary, add ghosts
393  for (Size j = 0; j < 3; ++j) {
394  if (r[i][Z] < radius * r[i][H]) {
395  duplIdxs.push(i);
396  ghosts.push(Ghost{ r[i] - Vector(0, 0, 2._f * r[i][Z]), i });
397  }
398  }
399  }
400 
401  ghostIdxs = storage.duplicate(duplIdxs);
402  SPH_ASSERT(ghostIdxs.size() == duplIdxs.size());
403 
404  for (Size i = 0; i < ghostIdxs.size(); ++i) {
405  r[ghostIdxs[i]] = ghosts[i].position;
406  }
407 }
408 
410  storage.remove(ghostIdxs);
411  ghostIdxs.clear();
412 
413  storage.setUserData(makeShared<GhostParticlesData>(std::move(ghosts)));
414 }
415 
416 //-----------------------------------------------------------------------------------------------------------
417 // KillEscapersBoundary implementation
418 //-----------------------------------------------------------------------------------------------------------
419 
421  : domain(domain) {}
422 
425  Array<Size> toRemove;
426  for (Size i = 0; i < r.size(); ++i) {
427  if (!domain->contains(r[i])) {
428  toRemove.push(i);
429  }
430  }
431  storage.remove(toRemove, Storage::IndicesFlag::INDICES_SORTED);
432 }
433 
435 
436 //-----------------------------------------------------------------------------------------------------------
437 // Projection1D implementation
438 //----------------------------------------------------------------------------------------------------------
439 
441  : domain(domain) {}
442 
445  tie(r, v, dv) = storage.getAll<Vector>(QuantityId::POSITION);
446  for (Size i = 0; i < r.size(); ++i) {
447  // throw away y and z, keep h
448  r[i] = Vector(domain.clamp(r[i][0]), 0._f, 0._f, r[i][H]);
449  v[i] = Vector(v[i][0], 0._f, 0._f);
450  }
451  // To get fixed boundary conditions at ends, we need to null all derivatives of first few and last few
452  // particles. Number of particles depends on smoothing length.
453  iterate<VisitorEnum::FIRST_ORDER>(storage, [](const QuantityId UNUSED(id), auto&& UNUSED(v), auto&& dv) {
454  using Type = typename std::decay_t<decltype(dv)>::Type;
455  const Size s = dv.size();
456  for (Size i : { 0u, 1u, 2u, 3u, 4u, s - 4, s - 3, s - 2, s - 1 }) {
457  dv[i] = Type(0._f);
458  }
459  });
460  iterate<VisitorEnum::SECOND_ORDER>(
461  storage, [](const QuantityId UNUSED(id), auto&& UNUSED(v), auto&& dv, auto&& d2v) {
462  using Type = typename std::decay_t<decltype(dv)>::Type;
463  const Size s = dv.size();
464  for (Size i : { 0u, 1u, 2u, 3u, 4u, s - 4, s - 3, s - 2, s - 1 }) {
465  dv[i] = Type(0._f);
466  d2v[i] = Type(0._f);
467  }
468  });
469 }
470 
INLINE bool isReal(const AntisymmetricTensor &t)
#define SPH_ASSERT(x,...)
Definition: Assert.h:94
NAMESPACE_SPH_BEGIN
Definition: BarnesHut.cpp:13
Boundary conditions.
const float radius
Definition: CurveDialog.cpp:18
Filling spatial domain with SPH particles.
Object defining computational domain.
@ OUTSIDE
Marks all vectors outside of the domain.
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
Base class for all particle materials.
Base interface for all solvers.
Functions for iterating over individual quantities in Storage.
Ordinary iterator for custom containers.
SPH kernels.
constexpr Float EPS
Definition: MathUtils.h:30
constexpr INLINE Float pow< 3 >(const Float v)
Definition: MathUtils.h:132
#define UNUSED(x)
Definition: Object.h:37
#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.
@ DEVIATORIC_STRESS
Deviatoric stress tensor, always a traceless tensor.
@ POSITION
Positions (velocities, accelerations) of particles, always a vector quantity,.
@ MASS
Paricles masses, always a scalar quantity.
@ SECOND
Quantity with 1st and 2nd derivative.
@ ZERO
Quantity without derivatives, or "zero order" of quantity.
SequentialScheduler SEQUENTIAL
Global instance of the sequential scheduler.
Definition: Scheduler.cpp:43
Interface for executing tasks (potentially) asynchronously.
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
INLINE Float getLength(const Vector &v)
Returns the length of the vector. Enabled only for vectors of floating-point precision.
Definition: Vector.h:579
BasicVector< Float > Vector
Definition: Vector.h:539
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
@ Y
Definition: Vector.h:23
@ X
Definition: Vector.h:22
@ Z
Definition: Vector.h:24
INLINE TCounter size() const
Definition: ArrayView.h:101
Generic dynamically allocated resizable storage.
Definition: Array.h:43
INLINE void push(U &&u)
Adds new element to the end of the array, resizing the array if necessary.
Definition: Array.h:306
void remove(const TCounter idx)
Removes an element with given index from the array.
Definition: Array.h:383
ArrayView< T, TCounter > view() noexcept
Explicit conversion to arrayview.
Definition: Array.h:495
void clear()
Removes all elements from the array, but does NOT release the memory.
Definition: Array.h:434
INLINE TCounter size() const noexcept
Definition: Array.h:193
INLINE bool empty() const noexcept
Definition: Array.h:201
Block aligned with coordinate axes, defined by its center and length of each side.
Definition: Domain.h:185
Helper object defining three-dimensional interval (box).
Definition: Box.h:17
INLINE void extend(const Vector &v)
Enlarges the box to contain the vector.
Definition: Box.h:49
INLINE const Vector & lower() const
Returns lower bounds of the box.
Definition: Box.h:82
INLINE const Vector & upper() const
Returns upper bounds of the box.
Definition: Box.h:94
INLINE Vector center() const
Returns the center of the box.
Definition: Box.h:112
INLINE Vector size() const
Returns box dimensions.
Definition: Box.h:106
INLINE Float volume() const
Returns the volume of the box.
Definition: Box.h:118
FixedParticles(const RunSettings &settings, Params &&params)
Definition: Boundary.cpp:120
virtual void finalize(Storage &storage) override
Applies the boundary conditions after the derivatives are computed.
Definition: Boundary.cpp:172
virtual void initialize(Storage &storage) override
Applies the boundary conditions before the derivatives are computed.
Definition: Boundary.cpp:164
Boundary condition that nulls all highest derivates of selected particles.
Definition: Boundary.h:160
void freeze(const Size flag)
Adds body ID particles of which shall be frozen by boundary conditions.
Definition: Boundary.cpp:199
std::set< Size > frozen
Definition: Boundary.h:165
Array< Size > idxs
Definition: Boundary.h:168
FrozenParticles()
Constructs boundary conditions with no particles frozen.
SharedPtr< IDomain > domain
Definition: Boundary.h:162
void thaw(const Size flag)
Remove a body from the list of frozen bodies.
Definition: Boundary.cpp:204
Array< Float > distances
Definition: Boundary.h:167
virtual void finalize(Storage &storage) override
Applies the boundary conditions after the derivatives are computed.
Definition: Boundary.cpp:208
virtual void finalize(Storage &storage) override
Applies the boundary conditions after the derivatives are computed.
Definition: Boundary.cpp:104
virtual void initialize(Storage &storage) override
Applies the boundary conditions before the derivatives are computed.
Definition: Boundary.cpp:33
Float minimalDist
Definition: Boundary.h:84
GhostParticles(SharedPtr< IDomain > domain, const Float searchRadius, const Float minimalDist)
Creates new boundary conditions.
Definition: Boundary.cpp:19
void setVelocityOverride(Function< Optional< Vector >(const Vector &r)> ghostVelocity)
Specifies a functor that overrides the default velocity assinged to each ghost.
Definition: Boundary.cpp:100
Float searchRadius
Definition: Boundary.h:83
static constexpr Size FLAG
Special flag denoting ghost particles.
Definition: Boundary.h:74
virtual void getSubset(ArrayView< const Vector > vs, Array< Size > &output, const SubsetType type) const =0
Returns an array of indices, marking vectors with given property by their index.
virtual void getDistanceToBoundary(ArrayView< const Vector > vs, Array< Float > &distances) const =0
Returns distances of particles lying close to the boundary.
virtual void project(ArrayView< Vector > vs, Optional< ArrayView< Size >> indices=NOTHING) const =0
Projects vectors outside of the domain onto its boundary.
virtual void addGhosts(ArrayView< const Vector > vs, Array< Ghost > &ghosts, const Float eta=2._f, const Float eps=0.05_f) const =0
Duplicates positions located close to the boundary, placing copies ("ghosts") symmetrically to the ot...
virtual bool contains(const Vector &v) const =0
Checks if the given point lies inside the domain.
Object representing a 1D interval of real numbers.
Definition: Interval.h:17
INLINE Float clamp(const Float &value) const
Clamps the given value by the interval.
Definition: Interval.h:68
KillEscapersBoundary(SharedPtr< IDomain > domain)
Definition: Boundary.cpp:420
virtual void initialize(Storage &storage) override
Applies the boundary conditions before the derivatives are computed.
Definition: Boundary.cpp:423
virtual void finalize(Storage &storage) override
Applies the boundary conditions after the derivatives are computed.
Definition: Boundary.cpp:434
Non-owning wrapper of a material and particles with this material.
Definition: IMaterial.h:30
Wrapper of type value of which may or may not be present.
Definition: Optional.h:23
PeriodicBoundary(const Box &domain)
Definition: Boundary.cpp:308
virtual void initialize(Storage &storage) override
Applies the boundary conditions before the derivatives are computed.
Definition: Boundary.cpp:317
virtual void finalize(Storage &storage) override
Applies the boundary conditions after the derivatives are computed.
Definition: Boundary.cpp:368
Projection1D(const Interval &domain)
Constructs using range as 1D domain.
Definition: Boundary.cpp:440
virtual void finalize(Storage &storage) override
Applies the boundary conditions after the derivatives are computed.
Definition: Boundary.cpp:443
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
Array with fixed number of allocated elements.
Definition: StaticArray.h:19
Container storing all quantities used within the simulations.
Definition: Storage.h:230
void merge(Storage &&other)
Merges another storage into this object.
Definition: Storage.cpp:472
Outcome isValid(const Flags< ValidFlag > flags=ValidFlag::COMPLETE) const
Checks whether the storage is in valid state.
Definition: Storage.cpp:609
Quantity & insert(const QuantityId key, const OrderEnum order, const TValue &defaultValue)
Creates a quantity in the storage, given its key, value type and order.
Definition: Storage.cpp:270
StaticArray< Array< TValue > &, 3 > getAll(const QuantityId key)
Retrieves quantity buffers from the storage, given its key and value type.
Definition: Storage.cpp:163
Array< TValue > & getDt(const QuantityId key)
Retrieves a quantity derivative from the storage, given its key and value type.
Definition: Storage.cpp:217
void setUserData(SharedPtr< IStorageUserData > newData)
Stores new user data into the storage.
Definition: Storage.cpp:824
Size getParticleCnt() const
Returns the number of particles.
Definition: Storage.cpp:445
Array< Size > duplicate(ArrayView< const Size > idxs, const Flags< IndicesFlag > flags=EMPTY_FLAGS)
Duplicates some particles in the storage.
Definition: Storage.cpp:674
@ INDICES_SORTED
Use if the given array is already sorted (optimization)
void remove(ArrayView< const Size > idxs, const Flags< IndicesFlag > flags=EMPTY_FLAGS)
Removes specified particles from the storage.
Definition: Storage.cpp:756
MaterialView getMaterial(const Size matIdx) const
Returns an object containing a reference to given material.
Definition: Storage.cpp:366
bool has(const QuantityId key) const
Checks if the storage contains quantity with given key.
Definition: Storage.cpp:130
Storage clone(const Flags< VisitorEnum > buffers) const
Clones specified buffers of the storage.
Definition: Storage.cpp:563
Array< TValue > & getValue(const QuantityId key)
Retrieves a quantity values from the storage, given its key and value type.
Definition: Storage.cpp:191
virtual void initialize(Storage &storage) override
Applies the boundary conditions before the derivatives are computed.
Definition: Boundary.cpp:379
virtual void finalize(Storage &storage) override
Applies the boundary conditions after the derivatives are computed.
Definition: Boundary.cpp:409
Symmetric traceless 2nd order tensor.
WindTunnel(SharedPtr< IDomain > domain, const Float radius)
Definition: Boundary.cpp:251
virtual void finalize(Storage &storage) override
Applies the boundary conditions after the derivatives are computed.
Definition: Boundary.cpp:254
Creating code components based on values from settings.
@ DENSITY
Density at zero pressure.
@ DOMAIN_GHOST_MIN_DIST
Minimal distance between a particle and its ghost, in units of smoothing length.
AutoPtr< ISolver > getSolver(IScheduler &scheduler, const RunSettings &settings)
Definition: Factory.cpp:278
Vector position(const Float a, const Float e, const Float u)
Computes the position on the elliptic trajectory.
Definition: TwoBody.cpp:82
Overload of std::swap for Sph::Array.
Definition: Array.h:578
Definition: Domain.h:22
Shared data used when creating all bodies in the simulation.
Definition: IMaterial.h:89