peclet.voro 1.0.0
Device-native moving-particle Voronoi dynamics
Loading...
Searching...
No Matches
reeval_tessellation.hpp
Go to the documentation of this file.
1
23#ifndef PECLET_VORO_REEVAL_TESSELLATION_HPP
24#define PECLET_VORO_REEVAL_TESSELLATION_HPP
25
26#include <Kokkos_Core.hpp>
27#include <string>
28
29#include "peclet/core/common/view.hpp"
33
34namespace peclet::voro {
35
40template <class Real, int MAXP, int MAXT>
42 const Kokkos::View<Real*, peclet::core::MemSpace>& pos,
43 const Kokkos::View<Real*, peclet::core::MemSpace>& vol, int N,
44 const Real L[3]) {
45 using Mem = peclet::core::MemSpace;
46 using Exec = peclet::core::ExecSpace;
48 using Kokkos::view_alloc;
49 using Kokkos::WithoutInitializing;
50 const Real Lx = L[0], Ly = L[1], Lz = L[2];
52 Kokkos::View<Real*, Mem> P = pos;
53
54 // ---- 1. per-cell live-face count (topology only: the >=3-incident-live-triangle criterion) ----
55 Kokkos::View<int*, Mem> facetCount("rp.facetCount", static_cast<std::size_t>(N));
56 Kokkos::parallel_for(
57 "reevalPublish.count", Kokkos::RangePolicy<Exec>(0, N), KOKKOS_LAMBDA(const int i) {
58 Cell c;
59 st.load(i, c, Lx, Ly, Lz);
60 int nf = 0;
61 for (int k = 0; k < c.np; ++k) {
62 int cnt = 0;
63 for (int t = 0; t < c.nt; ++t)
64 if (c.alive[t] && (c.t0[t] == k || c.t1[t] == k || c.t2[t] == k))
65 ++cnt;
66 if (cnt >= 3)
67 ++nf;
68 }
69 facetCount(i) = nf;
70 });
71
72 // ---- 2. exclusive prefix sum -> per-cell facet base + total facet count ----
73 Kokkos::View<int*, Mem> base(view_alloc(std::string("rp.base"), WithoutInitializing),
74 static_cast<std::size_t>(N));
75 int nFacets = 0;
76 {
77 Kokkos::View<int*, Mem> fc = facetCount, bs = base;
78 Kokkos::parallel_scan(
79 "reevalPublish.scan", N,
80 KOKKOS_LAMBDA(const int i, int& upd, const bool final_pass) {
81 if (final_pass)
82 bs(i) = upd;
83 upd += fc(i);
84 },
85 nFacets);
86 }
87
88 // ---- 3. fill the facet CSR: reeval geometry, then facetGeometry per live face ----
89 const std::size_t nF = static_cast<std::size_t>(nFacets);
90 Kokkos::View<gid_t*, Mem> fNbr(view_alloc(std::string("rp.fNbr"), WithoutInitializing), nF);
91 Kokkos::View<Real*, Mem> fArea(view_alloc(std::string("rp.fArea"), WithoutInitializing), nF * 3);
92 Kokkos::View<Real*, Mem> fDV(view_alloc(std::string("rp.fDV"), WithoutInitializing), nF * 3);
93 Kokkos::View<Real*, Mem> fConn(view_alloc(std::string("rp.fConn"), WithoutInitializing), nF * 3);
94 {
95 Kokkos::View<int*, Mem> bs = base;
96 Kokkos::parallel_for(
97 "reevalPublish.fill", Kokkos::RangePolicy<Exec>(0, N), KOKKOS_LAMBDA(const int i) {
98 Cell c;
99 st.load(i, c, Lx, Ly, Lz);
100 c.reevalGeometry(P(3 * i), P(3 * i + 1), P(3 * i + 2), P.data(), Lx);
101 int idx = 0;
102 const int b = bs(i);
103 for (int k = 0; k < c.np; ++k) {
104 int cnt = 0;
105 for (int t = 0; t < c.nt; ++t)
106 if (c.alive[t] && (c.t0[t] == k || c.t1[t] == k || c.t2[t] == k))
107 ++cnt;
108 if (cnt < 3)
109 continue; // not a polygon face — same criterion as the count pass
110 Real area[3] = {0, 0, 0}, dv[3] = {0, 0, 0}, conn[3];
111 conn[0] = Real(2) * c.n[k][0];
112 conn[1] = Real(2) * c.n[k][1];
113 conn[2] = Real(2) * c.n[k][2];
114 c.facetGeometry(k, area, dv, conn); // zeros for a degenerate face (matches buildCell)
115 const std::size_t g = static_cast<std::size_t>(b + idx);
116 fNbr(g) = static_cast<gid_t>(c.pnbr[k]);
117 for (int cc = 0; cc < 3; ++cc) {
118 fArea(3 * g + cc) = area[cc];
119 fDV(3 * g + cc) = dv[cc];
120 fConn(3 * g + cc) = conn[cc];
121 }
122 ++idx;
123 }
124 });
125 }
126
127 // ---- 4. assemble the published view (cellVolume reuses the repair's volumes) ----
129 view.cellFacetOffset = base;
130 view.cellFacetCount = facetCount;
131 view.cellVolume = vol;
132 view.cellSeedId = Kokkos::View<gid_t*, Mem>(
133 view_alloc(std::string("rp.seedId"), WithoutInitializing), static_cast<std::size_t>(N));
134 {
135 Kokkos::View<gid_t*, Mem> vSeed = view.cellSeedId;
136 Kokkos::parallel_for(
137 "reevalPublish.seedId", Kokkos::RangePolicy<Exec>(0, N),
138 KOKKOS_LAMBDA(const int i) { vSeed(i) = static_cast<gid_t>(i); });
139 }
140 view.facetNeighbor = fNbr;
141 view.facetArea = fArea;
142 view.facetConnect = fDV;
143 view.facetConnVec = fConn;
144 return view;
145}
146
147} // namespace peclet::voro
148
149#endif // PECLET_VORO_REEVAL_TESSELLATION_HPP
Definition convex_cell.hpp:40
TessellationView< Real > reevalPublish(const TopologyStore< MAXP, MAXT > &store, const Kokkos::View< Real *, peclet::core::MemSpace > &pos, const Kokkos::View< Real *, peclet::core::MemSpace > &vol, int N, const Real L[3])
Definition reeval_tessellation.hpp:41
std::int32_t gid_t
Definition tessellation_view.hpp:41
Definition convex_cell.hpp:139
Definition tessellation_view.hpp:111
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::View< Real *, peclet::core::MemSpace > cellVolume
Definition tessellation_view.hpp:120
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::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::View< Real *, peclet::core::MemSpace > facetConnVec
Definition tessellation_view.hpp:124
Definition topology_store.hpp:39
KOKKOS_INLINE_FUNCTION void load(int i, Cell &c, Real L0, Real L1, Real L2) const
Definition topology_store.hpp:93
Published, read-only device data layer for the tessellation (migration §2.1, §3).