28#ifndef COMMUNICATION_EQUATIONS_OF_MOTION_RESULTS_H
29#define COMMUNICATION_EQUATIONS_OF_MOTION_RESULTS_H
31#include <unordered_set>
39namespace communication {
42template <
typename T,
typename PARTICLECONTACTTYPE,
typename WALLCONTACTTYPE>
43std::unordered_set<int>
45 WALLCONTACTTYPE>& contactContainer,
46 const std::size_t globalParticleID)
48 std::unordered_set<int> destRanks;
50 for (
const PARTICLECONTACTTYPE& contact : contactContainer.particleContacts) {
53 (globalParticleID == contact.getIDs()[0] ||
54 globalParticleID == contact.getIDs()[1])) {
55 destRanks.insert(contact.getResponsibleRank());
58 for (
const WALLCONTACTTYPE& contact : contactContainer.wallContacts) {
61 globalParticleID == contact.getParticleID()) {
62 destRanks.insert(contact.getResponsibleRank());
70template <
typename T,
typename PARTICLETYPE>
80 using namespace descriptors;
86 const std::size_t currGlobalParticleID =
87 particle.template getField<PARALLELIZATION, ID>();
89 if (currGlobalParticleID == pID) {
90 particle.template setField<GENERAL, POSITION>(position);
91 particle.template setField<MOBILITY, VELOCITY>(velocity);
92 particle.template setField<SURFACE, ANGLE>(
94 PARTICLETYPE::d>::serialize_rotation(angle));
95 particle.template setField<MOBILITY, ANG_VELOCITY>(
97 PARTICLETYPE::d>::serialize_rotation(angVelocity));
103#ifdef PARALLEL_MODE_MPI
104template <
typename T,
typename PARTICLETYPE,
typename PARTICLECONTACTTYPE,
105 typename WALLCONTACTTYPE>
110 std::multimap<
int, std::unique_ptr<std::uint8_t[]>>& dataMap)
112 using namespace descriptors;
116 typename PARTICLETYPE ::template derivedField<descriptors::GENERAL>;
117 using MOBILITY_EVAL =
118 typename PARTICLETYPE ::template derivedField<descriptors::MOBILITY>;
120 typename PARTICLETYPE ::template derivedField<descriptors::SURFACE>;
121 using POSITION_EVAL =
122 typename GENERAL_EVAL ::template derivedField<descriptors::POSITION>;
123 using VELOCITY_EVAL =
124 typename MOBILITY_EVAL ::template derivedField<descriptors::VELOCITY>;
126 typename SURFACE_EVAL ::template derivedField<descriptors::ANGLE>;
127 using ANGVELOCITY_EVAL =
128 typename MOBILITY_EVAL ::template derivedField<descriptors::ANG_VELOCITY>;
146 const std::vector<unsigned int> indices {0};
147 const std::size_t serialSize =
148 communicatableID.size(indices) + communicatablePosition.size(indices) +
149 communicatableVelocity.size(indices) + communicatableAngle.size(indices) +
150 communicatableAngVelocity.size(indices);
157 using PCONDITION = std::conditional_t<
158 access::providesSurface<PARTICLETYPE>(),
160 valid_particle_centres,
163 if (PCONDITION::value(particle, globiC)) {
166 particle.template getField<PARALLELIZATION, ID>());
174 particle.template getField<PARALLELIZATION, ID>(),
179 std::unordered_set<int> destRanks {
182 for (
const int destRank : destRanks) {
183 std::unique_ptr<std::uint8_t[]> buffer(
184 new std::uint8_t[serialSize] {});
185 std::uint8_t* bufferRaw = buffer.get();
186 std::size_t serialIdx =
187 communicatableID.serialize(indices, bufferRaw);
188 serialIdx += communicatablePosition.serialize(
189 indices, &bufferRaw[serialIdx]);
190 serialIdx += communicatableVelocity.serialize(
191 indices, &bufferRaw[serialIdx]);
193 communicatableAngle.serialize(indices, &bufferRaw[serialIdx]);
194 serialIdx += communicatableAngVelocity.serialize(
195 indices, &bufferRaw[serialIdx]);
196 dataMap.insert(std::make_pair(destRank, std::move(buffer)));
199#ifdef VERBOSE_CONTACT_COMMUNICATION
201 <<
" sends particle data of ID " << fieldID.
getField(0)
203 for (
const int destRank : destRanks) {
204 std::cout << destRank <<
" ";
206 std::cout << std::endl;
215#ifdef PARALLEL_MODE_MPI
216template <
typename T,
typename PARTICLETYPE>
219 MPI_Comm equationsOfMotionComm,
222 using namespace descriptors;
229 typename PARTICLETYPE ::template derivedField<descriptors::GENERAL>;
230 using MOBILITY_EVAL =
231 typename PARTICLETYPE ::template derivedField<descriptors::MOBILITY>;
233 typename PARTICLETYPE ::template derivedField<descriptors::SURFACE>;
234 using POSITION_EVAL =
235 typename GENERAL_EVAL ::template derivedField<descriptors::POSITION>;
236 using VELOCITY_EVAL =
237 typename MOBILITY_EVAL ::template derivedField<descriptors::VELOCITY>;
239 typename SURFACE_EVAL ::template derivedField<descriptors::ANGLE>;
240 using ANGVELOCITY_EVAL =
241 typename MOBILITY_EVAL ::template derivedField<descriptors::ANG_VELOCITY>;
259 const std::vector<unsigned int> indices {0};
260 const std::size_t serialSize =
261 communicatableID.size(indices) + communicatablePosition.size(indices) +
262 communicatableVelocity.size(indices) + communicatableAngle.size(indices) +
263 communicatableAngVelocity.size(indices);
268 listNeighbourRanks, serialSize, equationsOfMotionComm, mpiNbHelper,
269 [&](
int rankOrig, std::uint8_t* buffer) {
270 std::size_t serialIdx = communicatableID.deserialize(indices, buffer);
272 communicatablePosition.deserialize(indices, &buffer[serialIdx]);
274 communicatableVelocity.deserialize(indices, &buffer[serialIdx]);
276 communicatableAngle.deserialize(indices, &buffer[serialIdx]);
278 communicatableAngVelocity.deserialize(indices, &buffer[serialIdx]);
284 const std::size_t currentGlobalParticleID =
285 particle.template getField<PARALLELIZATION, ID>();
286 if (fieldID.
getField(0) == currentGlobalParticleID) {
288 particle.template setField<GENERAL, POSITION>(
290 particle.template setField<MOBILITY, VELOCITY>(
292 particle.template setField<SURFACE, ANGLE>(
294 particle.template setField<MOBILITY, ANG_VELOCITY>(
302template <
typename T,
typename PARTICLETYPE,
typename PARTICLECONTACTTYPE,
303 typename WALLCONTACTTYPE>
308#ifdef PARALLEL_MODE_MPI
310 MPI_Comm equationsOfMotionComm
316#ifdef PARALLEL_MODE_MPI
318 std::multimap<int, std::unique_ptr<std::uint8_t[]>> dataMap;
320 std::size_t serialSize =
326 std::map<int, std::vector<std::uint8_t>> rankDataMapSorted;
332 equationsOfMotionComm, mpiNbHelper);
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.
const std::unordered_set< int > & getNeighbourRanks()
int getRank() const
Returns the process ID.
Helper class for non blocking MPI communication.
Vector< T, PARTICLETYPE::d > getVelocity(Particle< T, PARTICLETYPE > particle)
Vector< T, utilities::dimensions::convert< PARTICLETYPE::d >::rotation > getAngle(Particle< T, PARTICLETYPE > particle)
Vector< T, PARTICLETYPE::d > getPosition(Particle< T, PARTICLETYPE > particle)
Vector< T, utilities::dimensions::convert< PARTICLETYPE::d >::rotation > getAngularVelocity(Particle< T, PARTICLETYPE > particle)
void receiveAndExecuteForData(const std::unordered_set< int > &availableRanks, std::size_t serialSize, MPI_Comm Comm, singleton::MpiNonBlockingHelper &mpiNbHelper, F f)
std::size_t evalEquationsOfMotionResults(SuperParticleSystem< T, PARTICLETYPE > &sParticleSystem, contact::ContactContainer< T, PARTICLECONTACTTYPE, WALLCONTACTTYPE > &contactContainer, std::multimap< int, std::unique_ptr< std::uint8_t[]> > &dataMap)
void communicateEquationsOfMotionResultsIntra(SuperParticleSystem< T, PARTICLETYPE > &sParticleSystem, const std::size_t &pID, const Vector< T, PARTICLETYPE::d > &position, const Vector< T, PARTICLETYPE::d > &velocity, const Vector< T, utilities::dimensions::convert< PARTICLETYPE::d >::rotation > &angle, const Vector< T, utilities::dimensions::convert< PARTICLETYPE::d >::rotation > &angVelocity)
void communicateEquationsOfMotionResults(SuperParticleSystem< T, PARTICLETYPE > &sParticleSystem, contact::ContactContainer< T, PARTICLECONTACTTYPE, WALLCONTACTTYPE > &contactContainer, MPI_Comm equationsOfMotionComm)
void sendMappedData(std::map< int, std::vector< std::uint8_t > > &rankDataMapSorted, const std::unordered_set< int > &availableRanks, const std::size_t serialSize, MPI_Comm Comm, singleton::MpiNonBlockingHelper &mpiNbHelper)
void fillSendBuffer(std::multimap< int, std::unique_ptr< std::uint8_t[]> > &rankDataMap, std::map< int, std::vector< std::uint8_t > > &rankDataMapSorted, std::size_t serialSize)
std::unordered_set< int > evalDestRanks(contact::ContactContainer< T, PARTICLECONTACTTYPE, WALLCONTACTTYPE > &contactContainer, const std::size_t globalParticleID)
evaluates ranks that need the new particle data
void receiveEquationsOfMotionResults(SuperParticleSystem< T, PARTICLETYPE > &sParticleSystem, MPI_Comm equationsOfMotionComm, singleton::MpiNonBlockingHelper &mpiNbHelper)
void forParticlesInSuperParticleSystem(SuperParticleSystem< T, PARTICLETYPE > &sParticleSystem, F f)
Top level namespace for all of OpenLB.
Converts dimensions by deriving from given cartesian dimension D.