28 return Box(this->center - r, this->center + r);
32 return isInsideImpl(v);
40 for (
Size i = 0; i < vs.
size(); ++i) {
41 if (!isInsideImpl(vs[i])) {
47 for (
Size i = 0; i < vs.
size(); ++i) {
48 if (isInsideImpl(vs[i])) {
60 for (
const Vector& v : vs) {
67 auto impl = [
this](
Vector& v) {
68 if (!isInsideImpl(v)) {
76 for (
Size i : indices.value()) {
89 const Float eps)
const {
93 for (
Size i = 0; i < vs.
size(); ++i) {
94 if (!isInsideImpl(vs[i])) {
101 const Float diff = radius - length;
102 if (diff < h * eta) {
103 Vector v = vs[i] +
max(eps * h, 2._f * diff) * normalized;
117 effectiveRadius =
cbrt(radii[
X] * radii[
Y] * radii[
Z]);
131 constexpr
Float p = 1.6075_f;
133 return 4._f *
PI *
pow(
sum / 3._f, 1._f / p);
137 return Box(center - radii, center + radii);
141 return isInsideImpl(v);
149 for (
Size i = 0; i < vs.
size(); ++i) {
150 if (!isInsideImpl(vs[i])) {
156 for (
Size i = 0; i < vs.
size(); ++i) {
157 if (isInsideImpl(vs[i])) {
169 for (
const Vector& v : vs) {
171 const Float dist = effectiveRadius * (1._f -
getLength((v - this->center) / radii));
172 distances.
push(dist);
177 auto impl = [
this](
Vector& v) {
178 if (!isInsideImpl(v)) {
181 v =
getNormalized((v - this->center) / radii) * radii + this->center;
187 for (
Size i : indices.value()) {
200 const Float eps)
const {
211 : box(center - 0.5_f * edges, center + 0.5_f * edges) {}
223 return 2._f * (size[
X] * size[
Y] + size[
X] * size[
Z] + size[
Y] * size[
Z]);
237 for (
Size i = 0; i < vs.
size(); ++i) {
244 for (
Size i = 0; i < vs.
size(); ++i) {
254 for (
const Vector& v : vs) {
259 for (
int i = 0; i < 3; ++i) {
261 if (dist < minAbsDist) {
266 if (dist < minAbsDist) {
272 distances.
push(minDist);
277 auto impl = [
this](
Vector& v) {
286 for (
Size i : indices.value()) {
299 const Float eps)
const {
303 for (
Size i = 0; i < vs.
size(); ++i) {
308 const Float limitSqr =
sqr(eta * h);
320 const Vector offset = x + y + z;
321 if (offset ==
Vector(0._f)) {
324 Vector v = vs[i] + 2._f * offset;
341 const bool includeBases)
345 , includeBases(includeBases) {}
352 return PI *
sqr(radius) * height;
356 return 2._f *
PI *
sqr(radius) + height * 2._f *
PI * radius;
360 const Vector sides(radius, radius, 0.5_f * height);
361 return Box(this->center - sides, this->center + sides);
365 return this->isInsideImpl(v);
373 for (
Size i = 0; i < vs.
size(); ++i) {
374 if (!isInsideImpl(vs[i])) {
380 for (
Size i = 0; i < vs.
size(); ++i) {
381 if (isInsideImpl(vs[i])) {
390 for (
const Vector& v : vs) {
393 distances.
push(
min(dist,
abs(0.5_f * height -
abs(v[
Z] - this->center[
Z]))));
395 distances.
push(dist);
401 auto impl = [
this](
Vector& v) {
402 if (!isInsideImpl(v)) {
405 Vector(this->center[
X], this->center[
Y], v[
Z]);
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);
415 for (
Size i : indices.value()) {
428 const Float eps)
const {
431 for (
Size i = 0; i < vs.
size(); ++i) {
432 if (!isInsideImpl(vs[i])) {
441 Float diff =
max(eps * h, radius - length);
442 if (diff < h * eta) {
443 Vector v = vs[i] + 2._f * diff * normalized;
448 diff = 0.5_f * height - (vs[i][
Z] - this->center[
Z]);
449 if (diff < h * eta) {
452 diff = 0.5_f * height - (this->center[
Z] - vs[i][
Z]);
453 if (diff < h * eta) {
467 const bool includeBases)
470 , innerRadius(
sqrt(0.75_f) * outerRadius)
472 , includeBases(includeBases) {}
480 return 1.5_f *
sqrt(3._f) *
sqr(outerRadius);
488 const Vector sides(outerRadius, outerRadius, 0.5_f * height);
489 return Box(this->center - sides, this->center + sides);
493 return this->isInsideImpl(v);
501 for (
Size i = 0; i < vs.
size(); ++i) {
502 if (!isInsideImpl(vs[i])) {
508 for (
Size i = 0; i < vs.
size(); ++i) {
509 if (isInsideImpl(vs[i])) {
521 auto impl = [
this](
Vector& v) {
522 if (!isInsideImpl(v)) {
525 const Float r = (1._f -
EPS) * outerRadius * hexagon(phi);
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);
536 for (
Size i : indices.value()) {
549 const Float eps)
const {
553 for (
Size i = 0; i < vs.
size(); ++i) {
554 if (!isInsideImpl(vs[i])) {
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;
572 diff = 0.5_f * height - (vs[i][
Z] - this->center[
Z]);
573 if (diff < h * eta) {
576 diff = 0.5_f * height - (this->center[
Z] - vs[i][
Z]);
577 if (diff < h * eta) {
641 Float GaussianRandomSphere::sphericalHarmonic(
const Float theta,
const Float phi)
const {
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);
649 r += s1 * std::sph_legendre(l, m, theta) *
cos(m * phi) +
650 s2 * std::sph_legendre(l, -m, theta) *
sin(m * phi);
672 throw InvalidSetup(
"HalfSpace domain has an undefined volume.");
676 throw InvalidSetup(
"HalfSpace domain has an undefined surface area.");
692 for (
Size i = 0; i < vs.
size(); ++i) {
699 for (
Size i = 0; i < vs.
size(); ++i) {
709 for (
const Vector& v : vs) {
710 distances.
push(v[
Z]);
716 for (
Size i : indices.value()) {
722 for (
Size i = 0; i < vs.
size(); ++i) {
733 const Float eps)
const {
736 for (
Size i = 0; i < vs.
size(); ++i) {
741 const Float dist = vs[i][
Z];
743 if (dist < vs[i][
H] * eta) {
756 : domain(
std::move(domain)) {
778 for (
Size i = 0; i <= 1; ++i) {
779 for (
Size j = 0; j <= 1; ++j) {
780 for (
Size k = 0; k <= 1; ++k) {
782 transformedBox.
extend(tm * p);
786 return transformedBox;
796 domain->
getSubset(this->untransform(vs), output, type);
804 return domain->
project(this->untransform(vs), indices);
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;
819 for (
Size i = 0; i < vs.
size(); ++i) {
820 untransformed[i] = tmInv * vs[i];
822 return untransformed;
INLINE bool isReal(const AntisymmetricTensor &t)
#define SPH_ASSERT(x,...)
#define NOT_IMPLEMENTED
Helper macro marking missing implementation.
Object defining computational domain.
@ 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).
double Float
Precision used withing the code. Use Float instead of float or double where precision is important.
constexpr INLINE T max(const T &f1, const T &f2)
constexpr INLINE T clamp(const T &f, const T &f1, const T &f2)
NAMESPACE_SPH_BEGIN constexpr INLINE T min(const T &f1, const T &f2)
Minimum & Maximum value.
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(const Float v)
Power for floats.
constexpr INLINE Float sphereVolume(const Float radius)
Computes a volume of a sphere given its radius.
constexpr INLINE Float sphereSurfaceArea(const Float radius)
Computes a surface area of a sphere given its radius.
INLINE T atan2(const T y, const T x)
INLINE auto abs(const T &f)
constexpr Float PI
Mathematical constants.
#define MARK_USED(x)
Silences the "unused variable" warning for given variable.
#define NAMESPACE_SPH_END
INLINE Tuple< TArgs &... > tieToTuple(TArgs &... args)
Creates a tuple of l-value references. Use IGNORE placeholder to omit one or more parameters.
INLINE SphericalCoords cartensianToSpherical(const Vector &v)
Converts vector in cartesian coordinates to spherical coordinates.
INLINE Float getLength(const Vector &v)
Returns the length of the vector. Enabled only for vectors of floating-point precision.
INLINE Tuple< Vector, Float > getNormalizedWithLength(const Vector &v)
Returns normalized vector and length of the input vector as tuple.
INLINE Float getSqrLength(const Vector &v)
BasicVector< Float > Vector
INLINE Vector getNormalized(const Vector &v)
INLINE Float determinant() const
Computes determinant of the matrix.
INLINE Vector translation() const
AffineMatrix inverse() const
Object providing safe access to continuous memory of data.
INLINE TCounter size() const
INLINE void push(U &&u)
Adds new element to the end of the array, resizing the array if necessary.
void clear()
Removes all elements from the array, but does NOT release the memory.
virtual bool contains(const Vector &v) const override
Checks if the given point lies inside the domain.
virtual Float getVolume() const override
Returns the total volume of the domain.
virtual void getDistanceToBoundary(ArrayView< const Vector > vs, Array< Float > &distances) const override
Returns distances of particles lying close to the boundary.
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...
virtual void project(ArrayView< Vector > vs, Optional< ArrayView< Size >> indices=NOTHING) const override
Projects vectors outside of the domain onto its boundary.
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.
virtual Box getBoundingBox() const override
Returns the bounding box of the domain.
virtual Vector getCenter() const override
Returns the center of the domain.
virtual Float getSurfaceArea() const override
Returns the surface area of the domain.
BlockDomain(const Vector ¢er, const Vector &edges)
Helper object defining three-dimensional interval (box).
INLINE void extend(const Vector &v)
Enlarges the box to contain the vector.
INLINE const Vector & lower() const
Returns lower bounds of the box.
INLINE const Vector & upper() const
Returns upper bounds of the box.
INLINE Vector center() const
Returns the center of the box.
INLINE bool contains(const Vector &v) const
Checks if the vector lies inside the box.
INLINE Vector size() const
Returns box dimensions.
INLINE Float volume() const
Returns the volume of the box.
INLINE Vector clamp(const Vector &v) const
Clamps all components of the vector to fit within the box.
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.
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...
CylindricalDomain(const Vector ¢er, const Float radius, const Float height, const bool includeBases)
virtual Float getVolume() const override
Returns the total volume of the domain.
virtual Vector getCenter() const override
Returns the center of the domain.
virtual Float getSurfaceArea() const override
Returns the surface area of the domain.
virtual bool contains(const Vector &v) const override
Checks if the given point lies inside the domain.
virtual void project(ArrayView< Vector > vs, Optional< ArrayView< Size >> indices=NOTHING) const override
Projects vectors outside of the domain onto its boundary.
virtual void getDistanceToBoundary(ArrayView< const Vector > vs, Array< Float > &distances) const override
Returns distances of particles lying close to the boundary.
virtual Box getBoundingBox() const override
Returns the bounding box of the domain.
virtual Vector getCenter() const override
Returns the center of the domain.
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...
EllipsoidalDomain(const Vector ¢er, const Vector &axes)
virtual Float getVolume() const override
Returns the total volume of the domain.
virtual Float getSurfaceArea() const override
Returns the surface area of the domain.
virtual bool contains(const Vector &v) const override
Checks if the given point lies inside the domain.
virtual void getDistanceToBoundary(ArrayView< const Vector > vs, Array< Float > &distances) const override
Returns distances of particles lying close to the boundary.
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.
virtual Box getBoundingBox() const override
Returns the bounding box of the domain.
virtual void project(ArrayView< Vector > vs, Optional< ArrayView< Size >> indices=NOTHING) const override
Projects vectors outside of the domain onto its boundary.
virtual Float getVolume() const override
Returns the total volume of the domain.
GaussianRandomSphere(const Vector ¢er, const Float radius, const Float beta, const Size seed)
virtual void getDistanceToBoundary(ArrayView< const Vector > vs, Array< Float > &distances) const override
Returns distances of particles lying close to the boundary.
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.
virtual Vector getCenter() const override
Returns the center of the domain.
virtual Box getBoundingBox() const override
Returns the bounding box of the domain.
virtual bool contains(const Vector &v) const override
Checks if the given point lies inside the domain.
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...
virtual void project(ArrayView< Vector > vs, Optional< ArrayView< Size >> indices=NOTHING) const override
Projects vectors outside of the domain onto its boundary.
virtual Float getSurfaceArea() const override
Returns the surface area of the domain.
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.
virtual Vector getCenter() const override
Returns the center of the domain.
virtual bool contains(const Vector &v) const override
Checks if the given point lies inside the domain.
virtual Float getVolume() const override
Returns the total volume of the domain.
virtual Float getSurfaceArea() const override
Returns the surface area of the domain.
virtual Box getBoundingBox() const override
Returns the bounding box of the domain.
virtual void project(ArrayView< Vector > vs, Optional< ArrayView< Size >> indices=NOTHING) const override
Projects vectors outside of the domain onto its boundary.
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...
virtual void getDistanceToBoundary(ArrayView< const Vector > vs, Array< Float > &distances) const override
Returns distances of particles lying close to the boundary.
virtual Box getBoundingBox() const override
Returns the bounding box of the domain.
virtual void getDistanceToBoundary(ArrayView< const Vector >, Array< Float > &) const override
Returns distances of particles lying close to the boundary.
virtual Float getVolume() const override
Returns the total volume of the domain.
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.
HexagonalDomain(const Vector ¢er, const Float radius, const Float height, const bool includeBases)
virtual Float getSurfaceArea() const override
Returns the surface area of the domain.
virtual Vector getCenter() const override
Returns the center of the domain.
virtual void project(ArrayView< Vector > vs, Optional< ArrayView< Size >> indices=NOTHING) const override
Projects vectors outside of the domain onto its boundary.
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...
virtual bool contains(const Vector &v) const override
Checks if the given point lies inside the domain.
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.
Wrapper of type value of which may or may not be present.
virtual Float getSurfaceArea() const override
Returns the surface area of the domain.
virtual Box getBoundingBox() const override
Returns the bounding box of the domain.
virtual void getDistanceToBoundary(ArrayView< const Vector > vs, Array< Float > &distances) const override
Returns distances of particles lying close to the boundary.
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...
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.
virtual Float getVolume() const override
Returns the total volume of the domain.
virtual Vector getCenter() const override
Returns the center of the domain.
SphericalDomain(const Vector ¢er, const Float &radius)
virtual bool contains(const Vector &v) const override
Checks if the given point lies inside the domain.
virtual void project(ArrayView< Vector > vs, Optional< ArrayView< Size >> indices=NOTHING) const override
Projects vectors outside of the domain onto its boundary.
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.
virtual Float getVolume() const override
Returns the total volume of the domain.
virtual void getDistanceToBoundary(ArrayView< const Vector > vs, Array< Float > &distances) const override
Returns distances of particles lying close to the boundary.
virtual void project(ArrayView< Vector > vs, Optional< ArrayView< Size >> indices=NOTHING) const override
Projects vectors outside of the domain onto its boundary.
virtual Float getSurfaceArea() const override
Returns the surface area of the domain.
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...
TransformedDomain(SharedPtr< IDomain > domain, const AffineMatrix &matrix)
virtual Vector getCenter() const override
Returns the center of the domain.
virtual bool contains(const Vector &v) const override
Checks if the given point lies inside the domain.
virtual Box getBoundingBox() const override
Returns the bounding box of the domain.
Overload of std::swap for Sph::Array.