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///
4/// SPHKernel<2> -- 2D kernels (cubic sigma = 10/(7*pi*h^2), spiky =
5/// -15/(16*pi*h^5) (2h-r)^2) SPHKernel<3> -- 3D kernels (cubic sigma =
6/// 1/(pi*h^3), spiky = -45/(pi*(2h)^6) (2h-r)^2)
7///
8/// Support radius 2h throughout; q = r/h.
9///
10/// Cubic spline (density + Morris viscosity Laplacian):
11/// W = sigma * { 1 - 1.5q^2 + 0.75q^3 q <= 1
12/// { 0.25(2-q)^3 1 < q <= 2
13/// dW/dr = sigma/h * { -3q + 2.25q^2 q <= 1
14/// { -0.75(2-q)^2 1 < q <= 2
15///
16/// Spiky kernel (pressure gradient -- dW/dr != 0 as r->0 prevents clustering):
17/// dW/dr < 0, Spiky_gradW returns (dW/dr / r) * r_vec
18///
19/// Spiky_gradW takes std::array<float, Dim> and returns std::array<float, Dim>.
20#pragma once
21
22#include <cmath>
23#include <array>
24
25namespace num {
26
27namespace detail {
28
29template<int Dim>
31template<>
32struct CubicSigma<2> {
33 static float compute(float h) {
34 return 10.0f / (7.0f * 3.14159265f * h * h);
35 }
36};
37template<>
38struct CubicSigma<3> {
39 static float compute(float h) {
40 return 1.0f / (3.14159265f * h * h * h);
41 }
42};
43
44template<int Dim>
45struct SpikyDW;
46template<>
47struct SpikyDW<2> {
48 // dW/dr = -15/(16*pi*h^5) * (2h-r)^2
49 static float compute(float r, float h) {
50 const float H = 2.0f * h;
51 if (r >= H)
52 return 0.0f;
53 const float h5 = h * h * h * h * h;
54 const float d = H - r;
55 return (-15.0f / (16.0f * 3.14159265f * h5)) * d * d;
56 }
57};
58template<>
59struct SpikyDW<3> {
60 // dW/dr = -45/(pi*H^6) * (H-r)^2, H = 2h
61 static float compute(float r, float h) {
62 const float H = 2.0f * h;
63 if (r >= H || r < 1e-10f)
64 return 0.0f;
65 const float H6 = H * H * H * H * H * H;
66 const float d = H - r;
67 return -45.0f / (3.14159265f * H6) * d * d;
68 }
69};
70
71} // namespace detail
72
73/// Dimension-generic SPH smoothing kernels. Dim = 2 or 3.
74template<int Dim>
75struct SPHKernel {
76 static_assert(Dim == 2 || Dim == 3, "SPHKernel: Dim must be 2 or 3");
77
78 /// 2D/3D cubic spline density kernel. Support = 2h.
79 static float W(float r, float h) {
80 const float sigma = detail::CubicSigma<Dim>::compute(h);
81 const float q = r / h;
82 if (q <= 1.0f)
83 return sigma * (1.0f - 1.5f * q * q + 0.75f * q * q * q);
84 if (q <= 2.0f) {
85 const float t = 2.0f - q;
86 return sigma * 0.25f * t * t * t;
87 }
88 return 0.0f;
89 }
90
91 /// Radial derivative dW/dr of cubic spline (<= 0 for r > 0).
92 /// Used for the Morris SPH Laplacian in viscosity and heat.
93 static float dW_dr(float r, float h) {
94 const float sigma = detail::CubicSigma<Dim>::compute(h);
95 const float q = r / h;
96 if (q <= 1.0f)
97 return (sigma / h) * (-3.0f * q + 2.25f * q * q);
98 if (q <= 2.0f) {
99 const float t = 2.0f - q;
100 return (sigma / h) * (-0.75f * t * t);
101 }
102 return 0.0f;
103 }
104
105 /// Radial derivative dW/dr of spiky kernel (<= 0, non-zero at r=0).
106 static float Spiky_dW_dr(float r, float h) {
108 }
109
110 /// Gradient of spiky kernel: g = (dW/dr / r) * r_vec.
111 /// Returns zero array if r < eps or r >= 2h.
112 static std::array<float, Dim> Spiky_gradW(std::array<float, Dim> r_vec,
113 float r,
114 float h) {
115 std::array<float, Dim> g{};
116 if (r < 1e-10f || r >= 2.0f * h)
117 return g;
118 const float c = detail::SpikyDW<Dim>::compute(r, h) / r;
119 for (int d = 0; d < Dim; ++d)
120 g[d] = c * r_vec[d];
121 return g;
122 }
123};
124
125} // namespace num
Dimension-generic SPH smoothing kernels. Dim = 2 or 3.
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)
Radial derivative dW/dr of spiky kernel (<= 0, non-zero at r=0).
static float W(float r, float h)
2D/3D cubic spline density kernel. Support = 2h.
static float compute(float h)
static float compute(float h)
static float compute(float r, float h)
static float compute(float r, float h)