SPH
Domain.cpp
Go to the documentation of this file.
2 #include "objects/Exceptions.h"
3 
5 
6 //-----------------------------------------------------------------------------------------------------------
7 // SphericalDomain implementation
8 //-----------------------------------------------------------------------------------------------------------
9 
11  : center(center)
12  , radius(radius) {}
13 
15  return center;
16 }
17 
19  return sphereVolume(radius);
20 }
21 
23  return sphereSurfaceArea(radius);
24 }
25 
27  const Vector r(radius);
28  return Box(this->center - r, this->center + r);
29 }
30 
31 bool SphericalDomain::contains(const Vector& v) const {
32  return isInsideImpl(v);
33 }
34 
36  Array<Size>& output,
37  const SubsetType type) const {
38  switch (type) {
40  for (Size i = 0; i < vs.size(); ++i) {
41  if (!isInsideImpl(vs[i])) {
42  output.push(i);
43  }
44  }
45  break;
46  case SubsetType::INSIDE:
47  for (Size i = 0; i < vs.size(); ++i) {
48  if (isInsideImpl(vs[i])) {
49  output.push(i);
50  }
51  }
52  break;
53  default:
55  }
56 }
57 
59  distances.clear();
60  for (const Vector& v : vs) {
61  const Float dist = radius - getLength(v - this->center);
62  distances.push(dist);
63  }
64 }
65 
67  auto impl = [this](Vector& v) {
68  if (!isInsideImpl(v)) {
69  const Float h = v[H];
70  v = getNormalized(v - this->center) * (1._f - EPS) * radius + this->center;
71  v[H] = h;
72  SPH_ASSERT(isInsideImpl(v)); // these asserts are quite reduntant since we have unit tests for that
73  }
74  };
75  if (indices) {
76  for (Size i : indices.value()) {
77  impl(vs[i]);
78  }
79  } else {
80  for (Vector& v : vs) {
81  impl(v);
82  }
83  }
84 }
85 
87  Array<Ghost>& ghosts,
88  const Float eta,
89  const Float eps) const {
90  SPH_ASSERT(eps < eta);
91  ghosts.clear();
92  // iterate using indices as the array can reallocate during the loop
93  for (Size i = 0; i < vs.size(); ++i) {
94  if (!isInsideImpl(vs[i])) {
95  continue;
96  }
97  Float length;
98  Vector normalized;
99  tieToTuple(normalized, length) = getNormalizedWithLength(vs[i] - this->center);
100  const Float h = vs[i][H];
101  const Float diff = radius - length;
102  if (diff < h * eta) {
103  Vector v = vs[i] + max(eps * h, 2._f * diff) * normalized;
104  v[H] = h;
105  ghosts.push(Ghost{ v, i });
106  }
107  }
108 }
109 
110 //-----------------------------------------------------------------------------------------------------------
111 // EllipsoidalDomain implementation
112 //-----------------------------------------------------------------------------------------------------------
113 
115  : center(center)
116  , radii(axes) {
117  effectiveRadius = cbrt(radii[X] * radii[Y] * radii[Z]);
118  SPH_ASSERT(isReal(effectiveRadius));
119 }
120 
122  return center;
123 }
124 
126  return sphereVolume(effectiveRadius);
127 }
128 
130  // https://en.wikipedia.org/wiki/Ellipsoid#Surface_area
131  constexpr Float p = 1.6075_f;
132  const Float sum = pow(radii[X] * radii[Y], p) + pow(radii[X] * radii[Z], p) + pow(radii[Y] * radii[Z], p);
133  return 4._f * PI * pow(sum / 3._f, 1._f / p);
134 }
135 
137  return Box(center - radii, center + radii);
138 }
139 
140 bool EllipsoidalDomain::contains(const Vector& v) const {
141  return isInsideImpl(v);
142 }
143 
145  Array<Size>& output,
146  const SubsetType type) const {
147  switch (type) {
148  case SubsetType::OUTSIDE:
149  for (Size i = 0; i < vs.size(); ++i) {
150  if (!isInsideImpl(vs[i])) {
151  output.push(i);
152  }
153  }
154  break;
155  case SubsetType::INSIDE:
156  for (Size i = 0; i < vs.size(); ++i) {
157  if (isInsideImpl(vs[i])) {
158  output.push(i);
159  }
160  }
161  break;
162  default:
164  }
165 }
166 
168  distances.clear();
169  for (const Vector& v : vs) {
171  const Float dist = effectiveRadius * (1._f - getLength((v - this->center) / radii));
172  distances.push(dist);
173  }
174 }
175 
177  auto impl = [this](Vector& v) {
178  if (!isInsideImpl(v)) {
179  const Float h = v[H];
181  v = getNormalized((v - this->center) / radii) * radii + this->center;
182  v[H] = h;
183  SPH_ASSERT(isInsideImpl(v));
184  }
185  };
186  if (indices) {
187  for (Size i : indices.value()) {
188  impl(vs[i]);
189  }
190  } else {
191  for (Vector& v : vs) {
192  impl(v);
193  }
194  }
195 }
196 
198  Array<Ghost>& ghosts,
199  const Float eta,
200  const Float eps) const {
201  SPH_ASSERT(eps < eta);
202  ghosts.clear();
204 }
205 
206 //-----------------------------------------------------------------------------------------------------------
207 // BlockDomain implementation
208 //-----------------------------------------------------------------------------------------------------------
209 
210 BlockDomain::BlockDomain(const Vector& center, const Vector& edges)
211  : box(center - 0.5_f * edges, center + 0.5_f * edges) {}
212 
214  return box.center();
215 }
216 
218  return box.volume();
219 }
220 
222  const Vector size = box.size();
223  return 2._f * (size[X] * size[Y] + size[X] * size[Z] + size[Y] * size[Z]);
224 }
225 
227  return box;
228 }
229 
230 bool BlockDomain::contains(const Vector& v) const {
231  return box.contains(v);
232 }
233 
235  switch (type) {
236  case SubsetType::OUTSIDE:
237  for (Size i = 0; i < vs.size(); ++i) {
238  if (!box.contains(vs[i])) {
239  output.push(i);
240  }
241  }
242  break;
243  case SubsetType::INSIDE:
244  for (Size i = 0; i < vs.size(); ++i) {
245  if (box.contains(vs[i])) {
246  output.push(i);
247  }
248  }
249  }
250 }
251 
253  distances.clear();
254  for (const Vector& v : vs) {
255  const Vector d1 = v - box.lower();
256  const Vector d2 = box.upper() - v;
257  // we cannot just select min element of abs, we need signed distance
258  Float minDist = INFTY, minAbsDist = INFTY;
259  for (int i = 0; i < 3; ++i) {
260  Float dist = abs(d1[i]);
261  if (dist < minAbsDist) {
262  minAbsDist = dist;
263  minDist = d1[i];
264  }
265  dist = abs(d2[i]);
266  if (dist < minAbsDist) {
267  minAbsDist = dist;
268  minDist = d2[i];
269  }
270  }
271  SPH_ASSERT(minDist < INFTY);
272  distances.push(minDist);
273  }
274 }
275 
277  auto impl = [this](Vector& v) {
278  if (!box.contains(v)) {
279  const Float h = v[H];
280  v = box.clamp(v);
281  v[H] = h;
282  SPH_ASSERT(box.contains(v));
283  }
284  };
285  if (indices) {
286  for (Size i : indices.value()) {
287  impl(vs[i]);
288  }
289  } else {
290  for (Vector& v : vs) {
291  impl(v);
292  }
293  }
294 }
295 
297  Array<Ghost>& ghosts,
298  const Float eta,
299  const Float eps) const {
300  SPH_ASSERT(eps < eta);
301  ghosts.clear();
302 
303  for (Size i = 0; i < vs.size(); ++i) {
304  if (!box.contains(vs[i])) {
305  continue;
306  }
307  const Float h = vs[i][H];
308  const Float limitSqr = sqr(eta * h);
309 
310  const Vector d1 = max(vs[i] - box.lower(), Vector(eps * h));
311  const Vector d2 = max(box.upper() - vs[i], Vector(eps * h));
312 
313 
314  // each face for the box can potentially create a ghost
315  for (Vector x : { Vector(-d1[X], 0._f, 0._f), Vector(0._f), Vector(d2[X], 0._f, 0._f) }) {
316  for (Vector y : { Vector(0._f, -d1[Y], 0._f), Vector(0._f), Vector(0._f, d2[Y], 0._f) }) {
317  for (Vector z : { Vector(0._f, 0._f, -d1[Z]), Vector(0._f), Vector(0._f, 0._f, d2[Z]) }) {
318  if (getSqrLength(x) < limitSqr && getSqrLength(y) < limitSqr &&
319  getSqrLength(z) < limitSqr) {
320  const Vector offset = x + y + z;
321  if (offset == Vector(0._f)) {
322  continue;
323  }
324  Vector v = vs[i] + 2._f * offset;
325  v[H] = h;
326  ghosts.push(Ghost{ v, i });
327  }
328  }
329  }
330  }
331  }
332 }
333 
334 //-----------------------------------------------------------------------------------------------------------
335 // CylindricalDomain implementation
336 //-----------------------------------------------------------------------------------------------------------
337 
339  const Float radius,
340  const Float height,
341  const bool includeBases)
342  : center(center)
343  , radius(radius)
344  , height(height)
345  , includeBases(includeBases) {}
346 
348  return center;
349 }
350 
352  return PI * sqr(radius) * height;
353 }
354 
356  return 2._f * PI * sqr(radius) + height * 2._f * PI * radius;
357 }
358 
360  const Vector sides(radius, radius, 0.5_f * height);
361  return Box(this->center - sides, this->center + sides);
362 }
363 
364 bool CylindricalDomain::contains(const Vector& v) const {
365  return this->isInsideImpl(v);
366 }
367 
369  Array<Size>& output,
370  const SubsetType type) const {
371  switch (type) {
372  case SubsetType::OUTSIDE:
373  for (Size i = 0; i < vs.size(); ++i) {
374  if (!isInsideImpl(vs[i])) {
375  output.push(i);
376  }
377  }
378  break;
379  case SubsetType::INSIDE:
380  for (Size i = 0; i < vs.size(); ++i) {
381  if (isInsideImpl(vs[i])) {
382  output.push(i);
383  }
384  }
385  }
386 }
387 
389  distances.clear();
390  for (const Vector& v : vs) {
391  const Float dist = radius - getLength(Vector(v[X], v[Y], this->center[Z]) - this->center);
392  if (includeBases) {
393  distances.push(min(dist, abs(0.5_f * height - abs(v[Z] - this->center[Z]))));
394  } else {
395  distances.push(dist);
396  }
397  }
398 }
399 
401  auto impl = [this](Vector& v) {
402  if (!isInsideImpl(v)) {
403  const Float h = v[H];
404  v = getNormalized(Vector(v[X], v[Y], this->center[Z]) - this->center) * (1._f - EPS) * radius +
405  Vector(this->center[X], this->center[Y], v[Z]);
406  if (includeBases) {
407  const Float halfHeight = 0.5_f * (1._f - EPS) * height;
408  v[Z] = clamp(v[Z], this->center[Z] - halfHeight, this->center[Z] + halfHeight);
409  }
410  v[H] = h;
411  SPH_ASSERT(isInsideImpl(v));
412  }
413  };
414  if (indices) {
415  for (Size i : indices.value()) {
416  impl(vs[i]);
417  }
418  } else {
419  for (Vector& v : vs) {
420  impl(v);
421  }
422  }
423 }
424 
426  Array<Ghost>& ghosts,
427  const Float eta,
428  const Float eps) const {
429  ghosts.clear();
430  SPH_ASSERT(eps < eta);
431  for (Size i = 0; i < vs.size(); ++i) {
432  if (!isInsideImpl(vs[i])) {
433  continue;
434  }
435  Float length;
436  Vector normalized;
437  tieToTuple(normalized, length) =
438  getNormalizedWithLength(Vector(vs[i][X], vs[i][Y], this->center[Z]) - this->center);
439  const Float h = vs[i][H];
440  SPH_ASSERT(radius - length >= 0._f);
441  Float diff = max(eps * h, radius - length);
442  if (diff < h * eta) {
443  Vector v = vs[i] + 2._f * diff * normalized;
444  v[H] = h;
445  ghosts.push(Ghost{ v, i });
446  }
447  if (includeBases) {
448  diff = 0.5_f * height - (vs[i][Z] - this->center[Z]);
449  if (diff < h * eta) {
450  ghosts.push(Ghost{ vs[i] + Vector(0._f, 0._f, 2._f * diff), i });
451  }
452  diff = 0.5_f * height - (this->center[Z] - vs[i][Z]);
453  if (diff < h * eta) {
454  ghosts.push(Ghost{ vs[i] - Vector(0._f, 0._f, 2._f * diff), i });
455  }
456  }
457  }
458 }
459 
460 //-----------------------------------------------------------------------------------------------------------
461 // HexagonalDomain implementation
462 //-----------------------------------------------------------------------------------------------------------
463 
465  const Float radius,
466  const Float height,
467  const bool includeBases)
468  : center(center)
469  , outerRadius(radius)
470  , innerRadius(sqrt(0.75_f) * outerRadius)
471  , height(height)
472  , includeBases(includeBases) {}
473 
475  return center;
476 }
477 
479  // 6 equilateral triangles
480  return 1.5_f * sqrt(3._f) * sqr(outerRadius);
481 }
482 
485 }
486 
488  const Vector sides(outerRadius, outerRadius, 0.5_f * height);
489  return Box(this->center - sides, this->center + sides);
490 }
491 
492 bool HexagonalDomain::contains(const Vector& v) const {
493  return this->isInsideImpl(v);
494 }
495 
497  Array<Size>& output,
498  const SubsetType type) const {
499  switch (type) {
500  case SubsetType::OUTSIDE:
501  for (Size i = 0; i < vs.size(); ++i) {
502  if (!isInsideImpl(vs[i])) {
503  output.push(i);
504  }
505  }
506  break;
507  case SubsetType::INSIDE:
508  for (Size i = 0; i < vs.size(); ++i) {
509  if (isInsideImpl(vs[i])) {
510  output.push(i);
511  }
512  }
513  }
514 }
515 
518 }
519 
521  auto impl = [this](Vector& v) {
522  if (!isInsideImpl(v)) {
523  // find triangle
524  const Float phi = atan2(v[Y], v[X]);
525  const Float r = (1._f - EPS) * outerRadius * hexagon(phi);
526  const Vector u = r * getNormalized(Vector(v[X], v[Y], 0._f));
527  v = Vector(u[X], u[Y], v[Z], v[H]);
528  if (includeBases) {
529  const Float halfHeight = 0.5_f * (1._f - EPS) * height;
530  v[Z] = clamp(v[Z], this->center[Z] - halfHeight, this->center[Z] + halfHeight);
531  }
532  SPH_ASSERT(isInsideImpl(v));
533  }
534  };
535  if (indices) {
536  for (Size i : indices.value()) {
537  impl(vs[i]);
538  }
539  } else {
540  for (Vector& v : vs) {
541  impl(v);
542  }
543  }
544 }
545 
547  Array<Ghost>& ghosts,
548  const Float eta,
549  const Float eps) const {
550  ghosts.clear();
551  SPH_ASSERT(eps < eta);
553  for (Size i = 0; i < vs.size(); ++i) {
554  if (!isInsideImpl(vs[i])) {
555  continue;
556  }
557  Float length;
558  Vector normalized;
559  tieToTuple(normalized, length) =
560  getNormalizedWithLength(Vector(vs[i][X], vs[i][Y], this->center[Z]) - this->center);
561  const Float h = vs[i][H];
562  SPH_ASSERT(outerRadius - length >= 0._f);
563  const Float phi = atan2(vs[i][Y], vs[i][X]);
564  const Float r = outerRadius * hexagon(phi);
565  Float diff = max(eps * h, r - length);
566  if (diff < h * eta) {
567  Vector v = vs[i] + 2._f * diff * normalized;
568  v[H] = h;
569  ghosts.push(Ghost{ v, i });
570  }
571  if (includeBases) {
572  diff = 0.5_f * height - (vs[i][Z] - this->center[Z]);
573  if (diff < h * eta) {
574  ghosts.push(Ghost{ vs[i] + Vector(0._f, 0._f, 2._f * diff), i });
575  }
576  diff = 0.5_f * height - (this->center[Z] - vs[i][Z]);
577  if (diff < h * eta) {
578  ghosts.push(Ghost{ vs[i] - Vector(0._f, 0._f, 2._f * diff), i });
579  }
580  }
581  }
582 }
583 
584 //-----------------------------------------------------------------------------------------------------------
585 // GaussianRandomSphere implementation
586 //-----------------------------------------------------------------------------------------------------------
587 
589  const Float radius,
590  const Float beta,
591  const Size seed)
592  : center(center)
593  , a(radius)
594  , beta(beta) {
595  (void)seed;
596 }
597 
598 
600  return center;
601 }
602 
604  return sphereVolume(a) * exp(3._f * sqr(beta));
605 }
606 
609  return 0._f;
610 }
611 
613  Box box;
614  box.extend(center - 2._f * Vector(a));
615  box.extend(center + 2._f * Vector(a));
616  return box;
617 }
618 
620  const SphericalCoords sp = cartensianToSpherical(v - center);
621  const Float r = a * exp(this->sphericalHarmonic(sp.theta, sp.phi) - 0.5_f * sqr(beta));
622  return sp.r < r;
623 }
624 
627 }
628 
631 }
632 
635 }
636 
639 }
640 
641 Float GaussianRandomSphere::sphericalHarmonic(const Float theta, const Float phi) const {
642 #ifdef SPH_CPP17
643  Float r = 0._f;
644  for (int l = 0; l < 5; ++l) {
645  for (int m = 0; m <= l; ++m) {
646  const Float s1 = (1._f + (m == 0)) * 2._f * PI / (2 * l + 1) * sqr(beta);
647  const Float s2 = (1._f - (m == 0)) * 2._f * PI / (2 * l + 1) * sqr(beta);
648 
649  r += s1 * std::sph_legendre(l, m, theta) * cos(m * phi) +
650  s2 * std::sph_legendre(l, -m, theta) * sin(m * phi);
651  }
652  }
653  return r;
654 #else
655  MARK_USED(theta);
656  MARK_USED(phi);
658 #endif
659 }
660 
661 
662 //-----------------------------------------------------------------------------------------------------------
663 // HalfSpaceDomain implementation
664 //-----------------------------------------------------------------------------------------------------------
665 
667  // z == 0, x and y are arbitrary
668  return Vector(0._f);
669 }
670 
672  throw InvalidSetup("HalfSpace domain has an undefined volume.");
673 }
674 
676  throw InvalidSetup("HalfSpace domain has an undefined surface area.");
677 }
678 
680  return Box(Vector(-INFTY, -INFTY, 0._f), Vector(INFTY));
681 }
682 
683 bool HalfSpaceDomain::contains(const Vector& v) const {
684  return v[Z] > 0._f;
685 }
686 
688  Array<Size>& output,
689  const SubsetType type) const {
690  switch (type) {
691  case SubsetType::OUTSIDE:
692  for (Size i = 0; i < vs.size(); ++i) {
693  if (!this->contains(vs[i])) {
694  output.push(i);
695  }
696  }
697  break;
698  case SubsetType::INSIDE:
699  for (Size i = 0; i < vs.size(); ++i) {
700  if (this->contains(vs[i])) {
701  output.push(i);
702  }
703  }
704  }
705 }
706 
708  distances.clear();
709  for (const Vector& v : vs) {
710  distances.push(v[Z]);
711  }
712 }
713 
715  if (indices) {
716  for (Size i : indices.value()) {
717  if (!this->contains(vs[i])) {
718  vs[i][Z] = 0._f;
719  }
720  }
721  } else {
722  for (Size i = 0; i < vs.size(); ++i) {
723  if (!this->contains(vs[i])) {
724  vs[i][Z] = 0._f;
725  }
726  }
727  }
728 }
729 
731  Array<Ghost>& ghosts,
732  const Float eta,
733  const Float eps) const {
734  SPH_ASSERT(eps < eta);
735  ghosts.clear();
736  for (Size i = 0; i < vs.size(); ++i) {
737  if (!this->contains(vs[i])) {
738  continue;
739  }
740 
741  const Float dist = vs[i][Z];
742  SPH_ASSERT(dist > 0._f);
743  if (dist < vs[i][H] * eta) {
744  Vector g = vs[i];
745  g[Z] -= 2._f * dist;
746  ghosts.push(Ghost{ g, i });
747  }
748  }
749 }
750 
751 //-----------------------------------------------------------------------------------------------------------
752 // TransformedDomain implementation
753 //-----------------------------------------------------------------------------------------------------------
754 
756  : domain(std::move(domain)) {
757  tm = matrix;
758  tmInv = matrix.inverse();
759 }
760 
762  return domain->getCenter() + tm.translation();
763 }
764 
766  return domain->getVolume() * tm.determinant();
767 }
768 
771  return domain->getSurfaceArea();
772 }
773 
775  const Box box = domain->getBoundingBox();
776  // transform all 8 points
777  Box transformedBox;
778  for (Size i = 0; i <= 1; ++i) {
779  for (Size j = 0; j <= 1; ++j) {
780  for (Size k = 0; k <= 1; ++k) {
781  const Vector p = box.lower() * Vector(i, j, k) + box.upper() * Vector(1 - i, 1 - j, 1 - k);
782  transformedBox.extend(tm * p);
783  }
784  }
785  }
786  return transformedBox;
787 }
788 
789 bool TransformedDomain::contains(const Vector& v) const {
790  return domain->contains(tmInv * v);
791 }
792 
794  Array<Size>& output,
795  const SubsetType type) const {
796  domain->getSubset(this->untransform(vs), output, type);
797 }
798 
800  return domain->getDistanceToBoundary(this->untransform(vs), distances);
801 }
802 
804  return domain->project(this->untransform(vs), indices);
805 }
806 
808  Array<Ghost>& ghosts,
809  const Float eta,
810  const Float eps) const {
811  domain->addGhosts(this->untransform(vs), ghosts, eta, eps);
812  for (Ghost& g : ghosts) {
813  g.position = tm * g.position;
814  }
815 }
816 
817 Array<Vector> TransformedDomain::untransform(ArrayView<const Vector> vs) const {
818  Array<Vector> untransformed(vs.size());
819  for (Size i = 0; i < vs.size(); ++i) {
820  untransformed[i] = tmInv * vs[i];
821  }
822  return untransformed;
823 }
824 
825 
INLINE bool isReal(const AntisymmetricTensor &t)
#define SPH_ASSERT(x,...)
Definition: Assert.h:94
#define NOT_IMPLEMENTED
Helper macro marking missing implementation.
Definition: Assert.h:100
NAMESPACE_SPH_BEGIN
Definition: BarnesHut.cpp:13
const float radius
Definition: CurveDialog.cpp:18
Object defining computational domain.
SubsetType
Definition: Domain.h:16
@ INSIDE
Marks all vectors inside of the 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
constexpr INLINE T max(const T &f1, const T &f2)
Definition: MathBasic.h:20
constexpr INLINE T clamp(const T &f, const T &f1, const T &f2)
Definition: MathBasic.h:35
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 INLINE T sqr(const T &f) noexcept
Return a squared value.
Definition: MathUtils.h:67
INLINE Float cbrt(const Float f)
Returns a cubed root of a value.
Definition: MathUtils.h:84
INLINE T sin(const T f)
Definition: MathUtils.h:296
INLINE T cos(const T f)
Definition: MathUtils.h:291
INLINE T sqrt(const T f)
Return a squared root of a value.
Definition: MathUtils.h:78
constexpr INLINE Float pow(const Float v)
Power for floats.
constexpr INLINE Float sphereVolume(const Float radius)
Computes a volume of a sphere given its radius.
Definition: MathUtils.h:375
constexpr Float INFTY
Definition: MathUtils.h:38
INLINE T exp(const T f)
Definition: MathUtils.h:269
constexpr INLINE Float sphereSurfaceArea(const Float radius)
Computes a surface area of a sphere given its radius.
Definition: MathUtils.h:380
INLINE T atan2(const T y, const T x)
Definition: MathUtils.h:321
INLINE auto abs(const T &f)
Definition: MathUtils.h:276
constexpr Float PI
Mathematical constants.
Definition: MathUtils.h:361
#define UNUSED(x)
Definition: Object.h:37
#define MARK_USED(x)
Silences the "unused variable" warning for given variable.
Definition: Object.h:42
#define NAMESPACE_SPH_END
Definition: Object.h:12
INLINE Tuple< TArgs &... > tieToTuple(TArgs &... args)
Creates a tuple of l-value references. Use IGNORE placeholder to omit one or more parameters.
Definition: Tuple.h:304
INLINE SphericalCoords cartensianToSpherical(const Vector &v)
Converts vector in cartesian coordinates to spherical coordinates.
Definition: Vector.h:806
INLINE Float getLength(const Vector &v)
Returns the length of the vector. Enabled only for vectors of floating-point precision.
Definition: Vector.h:579
INLINE Tuple< Vector, Float > getNormalizedWithLength(const Vector &v)
Returns normalized vector and length of the input vector as tuple.
Definition: Vector.h:597
INLINE Float getSqrLength(const Vector &v)
Definition: Vector.h:574
BasicVector< Float > Vector
Definition: Vector.h:539
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 Float determinant() const
Computes determinant of the matrix.
Definition: AffineMatrix.h:80
INLINE Vector translation() const
Definition: AffineMatrix.h:49
AffineMatrix inverse() const
Definition: AffineMatrix.h:86
Object providing safe access to continuous memory of data.
Definition: ArrayView.h:17
INLINE TCounter size() const
Definition: ArrayView.h:101
INLINE void push(U &&u)
Adds new element to the end of the array, resizing the array if necessary.
Definition: Array.h:306
void clear()
Removes all elements from the array, but does NOT release the memory.
Definition: Array.h:434
virtual bool contains(const Vector &v) const override
Checks if the given point lies inside the domain.
Definition: Domain.cpp:230
virtual Float getVolume() const override
Returns the total volume of the domain.
Definition: Domain.cpp:217
virtual void getDistanceToBoundary(ArrayView< const Vector > vs, Array< Float > &distances) const override
Returns distances of particles lying close to the boundary.
Definition: Domain.cpp:252
virtual void addGhosts(ArrayView< const Vector > vs, Array< Ghost > &ghosts, const Float eta, const Float eps) const override
Duplicates positions located close to the boundary, placing copies ("ghosts") symmetrically to the ot...
Definition: Domain.cpp:296
virtual void project(ArrayView< Vector > vs, Optional< ArrayView< Size >> indices=NOTHING) const override
Projects vectors outside of the domain onto its boundary.
Definition: Domain.cpp:276
virtual void getSubset(ArrayView< const Vector > vs, Array< Size > &output, const SubsetType type) const override
Returns an array of indices, marking vectors with given property by their index.
Definition: Domain.cpp:234
virtual Box getBoundingBox() const override
Returns the bounding box of the domain.
Definition: Domain.cpp:226
virtual Vector getCenter() const override
Returns the center of the domain.
Definition: Domain.cpp:213
virtual Float getSurfaceArea() const override
Returns the surface area of the domain.
Definition: Domain.cpp:221
BlockDomain(const Vector &center, const Vector &edges)
Definition: Domain.cpp:210
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 bool contains(const Vector &v) const
Checks if the vector lies inside the box.
Definition: Box.h:66
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
INLINE Vector clamp(const Vector &v) const
Clamps all components of the vector to fit within the box.
Definition: Box.h:76
virtual void getSubset(ArrayView< const Vector > vs, Array< Size > &output, const SubsetType type) const override
Returns an array of indices, marking vectors with given property by their index.
Definition: Domain.cpp:368
virtual void addGhosts(ArrayView< const Vector > vs, Array< Ghost > &ghosts, const Float eta, const Float eps) const override
Duplicates positions located close to the boundary, placing copies ("ghosts") symmetrically to the ot...
Definition: Domain.cpp:425
CylindricalDomain(const Vector &center, const Float radius, const Float height, const bool includeBases)
Definition: Domain.cpp:338
virtual Float getVolume() const override
Returns the total volume of the domain.
Definition: Domain.cpp:351
virtual Vector getCenter() const override
Returns the center of the domain.
Definition: Domain.cpp:347
virtual Float getSurfaceArea() const override
Returns the surface area of the domain.
Definition: Domain.cpp:355
virtual bool contains(const Vector &v) const override
Checks if the given point lies inside the domain.
Definition: Domain.cpp:364
virtual void project(ArrayView< Vector > vs, Optional< ArrayView< Size >> indices=NOTHING) const override
Projects vectors outside of the domain onto its boundary.
Definition: Domain.cpp:400
virtual void getDistanceToBoundary(ArrayView< const Vector > vs, Array< Float > &distances) const override
Returns distances of particles lying close to the boundary.
Definition: Domain.cpp:388
virtual Box getBoundingBox() const override
Returns the bounding box of the domain.
Definition: Domain.cpp:359
virtual Vector getCenter() const override
Returns the center of the domain.
Definition: Domain.cpp:121
virtual void addGhosts(ArrayView< const Vector > vs, Array< Ghost > &ghosts, const Float eta, const Float eps) const override
Duplicates positions located close to the boundary, placing copies ("ghosts") symmetrically to the ot...
Definition: Domain.cpp:197
EllipsoidalDomain(const Vector &center, const Vector &axes)
Definition: Domain.cpp:114
virtual Float getVolume() const override
Returns the total volume of the domain.
Definition: Domain.cpp:125
virtual Float getSurfaceArea() const override
Returns the surface area of the domain.
Definition: Domain.cpp:129
virtual bool contains(const Vector &v) const override
Checks if the given point lies inside the domain.
Definition: Domain.cpp:140
virtual void getDistanceToBoundary(ArrayView< const Vector > vs, Array< Float > &distances) const override
Returns distances of particles lying close to the boundary.
Definition: Domain.cpp:167
virtual void getSubset(ArrayView< const Vector > vs, Array< Size > &output, const SubsetType type) const override
Returns an array of indices, marking vectors with given property by their index.
Definition: Domain.cpp:144
virtual Box getBoundingBox() const override
Returns the bounding box of the domain.
Definition: Domain.cpp:136
virtual void project(ArrayView< Vector > vs, Optional< ArrayView< Size >> indices=NOTHING) const override
Projects vectors outside of the domain onto its boundary.
Definition: Domain.cpp:176
virtual Float getVolume() const override
Returns the total volume of the domain.
Definition: Domain.cpp:603
GaussianRandomSphere(const Vector &center, const Float radius, const Float beta, const Size seed)
Definition: Domain.cpp:588
virtual void getDistanceToBoundary(ArrayView< const Vector > vs, Array< Float > &distances) const override
Returns distances of particles lying close to the boundary.
Definition: Domain.cpp:629
virtual void getSubset(ArrayView< const Vector > vs, Array< Size > &output, const SubsetType type) const override
Returns an array of indices, marking vectors with given property by their index.
Definition: Domain.cpp:625
virtual Vector getCenter() const override
Returns the center of the domain.
Definition: Domain.cpp:599
virtual Box getBoundingBox() const override
Returns the bounding box of the domain.
Definition: Domain.cpp:612
virtual bool contains(const Vector &v) const override
Checks if the given point lies inside the domain.
Definition: Domain.cpp:619
virtual void addGhosts(ArrayView< const Vector > vs, Array< Ghost > &ghosts, const Float eta, const Float eps) const override
Duplicates positions located close to the boundary, placing copies ("ghosts") symmetrically to the ot...
Definition: Domain.cpp:637
virtual void project(ArrayView< Vector > vs, Optional< ArrayView< Size >> indices=NOTHING) const override
Projects vectors outside of the domain onto its boundary.
Definition: Domain.cpp:633
virtual Float getSurfaceArea() const override
Returns the surface area of the domain.
Definition: Domain.cpp:607
virtual void getSubset(ArrayView< const Vector > vs, Array< Size > &output, const SubsetType type) const override
Returns an array of indices, marking vectors with given property by their index.
Definition: Domain.cpp:687
virtual Vector getCenter() const override
Returns the center of the domain.
Definition: Domain.cpp:666
virtual bool contains(const Vector &v) const override
Checks if the given point lies inside the domain.
Definition: Domain.cpp:683
virtual Float getVolume() const override
Returns the total volume of the domain.
Definition: Domain.cpp:671
virtual Float getSurfaceArea() const override
Returns the surface area of the domain.
Definition: Domain.cpp:675
virtual Box getBoundingBox() const override
Returns the bounding box of the domain.
Definition: Domain.cpp:679
virtual void project(ArrayView< Vector > vs, Optional< ArrayView< Size >> indices=NOTHING) const override
Projects vectors outside of the domain onto its boundary.
Definition: Domain.cpp:714
virtual void addGhosts(ArrayView< const Vector > vs, Array< Ghost > &ghosts, const Float eta, const Float eps) const override
Duplicates positions located close to the boundary, placing copies ("ghosts") symmetrically to the ot...
Definition: Domain.cpp:730
virtual void getDistanceToBoundary(ArrayView< const Vector > vs, Array< Float > &distances) const override
Returns distances of particles lying close to the boundary.
Definition: Domain.cpp:707
virtual Box getBoundingBox() const override
Returns the bounding box of the domain.
Definition: Domain.cpp:487
virtual void getDistanceToBoundary(ArrayView< const Vector >, Array< Float > &) const override
Returns distances of particles lying close to the boundary.
Definition: Domain.cpp:516
virtual Float getVolume() const override
Returns the total volume of the domain.
Definition: Domain.cpp:478
virtual void getSubset(ArrayView< const Vector > vs, Array< Size > &output, const SubsetType type) const override
Returns an array of indices, marking vectors with given property by their index.
Definition: Domain.cpp:496
HexagonalDomain(const Vector &center, const Float radius, const Float height, const bool includeBases)
Definition: Domain.cpp:464
virtual Float getSurfaceArea() const override
Returns the surface area of the domain.
Definition: Domain.cpp:483
virtual Vector getCenter() const override
Returns the center of the domain.
Definition: Domain.cpp:474
virtual void project(ArrayView< Vector > vs, Optional< ArrayView< Size >> indices=NOTHING) const override
Projects vectors outside of the domain onto its boundary.
Definition: Domain.cpp:520
virtual void addGhosts(ArrayView< const Vector > vs, Array< Ghost > &ghosts, const Float eta, const Float eps) const override
Duplicates positions located close to the boundary, placing copies ("ghosts") symmetrically to the ot...
Definition: Domain.cpp:546
virtual bool contains(const Vector &v) const override
Checks if the given point lies inside the domain.
Definition: Domain.cpp:492
virtual Float getSurfaceArea() const =0
Returns the surface area of the domain.
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 Box getBoundingBox() const =0
Returns the bounding box of the domain.
virtual Float getVolume() const =0
Returns the total volume of the domain.
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.
virtual Vector getCenter() const =0
Returns the center of the domain.
Thrown when components of the run are mutually incompatible.
Definition: Exceptions.h:24
Wrapper of type value of which may or may not be present.
Definition: Optional.h:23
virtual Float getSurfaceArea() const override
Returns the surface area of the domain.
Definition: Domain.cpp:22
virtual Box getBoundingBox() const override
Returns the bounding box of the domain.
Definition: Domain.cpp:26
virtual void getDistanceToBoundary(ArrayView< const Vector > vs, Array< Float > &distances) const override
Returns distances of particles lying close to the boundary.
Definition: Domain.cpp:58
virtual void addGhosts(ArrayView< const Vector > vs, Array< Ghost > &ghosts, const Float eta, const Float eps) const override
Duplicates positions located close to the boundary, placing copies ("ghosts") symmetrically to the ot...
Definition: Domain.cpp:86
virtual void getSubset(ArrayView< const Vector > vs, Array< Size > &output, const SubsetType type) const override
Returns an array of indices, marking vectors with given property by their index.
Definition: Domain.cpp:35
virtual Float getVolume() const override
Returns the total volume of the domain.
Definition: Domain.cpp:18
virtual Vector getCenter() const override
Returns the center of the domain.
Definition: Domain.cpp:14
SphericalDomain(const Vector &center, const Float &radius)
Definition: Domain.cpp:10
virtual bool contains(const Vector &v) const override
Checks if the given point lies inside the domain.
Definition: Domain.cpp:31
virtual void project(ArrayView< Vector > vs, Optional< ArrayView< Size >> indices=NOTHING) const override
Projects vectors outside of the domain onto its boundary.
Definition: Domain.cpp:66
virtual void getSubset(ArrayView< const Vector > vs, Array< Size > &output, const SubsetType type) const override
Returns an array of indices, marking vectors with given property by their index.
Definition: Domain.cpp:793
virtual Float getVolume() const override
Returns the total volume of the domain.
Definition: Domain.cpp:765
virtual void getDistanceToBoundary(ArrayView< const Vector > vs, Array< Float > &distances) const override
Returns distances of particles lying close to the boundary.
Definition: Domain.cpp:799
virtual void project(ArrayView< Vector > vs, Optional< ArrayView< Size >> indices=NOTHING) const override
Projects vectors outside of the domain onto its boundary.
Definition: Domain.cpp:803
virtual Float getSurfaceArea() const override
Returns the surface area of the domain.
Definition: Domain.cpp:769
virtual void addGhosts(ArrayView< const Vector > vs, Array< Ghost > &ghosts, const Float eta, const Float eps) const override
Duplicates positions located close to the boundary, placing copies ("ghosts") symmetrically to the ot...
Definition: Domain.cpp:807
TransformedDomain(SharedPtr< IDomain > domain, const AffineMatrix &matrix)
Definition: Domain.cpp:755
virtual Vector getCenter() const override
Returns the center of the domain.
Definition: Domain.cpp:761
virtual bool contains(const Vector &v) const override
Checks if the given point lies inside the domain.
Definition: Domain.cpp:789
virtual Box getBoundingBox() const override
Returns the bounding box of the domain.
Definition: Domain.cpp:774
constexpr Size sum()
Definition: Multipole.h:31
Overload of std::swap for Sph::Array.
Definition: Array.h:578
Definition: Domain.h:22
Float r
radius
Definition: Vector.h:800
Float phi
longitude
Definition: Vector.h:802
Float theta
latitude
Definition: Vector.h:801