46#ifdef PARALLEL_MODE_MPI
47 , MPI_Comm surfaceForceComm
52 using namespace descriptors;
54 constexpr unsigned D = PARTICLETYPE::d;
62 using FORCING_EVAL =
typename PARTICLETYPE
63 ::template derivedField<descriptors::FORCING>;
64 using TORQUE_EVAL =
typename FORCING_EVAL
65 ::template derivedField<descriptors::TORQUE>;
74 const std::vector<unsigned int> indices{0};
75 auto serialSize = communicatableForce.size(indices)
76 + communicatableTorque.size(indices)
77 + communicatableID.size(indices);
79 std::multimap<int,std::unique_ptr<std::uint8_t[]>> rankDataMap;
87 int globiCcentre = particle.template getField<PARALLELIZATION,IC>();
88 int rankDest = loadBalancer.rank(globiCcentre);
90 auto force = particle.template getField<FORCING,FORCE>();
91 auto torque = particle.template getField<FORCING,TORQUE>();
92 auto globalID = particle.template getField<PARALLELIZATION,ID>();
93#ifdef VERBOSE_COMMUNICATION
94 std::cout <<
"EVALUATING: force=" << force <<
", torque=" << torque <<
", globalID=" << globalID << std::endl;
100 std::unique_ptr<std::uint8_t[]> buffer(
new std::uint8_t[serialSize]{ });
101 std::uint8_t* bufferRaw = buffer.get();
103 std::size_t serialIdx = communicatableForce.serialize(indices, bufferRaw);
105 serialIdx += communicatableTorque.serialize(indices, &bufferRaw[serialIdx]);
107 communicatableID.serialize(indices, &bufferRaw[serialIdx]);
109 rankDataMap.insert(std::make_pair(rankDest, std::move(buffer)));
119 std::map<int, std::vector<std::uint8_t> > rankDataMapSorted;
126 listNeighbourRanks, serialSize, surfaceForceComm, mpiNbHelper );
130 surfaceForceComm, mpiNbHelper,
131 [&](
int rankOrig, std::uint8_t* bufferRaw){
133 std::size_t serialIdx = communicatableForce.deserialize(indices, bufferRaw);
135 serialIdx += communicatableTorque.deserialize(indices, &bufferRaw[serialIdx]);
137 communicatableID.deserialize(indices, &bufferRaw[serialIdx]);
139 auto force = fieldForce.
getField(0);
140 auto torque = fieldTorque.
getField(0);
141 auto globalID = fieldID.
getField(0);
143#ifdef VERBOSE_COMMUNICATION
145 std::cout <<
"Received (on rank=" << rank
146 <<
" from rank=" << rankOrig
147 <<
"): force=" << force
150 <<
", torque=" << torque
151 <<
", globalID=" << globalID
157 for (
unsigned iDim=0; iDim<D; ++iDim) {
158 forceData[iDim] = force[iDim];
162 forceData[D] = torque;
165 for (
unsigned iDim=0; iDim<Drot; ++iDim) {
166 forceData[iDim+D] = torque[iDim];
171 auto mapPair = globalIdDataMap.insert( std::pair<std::size_t,
173 if (mapPair.second==
false){
174 globalIdDataMap[globalID] += forceData;
189 using namespace descriptors;
191 constexpr unsigned D = PARTICLETYPE::d;
198 for (
auto globalIdDataPair : globalIdDataMap ){
201 for (std::size_t iP=0; iP<particleSystem.
size(); ++iP){
202 auto particle = particleSystem.
get(iP);
206 std::size_t globalID = globalIdDataPair.first;
207 std::size_t globalIDiP = particle.template getField<PARALLELIZATION,ID>();
209 if (globalIDiP==globalID){
211 auto forceData = globalIdDataPair.second;
212 auto force = particle.template getField<FORCING,FORCE>();
213 auto torque = particle.template getField<FORCING,TORQUE>();
215 for (
unsigned iDim=0; iDim<D; ++iDim) {
216 force[iDim] += forceData[iDim];
220 torque += forceData[D];
223 for (
unsigned iDim=0; iDim<Drot; ++iDim) {
224 torque[iDim] += forceData[iDim+D];
228#ifdef VERBOSE_COMMUNICATION
230 std::cout <<
"Assigned (on rank=" << rank
231 <<
"): force=" << force
234 <<
", torque=" << torque
235 <<
", globalID=" << globalID
239 particle.template setField<FORCING,FORCE>( force );
240 particle.template setField<FORCING,TORQUE>( torque );
constexpr std::size_t size()
Size of ParticleSystem.
SuperStructure< T, PARTICLETYPE::d > & getSuperStructure()
const std::unordered_set< int > & getNeighbourRanks()
void receiveAndExecuteForData(const std::unordered_set< int > &availableRanks, std::size_t serialSize, MPI_Comm Comm, singleton::MpiNonBlockingHelper &mpiNbHelper, F f)
void forSystemsInSuperParticleSystem(SuperParticleSystem< T, PARTICLETYPE > &sParticleSystem, F f)
void communicateSurfaceForce(SuperParticleSystem< T, PARTICLETYPE > &sParticleSystem, std::map< std::size_t, Vector< T, forceDataSize > > &globalIdDataMap, MPI_Comm surfaceForceComm)
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)
void assignSurfaceForce(SuperParticleSystem< T, PARTICLETYPE > &sParticleSystem, std::map< std::size_t, Vector< T, forceDataSize > > &globalIdDataMap)
void forParticlesInSuperParticleSystem(SuperParticleSystem< T, PARTICLETYPE > &sParticleSystem, F f)
static bool value(Particle< T, PARTICLETYPE > &particle, int globiC)