peclet.voro 1.0.4
Device-native moving-particle Voronoi dynamics
Loading...
Searching...
No Matches
distributed_moving.hpp
Go to the documentation of this file.
1
20#ifndef PECLET_VORO_MPI_DISTRIBUTED_MOVING_HPP
21#define PECLET_VORO_MPI_DISTRIBUTED_MOVING_HPP
22
23#include <mpi.h>
24
25#include <array>
26#include <cmath>
27#include <vector>
28
29#include "../repair.hpp"
30#include "voronoi_halo.hpp"
31
33
37template <class Real, int MAXP = kMaxPlanes, int MAXT = kMaxTriangles, class Sdf = NoSdf>
39 using Vec3 = std::array<Real, 3>;
40 using Mem = typename Kokkos::DefaultExecutionSpace::memory_space;
41
42 struct StepStats {
43 bool regathered = false;
45 };
46
48 void init(std::array<Real, 3> origin, std::array<Real, 3> size, std::array<long, 3> gsize,
49 std::array<bool, 3> periodic, Real rcut, Real skin, Real tol, MPI_Comm comm,
50 int searchWindow = 4, int densityCount = -1) {
51 halo_.init(origin, size, gsize, periodic, comm);
52 comm_ = comm;
53 for (int d = 0; d < 3; ++d)
54 L_[d] = size[d];
55 rcut_ = rcut;
56 skin_ = skin;
57 tol_ = tol;
58 sw_ = searchWindow;
59 density_ = densityCount;
60 }
61
62 int ownerOf(const Vec3& x) const { return halo_.ownerOf(x); }
63
65 void setSdf(const Sdf& s) { sdf_ = s; }
68 void setProfile(bool on) {
69 profile_ = on;
70 mt_.profile = on;
71 }
72 void setWallMode(bool exact, Real skin = Real(0)) {
73 wallExact_ = exact;
74 wallSkin_ = skin;
75 }
76
79 void establish(const std::vector<Vec3>& ownedPos, const std::vector<long>& ownedGid,
80 const std::vector<Real>& ownedW) {
81 gid_ = ownedGid;
82 w_ = ownedW;
83 regather(ownedPos);
84 }
85
87 StepStats step(const std::vector<Vec3>& ownedPos) {
88 StepStats st;
89 int localTrip = (maxDispFrom(ownedPos, refPos_) > Real(0.5) * skin_) ? 1 : 0;
90 int anyTrip = 0;
91 MPI_Allreduce(&localTrip, &anyTrip, 1, MPI_INT, MPI_MAX, comm_);
92 if (anyTrip) {
93 regather(ownedPos);
94 st.regathered = true;
95 } else {
96 std::vector<Vec3> comb;
97 halo_.refreshPositions(ownedPos, comb);
98 upload(comb);
99 st.repair = mt_.step(dPos_);
100 }
101 return st;
102 }
103
105 int nCombined() const { return nComb_; }
106 int nOwned() const { return nOwned_; }
109 const Sdf& sdf() const { return sdf_; }
110 const Kokkos::View<Real*, Mem>& positions() const { return dPos_; }
112 const std::vector<long>& combinedGid() const { return combGid_; }
113 long numRegathers() const { return nRegather_; }
114
115 private:
116 void regather(const std::vector<Vec3>& ownedPos) {
117 auto g = halo_.gather(ownedPos, gid_, w_, rcut_);
118 nComb_ = (int)g.pos.size();
119 nOwned_ = g.nOwned;
120 combGid_ = g.gid;
121 upload(g.pos);
122 mt_.sdf = sdf_;
123 mt_.wallExact = wallExact_;
124 mt_.wallSkin = wallSkin_;
125 mt_.profile = profile_;
126 mt_.alloc(nComb_, L_, tol_, skin_, sw_, density_, nOwned_);
127 mt_.rebuild(dPos_);
128 refPos_ = ownedPos;
129 ++nRegather_;
130 }
131
132 void upload(const std::vector<Vec3>& p) {
133 const int n = (int)p.size();
134 // exact size: MovingTessellation deep_copies the whole extent (xRef), so a slack buffer trips
135 // the extent check
136 if ((int)dPos_.extent(0) != 3 * n)
137 dPos_ = Kokkos::View<Real*, Mem>(
138 Kokkos::view_alloc(std::string("dmt_pos"), Kokkos::WithoutInitializing), (size_t)n * 3);
139 auto h = Kokkos::create_mirror_view(dPos_);
140 for (int i = 0; i < n; ++i)
141 for (int k = 0; k < 3; ++k)
142 h(3 * i + k) = wrap1(p[i][k], L_[k]);
143 Kokkos::deep_copy(dPos_, h);
144 }
145
146 Real maxDispFrom(const std::vector<Vec3>& a, const std::vector<Vec3>& b) const {
147 if (a.size() != b.size())
148 return Real(1e30); // ownership changed under us: force a re-gather
149 Real m2 = 0;
150 for (std::size_t i = 0; i < a.size(); ++i) {
151 Real d2 = 0;
152 for (int d = 0; d < 3; ++d) {
153 Real q = a[i][d] - b[i][d];
154 q -= std::round(q / L_[d]) * L_[d];
155 d2 += q * q;
156 }
157 m2 = std::max(m2, d2);
158 }
159 return std::sqrt(m2);
160 }
161
162 static Real wrap1(Real x, Real L) {
163 Real y = std::fmod(x, L);
164 return y < 0 ? y + L : y;
165 }
166
167 VoronoiHalo<Real> halo_;
168 MovingTessellation<Real, MAXP, MAXT, false, Sdf> mt_;
169 Sdf sdf_{};
170 bool wallExact_ = true;
171 bool profile_ = false;
172 Real wallSkin_ = 0;
173 Kokkos::View<Real*, Mem> dPos_;
174 std::vector<Vec3> refPos_; // owned positions at the last (re)gather (Verlet reference)
175 std::vector<long> gid_, combGid_;
176 std::vector<Real> w_;
177 Real L_[3] = {1, 1, 1};
178 Real rcut_ = 0, skin_ = 0, tol_ = 0;
179 int sw_ = 4, density_ = -1, nComb_ = 0, nOwned_ = 0;
180 long nRegather_ = 0;
181 MPI_Comm comm_ = MPI_COMM_WORLD;
182};
183
184} // namespace peclet::voro::mpi
185
186#endif // PECLET_VORO_MPI_DISTRIBUTED_MOVING_HPP
Definition distributed_moving.hpp:32
Definition repair.hpp:90
Per-step repair telemetry.
Definition repair.hpp:61
bool regathered
this step took the re-gather + cold-rebuild path (collective)
Definition distributed_moving.hpp:43
RepairStats repair
fast-path repair stats (valid when !regathered)
Definition distributed_moving.hpp:44
Definition distributed_moving.hpp:38
StepStats step(const std::vector< Vec3 > &ownedPos)
Advance to new owned positions (same ownership as establish; collective every step).
Definition distributed_moving.hpp:87
const std::vector< long > & combinedGid() const
Global ids of the combined (owned+ghost) seeds after the last (re)gather.
Definition distributed_moving.hpp:112
void setWallMode(bool exact, Real skin=Real(0))
Definition distributed_moving.hpp:72
int ownerOf(const Vec3 &x) const
Definition distributed_moving.hpp:62
long numRegathers() const
Definition distributed_moving.hpp:113
int nOwned() const
Definition distributed_moving.hpp:106
std::array< Real, 3 > Vec3
Definition distributed_moving.hpp:39
void init(std::array< Real, 3 > origin, std::array< Real, 3 > size, std::array< long, 3 > gsize, std::array< bool, 3 > periodic, Real rcut, Real skin, Real tol, MPI_Comm comm, int searchWindow=4, int densityCount=-1)
One-time setup. gsize is the ORB decomposition granularity (cells per axis).
Definition distributed_moving.hpp:48
void setSdf(const Sdf &s)
Replicated SDF geometry (every rank holds the same provider). Call before establish().
Definition distributed_moving.hpp:65
void establish(const std::vector< Vec3 > &ownedPos, const std::vector< long > &ownedGid, const std::vector< Real > &ownedW)
Definition distributed_moving.hpp:79
const Sdf & sdf() const
Definition distributed_moving.hpp:109
typename Kokkos::DefaultExecutionSpace::memory_space Mem
Definition distributed_moving.hpp:40
const Kokkos::View< Real *, Mem > & positions() const
Definition distributed_moving.hpp:110
void setProfile(bool on)
Definition distributed_moving.hpp:68
int nCombined() const
Combined owned+ghost count and owned count of the current tessellation.
Definition distributed_moving.hpp:105
MovingTessellation< Real, MAXP, MAXT, false, Sdf > & tess()
The device tessellation (cells [0, nOwned) are this rank's owned cells).
Definition distributed_moving.hpp:108
Distributed Voronoi halo over core (migration Phase 6).