21#ifndef PECLET_CORE_HALO_PARTICLE_HALO_TOPOLOGY_HPP
22#define PECLET_CORE_HALO_PARTICLE_HALO_TOPOLOGY_HPP
67 numOwned_ =
pos.size();
70 const int me = mig_->rank();
73 std::map<int, std::vector<Index>>
sendMap;
74 std::map<int, std::vector<Vec<Dim>>>
shiftMap;
81 std::vector<int>
cand;
84 for (
const auto& x :
pos)
85 for (
int d = 0;
d <
Dim; ++
d) {
89 for (
int r = 0; r <
nranks; ++r)
93 for (std::size_t
i = 0;
i <
pos.size(); ++
i) {
94 for (
const int r :
cand) {
105 if (!mig_->withinRcutOfBlock(
pos[
i], r,
rcut,
img))
108 for (
int d = 0;
d <
Dim; ++
d)
117 sendRankPos_.clear();
118 for (
auto& [r, idx] :
sendMap) {
119 sendRankPos_[r] = sendRanks_.size();
120 sendRanks_.push_back(r);
121 sendIdx_.push_back(std::move(idx));
128 recvRankPos_.clear();
132 auto packNext = [&](std::vector<char>&
out) ->
int {
133 if (
k >= sendRanks_.size())
135 int dst = sendRanks_[
k];
139 std::memcpy(
out.data(),
sh.data(),
out.size());
144 recvRankPos_[
src] = recvRanks_.size();
145 recvRanks_.push_back(
src);
146 recvCount_.push_back(
cnt);
148 for (
int i = 0;
i <
cnt; ++
i)
149 shift_.push_back(
sh[
i]);
153 recvOffset_.assign(recvRanks_.size() + 1, 0);
154 for (std::size_t
i = 0;
i < recvCount_.size(); ++
i)
155 recvOffset_[
i + 1] = recvOffset_[
i] + recvCount_[
i];
156 numReceived_ = shift_.size();
164 std::vector<Vec<Dim>>
imgs;
165 for (std::size_t
i = 0;
i <
pos.size(); ++
i) {
168 for (
const auto&
sh :
imgs) {
169 selfIdx_.push_back(
static_cast<Index>(
i));
170 selfShift_.push_back(
sh);
174 for (
const auto&
sh : selfShift_)
175 shift_.push_back(
sh);
176 numGhost_ = shift_.size();
179 ghostPos_.assign(numGhost_,
Vec<Dim>{});
192 Index off = recvOffset_[p];
193 for (
int i = 0;
i < recvCount_[p]; ++
i)
194 for (
int d = 0;
d <
Dim; ++
d)
195 ghost[off +
i][
d] =
in[
i][
d] + shift_[off +
i][
d];
198 for (std::size_t
j = 0;
j < selfIdx_.size(); ++
j)
199 for (
int d = 0;
d <
Dim; ++
d)
200 ghost[numReceived_ +
j][
d] =
owned[selfIdx_[
j]][
d] + shift_[numReceived_ +
j][
d];
204 template <
typename T>
207 Index off = recvOffset_[p];
208 for (
int i = 0;
i < recvCount_[p]; ++
i)
209 ghost[off +
i] =
in[
i];
212 for (std::size_t
j = 0;
j < selfIdx_.size(); ++
j)
213 ghost[numReceived_ +
j] =
owned[selfIdx_[
j]];
218 template <
typename T>
222 const int ns =
static_cast<int>(sendRanks_.size());
223 const int nr =
static_cast<int>(recvRanks_.size());
226 for (
int k = 0;
k <
ns; ++
k) {
227 rbuf[
k].resize(sendIdx_[
k].size());
229 sendRanks_[
k], 7504, mig_->comm(), &
rreq[
k]);
231 for (
int p = 0; p <
nr; ++p) {
232 Index off = recvOffset_[p];
233 sbuf[p].assign(ghost + off, ghost + off + recvCount_[p]);
235 recvRanks_[p], 7504, mig_->comm(), &
sreq[p]);
238 for (
int k = 0;
k <
ns; ++
k) {
239 auto& idx = sendIdx_[
k];
240 for (std::size_t
i = 0;
i < idx.size(); ++
i)
244 for (std::size_t
j = 0;
j < selfIdx_.size(); ++
j)
245 owned[selfIdx_[
j]] += ghost[numReceived_ +
j];
253 template <
typename T,
typename Store>
255 const int ns =
static_cast<int>(sendRanks_.size());
256 const int nr =
static_cast<int>(recvRanks_.size());
259 for (
int p = 0; p <
nr; ++p) {
260 rbuf[p].resize(recvCount_[p]);
262 recvRanks_[p],
tag, mig_->comm(), &
rreq[p]);
264 for (
int k = 0;
k <
ns; ++
k) {
265 auto& idx = sendIdx_[
k];
266 sbuf[
k].resize(idx.size());
267 for (std::size_t
i = 0;
i < idx.size(); ++
i)
270 sendRanks_[
k],
tag, mig_->comm(), &
sreq[
k]);
273 for (
int p = 0; p <
nr; ++p)
274 store(
static_cast<std::size_t
>(p),
rbuf[p].data());
305 t.sendOffsets.push_back(0);
306 for (std::size_t
k = 0;
k < sendIdx_.size(); ++
k) {
307 const auto& idx = sendIdx_[
k];
308 t.sendCounts.push_back(
static_cast<int>(idx.size()));
310 t.sendIdx.push_back(
id);
311 for (
const auto&
sh : sendShift_[
k])
312 t.sendShift.push_back(
sh);
313 t.sendOffsets.push_back(
static_cast<int>(
t.sendIdx.size()));
315 t.recvRanks = recvRanks_;
316 t.recvCounts = recvCount_;
317 t.recvOffsets.assign(recvOffset_.begin(),
318 recvOffset_.begin() +
static_cast<std::ptrdiff_t
>(recvRanks_.size()));
320 t.selfIdx = selfIdx_;
321 t.numReceived =
static_cast<Index>(numReceived_);
327 std::size_t numOwned_ = 0, numGhost_ = 0;
330 std::vector<int> sendRanks_;
331 std::vector<std::vector<Index>> sendIdx_;
332 std::vector<std::vector<Vec<Dim>>> sendShift_;
333 std::map<int, std::size_t> sendRankPos_;
336 std::vector<int> recvRanks_;
337 std::vector<int> recvCount_;
338 std::vector<Index> recvOffset_;
339 std::map<int, std::size_t> recvRankPos_;
343 std::vector<Index> selfIdx_;
344 std::vector<Vec<Dim>> selfShift_;
345 std::size_t numReceived_ = 0;
347 std::vector<Vec<Dim>>
349 std::vector<Vec<Dim>> ghostPos_;
void init(const ParticleMigrator< Dim > &mig)
Bind to a migrator (provides the decomposition, domain map, rank and comm).
void forwardPositions(const Vec< Dim > *owned, Vec< Dim > *ghost)
owned[N] -> ghost[G], with the periodic image shift added (use for positions).
void forward(const T *owned, T *ghost)
owned[N] -> ghost[G], verbatim (translation-invariant fields: velocity, id, radius,...
std::size_t numOwned() const
void reverse(const T *ghost, T *owned)
ghost[G] -> owned[N], accumulated (T must have operator+=).
void build(const std::vector< Vec< Dim > > &pos, double rcut, bool includePeriodicSelf=false, bool allImages=false)
(Re)establish the owner<->ghost correspondence: every owned particle within rcut of another rank's bl...
const std::vector< Vec< Dim > > & ghostPositions() const
std::size_t numGhost() const
int MPI_Comm_size(MPI_Comm, int *s)
int MPI_Waitall(int, MPI_Request *, MPI_Status *)
#define MPI_STATUSES_IGNORE
int MPI_Isend(const void *, int, MPI_Datatype, int, int, MPI_Comm, MPI_Request *)
int MPI_Irecv(void *, int, MPI_Datatype, int, int, MPI_Comm, MPI_Request *)
Kokkos::View< T *, MemSpace > View
1D device array.
std::int64_t Index
Signed index type for grids and particles (supersedes block_decomposer's long int IndxT).
std::vector< Vec< Dim > > shift
std::vector< int > sendOffsets
std::vector< int > recvRanks
std::vector< Index > sendIdx
std::vector< int > sendCounts
std::vector< Index > recvOffsets
std::vector< int > recvCounts
std::vector< Index > selfIdx
std::vector< Vec< Dim > > sendShift
std::vector< int > sendRanks