chombo-discharge
Loading...
Searching...
No Matches
CD_NearestNeighborParticleMerge.H
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2021-2026 SINTEF Energy Research
3 *
4 * SPDX-License-Identifier: GPL-3.0-or-later
5 */
6
18#ifndef CD_NEARESTNEIGHBORPARTICLEMERGE_H
19#define CD_NEARESTNEIGHBORPARTICLEMERGE_H
20
21// Std includes
22#include <algorithm>
23#include <functional>
24#include <limits>
25#include <map>
26#include <optional>
27#include <unordered_set>
28#include <unordered_map>
29#include <utility>
30#include <vector>
31
32// Chombo includes
33#include <RealVect.H>
34#include <IntVect.H>
35
36// EBGeometry includes
37#include <EBGeometry.hpp>
38
39// Our includes
40#include <CD_ParticleSoA.H>
43#include <CD_NamespaceHeader.H>
44
45class AmrMesh;
46
47namespace ParticleManagement {
48
49namespace detail {
50
62template <typename Packed>
76
103
113template <typename Packed>
115{
120
126
132
140
149 std::vector<NNFallbackCandidate> fallbackCandidates;
150};
151
161template <typename Packed>
181
204
210template <typename Packed>
233
234} // namespace detail
235
250template <typename Packed>
251using PayloadCombine = std::function<
252 Packed(const Packed& a_first, const Real a_firstWeight, const Packed& a_second, const Real a_secondWeight)>;
253
266using PositionValid = std::function<bool(const RealVect& a_mergedPosition)>;
267
278using IDAllocator = std::function<ParticleID()>;
279
291template <typename Packed>
292using MergeCommittedCallback = std::function<void(const MergeParticle<Packed>& a_first,
293 const MergeParticle<Packed>& a_second,
294 const MergeParticle<Packed>& a_merged)>;
295
296namespace detail {
297
312inline IntVect
313cellKeyOf(const RealVect& a_position, const RealVect& a_probLo, const RealVect& a_dx) noexcept;
314
323using NNCellKey = std::pair<int, IntVect>;
324
336{
342 std::size_t
343 operator()(const NNCellKey& a_key) const noexcept
344 {
345 std::size_t hash = LevelTiles::TileHasher()(a_key.second);
346 hash ^= static_cast<std::size_t>(static_cast<unsigned int>(a_key.first)) + 0x9e3779b9 + (hash << 6) + (hash >> 2);
347 return hash;
348 }
349};
350
351} // namespace detail
352
372{
373public:
378 NNCellBudget(const int a_uniform) noexcept : m_uniform(a_uniform)
379 {}
380
387 inline void
388 reserveOne(const int a_level, const IntVect& a_cell)
389 {
390 const int count = ++m_reserved[detail::NNCellKey(a_level, a_cell)];
391
392 m_minBudget = std::min(m_minBudget, std::max(0, m_uniform - count));
393 }
394
404 inline void
405 reserveOne(const int a_level, const RealVect& a_position, const RealVect& a_probLo, const RealVect& a_dx)
406 {
407 this->reserveOne(a_level, detail::cellKeyOf(a_position, a_probLo, a_dx));
408 }
409
415 inline int
416 operator()(const detail::NNCellKey& a_key) const noexcept
417 {
418 if (m_reserved.empty()) {
419 return m_uniform;
420 }
421
422 const auto it = m_reserved.find(a_key);
423
424 return (it == m_reserved.end()) ? m_uniform : std::max(0, m_uniform - it->second);
425 }
426
434 inline int
435 minimum() const noexcept
436 {
437 return m_reserved.empty() ? m_uniform : std::min(m_uniform, m_minBudget);
438 }
439
440private:
444 int m_uniform;
445
449 int m_minBudget = std::numeric_limits<int>::max();
450
454 std::unordered_map<detail::NNCellKey, int, detail::NNCellKeyHasher> m_reserved;
455};
456
457namespace detail {
458
467using NNWalkCell = IntVect;
468
486template <typename Packed, typename Cloud = EBGeometry::PointCloudBVH<Real, ParticleID>>
487struct NNSpatialIndex
488{
494 std::shared_ptr<Cloud> pointCloud;
495
501 std::size_t pointCloudNLocal = 0;
502
510 std::vector<typename Cloud::Hit> pointCloudGraph;
511
515 int pointCloudK = 0;
516};
517
552template <typename Packed, typename Cloud = EBGeometry::PointCloudBVH<Real, ParticleID>>
553inline void
554buildNNSpatialIndex(NNSpatialIndex<Packed, Cloud>& a_index,
555 const std::vector<MergeParticle<Packed>>& a_localValid,
556 const std::vector<MergeParticle<Packed>>& a_ghosts,
557 const RealVect& a_probLo,
558 const RealVect& a_dx,
559 const NNCellBudget& a_cellBudget,
560 const int a_kNearest) noexcept;
561
630template <typename Packed, typename Cloud = EBGeometry::PointCloudBVH<Real, ParticleID>>
631inline void
632findNearestNeighborCandidates(std::vector<NNMergeEdge<Packed>>& a_edges,
633 const std::vector<MergeParticle<Packed>>& a_localValid,
634 const std::vector<MergeParticle<Packed>>& a_ghosts,
635 const std::unordered_set<ParticleID>& a_consumedIDs,
636 const NNSpatialIndex<Packed, Cloud>& a_spatialIndex,
637 const std::unordered_map<NNCellKey, int, NNCellKeyHasher>& a_liveCellCount,
638 const RealVect& a_probLo,
639 const RealVect& a_dx,
640 const NNCellBudget& a_cellBudget,
641 const int a_maxFallbackCandidates = 0,
642 const std::optional<int> a_maxCellDistance = std::nullopt) noexcept;
643
651struct NNCellMeta
652{
656 ParticleID globalID;
657
663 bool isLocal;
664
671 int level;
672};
673
678using NNCellCloud = EBGeometry::PointCloudBVH<Real, NNCellMeta>;
679
686using NNCellSpatialIndex = std::unordered_map<NNWalkCell, std::shared_ptr<NNCellCloud>, LevelTiles::TileHasher>;
687
705template <typename Packed>
706inline void
707buildNNCellSpatialIndex(NNCellSpatialIndex& a_index,
708 const std::vector<MergeParticle<Packed>>& a_localValid,
709 const std::vector<MergeParticle<Packed>>& a_ghosts,
710 const RealVect& a_probLo,
711 const RealVect& a_dx,
712 const NNCellBudget& a_cellBudget) noexcept;
713
753template <typename Packed>
754inline void
755findNearestNeighborCandidatesOneCell(std::vector<NNMergeEdge<Packed>>& a_edges,
756 const std::vector<MergeParticle<Packed>>& a_localValid,
757 const std::unordered_set<ParticleID>& a_consumedIDs,
758 const NNCellSpatialIndex& a_cellIndex,
759 const std::unordered_map<NNCellKey, int, NNCellKeyHasher>& a_liveCellCount,
760 const RealVect& a_probLo,
761 const RealVect& a_dx,
762 const std::vector<RealVect>& a_dxByLevel,
763 const NNCellBudget& a_cellBudget,
764 const int a_maxFallbackCandidates = 0) noexcept;
765
864template <typename Packed, typename Combine, typename PosValid, typename Allocator, typename OnMerge>
865inline void
866resolveTrivialTier(
867 std::unordered_map<NNCellKey, int, NNCellKeyHasher>& a_liveCellCount,
868 std::unordered_set<ParticleID>& a_consumedIDs,
869 std::unordered_set<ParticleID>& a_hasOutgoingCommitment,
870 std::vector<NNMergeResult<Packed>>& a_results,
871 const std::vector<NNMergeEdge<Packed>>& a_edges,
872 const std::unordered_map<ParticleID, NNPooledParticle<Packed>>& a_particlesByID,
873 const Combine& a_combine,
874 const NNCellBudget& a_cellBudget,
875 const RealVect& a_probLo,
876 const std::vector<RealVect>& a_dxByLevel,
877 const PosValid& a_isPositionValid,
878 const Allocator& a_allocateID,
879 const int a_maxFallbackCandidates = 0,
880 const std::optional<int> a_maxCellDistance = std::nullopt,
881 unsigned long long* a_crossLevelMergeCount = nullptr,
882 const OnMerge& a_onMergeCommitted =
883 [](const MergeParticle<Packed>&, const MergeParticle<Packed>&, const MergeParticle<Packed>&) {
884 }) noexcept;
885
909template <typename Packed>
910inline void
911generateProposals(std::vector<std::vector<NNMergeProposal<Packed>>>& a_proposalsByDestRank,
912 const std::vector<NNMergeEdge<Packed>>& a_edges,
913 const std::unordered_set<ParticleID>& a_hasOutgoingCommitment,
914 const std::unordered_map<ParticleID, NNPooledParticle<Packed>>& a_particlesByID,
915 const int a_numRanks) noexcept;
916
999template <typename Packed, typename Combine, typename PosValid, typename Allocator, typename OnMerge>
1000inline void
1001judgeProposals(
1002 std::unordered_map<NNCellKey, int, NNCellKeyHasher>& a_liveCellCount,
1003 std::vector<NNMergeResult<Packed>>& a_results,
1004 std::vector<std::vector<NNMergeVerdict>>& a_verdictsByDestRank,
1005 const std::vector<NNMergeProposal<Packed>>& a_incomingProposals,
1006 const std::unordered_map<ParticleID, NNPooledParticle<Packed>>& a_particlesByID,
1007 const std::unordered_set<ParticleID>& a_consumedIDs,
1008 const std::unordered_set<ParticleID>& a_hasOutgoingCommitment,
1009 const std::map<ParticleID, ParticleID>& a_outgoingTargetOf,
1010 const Combine& a_combine,
1011 const NNCellBudget& a_cellBudget,
1012 const RealVect& a_probLo,
1013 const std::vector<RealVect>& a_dxByLevel,
1014 const PosValid& a_isPositionValid,
1015 const Allocator& a_allocateID,
1016 const std::optional<int> a_maxCellDistance = std::nullopt,
1017 unsigned long long* a_crossLevelMergeCount = nullptr,
1018 const OnMerge& a_onMergeCommitted =
1019 [](const MergeParticle<Packed>&, const MergeParticle<Packed>&, const MergeParticle<Packed>&) {
1020 }) noexcept;
1021
1033inline void
1034applyVerdicts(std::unordered_set<ParticleID>& a_consumedIDs,
1035 const std::vector<NNMergeVerdict>& a_incomingVerdicts) noexcept;
1036
1052using PositionLocator = std::function<LevelTiles::LevelAndBox(const RealVect& a_position)>;
1053
1074template <typename Packed>
1075inline void
1076placeMergedParticles(std::map<std::pair<int, unsigned int>, std::vector<MergeParticle<Packed>>>& a_localByPatch,
1077 std::vector<std::vector<MergeParticle<Packed>>>& a_scatterByDestRank,
1078 const std::vector<NNMergeResult<Packed>>& a_results,
1079 const PositionLocator& a_locate,
1080 const int a_thisRank) noexcept;
1081
1088struct NNPatchWork
1089{
1093 int level;
1094
1098 DataIndex din;
1099
1103 RealVect dx;
1104};
1105
1136template <typename P, typename Packed, typename Traits, typename Gather>
1137inline void
1138gatherMergeParticles(ParticleContainer<P, Traits>& a_particles,
1139 std::vector<NNPatchWork>& a_patchWork,
1140 std::vector<std::vector<MergeParticle<Packed>>>& a_patchLocalValid,
1141 std::vector<std::vector<MergeParticle<Packed>>>& a_patchGhosts,
1142 std::unordered_map<ParticleID, NNPooledParticle<Packed>>& a_particlesByID,
1143 std::unordered_map<NNCellKey, int, NNCellKeyHasher>& a_liveCellCount,
1144 const AmrMesh& a_amr,
1145 const std::string& a_realm,
1146 const int a_finestLevel,
1147 const RealVect& a_probLo,
1148 const std::vector<RealVect>& a_dxByLevel,
1149 const int a_ghostWidth,
1150 const Gather& a_gather) noexcept;
1151
1195template <typename P,
1196 typename Packed,
1197 typename Traits,
1198 typename Combine,
1199 typename Scatter,
1200 typename PosValid,
1201 typename Allocator,
1202 typename OnMerge>
1203inline void
1204finishMergeRound(ParticleContainer<P, Traits>& a_particles,
1205 std::unordered_map<ParticleID, NNPooledParticle<Packed>>& a_particlesByID,
1206 std::unordered_set<ParticleID>& a_consumedIDs,
1207 std::unordered_map<NNCellKey, int, NNCellKeyHasher>& a_liveCellCount,
1208 std::vector<NNMergeResult<Packed>>& a_allResults,
1209 unsigned long long* a_crossLevelMergeCount,
1210 const AmrMesh& a_amr,
1211 const std::string& a_realm,
1212 const NNCellBudget& a_cellBudget,
1213 const Combine& a_combine,
1214 const Scatter& a_scatter,
1215 const Allocator& a_allocateID,
1216 const std::optional<int> a_maxCellDistance,
1217 const PosValid& a_isPositionValid,
1218 const RealVect& a_probLo,
1219 const std::vector<RealVect>& a_dxByLevel,
1220 const std::vector<NNPatchWork>& a_patchWork,
1221 const std::vector<NNMergeEdge<Packed>>& a_pooledEdges,
1222 const std::unordered_set<ParticleID>& a_hasOutgoingCommitment,
1223 const OnMerge& a_onMergeCommitted) noexcept;
1224
1241template <typename P,
1242 typename Packed,
1243 typename Traits,
1244 typename Cloud,
1245 typename Gather,
1246 typename Combine,
1247 typename Scatter,
1248 typename Allocator,
1249 typename PosValid,
1250 typename OnMerge>
1251inline void
1252mergeNearestNeighborsRoundImpl(ParticleContainer<P, Traits>& a_particles,
1253 unsigned long long* a_crossLevelMergeCount,
1254 const AmrMesh& a_amr,
1255 const NNCellBudget& a_cellBudget,
1256 const Gather& a_gather,
1257 const Combine& a_combine,
1258 const Scatter& a_scatter,
1259 const Allocator& a_allocateID,
1260 const bool a_iterateLocalTierToConvergence,
1261 const int a_maxFallbackCandidates,
1262 const std::optional<int> a_maxCellDistance,
1263 const int a_ghostWidth,
1264 const PosValid& a_isPositionValid,
1265 const OnMerge& a_onMergeCommitted);
1266
1267} // namespace detail
1268
1354template <typename P,
1355 typename Packed,
1356 typename Traits = ParticleTraits<P>,
1357 typename Gather,
1358 typename Combine,
1359 typename Scatter,
1360 typename Allocator,
1361 typename PosValid = std::function<bool(const RealVect&)>,
1362 typename OnMerge = std::function<
1363 void(const MergeParticle<Packed>&, const MergeParticle<Packed>&, const MergeParticle<Packed>&)>>
1364inline void
1366 ParticleContainer<P, Traits>& a_particles,
1367 const AmrMesh& a_amr,
1368 const NNCellBudget& a_cellBudget,
1369 const Gather& a_gather,
1370 const Combine& a_combine,
1371 const Scatter& a_scatter,
1372 const Allocator& a_allocateID,
1373 const bool a_iterateLocalTierToConvergence = false,
1374 const int a_maxFallbackCandidates = 0,
1375 const std::optional<int> a_maxCellDistance = std::nullopt,
1376 const int a_ghostWidth = 1,
1377 const PosValid& a_isPositionValid =
1378 [](const RealVect&) {
1379 return true;
1380 },
1381 unsigned long long* a_crossLevelMergeCount = nullptr,
1382 const OnMerge& a_onMergeCommitted =
1383 [](const MergeParticle<Packed>&, const MergeParticle<Packed>&, const MergeParticle<Packed>&) {
1384 });
1385
1402template <typename P,
1403 typename Packed,
1404 typename Traits = ParticleTraits<P>,
1405 typename Gather,
1406 typename Combine,
1407 typename Scatter,
1408 typename Allocator,
1409 typename PosValid = std::function<bool(const RealVect&)>,
1410 typename OnMerge = std::function<
1411 void(const MergeParticle<Packed>&, const MergeParticle<Packed>&, const MergeParticle<Packed>&)>>
1412inline void
1414 ParticleContainer<P, Traits>& a_particles,
1415 const AmrMesh& a_amr,
1416 const NNCellBudget& a_cellBudget,
1417 const Gather& a_gather,
1418 const Combine& a_combine,
1419 const Scatter& a_scatter,
1420 const Allocator& a_allocateID,
1421 const bool a_iterateLocalTierToConvergence = false,
1422 const int a_maxFallbackCandidates = 0,
1423 const std::optional<int> a_maxCellDistance = std::nullopt,
1424 const int a_ghostWidth = 1,
1425 const PosValid& a_isPositionValid =
1426 [](const RealVect&) {
1427 return true;
1428 },
1429 unsigned long long* a_crossLevelMergeCount = nullptr,
1430 const OnMerge& a_onMergeCommitted =
1431 [](const MergeParticle<Packed>&, const MergeParticle<Packed>&, const MergeParticle<Packed>&) {
1432 });
1433
1473template <typename P,
1474 typename Packed,
1475 typename Traits = ParticleTraits<P>,
1476 typename Gather,
1477 typename Combine,
1478 typename Scatter,
1479 typename Allocator,
1480 typename PosValid = std::function<bool(const RealVect&)>,
1481 typename OnMerge = std::function<
1482 void(const MergeParticle<Packed>&, const MergeParticle<Packed>&, const MergeParticle<Packed>&)>>
1483inline void
1485 ParticleContainer<P, Traits>& a_particles,
1486 const AmrMesh& a_amr,
1487 const NNCellBudget& a_cellBudget,
1488 const Gather& a_gather,
1489 const Combine& a_combine,
1490 const Scatter& a_scatter,
1491 const Allocator& a_allocateID,
1492 const bool a_iterateLocalTierToConvergence = false,
1493 const int a_maxFallbackCandidates = 0,
1494 const PosValid& a_isPositionValid =
1495 [](const RealVect&) {
1496 return true;
1497 },
1498 unsigned long long* a_crossLevelMergeCount = nullptr,
1499 const OnMerge& a_onMergeCommitted =
1500 [](const MergeParticle<Packed>&, const MergeParticle<Packed>&, const MergeParticle<Packed>&) {
1501 });
1502
1503} // namespace ParticleManagement
1504
1505#include <CD_NamespaceFooter.H>
1506
1508
1509#endif
Implementation of CD_NearestNeighborParticleMerge.H.
Declaration of an AMR-hierarchy container that owns per-patch ParticleSoA leaves.
Namespace containing various particle management utilities.
Declaration of ParticleSoA, an arena-backed Struct-of-Arrays particle container.
std::int64_t ParticleID
Global particle identifier type (container-owned metadata column; fixed-width for I/O).
Definition CD_ParticleSoA.H:161
Class for handling spatial operations.
Definition CD_AmrMesh.H:45
AMR-hierarchy container of computational particles, stored per patch in Struct-of-Arrays form.
Definition CD_ParticleContainer.H:123
The per-cell particle count this merge drains each cell down to.
Definition CD_NearestNeighborParticleMerge.H:372
void reserveOne(const int a_level, const IntVect &a_cell)
Reserve one slot in a cell, lowering that cell's budget by one.
Definition CD_NearestNeighborParticleMerge.H:388
int operator()(const detail::NNCellKey &a_key) const noexcept
The budget for one cell: the uniform count less that cell's reservations, floored at 0.
Definition CD_NearestNeighborParticleMerge.H:416
NNCellBudget(const int a_uniform) noexcept
Construct a uniform budget. Deliberately implicit – a bare count is the common case.
Definition CD_NearestNeighborParticleMerge.H:378
void reserveOne(const int a_level, const RealVect &a_position, const RealVect &a_probLo, const RealVect &a_dx)
Reserve one slot in the cell a position falls in.
Definition CD_NearestNeighborParticleMerge.H:405
int minimum() const noexcept
The smallest budget any cell has.
Definition CD_NearestNeighborParticleMerge.H:435
IntVect cellKeyOf(const RealVect &a_position, const RealVect &a_probLo, const RealVect &a_dx) noexcept
The unclamped, position-derived cell index a given physical position falls in.
Definition CD_NearestNeighborParticleMergeImplem.H:254
std::pair< int, IntVect > NNCellKey
A cell key together with the AMR level it was computed on – see cellKeyOf()'s warning.
Definition CD_NearestNeighborParticleMerge.H:323
Namespace for various particle management tools.
Definition CD_KDParticleMerge.H:33
std::function< ParticleID()> IDAllocator
Illustrative signature of the fresh-id allocator: produce one globally-unique id for a newly created ...
Definition CD_NearestNeighborParticleMerge.H:278
std::function< void(const MergeParticle< Packed > &a_first, const MergeParticle< Packed > &a_second, const MergeParticle< Packed > &a_merged)> MergeCommittedCallback
Optional per-merge diagnostic callback: observe every individual merge as it commits.
Definition CD_NearestNeighborParticleMerge.H:294
void mergeNearestNeighborsOneCell(ParticleContainer< P, Traits > &a_particles, const AmrMesh &a_amr, const NNCellBudget &a_cellBudget, const Gather &a_gather, const Combine &a_combine, const Scatter &a_scatter, const Allocator &a_allocateID, const bool a_iterateLocalTierToConvergence=false, const int a_maxFallbackCandidates=0, const PosValid &a_isPositionValid=[](const RealVect &) { return true;}, unsigned long long *a_crossLevelMergeCount=nullptr, const OnMerge &a_onMergeCommitted=[](const MergeParticle< Packed > &, const MergeParticle< Packed > &, const MergeParticle< Packed > &) { })
Run one full round of the one-cell nearest-neighbor merge: the same distributed propose/judge/verdict...
Definition CD_NearestNeighborParticleMergeImplem.H:1876
void mergeNearestNeighborsHash(ParticleContainer< P, Traits > &a_particles, const AmrMesh &a_amr, const NNCellBudget &a_cellBudget, const Gather &a_gather, const Combine &a_combine, const Scatter &a_scatter, const Allocator &a_allocateID, const bool a_iterateLocalTierToConvergence=false, const int a_maxFallbackCandidates=0, const std::optional< int > a_maxCellDistance=std::nullopt, const int a_ghostWidth=1, const PosValid &a_isPositionValid=[](const RealVect &) { return true;}, unsigned long long *a_crossLevelMergeCount=nullptr, const OnMerge &a_onMergeCommitted=[](const MergeParticle< Packed > &, const MergeParticle< Packed > &, const MergeParticle< Packed > &) { })
Run one full round of the nearest-neighbor merge algorithm, identical in every respect to mergeNeares...
Definition CD_NearestNeighborParticleMergeImplem.H:1832
std::function< Packed(const Packed &a_first, const Real a_firstWeight, const Packed &a_second, const Real a_secondWeight)> PayloadCombine
Illustrative signature of the combine callback: produce a merged particle's opaque payload from its t...
Definition CD_NearestNeighborParticleMerge.H:252
void mergeNearestNeighborsTree(ParticleContainer< P, Traits > &a_particles, const AmrMesh &a_amr, const NNCellBudget &a_cellBudget, const Gather &a_gather, const Combine &a_combine, const Scatter &a_scatter, const Allocator &a_allocateID, const bool a_iterateLocalTierToConvergence=false, const int a_maxFallbackCandidates=0, const std::optional< int > a_maxCellDistance=std::nullopt, const int a_ghostWidth=1, const PosValid &a_isPositionValid=[](const RealVect &) { return true;}, unsigned long long *a_crossLevelMergeCount=nullptr, const OnMerge &a_onMergeCommitted=[](const MergeParticle< Packed > &, const MergeParticle< Packed > &, const MergeParticle< Packed > &) { })
Run one full round (one timestep's worth) of the nearest-neighbor merge algorithm.
Definition CD_NearestNeighborParticleMergeImplem.H:1788
std::function< bool(const RealVect &a_mergedPosition)> PositionValid
Illustrative signature of the position-validity predicate for a would-be merged particle.
Definition CD_NearestNeighborParticleMerge.H:266
Result of a point->block query. See findDestination.
Definition CD_LevelTiles.H:123
Hash functor for using IntVect tiles as unordered_map keys.
Definition CD_LevelTiles.H:55
Minimal, payload-agnostic description of one particle as input to a distributed merge.
Definition CD_ParticleManagement.H:430
Hash functor for NNCellKey – REQUIRED whenever NNCellKey is used as a hash-map key; NNCellKey must ne...
Definition CD_NearestNeighborParticleMerge.H:336
std::size_t operator()(const NNCellKey &a_key) const noexcept
Hash operator.
Definition CD_NearestNeighborParticleMerge.H:343
One additional ranked candidate beyond a query's primary nearest neighbor.
Definition CD_NearestNeighborParticleMerge.H:86
ParticleID candidateID
Global id of this candidate.
Definition CD_NearestNeighborParticleMerge.H:90
bool candidateIsLocal
True iff this candidate is a locally-valid particle in the SAME patch as the query (i....
Definition CD_NearestNeighborParticleMerge.H:101
Real distanceSquared
Squared distance between the query particle and this candidate.
Definition CD_NearestNeighborParticleMerge.H:95
One candidate merge edge: a single particle's own nearest-neighbor query result.
Definition CD_NearestNeighborParticleMerge.H:115
ParticleID candidateID
Global id of the candidate (query's nearest neighbor). May be a local valid particle (same patch) or ...
Definition CD_NearestNeighborParticleMerge.H:131
bool candidateIsLocal
True iff the candidate is a locally-valid particle in the SAME patch as the query (i....
Definition CD_NearestNeighborParticleMerge.H:139
Real distanceSquared
Squared distance between the query particle and its candidate.
Definition CD_NearestNeighborParticleMerge.H:119
std::vector< NNFallbackCandidate > fallbackCandidates
Next-nearest candidates beyond candidateID, in ascending distanceSquared order.
Definition CD_NearestNeighborParticleMerge.H:149
ParticleID queryID
Global id of the query particle (always locally valid/owned – ghosts never initiate a query).
Definition CD_NearestNeighborParticleMerge.H:125
A cross-patch merge proposal: one particle's own nearest-neighbor query result, bundled as a self-con...
Definition CD_NearestNeighborParticleMerge.H:163
ParticleID targetID
Global id of the particle being proposed to. Owned by the receiving (judge) rank.
Definition CD_NearestNeighborParticleMerge.H:173
MergeParticle< Packed > source
The proposer's own particle (full data) – always locally valid/owned by the sending rank.
Definition CD_NearestNeighborParticleMerge.H:168
Real distanceSquared
Squared distance between source and the target. Duplicated from the originating NNMergeEdge so the ju...
Definition CD_NearestNeighborParticleMerge.H:179
One resolved merge: the two consumed particles' ids and the newly created merged particle (not yet pl...
Definition CD_NearestNeighborParticleMerge.H:212
ParticleID secondID
Global id of the second consumed particle. For a trivial-tier result, this is the local candidate....
Definition CD_NearestNeighborParticleMerge.H:223
MergeParticle< Packed > merged
The newly created merged particle: weighted-centroid position, weighted-average opaque payload (compu...
Definition CD_NearestNeighborParticleMerge.H:231
ParticleID firstID
Global id of the first consumed particle. For a trivial-tier result, this is the query particle....
Definition CD_NearestNeighborParticleMerge.H:217
The judge's reply to one proposal.
Definition CD_NearestNeighborParticleMerge.H:190
bool accepted
True iff the judge accepted this specific proposal (i.e. it was the winning candidate for its target ...
Definition CD_NearestNeighborParticleMerge.H:202
ParticleID proposerID
Global id of the proposer this verdict is a reply to (i.e. NNMergeProposal::source's id)....
Definition CD_NearestNeighborParticleMerge.H:196
Pooled per-round record for one particle: the particle plus its cached boundary-exposure flag.
Definition CD_NearestNeighborParticleMerge.H:64
MergeParticle< Packed > particle
The pooled particle (position/weight/ids/level/payload).
Definition CD_NearestNeighborParticleMerge.H:68
bool exposed
Whether this local valid particle's cell touches a patch boundary (has ghost targets)....
Definition CD_NearestNeighborParticleMerge.H:74
Traits class that a user specializes to describe the PAYLOAD columns of a particle type....
Definition CD_ParticleSoA.H:192