18 template <
typename TDerived, Size D>
28 const Float hInv = 1._f / h;
34 const Float hInv = 1._f / h;
35 return r * pow<D + 2>(hInv) * impl().gradImpl(
getSqrLength(r) *
sqr(hInv));
39 INLINE const TDerived& impl() const noexcept {
40 return static_cast<const TDerived&
>(*this);
53 static constexpr
Size NEntries = 40000;
59 Float qSqrToIdx = 0._f;
69 *
this = std::move(other);
74 qSqrToIdx = other.qSqrToIdx;
83 template <
typename TKernel,
86 rad = source.radius();
89 const Float radInvSqr = 1._f / (rad * rad);
90 qSqrToIdx =
Float(NEntries) * radInvSqr;
93 values.
resize(NEntries + 1);
94 grads.
resize(NEntries + 1);
95 for (
Size i = 0; i < NEntries + 1; ++i) {
97 values[i] = source.valueImpl(qSqr);
98 grads[i] = source.gradImpl(qSqr);
119 const Float floatIdx = qSqrToIdx * qSqr;
122 const Size idx2 = idx1 + 1;
126 return values[idx1] * (1._f - ratio) + values[idx2] * ratio;
136 const Float floatIdx = qSqrToIdx * qSqr;
138 SPH_ASSERT(
unsigned(idx1) <
unsigned(NEntries));
139 const Size idx2 = idx1 + 1;
143 return grads[idx1] * (1._f - ratio) + grads[idx2] * ratio;
152 const Float normalization[3] = { 2._f / 3._f, 10._f / (7._f *
PI), 1._f /
PI };
164 return normalization[D - 1] * (0.25_f *
pow<3>(2._f - q) -
pow<3>(1._f - q));
167 return normalization[D - 1] * (0.25_f *
pow<3>(2._f - q));
178 return -3._f * normalization[D - 1];
181 return (1._f / q) * normalization[D - 1] * (-0.75_f *
pow<2>(2._f - q) + 3._f *
pow<2>(1._f - q));
184 return (1._f / q) * normalization[D - 1] * (-0.75_f *
pow<2>(2._f - q));
194 const Float normalization[3] = { 1._f / 24._f, 96._f / (1199._f *
PI), 1._f / (20._f *
PI) };
206 return normalization[D - 1] *
210 return normalization[D - 1] * (
pow<4>(2.5_f - q) - 5._f *
pow<4>(1.5_f - q));
213 return normalization[D - 1] * (
pow<4>(2.5_f - q));
222 return -30._f * normalization[D - 1];
225 return (1._f / q) * normalization[D - 1] *
229 return (1._f / q) * normalization[D - 1] *
230 (-4._f *
pow<3>(2.5_f - q) + 20._f *
pow<3>(1.5_f - q));
233 return (1._f / q) * normalization[D - 1] * (-4._f *
pow<3>(2.5_f - q));
244 const Float alpha = 1._f / 3._f;
245 const Float beta = 1._f + 6._f *
sqr(alpha) - 12._f *
pow<3>(alpha);
246 const Float normalization = 8._f / (
PI * (6.4_f *
pow<5>(alpha) - 16._f *
pow<6>(alpha) + 1._f));
257 return normalization * ((-12._f * alpha + 18._f *
sqr(alpha)) * q + beta);
258 }
else if (q < 0.5_f) {
259 return normalization * (1._f - 6._f *
sqr(q) * (1._f - q));
260 }
else if (q < 1._f) {
261 return normalization * 2._f *
pow<3>(1._f - q);
270 return normalization / q * (-12._f * alpha + 18._f *
sqr(alpha));
271 }
else if (q < 0.5_f) {
272 return normalization / q * (-12._f * q + 18._f *
sqr(q));
273 }
else if (q < 1._f) {
274 return normalization / q * (-6._f *
sqr(1._f - q));
290 const Float normalization[3] = { 2._f / 3._f, 10._f / (7._f *
PI), 1._f /
PI };
308 if (q < 2._f / 3._f) {
309 return -(1._f / q) * normalization[D - 1];
312 return (1._f / q) * normalization[D - 1] * (-0.75_f * q * (4._f - 3._f * q));
315 return (1._f / q) * normalization[D - 1] * (-0.75_f *
pow<2>(2._f - q));
323 const Float normalization = 21._f / (16._f *
PI);
334 return normalization *
pow<4>(1._f - 0.5_f * q) * (2._f * q + 1._f);
342 return -5._f * normalization;
345 return (1._f / q) * normalization * 0.625_f *
pow<3>(q - 2._f) * q;
353 const Float normalization = 495._f / (256._f *
PI);
364 return normalization *
pow<6>(1._f - 0.5_f * q) * (35._f / 12._f *
pow<2>(q) + 3._f * q + 1._f);
372 return -14._f / 3._f * normalization;
375 return (1._f / q) * normalization *
378 240._f *
pow<2>(q) - 64._f));
386 const Float normalization = 1365._f / (512._f *
PI);
397 return normalization *
pow<8>(1._f - 0.5_f * q) *
398 (4._f *
pow<3>(q) + 25._f / 4._f *
pow<2>(q) + 4._f * q + 1._f);
406 return -5.5_f * normalization;
409 return (1._f / q) * normalization * 0.0214844_f *
pow<7>(q - 2._f) * q *
410 (8._f *
pow<2>(q) + 7._f * q + 2._f);
433 return normalization[D - 1] *
exp(-qSqr);
441 return -2._f * normalization[D - 1];
444 return normalization[D - 1] / q *
exp(-qSqr) * (-2._f * q);
454 const Float normalization[3] = { 1._f, 3._f /
PI, 3._f /
PI };
466 return normalization[D - 1] * (1._f - q);
479 return -normalization[D - 1] / q;
484 template <Size D,
typename TKernel>
492 scaling = newRadius / kernel.radius();
496 return scaling * kernel.radius();
500 return kernel.valueImpl(qSqr /
sqr(scaling)) / pow<D>(scaling);
504 return kernel.gradImpl(qSqr /
sqr(scaling)) / pow<D + 2>(scaling);
518 template <
typename T>
530 const Float f =
dot(dr, grad) / rSqr;
531 return (
DIMENSIONS + 2) *
dot(value, dr) * dr * f / rSqr - value * f;
538 template <
typename TKernel>
544 template <
typename... TArgs>
546 : kernel(
std::forward<TArgs>(args)...) {}
550 return 0.5_f * (kernel.value(r1 - r2, r1[
H]) + kernel.value(r1 - r2, r2[
H]));
555 return 0.5_f * (kernel.grad(r1 - r2, r1[
H]) + kernel.grad(r1 - r2, r2[
H]));
559 return kernel.radius();
563 template <
typename TKernel>
569 template <
typename... TArgs>
571 : kernel(
std::forward<TArgs>(args)...) {}
575 return kernel.value(r1 - r2, 0.5_f * (r1[
H] + r2[
H]));
580 return kernel.grad(r1 - r2, 0.5_f * (r1[
H] + r2[
H]));
584 return kernel.radius();
588 template <
typename T,
typename =
void>
590 static constexpr
bool value =
false;
593 template <
typename T>
Generic dynamically allocated resizable storage.
INLINE CopyableArray< T, TAllocator, TCounter > copyable(const Array< T, TAllocator, TCounter > &array)
#define SPH_ASSERT(x,...)
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 int DIMENSIONS
Number of spatial dimensions in the code.
INLINE Vector gradientOfDivergence(const Vector &value, const Vector &grad, const Vector &dr)
Second derivative of vector quantity, applying gradient on a divergence.
INLINE T laplacian(const T &value, const Vector &grad, const Vector &dr)
SPH approximation of laplacian, computed from a kernel gradient.
constexpr INLINE Float pow< 5 >(const Float v)
constexpr INLINE T sqr(const T &f) noexcept
Return a squared value.
INLINE T sqrt(const T f)
Return a squared root of a value.
constexpr INLINE Float pow< 3 >(const Float v)
constexpr INLINE Float pow< 4 >(const Float v)
constexpr INLINE Float pow< 6 >(const Float v)
constexpr INLINE Float pow< 2 >(const Float v)
constexpr INLINE Float pow< 7 >(const Float v)
constexpr INLINE Float pow< 8 >(const Float v)
constexpr Float PI
Mathematical constants.
#define INLINE
Macros for conditional compilation based on selected compiler.
#define NAMESPACE_SPH_END
typename MakeVoid< Ts... >::Type VoidType
Basic vector algebra. Computations are accelerated using SIMD.
INLINE Float getSqrLength(const Vector &v)
BasicVector< Float > Vector
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...
void resize(const TCounter newSize)
Resizes the array to new size.
Kernel proposed by Read et al. (2010) with improved stability.
INLINE Float gradImpl(const Float qSqr) const
INLINE Float valueImpl(const Float qSqr) const
INLINE Float radius() const
Cubic spline (M4) kernel.
INLINE Float gradImpl(const Float qSqr) const
INLINE Float valueImpl(const Float qSqr) const
INLINE Float radius() const
Fourth-order spline (M5) kernel.
INLINE Float valueImpl(const Float qSqr) const
INLINE Float gradImpl(const Float qSqr) const
INLINE Float radius() const
INLINE Float valueImpl(const Float qSqr) const
INLINE Float radius() const
INLINE Float gradImpl(const Float qSqr) const
Base class for all SPH kernels.
INLINE Float value(const Vector &r, const Float h) const noexcept
INLINE Vector grad(const Vector &r, const Float h) const noexcept
A look-up table approximation of the kernel.
LutKernel & operator=(const LutKernel &other)
LutKernel(const LutKernel &other)
INLINE Float valueImpl(const Float qSqr) const noexcept
INLINE Float radius() const noexcept
INLINE bool isInit() const
LutKernel(TKernel &&source)
Constructs LUT kernel given an exact SPH kernel.
LutKernel(LutKernel &&other)
LutKernel & operator=(LutKernel &&other)=default
INLINE Float gradImpl(const Float qSqr) const noexcept
Helper kernel wrapper that modifies the support of another kernel.
INLINE Float radius() const
ScalingKernel(const Float newRadius)
INLINE Float gradImpl(const Float qSqr) const
INLINE Float valueImpl(const Float qSqr) const
SymmetrizeSmoothingLengths(TArgs &&... args)
INLINE Float value(const Vector &r1, const Vector &r2) const
INLINE Float radius() const
INLINE Vector grad(const Vector &r1, const Vector &r2) const
INLINE Vector grad(const Vector &r1, const Vector &r2) const
INLINE Float radius() const
INLINE Float value(const Vector &r1, const Vector &r2) const
SymmetrizeValues(TArgs &&... args)
Kernel introduced by Thomas & Couchman (1992).
INLINE Float gradImpl(const Float qSqr) const
INLINE Float valueImpl(const Float qSqr) const
INLINE Float radius() const
Triangular (piecewise linear) kernel.
INLINE Float valueImpl(const Float qSqr) const
INLINE Float gradImpl(const Float qSqr) const
INLINE Float radius() const
INLINE Float valueImpl(const Float qSqr) const
INLINE Float radius() const
INLINE Float gradImpl(const Float qSqr) const
INLINE Float radius() const
INLINE Float gradImpl(const Float qSqr) const
INLINE Float valueImpl(const Float qSqr) const
INLINE Float valueImpl(const Float qSqr) const
INLINE Float gradImpl(const Float qSqr) const
INLINE Float radius() const
Overload of std::swap for Sph::Array.
static constexpr bool value
Object with deleted copy constructor and copy operator.