peclet.voro 1.0.0
Device-native moving-particle Voronoi dynamics
Loading...
Searching...
No Matches
tessellation_view.hpp
Go to the documentation of this file.
1
26#ifndef PECLET_VORO_TESSELLATION_VIEW_HPP
27#define PECLET_VORO_TESSELLATION_VIEW_HPP
28
29#include <cmath>
30#include <cstdint>
31#include <Kokkos_Core.hpp>
32#include <map>
33#include <vector>
34
35#include "peclet/core/common/view.hpp"
36namespace peclet::voro {
37
41using gid_t = std::int32_t;
42
43inline gid_t toGid(std::uint32_t id) {
44 return static_cast<gid_t>(static_cast<std::int32_t>(id));
45}
46
48template <class Real>
50 int nCells = 0;
51 int nFacets = 0;
52 std::vector<int> cellFacetOffset;
53 std::vector<gid_t> cellSeedId;
54 std::vector<Real> cellVolume;
55 std::vector<gid_t> facetNeighbor;
56 std::vector<Real> facetArea;
57 std::vector<Real> facetConnect;
58 std::vector<Real> facetConnVec;
59};
60
71template <class Real>
72std::vector<int> buildReciprocalMap(const HostTessellation<Real>& t) {
73 std::map<gid_t, int> seedToCell;
74 for (int i = 0; i < t.nCells; ++i)
75 seedToCell[t.cellSeedId[i]] = i;
76 std::vector<int> recip(t.nFacets, -1);
77 for (int i = 0; i < t.nCells; ++i) {
78 const gid_t idi = t.cellSeedId[i];
79 for (int g = t.cellFacetOffset[i]; g < t.cellFacetOffset[i + 1]; ++g) {
80 const gid_t j = t.facetNeighbor[g];
81 if (j < 0)
82 continue; // boundary
83 auto it = seedToCell.find(j);
84 if (it == seedToCell.end())
85 continue;
86 const int cj = it->second;
87 int best = -1;
88 Real bestErr = Real(1e300);
89 for (int h = t.cellFacetOffset[cj]; h < t.cellFacetOffset[cj + 1]; ++h) {
90 if (t.facetNeighbor[h] != idi)
91 continue;
92 Real e = 0; // prefer the facet whose area best negates g's (same interface)
93 for (int c = 0; c < 3; ++c) {
94 Real s = t.facetArea[3 * g + c] + t.facetArea[3 * h + c];
95 e += s * s;
96 }
97 if (e < bestErr) {
98 bestErr = e;
99 best = h;
100 }
101 }
102 recip[g] = best;
103 }
104 }
105 return recip;
106}
107
110template <class Real>
112 // facetBegin(i) = cellFacetOffset(i); facetEnd(i) = cellFacetOffset(i)+cellFacetCount(i).
113 // The device tessellator packs the CSR in finish-order via an atomic cursor (so
114 // cellFacetOffset is a per-cell base, not a prefix sum), hence the explicit count;
115 // the legacy upload path fills count from its prefix-sum offsets. Consumers use
116 // facetBegin/facetEnd and are agnostic to which.
117 Kokkos::View<int*, peclet::core::MemSpace> cellFacetOffset; // nCells (per-cell facet base)
118 Kokkos::View<int*, peclet::core::MemSpace> cellFacetCount; // nCells
119 Kokkos::View<gid_t*, peclet::core::MemSpace> cellSeedId; // nCells
120 Kokkos::View<Real*, peclet::core::MemSpace> cellVolume; // nCells
121 Kokkos::View<gid_t*, peclet::core::MemSpace> facetNeighbor; // nFacets
122 Kokkos::View<Real*, peclet::core::MemSpace> facetArea; // 3*nFacets
123 Kokkos::View<Real*, peclet::core::MemSpace> facetConnect; // 3*nFacets (dV)
124 Kokkos::View<Real*, peclet::core::MemSpace> facetConnVec; // 3*nFacets
125 // Vertex CSR (seed-relative positions) — published when a consumer needs cell
126 // geometry (rendering, the interface-tension force, future Hamiltonian solver);
127 // empty otherwise.
128 Kokkos::View<int*, peclet::core::MemSpace> cellVertexOffset; // nCells+1 (empty if unused)
129 Kokkos::View<Real*, peclet::core::MemSpace> vertexPos; // 3*nVerts
130
131 KOKKOS_INLINE_FUNCTION int numCells() const { return static_cast<int>(cellSeedId.extent(0)); }
132 KOKKOS_INLINE_FUNCTION bool hasVertices() const { return cellVertexOffset.extent(0) > 0; }
133 KOKKOS_INLINE_FUNCTION int vertexBegin(int i) const { return cellVertexOffset(i); }
134 KOKKOS_INLINE_FUNCTION int vertexEnd(int i) const { return cellVertexOffset(i + 1); }
135 KOKKOS_INLINE_FUNCTION Real vertex(int v, int c) const { return vertexPos(3 * v + c); }
136 KOKKOS_INLINE_FUNCTION int numFacets() const { return static_cast<int>(facetNeighbor.extent(0)); }
137 KOKKOS_INLINE_FUNCTION gid_t cellSeed(int i) const { return cellSeedId(i); }
138 KOKKOS_INLINE_FUNCTION Real volume(int i) const { return cellVolume(i); }
139 KOKKOS_INLINE_FUNCTION int facetBegin(int i) const { return cellFacetOffset(i); }
140 KOKKOS_INLINE_FUNCTION int facetEnd(int i) const {
141 return cellFacetOffset(i) + cellFacetCount(i);
142 }
143 KOKKOS_INLINE_FUNCTION gid_t facetNbr(int f) const { return facetNeighbor(f); }
144 KOKKOS_INLINE_FUNCTION Real area(int f, int c) const { return facetArea(3 * f + c); }
145 KOKKOS_INLINE_FUNCTION Real connect(int f, int c) const { return facetConnect(3 * f + c); }
146 KOKKOS_INLINE_FUNCTION Real connVec(int f, int c) const { return facetConnVec(3 * f + c); }
147};
148
149namespace detail {
150template <class T>
151Kokkos::View<T*, peclet::core::MemSpace> viewFrom(const std::vector<T>& h,
152 const std::string& label) {
153 // NOTE: pass a std::string label — a bare const char* is interpreted by
154 // Kokkos::view_alloc as a user pointer-to-memory, not an allocation label.
155 Kokkos::View<T*, peclet::core::MemSpace> d(Kokkos::view_alloc(label, Kokkos::WithoutInitializing),
156 h.size());
157 if (!h.empty()) {
158 using Host =
159 Kokkos::View<const T*, Kokkos::HostSpace, Kokkos::MemoryTraits<Kokkos::Unmanaged> >;
160 Host hv(h.data(), h.size());
161 Kokkos::deep_copy(d, hv);
162 }
163 return d;
164}
165} // namespace detail
166
168template <class Real>
171 // Legacy CSR is a prefix sum (nCells+1); derive the per-cell count so facetEnd
172 // works (the device path instead writes base + count directly).
173 v.cellFacetOffset = detail::viewFrom(h.cellFacetOffset, "tess.cellFacetOffset");
174 {
175 const int nC = static_cast<int>(h.cellSeedId.size());
176 std::vector<int> cnt(nC);
177 for (int i = 0; i < nC; ++i)
178 cnt[i] = h.cellFacetOffset[i + 1] - h.cellFacetOffset[i];
179 v.cellFacetCount = detail::viewFrom(cnt, "tess.cellFacetCount");
180 }
181 v.cellSeedId = detail::viewFrom(h.cellSeedId, "tess.cellSeedId");
182 v.cellVolume = detail::viewFrom(h.cellVolume, "tess.cellVolume");
183 v.facetNeighbor = detail::viewFrom(h.facetNeighbor, "tess.facetNeighbor");
184 v.facetArea = detail::viewFrom(h.facetArea, "tess.facetArea");
185 v.facetConnect = detail::viewFrom(h.facetConnect, "tess.facetConnect");
186 v.facetConnVec = detail::viewFrom(h.facetConnVec, "tess.facetConnVec");
187 return v;
188}
189
190} // namespace peclet::voro
191
192#endif // PECLET_VORO_TESSELLATION_VIEW_HPP
KOKKOS_INLINE_FUNCTION Dual< Real, K > dnum(Real c)
Definition convex_cell.hpp:52
Kokkos::View< T *, peclet::core::MemSpace > viewFrom(const std::vector< T > &h, const std::string &label)
Definition tessellation_view.hpp:151
Definition convex_cell.hpp:40
std::int32_t gid_t
Definition tessellation_view.hpp:41
TessellationView< Real > upload(const HostTessellation< Real > &h)
Upload a HostTessellation to device Views.
Definition tessellation_view.hpp:169
std::vector< int > buildReciprocalMap(const HostTessellation< Real > &t)
Definition tessellation_view.hpp:72
gid_t toGid(std::uint32_t id)
Definition tessellation_view.hpp:43
Host-side CSR buffers — the conversion target and the round-trip oracle.
Definition tessellation_view.hpp:49
std::vector< Real > facetConnect
size 3*nFacets, dV (volume gradient)
Definition tessellation_view.hpp:57
std::vector< Real > facetConnVec
size 3*nFacets, connecting vector to neighbour seed
Definition tessellation_view.hpp:58
std::vector< int > cellFacetOffset
size nCells+1, exclusive scan of facet counts
Definition tessellation_view.hpp:52
std::vector< Real > cellVolume
size nCells
Definition tessellation_view.hpp:54
int nFacets
Definition tessellation_view.hpp:51
int nCells
Definition tessellation_view.hpp:50
std::vector< gid_t > facetNeighbor
size nFacets (negative => boundary/none)
Definition tessellation_view.hpp:55
std::vector< Real > facetArea
size 3*nFacets, area vectors (3*f + c)
Definition tessellation_view.hpp:56
std::vector< gid_t > cellSeedId
size nCells, stable seed id per cell
Definition tessellation_view.hpp:53
Definition tessellation_view.hpp:111
KOKKOS_INLINE_FUNCTION Real vertex(int v, int c) const
Definition tessellation_view.hpp:135
KOKKOS_INLINE_FUNCTION bool hasVertices() const
Definition tessellation_view.hpp:132
Kokkos::View< Real *, peclet::core::MemSpace > vertexPos
Definition tessellation_view.hpp:129
Kokkos::View< Real *, peclet::core::MemSpace > facetConnect
Definition tessellation_view.hpp:123
Kokkos::View< Real *, peclet::core::MemSpace > facetArea
Definition tessellation_view.hpp:122
KOKKOS_INLINE_FUNCTION int vertexEnd(int i) const
Definition tessellation_view.hpp:134
Kokkos::View< int *, peclet::core::MemSpace > cellVertexOffset
Definition tessellation_view.hpp:128
KOKKOS_INLINE_FUNCTION Real area(int f, int c) const
Definition tessellation_view.hpp:144
KOKKOS_INLINE_FUNCTION int facetEnd(int i) const
Definition tessellation_view.hpp:140
KOKKOS_INLINE_FUNCTION gid_t facetNbr(int f) const
Definition tessellation_view.hpp:143
KOKKOS_INLINE_FUNCTION gid_t cellSeed(int i) const
Definition tessellation_view.hpp:137
KOKKOS_INLINE_FUNCTION Real connVec(int f, int c) const
Definition tessellation_view.hpp:146
Kokkos::View< Real *, peclet::core::MemSpace > cellVolume
Definition tessellation_view.hpp:120
KOKKOS_INLINE_FUNCTION int facetBegin(int i) const
Definition tessellation_view.hpp:139
KOKKOS_INLINE_FUNCTION Real volume(int i) const
Definition tessellation_view.hpp:138
KOKKOS_INLINE_FUNCTION int numFacets() const
Definition tessellation_view.hpp:136
Kokkos::View< gid_t *, peclet::core::MemSpace > cellSeedId
Definition tessellation_view.hpp:119
Kokkos::View< int *, peclet::core::MemSpace > cellFacetOffset
Definition tessellation_view.hpp:117
KOKKOS_INLINE_FUNCTION int vertexBegin(int i) const
Definition tessellation_view.hpp:133
KOKKOS_INLINE_FUNCTION int numCells() const
Definition tessellation_view.hpp:131
Kokkos::View< gid_t *, peclet::core::MemSpace > facetNeighbor
Definition tessellation_view.hpp:121
Kokkos::View< int *, peclet::core::MemSpace > cellFacetCount
Definition tessellation_view.hpp:118
KOKKOS_INLINE_FUNCTION Real connect(int f, int c) const
Definition tessellation_view.hpp:145
Kokkos::View< Real *, peclet::core::MemSpace > facetConnVec
Definition tessellation_view.hpp:124