Peano
Loading...
Searching...
No Matches
kernel_hydro.h
Go to the documentation of this file.
1#pragma once
2#include "cmath"
3#include "tarch/tarch.h"
4
18
19
20namespace exaparty {
21 namespace kernels {
22 namespace legacy {
23 namespace kernelHydro {
24
25#if defined(QUARTIC_SPLINE_KERNEL)
26 /* -------------------------------------------------------------------------
27 */
28
29 /* Quartic spline M5 kernel -- SWIFT version */
30
31#define kernel_name "Quartic spline (M5)"
32/* Coefficients for the kernel. */
33#define kernel_degree 4 /* Degree of the polynomial */
34#define kernel_ivals 5 /* Number of branches */
35
36#if HYDRO_DIMENSION == 1
37#define kernel_gamma ((float)(1.936492))
38#define kernel_constant ((float)(3125. / 768.))
39#elif HYDRO_DIMENSION == 2
40#define kernel_gamma ((float)(1.977173))
41#define kernel_constant ((float)(46875. * M_1_PI / 2398.))
42#elif HYDRO_DIMENSION == 3
43#define kernel_gamma ((float)(2.018932))
44#define kernel_constant ((float)(15625. * M_1_PI / 512.))
45#else
46#pragma error "Hydro dimension undefined"
47#endif
48
49#if defined(GPUOffloadingOMP)
50#pragma omp begin declare target
51#endif
52 static const double
53 kernel_coeffs[(kernel_degree + 1) * (kernel_ivals + 1)]
55 = {
56 6.0, 0.0, -2.4, 0.0, 0.368, /* 0 < u < 0.2 */
57 -4.0, 8.0, -4.8, 0.32, 0.352, /* 0.2 < u < 0.4 */
58 -4.0, 8.0, -4.8, 0.32, 0.352, /* 0.4 < u < 0.6 */
59 1.0, -4.0, 6.0, -4.0, 1.0, /* 0.6 < u < 0.8 */
60 1.0, -4.0, 6.0, -4.0, 1.0, /* 0.8 < u < 1 */
61 0.0, 0.0, 0.0, 0.0, 0.0}; /* 1 < u */
62#if defined(GPUOffloadingOMP)
63#pragma omp end declare target
64#endif
65
66/* ------------------------------------------------------------------------- */
67
68// @todo implement additional kernels (M4)
69#else
70
71#error "An SPH projection kernel function must be chosen !"
72/* ------------------------------------------------------------------------- */
73#endif
74
75/* ------------------------------------------------------------------------- */
76
77/* Define generic values (i.e. common to all kernels) */
78
79/* First some powers of gamma = H/h */
80#define kernel_gamma_inv ((float)(1. / kernel_gamma))
81#define kernel_gamma2 ((float)(kernel_gamma * kernel_gamma))
82
83/* define gamma^d, gamma^(d+1), 1/gamma^d and 1/gamma^(d+1) */
84#if HYDRO_DIMENSION == 1
85#define kernel_gamma_dim ((float)(kernel_gamma))
86#define kernel_gamma_dim_plus_one ((float)(kernel_gamma * kernel_gamma))
87#define kernel_gamma_inv_dim ((float)(1. / (kernel_gamma)))
88#define kernel_gamma_inv_dim_plus_one \
89 ((float)(1. / (kernel_gamma * kernel_gamma)))
90#elif HYDRO_DIMENSION == 2
91#define kernel_gamma_dim ((float)(kernel_gamma * kernel_gamma))
92#define kernel_gamma_dim_plus_one \
93 ((float)(kernel_gamma * kernel_gamma * kernel_gamma))
94#define kernel_gamma_inv_dim ((float)(1. / (kernel_gamma * kernel_gamma)))
95#define kernel_gamma_inv_dim_plus_one \
96 ((float)(1. / (kernel_gamma * kernel_gamma * kernel_gamma)))
97#elif HYDRO_DIMENSION == 3
98#define kernel_gamma_dim ((float)(kernel_gamma * kernel_gamma * kernel_gamma))
99#define kernel_gamma_dim_plus_one \
100 ((float)(kernel_gamma * kernel_gamma * kernel_gamma * kernel_gamma))
101#define kernel_gamma_inv_dim \
102 ((float)(1. / (kernel_gamma * kernel_gamma * kernel_gamma)))
103#define kernel_gamma_inv_dim_plus_one \
104 ((float)(1. / (kernel_gamma * kernel_gamma * kernel_gamma * kernel_gamma)))
105#endif
106
107/* The number of branches (floating point conversion) */
108#define kernel_ivals_f ((float)(kernel_ivals))
109
110/* Kernel self contribution (i.e. W(0,h)) */
111#define kernel_root \
112 ((float)(kernel_coeffs[kernel_degree]) * kernel_constant \
113 * kernel_gamma_inv_dim)
114
115 /* -------------------------------------------------------------------------
116 */
117
149 static void kernel_eval(double u, double& W) {
150
151 /* Go to the range [0,1[ from [0,H[ */
152 const double x = u * kernel_gamma_inv;
153
154 /* Pick the correct branch of the kernel */
155 const int temp = (int)(x * kernel_ivals_f);
156 const int ind = temp > kernel_ivals ? kernel_ivals : temp;
157 const double* const coeffs = &kernel_coeffs[ind * (kernel_degree + 1)];
158
159 /* First two terms of the polynomial ... */
160 double w = coeffs[0] * x + coeffs[1];
161
162 /* ... and the rest of them */
163 for (int k = 2; k <= kernel_degree; k++)
164 w = x * w + coeffs[k];
165
166 w = std::max(w, 0.0);
167
168 /* Return everything */
169 W = w * kernel_constant * kernel_gamma_inv_dim;
170 }
171
251 static void kernel_deval(double u, double& W, double& dW_dx) {
252 /* Go to the range [0,1[ from [0,H[ */
253 const double x = u * kernel_gamma_inv;
254
255 /* Pick the correct branch of the kernel */
256 const int temp = (int)(x * kernel_ivals_f);
257 const int ind = temp > kernel_ivals ? kernel_ivals : temp;
258 const double* const coeffs = &kernel_coeffs[ind * (kernel_degree + 1)];
259
260 /* w term in Horner's scheme */
261 double w = coeffs[0];
262 for (int k = 1; k <= kernel_degree; k++) {
263 w = w * x + coeffs[k];
264 }
265
266 /* dw_dx term in Horner's scheme */
267
268 double dw_dx = coeffs[0] * kernel_degree;
269
270 /* ... and the rest of them */
271 for (int k = 1; k <= kernel_degree - 1; k++) {
272 dw_dx = dw_dx * x + coeffs[k] * (kernel_degree - k);
273 }
274
275 w = std::max(w, 0.0);
276 dw_dx = std::min(dw_dx, 0.0);
277
278 /* Return everything */
279 W = u == 0 ? 0: w * kernel_constant * kernel_gamma_inv_dim;
280 dW_dx = u == 0 ? 0: dw_dx * kernel_constant * kernel_gamma_inv_dim_plus_one;
281 }
282 } // namespace kernelHydro
283 } // namespace legacy
284 } // namespace kernels
285} // namespace exaparty
#define AlignmentOnHeap
Definition LinuxAMD.h:23
#define kernel_gamma_inv
#define kernel_ivals_f
static void kernel_deval(double u, double &W, double &dW_dx)
Computes the kernel function and its derivative.
static void kernel_eval(double u, double &W)
Computes the kernel function.
void __attribute__((always_inline)) force_kernel(ParticleA &localParticle
The actual force kernel, which interacts a local particle and an active particle, and updates the loc...
This file is part of the ExaParty project.
Definition __init__.py:1