core 1.5.0
Shared MPI block decomposition, asynchronous ghost-layer exchange, SDF geometry, load balancing (header-only C++20)
Loading...
Searching...
No Matches
sdf.hpp
Go to the documentation of this file.
1// core — signed-distance geometry for solids (see suite/docs/CONVENTIONS.md §2).
2//
3// Sign convention (load-bearing, shared across the suite): sdf < 0 inside solid, > 0 in fluid/void,
4// 0 on the surface; the gradient points outward (into the fluid). Analytic primitives mirror the
5// shapes packing-gpu already uses (sphere, box, hollow cylinder); a generic finite-difference
6// gradient covers any shape, and a `Sdf` concept lets solvers accept analytic or grid SDFs
7// uniformly.
8//
9// DELEGATION (Layer 0, docs/ANALYTIC_SDF_GEOMETRY.md): the shapes here are the HOST-FACING layer --
10// they carry a `center` (and an `axis`) and model the `Sdf` concept for host consumers like
11// refineToSdf and the VTI path. Their eval() bodies hold NO formulas: each translates (and, for the
12// cylinder, permutes) into the canonical frame and calls the corresponding device-callable leaf in
13// peclet::core::geom::prim (geom/primitives.hpp), which is the single source of the formulas.
14// Note `Box` now goes through the leaf's fmax/fmin where it previously used std::max/std::min --
15// identical for every non-NaN input, and the leaf's form is the one dem's bit-exactness depends on.
16//
17// C++17-clean below the concept so this header can be pulled into CUDA translation units; the
18// concept itself is guarded for C++20 host use.
19#ifndef PECLET_CORE_GEOM_SDF_HPP
20#define PECLET_CORE_GEOM_SDF_HPP
21
22#include <algorithm>
23#include <cmath>
24
27
28namespace peclet::core::geom {
29
30namespace detail {
31inline Vec<3> sub(const Vec<3>& a, const Vec<3>& b) {
32 return {a[0] - b[0], a[1] - b[1], a[2] - b[2]};
33}
34inline double norm(const Vec<3>& a) {
35 return std::sqrt(a[0] * a[0] + a[1] * a[1] + a[2] * a[2]);
36}
37} // namespace detail
38
40struct Sphere {
42 double radius = 1.0;
43 double eval(const Vec<3>& p) const {
44 const Vec<3> d = detail::sub(p, center);
45 return prim::Sphere<double>{radius}.eval(Vec3<double>{d[0], d[1], d[2]});
46 }
47};
48
50struct Box {
52 Vec<3> half{0.5, 0.5, 0.5};
53 double eval(const Vec<3>& p) const {
54 const Vec<3> d = detail::sub(p, center);
55 return prim::Box<double>{half[0], half[1], half[2]}.eval(Vec3<double>{d[0], d[1], d[2]});
56 }
57};
58
64 double rOuter = 1.0;
65 double rInner = 0.5;
66 double height = 1.0;
67 int axis = 2;
68 double eval(const Vec<3>& p) const {
69 const Vec<3> d = detail::sub(p, center);
70 const int a0 = (axis + 1) % 3, a1 = (axis + 2) % 3;
71 const double r = std::sqrt(d[a0] * d[a0] + d[a1] * d[a1]);
73 }
74};
75
78template <typename S>
79struct Complement {
81 double eval(const Vec<3>& p) const { return -shape.eval(p); }
82};
83
85template <typename S>
86Vec<3> gradient(const S& shape, const Vec<3>& p, double h = 1e-4) {
87 Vec<3> g{};
88 for (int i = 0; i < 3; ++i) {
89 Vec<3> pp = p, pm = p;
90 pp[i] += h;
91 pm[i] -= h;
92 g[i] = (shape.eval(pp) - shape.eval(pm)) / (2.0 * h);
93 }
94 return g;
95}
96
97#if defined(__cpp_concepts)
99template <typename S>
100concept Sdf = requires(const S s, Vec<3> p) {
101 { s.eval(p) } -> std::convertible_to<double>;
102};
103#endif
104
105} // namespace peclet::core::geom
106
107#endif // PECLET_CORE_GEOM_SDF_HPP
double norm(const Vec< 3 > &a)
Definition sdf.hpp:34
Vec< 3 > sub(const Vec< 3 > &a, const Vec< 3 > &b)
Definition sdf.hpp:31
Vec< 3 > gradient(const S &shape, const Vec< 3 > &p, double h=1e-4)
Generic outward normal via central differences; works for any shape with eval().
Definition sdf.hpp:86
Kokkos::View< T *, MemSpace > View
1D device array.
Definition view.hpp:26
Axis-aligned solid box of half-extents half: standard exact box SDF, negative inside.
Definition sdf.hpp:50
double eval(const Vec< 3 > &p) const
Definition sdf.hpp:53
Negation: the solid and the void swap (sdf -> -sdf).
Definition sdf.hpp:79
double eval(const Vec< 3 > &p) const
Definition sdf.hpp:81
Solid hollow cylinder (a tube wall) of given outer/inner radius and height about axis.
Definition sdf.hpp:62
double eval(const Vec< 3 > &p) const
Definition sdf.hpp:68
Solid ball: negative inside.
Definition sdf.hpp:40
double eval(const Vec< 3 > &p) const
Definition sdf.hpp:43
Axis-aligned solid box of half-extents (hx, hy, hz), centred on the origin.
PECLET_HD Real eval(Vec3< Real > p) const
Solid tube wall about the z axis as a CSG intersection of half-spaces: max(r - rOuter,...
PECLET_HD Real evalRZ(Real r, Real z) const
Cross-section form: r is the in-plane radius, z the axial coordinate.
Solid ball of radius radius, centred on the origin.
PECLET_HD Real eval(Vec3< Real > p) const