numerics 0.1.0
Loading...
Searching...
No Matches
sph_kernel.hpp
Go to the documentation of this file.
1/// @file spatial/sph_kernel.hpp
2/// @brief Dimension-generic SPH smoothing kernels.
3#pragma once
4
5#include <array>
6#include <cmath>
7
8namespace num {
9
10namespace detail {
11
12template<int Dim>
14template<>
15struct CubicSigma<2> {
16 static float compute(float h) { return 10.0f / (7.0f * 3.14159265f * h * h); }
17};
18template<>
19struct CubicSigma<3> {
20 static float compute(float h) { return 1.0f / (3.14159265f * h * h * h); }
21};
22
23template<int Dim>
24struct SpikyDW;
25template<>
26struct SpikyDW<2> {
27 static float compute(float r, float h) {
28 const float H = 2.0f * h;
29 if (r >= H)
30 return 0.0f;
31 const float h5 = h * h * h * h * h;
32 const float d = H - r;
33 return (-15.0f / (16.0f * 3.14159265f * h5)) * d * d;
34 }
35};
36template<>
37struct SpikyDW<3> {
38 static float compute(float r, float h) {
39 const float H = 2.0f * h;
40 if (r >= H || r < 1e-10f)
41 return 0.0f;
42 const float H6 = H * H * H * H * H * H;
43 const float d = H - r;
44 return -45.0f / (3.14159265f * H6) * d * d;
45 }
46};
47
48} // namespace detail
49
50template<int Dim>
51struct SPHKernel {
52 static_assert(Dim == 2 || Dim == 3, "SPHKernel: Dim must be 2 or 3");
53
54 static float W(float r, float h) {
55 const float sigma = detail::CubicSigma<Dim>::compute(h);
56 const float q = r / h;
57 if (q <= 1.0f)
58 return sigma * (1.0f - 1.5f * q * q + 0.75f * q * q * q);
59 if (q <= 2.0f) {
60 const float t = 2.0f - q;
61 return sigma * 0.25f * t * t * t;
62 }
63 return 0.0f;
64 }
65
66 static float dW_dr(float r, float h) {
67 const float sigma = detail::CubicSigma<Dim>::compute(h);
68 const float q = r / h;
69 if (q <= 1.0f)
70 return (sigma / h) * (-3.0f * q + 2.25f * q * q);
71 if (q <= 2.0f) {
72 const float t = 2.0f - q;
73 return (sigma / h) * (-0.75f * t * t);
74 }
75 return 0.0f;
76 }
77
78 static float Spiky_dW_dr(float r, float h) {
80 }
81
82 static std::array<float, Dim> Spiky_gradW(std::array<float, Dim> r_vec,
83 float r,
84 float h) {
85 std::array<float, Dim> g{};
86 if (r < 1e-10f || r >= 2.0f * h)
87 return g;
88 const float c = detail::SpikyDW<Dim>::compute(r, h) / r;
89 for (int d = 0; d < Dim; ++d)
90 g[d] = c * r_vec[d];
91 return g;
92 }
93};
94
95} // namespace num
static std::array< float, Dim > Spiky_gradW(std::array< float, Dim > r_vec, float r, float h)
static float dW_dr(float r, float h)
static float Spiky_dW_dr(float r, float h)
static float W(float r, float h)
static float compute(float h)
static float compute(float h)
static float compute(float r, float h)
static float compute(float r, float h)