25#ifndef PARTICLE_COMMUNICATION_UTILITIES_H
26#define PARTICLE_COMMUNICATION_UTILITIES_H
34namespace communication {
38template<
typename T,
unsigned D,
bool verbose=false>
42 std::vector<int> neighbors;
43 cuboidGeometry.getNeighbourhood(globiC, neighbors, offset);
46 if constexpr(verbose){
47 std::cout << globiC <<
": " << neighbors << std::endl;
54template<
typename T,
unsigned D,
bool verbose=false>
56 SuperStructure<T,D>& superStructure,
int rank, std::map<
int,std::vector<int>> neighbourhood )
58 std::unordered_set<int> rankNeighbours;
60#ifdef PARALLEL_MODE_MPI
63 for (
auto cuboidNeighbourPair : neighbourhood){
64 int globiC = cuboidNeighbourPair.first;
65 if (loadBalancer.rank(globiC) == rank) {
66 std::vector<int>& neighbours = cuboidNeighbourPair.second;
67 for (
int globiCN : neighbours ){
68 rankNeighbours.insert( loadBalancer.rank(globiCN));
73 if constexpr(verbose){
74 std::cout << rank <<
": " << rankNeighbours << std::endl;
78 return rankNeighbours;
83template<
typename T,
unsigned D,
bool verbose=false>
85 SuperStructure<T,D>& superStructure,
int rank,
const std::vector<std::unordered_set<int>>& neighbourhood )
87 std::map<int,std::vector<int>> neighbourhoodMap;
89 for(
unsigned i=0; i<neighbourhood.size(); ++i) {
90 neighbourhoodMap[i] = std::vector<int>();
91 for(
int iC : neighbourhood[i]) {
92 neighbourhoodMap[i].push_back(iC);
96 return getNeighbourRanksFromCuboidNeighbourhood<T,D,verbose>(
97 superStructure, rank, neighbourhoodMap );
101template<
typename T,
unsigned D,
bool verbose=false>
103 SuperStructure<T,D>& superStructure,
const std::vector<std::unordered_set<int>>& neighbourhood )
106 return getNeighbourRanksFromCuboidNeighbourhood<T,D,verbose>(
107 superStructure, rank, neighbourhood);
112template<
typename T,
unsigned D,
bool verbose=false>
116 std::unordered_set<int> rankNeighbours;
118#ifdef PARALLEL_MODE_MPI
124 std::map<int,std::vector<int>> neighbourhood;
128 constexpr bool correctFaultyNeighbourhood =
true;
132 rankNeighbours = getNeighbourRanksFromCuboidNeighbourhood<T,D,verbose>(
133 superStructure, rank, neighbourhood );
136 return rankNeighbours;
140template<
typename T,
unsigned D,
bool verbose=false>
146 return getNeighbourRanks<T,D,false>(superStructure, offset, rank);
150template<
typename T,
typename PARTICLETYPE>
152 std::uint8_t* bufferiCandParticle )
157 const std::vector<unsigned int> index{0};
160 communicatable.serialize(index, bufferiCandParticle);
162 return communicatable.size(index);
165template<
typename T,
typename PARTICLETYPE>
168 std::uint8_t* bufferiCandParticle )
171 std::size_t serialSizeField =
172 serializeIcDest<T,PARTICLETYPE>( globiCdest, bufferiCandParticle );
173 std::uint8_t* bufferRawParticle = &bufferiCandParticle[serialSizeField];
178template<
typename T,
typename PARTICLETYPE>
180 std::uint8_t* bufferRaw )
184 const std::vector<unsigned int> index{0};
187 communicatable.deserialize(index, bufferRaw);
190 return communicatable.size(index);
194template<
typename T,
typename PARTICLETYPE>
197 std::uint8_t* bufferiCandParticle )
200 std::size_t serialSizeField =
201 deserializeIcDest<T,PARTICLETYPE>(globiCdest,bufferiCandParticle);
202 std::uint8_t* bufferRawParticle = &bufferiCandParticle[serialSizeField];
212template<
typename T,
typename PARTICLETYPE>
215 constexpr unsigned D = PARTICLETYPE::d;
218 const T physDeltaX = cuboidGeometry.getMotherCuboid().getDeltaR();
220 T maxCircumRadius{0};
225 maxCircumRadius =
util::max(maxCircumRadius,
228#ifdef PARALLEL_MODE_MPI
233 int minCuboidExtent{std::numeric_limits<int>::max()};
234 for (
int iC=0; iC<cuboidGeometry.getNc(); ++iC){
235 for(
unsigned iD=0; iD<D; ++iD){
236 minCuboidExtent =
util::min(minCuboidExtent,
237 cuboidGeometry.get(iC).getExtent()[iD]);
240#ifdef PARALLEL_MODE_MPI
247 OLB_ASSERT(minCuboidExtent*physDeltaX > maxCircumRadius,
248 "At least one cuboid too small so that the currently implemented "
249 "particle parallelization strategy does not work.");
256 return min + (position - max);
262 return max - (min - position);
272 else if(position > max) {
283template<
typename T,
unsigned D>
286 const T physDeltaX = cuboidGeometry.getMotherCuboid().getDeltaR();
287 return (cuboidGeometry.getMotherCuboid().getOrigin() - 0.5 * physDeltaX);
292template<
typename T,
unsigned D>
296 const T physDeltaX = cuboidGeometry.getMotherCuboid().getDeltaR();
297 return min + physDeltaX * cuboidGeometry.getMotherCuboid().getExtent();
301template<
typename T,
unsigned D>
307 const PhysR<T,D> min = getCuboidMin<T,D>(cuboidGeometry);
308 const PhysR<T,D> max = getCuboidMax<T,D>(cuboidGeometry, min);
310 for(
unsigned iD=0; iD<D; ++iD) {
312 position[iD], max[iD], min[iD]);
319template<
typename T,
unsigned D>
326 return cuboidGeometry.getC(newPosition, iC);
SoA storage for instances of a single FIELD.
auto getField(std::size_t iCell) const
Return copy of FIELD data for cell iCell.
void setField(std::size_t iCell, const FieldD< T, DESCRIPTOR, FIELD > &v)
Set FIELD data at cell iCell.
CuboidGeometry< T, D > & getCuboidGeometry()
Read and write access to cuboid geometry.
LoadBalancer< T > & getLoadBalancer()
Read and write access to the load balancer.
std::size_t deserialize(const std::uint8_t *buffer)
Deserialize data.
std::size_t serialize(std::uint8_t *buffer) const
Serialize data.
SuperStructure< T, PARTICLETYPE::d > & getSuperStructure()
void reduceAndBcast(T &reductVal, MPI_Op op, int root=0, MPI_Comm comm=MPI_COMM_WORLD)
Reduction operation, followed by a broadcast.
int getRank() const
Returns the process ID.
T movePositionToEnd(const T position, const T max, const T min)
std::size_t serializeIcDest(int globiCdest, std::uint8_t *bufferiCandParticle)
std::vector< int > getNeighborCuboids(CuboidGeometry< T, D > &cuboidGeometry, unsigned offset, int globiC)
Get neighbour cuboids.
std::unordered_set< int > getNeighbourRanksFromCuboidNeighbourhood(SuperStructure< T, D > &superStructure, int rank, std::map< int, std::vector< int > > neighbourhood)
Get neighbour ranks.
Vector< T, D > getCuboidMin(const CuboidGeometry< T, D > &cuboidGeometry)
Returns minimal coordinate of domain for periodic particle boundaries.
std::size_t deserializeIcDest(int &globiCdest, std::uint8_t *bufferRaw)
bool getCuboid(const CuboidGeometry< T, D > &cuboidGeometry, const Vector< bool, D > &periodicity, const PhysR< T, D > &position, int &iC)
Function returns true if cuboid was found and gives iC.
void checkCuboidSizes(SuperParticleSystem< T, PARTICLETYPE > &sParticleSystem)
void forParticlesInSuperParticleSystem(SuperParticleSystem< T, PARTICLETYPE > &sParticleSystem, F f)
std::unordered_set< int > getNeighbourRanks(SuperStructure< T, D > &superStructure, unsigned offset, int rank)
Get neighbour ranks.
Vector< T, D > getCuboidMax(const CuboidGeometry< T, D > &cuboidGeometry, const PhysR< T, D > &min)
Returns maximal coordinate of domain for periodic particle boundaries.
T movePositionToStart(const T position, const T max, const T min)
void deserializeIcDestAndParticle(int &globiCdest, Particle< T, PARTICLETYPE > &particle, std::uint8_t *bufferiCandParticle)
T applyPeriodicityToPosition(const bool isPeriodic, T position, const T max, const T min)
void serializeIcDestAndParticle(int globiCdest, Particle< T, PARTICLETYPE > &particle, std::uint8_t *bufferiCandParticle)
T evalCircumRadius(T const contactDetectionDistance, T const circumRadius, T const epsilon)
constexpr bool isPeriodic(const Vector< bool, D > &periodic)
cpu::simd::Pack< T > min(cpu::simd::Pack< T > rhs, cpu::simd::Pack< T > lhs)
cpu::simd::Pack< T > max(cpu::simd::Pack< T > rhs, cpu::simd::Pack< T > lhs)
Top level namespace for all of OpenLB.
std::conditional_t< D==2, CuboidGeometry2D< T >, CuboidGeometry3D< T > > CuboidGeometry
void evaluateCuboidGeometryNeighbourhood(CuboidGeometry2D< T > &cuboidGeometry, std::map< int, std::vector< int > > &neighbourhood, int offset=0)
Evaluate complete neighbourhood and store in std::map.
bool checkCuboidNeighbourhoodConsistency(std::map< int, std::vector< int > > &neighbourhood, bool correct=false, bool verbose=false)
Consistency check for neighbour retrieval.
#define OLB_ASSERT(COND, MESSAGE)