peclet-dem
Performance-portable XPBD Discrete Element Method (Kokkos + ArborX)
Loading...
Searching...
No Matches
dem_portable.hpp
Go to the documentation of this file.
1
8#ifndef DEM_PORTABLE_HPP
9#define DEM_PORTABLE_HPP
10
11#include <Kokkos_Core.hpp>
12#include <Kokkos_MathematicalFunctions.hpp>
13
14namespace peclet::dem {
15
16// Portable mirrors of CUDA float3/float4 (POD, trivially copyable).
17struct F3 {
18 float x, y, z;
19};
20struct F4 {
21 float x, y, z, w;
22};
23
24// --- vector ops ---
25KOKKOS_INLINE_FUNCTION F3 add3(F3 a, F3 b) {
26 return F3{a.x + b.x, a.y + b.y, a.z + b.z};
27}
28KOKKOS_INLINE_FUNCTION F3 sub3(F3 a, F3 b) {
29 return F3{a.x - b.x, a.y - b.y, a.z - b.z};
30}
31KOKKOS_INLINE_FUNCTION F3 scale3(F3 a, float s) {
32 return F3{a.x * s, a.y * s, a.z * s};
33}
34KOKKOS_INLINE_FUNCTION float dot3(F3 a, F3 b) {
35 return a.x * b.x + a.y * b.y + a.z * b.z;
36}
37KOKKOS_INLINE_FUNCTION float len3(F3 v) {
38 return Kokkos::sqrt(dot3(v, v));
39}
40KOKKOS_INLINE_FUNCTION F3 cross3v(F3 a, F3 b) {
41 return F3{a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x};
42}
43KOKKOS_INLINE_FUNCTION F4 cross3(F4 a, F4 b) {
44 return F4{a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x, 0.0f};
45}
46
47// Load an F3 / F4 from a multidimensional Kokkos View row (templated => no per-header duplication).
48template <class V>
49KOKKOS_INLINE_FUNCTION F3 ldF3(const V& v, int i) {
50 return F3{v(i, 0), v(i, 1), v(i, 2)};
51}
52template <class V>
53KOKKOS_INLINE_FUNCTION F4 ldF4(const V& v, int i) {
54 return F4{v(i, 0), v(i, 1), v(i, 2), v(i, 3)};
55}
56
57// --- quaternion rotate (q = {x,y,z,w}) — copy of math_utils.cuh rotate_vector/inv_rotate_vector
58// ---
59KOKKOS_INLINE_FUNCTION F3 rotateVector(F4 q, F3 v) {
60 const F3 qv{q.x, q.y, q.z};
61 const F3 t = scale3(cross3v(qv, v), 2.0f);
62 return add3(add3(v, scale3(t, q.w)), cross3v(qv, t));
63}
64KOKKOS_INLINE_FUNCTION F3 invRotateVector(F4 q, F3 v) {
65 return rotateVector(F4{-q.x, -q.y, -q.z, q.w}, v);
66}
67KOKKOS_INLINE_FUNCTION F4 quatInverse(F4 q) {
68 return F4{-q.x, -q.y, -q.z, q.w};
69}
70KOKKOS_INLINE_FUNCTION F4 quatMult(F4 a, F4 b) {
71 return F4{
72 a.w * b.x + a.x * b.w + a.y * b.z - a.z * b.y, a.w * b.y - a.x * b.z + a.y * b.w + a.z * b.x,
73 a.w * b.z + a.x * b.y - a.y * b.x + a.z * b.w, a.w * b.w - a.x * b.x - a.y * b.y - a.z * b.z};
74}
75
76// --- analytic SDFs (canonical/unit space) — copy of shapes/sdf_analytic.cuh ---
78
79KOKKOS_INLINE_FUNCTION float sdfSphere(F3 p, F4 params) {
80 return len3(p) - params.x;
81}
82
83KOKKOS_INLINE_FUNCTION float sdfHollowCylinder(F3 p, F4 params) {
84 const float r_outer = params.x, h = params.y, thick = params.z;
85 const float r = Kokkos::sqrt(p.x * p.x + p.z * p.z);
86 const float r_mid = r_outer - thick * 0.5f;
87 const float dx = Kokkos::fabs(r - r_mid) - thick * 0.5f;
88 const float dy = Kokkos::fabs(p.y) - h * 0.5f;
89 const float ox = Kokkos::fmax(dx, 0.0f), oy = Kokkos::fmax(dy, 0.0f);
90 const float outside = Kokkos::sqrt(ox * ox + oy * oy);
91 const float inside = Kokkos::fmin(Kokkos::fmax(dx, dy), 0.0f);
92 return outside + inside;
93}
94
95KOKKOS_INLINE_FUNCTION float sdfBox(F3 p, F4 params) {
96 const float dx = Kokkos::fabs(p.x) - params.x;
97 const float dy = Kokkos::fabs(p.y) - params.y;
98 const float dz = Kokkos::fabs(p.z) - params.z;
99 const float ox = Kokkos::fmax(dx, 0.0f), oy = Kokkos::fmax(dy, 0.0f), oz = Kokkos::fmax(dz, 0.0f);
100 const float outside = Kokkos::sqrt(ox * ox + oy * oy + oz * oz);
101 const float inside = Kokkos::fmin(Kokkos::fmax(dx, Kokkos::fmax(dy, dz)), 0.0f);
102 return outside + inside;
103}
104
105KOKKOS_INLINE_FUNCTION float sdfEval(F3 p, int type, F4 params) {
106 if (type == SPHERE)
107 return sdfSphere(p, params);
108 if (type == HOLLOW_CYLINDER)
109 return sdfHollowCylinder(p, params);
110 if (type == BOX)
111 return sdfBox(p, params);
112 return 1e9f; // grid SDF (texture) not yet ported
113}
114
115} // namespace peclet::dem
116
117#endif // DEM_PORTABLE_HPP
F4 quatMult(F4 a, F4 b)
F4 quatInverse(F4 q)
float sdfEval(F3 p, int type, F4 params)
float sdfHollowCylinder(F3 p, F4 params)
F3 cross3v(F3 a, F3 b)
float sdfBox(F3 p, F4 params)
F3 invRotateVector(F4 q, F3 v)
F3 ldF3(const V &v, int i)
F3 rotateVector(F4 q, F3 v)
float dot3(F3 a, F3 b)
F3 sub3(F3 a, F3 b)
F4 ldF4(const V &v, int i)
F3 scale3(F3 a, float s)
float len3(F3 v)
F3 add3(F3 a, F3 b)
float sdfSphere(F3 p, F4 params)
F4 cross3(F4 a, F4 b)