SPH
Kernel.h
Go to the documentation of this file.
1 #pragma once
2 
7 
10 
12 
18 template <typename TDerived, Size D>
19 class Kernel : public Noncopyable {
20 public:
21  Kernel() = default;
22 
26  INLINE Float value(const Vector& r, const Float h) const noexcept {
27  SPH_ASSERT(h > 0._f);
28  const Float hInv = 1._f / h;
29  return pow<D>(hInv) * impl().valueImpl(getSqrLength(r) * sqr(hInv));
30  }
31 
32  INLINE Vector grad(const Vector& r, const Float h) const noexcept {
33  SPH_ASSERT(h > 0._f);
34  const Float hInv = 1._f / h;
35  return r * pow<D + 2>(hInv) * impl().gradImpl(getSqrLength(r) * sqr(hInv));
36  }
37 
38 private:
39  INLINE const TDerived& impl() const noexcept {
40  return static_cast<const TDerived&>(*this);
41  }
42 };
43 
44 
50 template <Size D>
51 class LutKernel : public Kernel<LutKernel<D>, D> {
52 private:
53  static constexpr Size NEntries = 40000;
54 
55  Array<Float> values;
56  Array<Float> grads;
57 
58  Float rad = 0._f;
59  Float qSqrToIdx = 0._f;
60 
61 public:
62  LutKernel() = default;
63 
64  LutKernel(const LutKernel& other) {
65  *this = other;
66  }
67 
68  LutKernel(LutKernel&& other) {
69  *this = std::move(other);
70  }
71 
72  LutKernel& operator=(const LutKernel& other) {
73  rad = other.rad;
74  qSqrToIdx = other.qSqrToIdx;
75  values = copyable(other.values);
76  grads = copyable(other.grads);
77  return *this;
78  }
79 
80  LutKernel& operator=(LutKernel&& other) = default;
81 
83  template <typename TKernel,
84  typename = std::enable_if_t<!std::is_same<std::decay_t<TKernel>, LutKernel<D>>::value>>
85  LutKernel(TKernel&& source) {
86  rad = source.radius();
87 
88  SPH_ASSERT(rad > 0._f);
89  const Float radInvSqr = 1._f / (rad * rad);
90  qSqrToIdx = Float(NEntries) * radInvSqr;
91 
92  // allocate and set NEntries + 1 for correct interpolation of the last value
93  values.resize(NEntries + 1);
94  grads.resize(NEntries + 1);
95  for (Size i = 0; i < NEntries + 1; ++i) {
96  const Float qSqr = Float(i) / qSqrToIdx;
97  values[i] = source.valueImpl(qSqr);
98  grads[i] = source.gradImpl(qSqr);
99  }
101  }
102 
103  INLINE bool isInit() const {
104  return rad > 0._f;
105  }
106 
107  INLINE Float radius() const noexcept {
108  return rad;
109  }
110 
111  INLINE Float valueImpl(const Float qSqr) const noexcept {
112  SPH_ASSERT(qSqr >= 0._f);
113  SPH_ASSERT(isInit());
114  if (SPH_UNLIKELY(qSqr >= sqr(rad))) {
115  // outside of kernel support
116  return 0._f;
117  }
118  // linear interpolation of stored values
119  const Float floatIdx = qSqrToIdx * qSqr;
120  const Size idx1 = Size(floatIdx);
121  SPH_ASSERT(idx1 < NEntries);
122  const Size idx2 = idx1 + 1;
123  const Float ratio = floatIdx - Float(idx1);
124  SPH_ASSERT(ratio >= 0._f && ratio < 1._f);
125 
126  return values[idx1] * (1._f - ratio) + values[idx2] * ratio;
127  }
128 
129  INLINE Float gradImpl(const Float qSqr) const noexcept {
130  SPH_ASSERT(qSqr >= 0._f);
131  SPH_ASSERT(isInit());
132  if (SPH_UNLIKELY(qSqr >= sqr(rad))) {
133  // outside of kernel support
134  return 0._f;
135  }
136  const Float floatIdx = qSqrToIdx * qSqr;
137  const Size idx1 = Size(floatIdx);
138  SPH_ASSERT(unsigned(idx1) < unsigned(NEntries));
139  const Size idx2 = idx1 + 1;
140  const Float ratio = floatIdx - Float(idx1);
141  SPH_ASSERT(ratio >= 0._f && ratio < 1._f);
142 
143  return grads[idx1] * (1._f - ratio) + grads[idx2] * ratio;
144  }
145 };
146 
147 
149 template <Size D>
150 class CubicSpline : public Kernel<CubicSpline<D>, D> {
151 private:
152  const Float normalization[3] = { 2._f / 3._f, 10._f / (7._f * PI), 1._f / PI };
153 
154 public:
155  INLINE Float radius() const {
156  return 2._f;
157  }
158 
159  // template <bool TApprox = false>
160  INLINE Float valueImpl(const Float qSqr) const {
161  const Float q = sqrt(qSqr);
162  SPH_ASSERT(q >= 0);
163  if (q < 1._f) {
164  return normalization[D - 1] * (0.25_f * pow<3>(2._f - q) - pow<3>(1._f - q));
165  }
166  if (q < 2._f) {
167  return normalization[D - 1] * (0.25_f * pow<3>(2._f - q));
168  }
169  return 0._f; // compact within 2r radius
170  }
171 
172  // template <bool TApprox = false>
173  INLINE Float gradImpl(const Float qSqr) const {
174  const Float q = sqrt(qSqr);
175  if (q == 0._f) {
176  // gradient of kernel is 0 at q = 0, but here we divide by q,
177  // the expression grad/q has a finite limit for q->0
178  return -3._f * normalization[D - 1];
179  }
180  if (q < 1._f) {
181  return (1._f / q) * normalization[D - 1] * (-0.75_f * pow<2>(2._f - q) + 3._f * pow<2>(1._f - q));
182  }
183  if (q < 2._f) {
184  return (1._f / q) * normalization[D - 1] * (-0.75_f * pow<2>(2._f - q));
185  }
186  return 0._f;
187  }
188 };
189 
191 template <Size D>
192 class FourthOrderSpline : public Kernel<FourthOrderSpline<D>, D> {
193 private:
194  const Float normalization[3] = { 1._f / 24._f, 96._f / (1199._f * PI), 1._f / (20._f * PI) };
195 
196 public:
197  INLINE Float radius() const {
198  return 2.5_f;
199  }
200 
201  // template <bool TApprox = false>
202  INLINE Float valueImpl(const Float qSqr) const {
203  const Float q = sqrt(qSqr);
204  SPH_ASSERT(q >= 0);
205  if (q < 0.5_f) {
206  return normalization[D - 1] *
207  (pow<4>(2.5_f - q) - 5._f * pow<4>(1.5_f - q) + 10._f * pow<4>(0.5_f - q));
208  }
209  if (q < 1.5_f) {
210  return normalization[D - 1] * (pow<4>(2.5_f - q) - 5._f * pow<4>(1.5_f - q));
211  }
212  if (q < 2.5_f) {
213  return normalization[D - 1] * (pow<4>(2.5_f - q));
214  }
215  return 0._f; // compact within 2r radius
216  }
217 
218  // template <bool TApprox = false>
219  INLINE Float gradImpl(const Float qSqr) const {
220  const Float q = sqrt(qSqr);
221  if (q == 0._f) {
222  return -30._f * normalization[D - 1];
223  }
224  if (q < 0.5_f) {
225  return (1._f / q) * normalization[D - 1] *
226  (-4._f * pow<3>(2.5_f - q) + 20._f * pow<3>(1.5_f - q) - 40._f * pow<3>(0.5_f - q));
227  }
228  if (q < 1.5_f) {
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));
231  }
232  if (q < 2.5_f) {
233  return (1._f / q) * normalization[D - 1] * (-4._f * pow<3>(2.5_f - q));
234  }
235  return 0._f;
236  }
237 };
238 
242 class CoreTriangle : public Kernel<CoreTriangle, 3> {
243 private:
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));
247 
248 public:
249  INLINE Float radius() const {
250  return 1._f;
251  }
252 
253  INLINE Float valueImpl(const Float qSqr) const {
254  const Float q = sqrt(qSqr);
255 
256  if (q < alpha) {
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);
262  } else {
263  return 0._f;
264  }
265  }
266 
267  INLINE Float gradImpl(const Float qSqr) const {
268  const Float q = sqrt(qSqr);
269  if (q < alpha) {
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));
275  } else {
276  return 0._f;
277  }
278  }
279 };
280 
285 template <Size D>
286 class ThomasCouchmanKernel : public Kernel<ThomasCouchmanKernel<D>, D> {
287 private:
288  CubicSpline<D> M4;
289 
290  const Float normalization[3] = { 2._f / 3._f, 10._f / (7._f * PI), 1._f / PI };
291 
292 public:
293  INLINE Float radius() const {
294  return 2._f;
295  }
296 
297  INLINE Float valueImpl(const Float qSqr) const {
298  return M4.valueImpl(qSqr);
299  }
300 
301  INLINE Float gradImpl(const Float qSqr) const {
302  const Float q = sqrt(qSqr);
303  if (q == 0._f) {
304  // this kernel has discontinuous gradient - it is nonzero for q->0, so the value for q = 0 is
305  // undefined (it is a "0/0" expression). To avoid this, return a reasonably high (nonzero) number.
306  return -100._f;
307  }
308  if (q < 2._f / 3._f) {
309  return -(1._f / q) * normalization[D - 1];
310  }
311  if (q < 1._f) {
312  return (1._f / q) * normalization[D - 1] * (-0.75_f * q * (4._f - 3._f * q));
313  }
314  if (q < 2._f) {
315  return (1._f / q) * normalization[D - 1] * (-0.75_f * pow<2>(2._f - q));
316  }
317  return 0._f;
318  }
319 };
320 
321 class WendlandC2 : public Kernel<WendlandC2, 3> {
322 private:
323  const Float normalization = 21._f / (16._f * PI);
324 
325 public:
326  INLINE Float radius() const {
327  return 2._f;
328  }
329 
330  INLINE Float valueImpl(const Float qSqr) const {
331  const Float q = sqrt(qSqr);
332  SPH_ASSERT(q >= 0);
333  if (q < 2._f) {
334  return normalization * pow<4>(1._f - 0.5_f * q) * (2._f * q + 1._f);
335  }
336  return 0._f;
337  }
338 
339  INLINE Float gradImpl(const Float qSqr) const {
340  const Float q = sqrt(qSqr);
341  if (q == 0._f) {
342  return -5._f * normalization;
343  }
344  if (q < 2._f) {
345  return (1._f / q) * normalization * 0.625_f * pow<3>(q - 2._f) * q;
346  }
347  return 0._f;
348  }
349 };
350 
351 class WendlandC4 : public Kernel<WendlandC4, 3> {
352 private:
353  const Float normalization = 495._f / (256._f * PI);
354 
355 public:
356  INLINE Float radius() const {
357  return 2._f;
358  }
359 
360  INLINE Float valueImpl(const Float qSqr) const {
361  const Float q = sqrt(qSqr);
362  SPH_ASSERT(q >= 0);
363  if (q < 2._f) {
364  return normalization * pow<6>(1._f - 0.5_f * q) * (35._f / 12._f * pow<2>(q) + 3._f * q + 1._f);
365  }
366  return 0._f;
367  }
368 
369  INLINE Float gradImpl(const Float qSqr) const {
370  const Float q = sqrt(qSqr);
371  if (q == 0._f) {
372  return -14._f / 3._f * normalization;
373  }
374  if (q < 2._f) {
375  return (1._f / q) * normalization *
376  (7._f / 96._f * q *
377  (5._f * pow<6>(q) - 48._f * pow<5>(q) + 180._f * pow<4>(q) - 320._f * pow<3>(q) +
378  240._f * pow<2>(q) - 64._f));
379  }
380  return 0._f;
381  }
382 };
383 
384 class WendlandC6 : public Kernel<WendlandC6, 3> {
385 private:
386  const Float normalization = 1365._f / (512._f * PI);
387 
388 public:
389  INLINE Float radius() const {
390  return 2._f;
391  }
392 
393  INLINE Float valueImpl(const Float qSqr) const {
394  const Float q = sqrt(qSqr);
395  SPH_ASSERT(q >= 0);
396  if (q < 2._f) {
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);
399  }
400  return 0._f;
401  }
402 
403  INLINE Float gradImpl(const Float qSqr) const {
404  const Float q = sqrt(qSqr);
405  if (q == 0._f) {
406  return -5.5_f * normalization;
407  }
408  if (q < 2._f) {
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);
411  }
412  return 0._f;
413  }
414 };
415 
419 template <Size D>
420 class Gaussian : public Kernel<Gaussian<D>, D> {
421 private:
422  const Float normalization[3] = { 1._f / sqrt(PI), 1._f / PI, 1._f / (PI * sqrt(PI)) };
423 
424 public:
425  INLINE Float radius() const {
426  return 5._f;
427  }
428 
429  INLINE Float valueImpl(const Float qSqr) const {
430  if (qSqr >= sqr(radius())) {
431  return 0._f;
432  }
433  return normalization[D - 1] * exp(-qSqr);
434  }
435 
436  INLINE Float gradImpl(const Float qSqr) const {
437  if (qSqr >= sqr(radius())) {
438  return 0._f;
439  }
440  if (qSqr == 0._f) {
441  return -2._f * normalization[D - 1];
442  }
443  const Float q = sqrt(qSqr);
444  return normalization[D - 1] / q * exp(-qSqr) * (-2._f * q);
445  }
446 };
447 
451 template <Size D>
452 class TriangleKernel : public Kernel<TriangleKernel<D>, D> {
453 private:
454  const Float normalization[3] = { 1._f, 3._f / PI, 3._f / PI };
455 
456 public:
457  INLINE Float radius() const {
458  return 1._f;
459  }
460 
461  INLINE Float valueImpl(const Float qSqr) const {
462  if (qSqr >= sqr(radius())) {
463  return 0._f;
464  }
465  const Float q = sqrt(qSqr);
466  return normalization[D - 1] * (1._f - q);
467  }
468 
469  INLINE Float gradImpl(const Float qSqr) const {
470  if (qSqr >= sqr(radius())) {
471  return 0._f;
472  }
473  // unfortunately this gradient is nonzero at q->0, so grad/q diverges;
474  // let's return a reasonable value to avoid numerical problems
475  if (qSqr == 0._f) {
476  return -100._f;
477  }
478  const Float q = sqrt(qSqr);
479  return -normalization[D - 1] / q;
480  }
481 };
482 
484 template <Size D, typename TKernel>
485 class ScalingKernel : public Kernel<ScalingKernel<D, TKernel>, D> {
486 private:
487  TKernel kernel;
488  Float scaling;
489 
490 public:
491  explicit ScalingKernel(const Float newRadius) {
492  scaling = newRadius / kernel.radius();
493  }
494 
495  INLINE Float radius() const {
496  return scaling * kernel.radius();
497  }
498 
499  INLINE Float valueImpl(const Float qSqr) const {
500  return kernel.valueImpl(qSqr / sqr(scaling)) / pow<D>(scaling);
501  }
502 
503  INLINE Float gradImpl(const Float qSqr) const {
504  return kernel.gradImpl(qSqr / sqr(scaling)) / pow<D + 2>(scaling);
505  }
506 };
507 
518 template <typename T>
519 INLINE T laplacian(const T& value, const Vector& grad, const Vector& dr) {
520  SPH_ASSERT(dr != Vector(0._f));
521  return 2._f * value * dot(dr, grad) / getSqrLength(dr);
522 }
523 
527 INLINE Vector gradientOfDivergence(const Vector& value, const Vector& grad, const Vector& dr) {
528  SPH_ASSERT(dr != Vector(0._f));
529  const Float rSqr = getSqrLength(dr);
530  const Float f = dot(dr, grad) / rSqr;
531  return (DIMENSIONS + 2) * dot(value, dr) * dr * f / rSqr - value * f;
532 }
533 
534 
538 template <typename TKernel>
540 private:
541  TKernel kernel;
542 
543 public:
544  template <typename... TArgs>
545  SymmetrizeValues(TArgs&&... args)
546  : kernel(std::forward<TArgs>(args)...) {}
547 
548  INLINE Float value(const Vector& r1, const Vector& r2) const {
549  SPH_ASSERT(r1[H] > 0 && r2[H] > 0, r1[H], r2[H]);
550  return 0.5_f * (kernel.value(r1 - r2, r1[H]) + kernel.value(r1 - r2, r2[H]));
551  }
552 
553  INLINE Vector grad(const Vector& r1, const Vector& r2) const {
554  SPH_ASSERT(r1[H] > 0 && r2[H] > 0, r1[H], r2[H]);
555  return 0.5_f * (kernel.grad(r1 - r2, r1[H]) + kernel.grad(r1 - r2, r2[H]));
556  }
557 
558  INLINE Float radius() const {
559  return kernel.radius();
560  }
561 };
562 
563 template <typename TKernel>
565 private:
566  TKernel kernel;
567 
568 public:
569  template <typename... TArgs>
570  SymmetrizeSmoothingLengths(TArgs&&... args)
571  : kernel(std::forward<TArgs>(args)...) {}
572 
573  INLINE Float value(const Vector& r1, const Vector& r2) const {
574  SPH_ASSERT(r1[H] > 0 && r2[H] > 0, r1[H], r2[H]);
575  return kernel.value(r1 - r2, 0.5_f * (r1[H] + r2[H]));
576  }
577 
578  INLINE Vector grad(const Vector& r1, const Vector& r2) const {
579  SPH_ASSERT(r1[H] > 0 && r2[H] > 0, r1[H], r2[H]);
580  return kernel.grad(r1 - r2, 0.5_f * (r1[H] + r2[H]));
581  }
582 
583  INLINE Float radius() const {
584  return kernel.radius();
585  }
586 };
587 
588 template <typename T, typename = void>
589 struct IsKernel {
590  static constexpr bool value = false;
591 };
592 
593 template <typename T>
594 struct IsKernel<T, VoidType<decltype(std::declval<T>().radius())>> {
595  static constexpr bool value = true;
596 };
597 
Generic dynamically allocated resizable storage.
INLINE CopyableArray< T, TAllocator, TCounter > copyable(const Array< T, TAllocator, TCounter > &array)
Definition: Array.h:558
#define SPH_ASSERT(x,...)
Definition: Assert.h:94
NAMESPACE_SPH_BEGIN
Definition: BarnesHut.cpp:13
const float radius
Definition: CurveDialog.cpp:18
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 int DIMENSIONS
Number of spatial dimensions in the code.
Definition: Globals.h:22
INLINE Vector gradientOfDivergence(const Vector &value, const Vector &grad, const Vector &dr)
Second derivative of vector quantity, applying gradient on a divergence.
Definition: Kernel.h:527
INLINE T laplacian(const T &value, const Vector &grad, const Vector &dr)
SPH approximation of laplacian, computed from a kernel gradient.
Definition: Kernel.h:519
constexpr INLINE Float pow< 5 >(const Float v)
Definition: MathUtils.h:140
constexpr INLINE T sqr(const T &f) noexcept
Return a squared value.
Definition: MathUtils.h:67
INLINE T sqrt(const T f)
Return a squared root of a value.
Definition: MathUtils.h:78
constexpr INLINE Float pow< 3 >(const Float v)
Definition: MathUtils.h:132
constexpr INLINE Float pow< 4 >(const Float v)
Definition: MathUtils.h:136
constexpr INLINE Float pow< 6 >(const Float v)
Definition: MathUtils.h:144
INLINE T exp(const T f)
Definition: MathUtils.h:269
constexpr INLINE Float pow< 2 >(const Float v)
Definition: MathUtils.h:128
constexpr INLINE Float pow< 7 >(const Float v)
Definition: MathUtils.h:148
constexpr INLINE Float pow< 8 >(const Float v)
Definition: MathUtils.h:152
constexpr Float PI
Mathematical constants.
Definition: MathUtils.h:361
#define INLINE
Macros for conditional compilation based on selected compiler.
Definition: Object.h:31
#define SPH_UNLIKELY(x)
Definition: Object.h:50
#define NAMESPACE_SPH_END
Definition: Object.h:12
typename MakeVoid< Ts... >::Type VoidType
Definition: Traits.h:49
Basic vector algebra. Computations are accelerated using SIMD.
INLINE Float getSqrLength(const Vector &v)
Definition: Vector.h:574
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
@ H
Definition: Vector.h:25
void resize(const TCounter newSize)
Resizes the array to new size.
Definition: Array.h:215
Kernel proposed by Read et al. (2010) with improved stability.
Definition: Kernel.h:242
INLINE Float gradImpl(const Float qSqr) const
Definition: Kernel.h:267
INLINE Float valueImpl(const Float qSqr) const
Definition: Kernel.h:253
INLINE Float radius() const
Definition: Kernel.h:249
Cubic spline (M4) kernel.
Definition: Kernel.h:150
INLINE Float gradImpl(const Float qSqr) const
Definition: Kernel.h:173
INLINE Float valueImpl(const Float qSqr) const
Definition: Kernel.h:160
INLINE Float radius() const
Definition: Kernel.h:155
Fourth-order spline (M5) kernel.
Definition: Kernel.h:192
INLINE Float valueImpl(const Float qSqr) const
Definition: Kernel.h:202
INLINE Float gradImpl(const Float qSqr) const
Definition: Kernel.h:219
INLINE Float radius() const
Definition: Kernel.h:197
Gaussian kernel.
Definition: Kernel.h:420
INLINE Float valueImpl(const Float qSqr) const
Definition: Kernel.h:429
INLINE Float radius() const
Definition: Kernel.h:425
INLINE Float gradImpl(const Float qSqr) const
Definition: Kernel.h:436
Base class for all SPH kernels.
Definition: Kernel.h:19
INLINE Float value(const Vector &r, const Float h) const noexcept
Definition: Kernel.h:26
Kernel()=default
INLINE Vector grad(const Vector &r, const Float h) const noexcept
Definition: Kernel.h:32
A look-up table approximation of the kernel.
Definition: Kernel.h:51
LutKernel & operator=(const LutKernel &other)
Definition: Kernel.h:72
LutKernel(const LutKernel &other)
Definition: Kernel.h:64
INLINE Float valueImpl(const Float qSqr) const noexcept
Definition: Kernel.h:111
INLINE Float radius() const noexcept
Definition: Kernel.h:107
INLINE bool isInit() const
Definition: Kernel.h:103
LutKernel(TKernel &&source)
Constructs LUT kernel given an exact SPH kernel.
Definition: Kernel.h:85
LutKernel()=default
LutKernel(LutKernel &&other)
Definition: Kernel.h:68
LutKernel & operator=(LutKernel &&other)=default
INLINE Float gradImpl(const Float qSqr) const noexcept
Definition: Kernel.h:129
Helper kernel wrapper that modifies the support of another kernel.
Definition: Kernel.h:485
INLINE Float radius() const
Definition: Kernel.h:495
ScalingKernel(const Float newRadius)
Definition: Kernel.h:491
INLINE Float gradImpl(const Float qSqr) const
Definition: Kernel.h:503
INLINE Float valueImpl(const Float qSqr) const
Definition: Kernel.h:499
SymmetrizeSmoothingLengths(TArgs &&... args)
Definition: Kernel.h:570
INLINE Float value(const Vector &r1, const Vector &r2) const
Definition: Kernel.h:573
INLINE Float radius() const
Definition: Kernel.h:583
INLINE Vector grad(const Vector &r1, const Vector &r2) const
Definition: Kernel.h:578
INLINE Vector grad(const Vector &r1, const Vector &r2) const
Definition: Kernel.h:553
INLINE Float radius() const
Definition: Kernel.h:558
INLINE Float value(const Vector &r1, const Vector &r2) const
Definition: Kernel.h:548
SymmetrizeValues(TArgs &&... args)
Definition: Kernel.h:545
Kernel introduced by Thomas & Couchman (1992).
Definition: Kernel.h:286
INLINE Float gradImpl(const Float qSqr) const
Definition: Kernel.h:301
INLINE Float valueImpl(const Float qSqr) const
Definition: Kernel.h:297
INLINE Float radius() const
Definition: Kernel.h:293
Triangular (piecewise linear) kernel.
Definition: Kernel.h:452
INLINE Float valueImpl(const Float qSqr) const
Definition: Kernel.h:461
INLINE Float gradImpl(const Float qSqr) const
Definition: Kernel.h:469
INLINE Float radius() const
Definition: Kernel.h:457
INLINE Float valueImpl(const Float qSqr) const
Definition: Kernel.h:330
INLINE Float radius() const
Definition: Kernel.h:326
INLINE Float gradImpl(const Float qSqr) const
Definition: Kernel.h:339
INLINE Float radius() const
Definition: Kernel.h:356
INLINE Float gradImpl(const Float qSqr) const
Definition: Kernel.h:369
INLINE Float valueImpl(const Float qSqr) const
Definition: Kernel.h:360
INLINE Float valueImpl(const Float qSqr) const
Definition: Kernel.h:393
INLINE Float gradImpl(const Float qSqr) const
Definition: Kernel.h:403
INLINE Float radius() const
Definition: Kernel.h:389
Overload of std::swap for Sph::Array.
Definition: Array.h:578
static constexpr bool value
Definition: Kernel.h:590
Object with deleted copy constructor and copy operator.
Definition: Object.h:54