peclet.voro 1.0.4
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 // Facet-edge AREA-JACOBIAN CSR (Voronoi methods plan, rung A3; opt-in `withAreaGrad`): for
131 // facet f, entries e in [edgeBegin(f), edgeEnd(f)) hold ∂A_f/∂n_l for every plane l the
132 // facet's area depends on — slot 0 is the facet's OWN plane (l = f, the diagonal block), the
133 // rest are the facets sharing an edge with f (each edge is where two of the cell's planes
134 // meet; a face's area depends on its own plane and on its edge-neighbours' planes only).
135 // `edgeFacet(e)` is the global facet index of plane l's facet in the SAME cell (its neighbour
136 // id / wall sentinel is facetNbr(edgeFacet(e))); `areaGrad(e, c)` the 3-vector ∂A_f/∂n_l.
137 // A_f is the facet's area MAGNITUDE (|facetArea|). Empty unless requested.
138 Kokkos::View<int*, peclet::core::MemSpace> facetEdgeOffset; // nFacets
139 Kokkos::View<int*, peclet::core::MemSpace> facetEdgeCount; // nFacets
140 Kokkos::View<int*, peclet::core::MemSpace> edgeFacet; // nEdges
141 Kokkos::View<Real*, peclet::core::MemSpace> edgeAreaGrad; // 3*nEdges
142 // Track C2a′: the Voronoi EDGE length of each facet-edge slot (0 for the self slot): the edge
143 // where the facet's plane meets the partner facet's plane — the dual of the Delaunay triangle
144 // (seed, facet neighbour, partner neighbour); the DEC curl-curl viscous term's Hodge star.
145 Kokkos::View<Real*, peclet::core::MemSpace> edgeLength; // nEdges
146
147 // Rung A1 (force half; opt-in `withWallFD`): per cell, the WALL part of dV/dx and dA_wall/dx
148 // by in-kernel central differences of the SDF clip (sdfWallFD) — exact for the clip actually
149 // used (sagitta placement included), where the seed-foot chain is the tangent-plane model.
150 // Zero for cells without wall planes. Empty unless requested.
151 Kokkos::View<Real*, peclet::core::MemSpace> cellWallDV; // 3*nCells
152 Kokkos::View<Real*, peclet::core::MemSpace> cellWallDA; // 3*nCells
153 KOKKOS_INLINE_FUNCTION bool hasWallFD() const { return cellWallDV.extent(0) > 0; }
154 KOKKOS_INLINE_FUNCTION Real wallDV(int i, int c) const { return cellWallDV(3 * i + c); }
155 KOKKOS_INLINE_FUNCTION Real wallDA(int i, int c) const { return cellWallDA(3 * i + c); }
156
157 // Track B, rung B1 (opt-in `withMoments`): per facet ∫_face |s|² dA, the second moment of the
158 // face polygon about the seed's foot point on its plane — what the Lloyd (centroidal) energy
159 // value needs (a pyramid's ∫|y|² dy = h (h² A + M2)/5). Empty unless requested.
160 Kokkos::View<Real*, peclet::core::MemSpace> facetMoment2; // nFacets
161 KOKKOS_INLINE_FUNCTION bool hasMoments() const { return facetMoment2.extent(0) > 0; }
162 KOKKOS_INLINE_FUNCTION Real moment2(int f) const { return facetMoment2(f); }
163
164 KOKKOS_INLINE_FUNCTION bool hasAreaGrad() const { return facetEdgeOffset.extent(0) > 0; }
165 KOKKOS_INLINE_FUNCTION int numEdges() const { return static_cast<int>(edgeFacet.extent(0)); }
166 KOKKOS_INLINE_FUNCTION int edgeBegin(int f) const { return facetEdgeOffset(f); }
167 KOKKOS_INLINE_FUNCTION int edgeEnd(int f) const { return facetEdgeOffset(f) + facetEdgeCount(f); }
168 KOKKOS_INLINE_FUNCTION int edgePartner(int e) const { return edgeFacet(e); }
169 KOKKOS_INLINE_FUNCTION Real areaGrad(int e, int c) const { return edgeAreaGrad(3 * e + c); }
170 KOKKOS_INLINE_FUNCTION Real edgeLen(int e) const { return edgeLength(e); }
171 KOKKOS_INLINE_FUNCTION bool hasEdgeLength() const { return edgeLength.extent(0) > 0; }
172
173 KOKKOS_INLINE_FUNCTION int numCells() const { return static_cast<int>(cellSeedId.extent(0)); }
174 KOKKOS_INLINE_FUNCTION bool hasVertices() const { return cellVertexOffset.extent(0) > 0; }
175 KOKKOS_INLINE_FUNCTION int vertexBegin(int i) const { return cellVertexOffset(i); }
176 KOKKOS_INLINE_FUNCTION int vertexEnd(int i) const { return cellVertexOffset(i + 1); }
177 KOKKOS_INLINE_FUNCTION Real vertex(int v, int c) const { return vertexPos(3 * v + c); }
178 KOKKOS_INLINE_FUNCTION int numFacets() const { return static_cast<int>(facetNeighbor.extent(0)); }
179 KOKKOS_INLINE_FUNCTION gid_t cellSeed(int i) const { return cellSeedId(i); }
180 KOKKOS_INLINE_FUNCTION Real volume(int i) const { return cellVolume(i); }
181 KOKKOS_INLINE_FUNCTION int facetBegin(int i) const { return cellFacetOffset(i); }
182 KOKKOS_INLINE_FUNCTION int facetEnd(int i) const {
183 return cellFacetOffset(i) + cellFacetCount(i);
184 }
185 KOKKOS_INLINE_FUNCTION gid_t facetNbr(int f) const { return facetNeighbor(f); }
186 KOKKOS_INLINE_FUNCTION Real area(int f, int c) const { return facetArea(3 * f + c); }
187 KOKKOS_INLINE_FUNCTION Real connect(int f, int c) const { return facetConnect(3 * f + c); }
188 KOKKOS_INLINE_FUNCTION Real connVec(int f, int c) const { return facetConnVec(3 * f + c); }
189};
190
191namespace detail {
192template <class T>
193Kokkos::View<T*, peclet::core::MemSpace> viewFrom(const std::vector<T>& h,
194 const std::string& label) {
195 // NOTE: pass a std::string label — a bare const char* is interpreted by
196 // Kokkos::view_alloc as a user pointer-to-memory, not an allocation label.
197 Kokkos::View<T*, peclet::core::MemSpace> d(Kokkos::view_alloc(label, Kokkos::WithoutInitializing),
198 h.size());
199 if (!h.empty()) {
200 using Host =
201 Kokkos::View<const T*, Kokkos::HostSpace, Kokkos::MemoryTraits<Kokkos::Unmanaged> >;
202 Host hv(h.data(), h.size());
203 Kokkos::deep_copy(d, hv);
204 }
205 return d;
206}
207} // namespace detail
208
210template <class Real>
213 // Legacy CSR is a prefix sum (nCells+1); derive the per-cell count so facetEnd
214 // works (the device path instead writes base + count directly).
215 v.cellFacetOffset = detail::viewFrom(h.cellFacetOffset, "tess.cellFacetOffset");
216 {
217 const int nC = static_cast<int>(h.cellSeedId.size());
218 std::vector<int> cnt(nC);
219 for (int i = 0; i < nC; ++i)
220 cnt[i] = h.cellFacetOffset[i + 1] - h.cellFacetOffset[i];
221 v.cellFacetCount = detail::viewFrom(cnt, "tess.cellFacetCount");
222 }
223 v.cellSeedId = detail::viewFrom(h.cellSeedId, "tess.cellSeedId");
224 v.cellVolume = detail::viewFrom(h.cellVolume, "tess.cellVolume");
225 v.facetNeighbor = detail::viewFrom(h.facetNeighbor, "tess.facetNeighbor");
226 v.facetArea = detail::viewFrom(h.facetArea, "tess.facetArea");
227 v.facetConnect = detail::viewFrom(h.facetConnect, "tess.facetConnect");
228 v.facetConnVec = detail::viewFrom(h.facetConnVec, "tess.facetConnVec");
229 return v;
230}
231
232} // namespace peclet::voro
233
234#endif // PECLET_VORO_TESSELLATION_VIEW_HPP
KOKKOS_INLINE_FUNCTION Dual< Real, K > dnum(Real c)
Definition convex_cell.hpp:53
Kokkos::View< T *, peclet::core::MemSpace > viewFrom(const std::vector< T > &h, const std::string &label)
Definition tessellation_view.hpp:193
Device-native Voronoi tessellation, geometry and finite-volume physics.
Definition convex_cell.hpp:41
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:211
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::View< Real *, peclet::core::MemSpace > cellWallDV
Definition tessellation_view.hpp:151
KOKKOS_INLINE_FUNCTION Real vertex(int v, int c) const
Definition tessellation_view.hpp:177
KOKKOS_INLINE_FUNCTION bool hasVertices() const
Definition tessellation_view.hpp:174
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_INLINE_FUNCTION Real moment2(int f) const
Definition tessellation_view.hpp:162
KOKKOS_INLINE_FUNCTION Real wallDA(int i, int c) const
Definition tessellation_view.hpp:155
Kokkos::View< Real *, peclet::core::MemSpace > facetArea
Definition tessellation_view.hpp:122
Kokkos::View< int *, peclet::core::MemSpace > facetEdgeOffset
Definition tessellation_view.hpp:138
KOKKOS_INLINE_FUNCTION int vertexEnd(int i) const
Definition tessellation_view.hpp:176
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:186
KOKKOS_INLINE_FUNCTION int facetEnd(int i) const
Definition tessellation_view.hpp:182
KOKKOS_INLINE_FUNCTION gid_t facetNbr(int f) const
Definition tessellation_view.hpp:185
Kokkos::View< int *, peclet::core::MemSpace > facetEdgeCount
Definition tessellation_view.hpp:139
KOKKOS_INLINE_FUNCTION gid_t cellSeed(int i) const
Definition tessellation_view.hpp:179
KOKKOS_INLINE_FUNCTION int edgePartner(int e) const
Definition tessellation_view.hpp:168
KOKKOS_INLINE_FUNCTION Real connVec(int f, int c) const
Definition tessellation_view.hpp:188
KOKKOS_INLINE_FUNCTION bool hasMoments() const
Definition tessellation_view.hpp:161
KOKKOS_INLINE_FUNCTION int numEdges() const
Definition tessellation_view.hpp:165
Kokkos::View< Real *, peclet::core::MemSpace > cellVolume
Definition tessellation_view.hpp:120
Kokkos::View< Real *, peclet::core::MemSpace > facetMoment2
Definition tessellation_view.hpp:160
KOKKOS_INLINE_FUNCTION bool hasAreaGrad() const
Definition tessellation_view.hpp:164
KOKKOS_INLINE_FUNCTION int facetBegin(int i) const
Definition tessellation_view.hpp:181
KOKKOS_INLINE_FUNCTION Real volume(int i) const
Definition tessellation_view.hpp:180
KOKKOS_INLINE_FUNCTION int numFacets() const
Definition tessellation_view.hpp:178
KOKKOS_INLINE_FUNCTION Real edgeLen(int e) const
Definition tessellation_view.hpp:170
Kokkos::View< Real *, peclet::core::MemSpace > edgeAreaGrad
Definition tessellation_view.hpp:141
Kokkos::View< gid_t *, peclet::core::MemSpace > cellSeedId
Definition tessellation_view.hpp:119
KOKKOS_INLINE_FUNCTION bool hasWallFD() const
Definition tessellation_view.hpp:153
Kokkos::View< Real *, peclet::core::MemSpace > cellWallDA
Definition tessellation_view.hpp:152
KOKKOS_INLINE_FUNCTION int edgeBegin(int f) const
Definition tessellation_view.hpp:166
Kokkos::View< int *, peclet::core::MemSpace > cellFacetOffset
Definition tessellation_view.hpp:117
KOKKOS_INLINE_FUNCTION int vertexBegin(int i) const
Definition tessellation_view.hpp:175
Kokkos::View< int *, peclet::core::MemSpace > edgeFacet
Definition tessellation_view.hpp:140
KOKKOS_INLINE_FUNCTION int numCells() const
Definition tessellation_view.hpp:173
KOKKOS_INLINE_FUNCTION Real wallDV(int i, int c) const
Definition tessellation_view.hpp:154
KOKKOS_INLINE_FUNCTION int edgeEnd(int f) const
Definition tessellation_view.hpp:167
KOKKOS_INLINE_FUNCTION bool hasEdgeLength() const
Definition tessellation_view.hpp:171
Kokkos::View< Real *, peclet::core::MemSpace > edgeLength
Definition tessellation_view.hpp:145
KOKKOS_INLINE_FUNCTION Real areaGrad(int e, int c) const
Definition tessellation_view.hpp:169
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:187
Kokkos::View< Real *, peclet::core::MemSpace > facetConnVec
Definition tessellation_view.hpp:124