Peano
Loading...
Searching...
No Matches
SieveParticles.cpph
Go to the documentation of this file.
4
5
6template <typename T>
7tarch::logging::Log toolbox::particles::SieveParticles<T>::_log("toolbox::particles::SieveParticles<T>");
8
9
10template <typename T>
12 "toolbox::particles::"
13 "SieveParticles<T>::_"
14 "SieveReductionTag"
15);
16
17
18template <typename T>
20
21
22template <typename T>
24
25
26template <typename T>
29
30
31template <typename T>
33 for (auto* p : list) {
34 delete p;
35 }
36 list.clear();
37}
38
39
40template <typename T>
42 const tarch::la::Vector<Dimensions,double> domainOffset,
44 const std::bitset<Dimensions> periodicBC
45 ) {
46 logDebug("exchangeSieveListsGlobally()", "there are " << _particlesThatHaveToBeSieved.size() << " sieve sets (each tied to one tree or the global sorting, respectively)");
47
48 deleteParticles(_particlesThatHaveToBeSieved);
49
50#ifdef Parallel
51 const int numberOfParticlesToSend = _particlesThatCanNotBeLiftedWithinTheirTree.size();
52 logDebug("exchangeSieveListsGlobally()", "inform all other ranks that I host " << numberOfParticlesToSend << " particles that cannot be sorted locally. Use tag " << _SieveReductionTag);
53 for (int rank = 0; rank < tarch::mpi::Rank::getInstance().getNumberOfRanks(); rank++) {
54 if (rank != tarch::mpi::Rank::getInstance().getRank()) {
55 tarch::mpi::IntegerMessage message(numberOfParticlesToSend);
56 tarch::mpi::IntegerMessage::sendAndPollDanglingMessages(message, rank, _SieveReductionTag, tarch::mpi::Rank::getInstance().getCommunicator());
57 }
58 }
59
60 logDebug("exchangeSieveListsGlobally()", "pack send information (vector of pointers) into array");
61 std::vector<T> sendBuffer; // no pointers here
62 sendBuffer.resize(numberOfParticlesToSend);
63 int i = 0;
64 for (auto& p : _particlesThatCanNotBeLiftedWithinTheirTree) {
65 sendBuffer[i] = *p;
66 i++;
67 }
68
69 for (int rank = 0; rank < tarch::mpi::Rank::getInstance().getNumberOfRanks(); rank++) {
70 if (rank != tarch::mpi::Rank::getInstance().getRank()) {
71 logDebug("exchangeSieveListsGlobally()", "ask rank " << rank << " how many messages have to be received");
72 tarch::mpi::IntegerMessage numberOfReceivedMessages;
73 tarch::mpi::IntegerMessage::receiveAndPollDanglingMessages(numberOfReceivedMessages, rank, _SieveReductionTag, tarch::mpi::Rank::getInstance().getCommunicator());
74 logDebug("exchangeSieveListsGlobally()", "will receive " << numberOfReceivedMessages.getValue() << " particles from rank " << rank);
75
76 MPI_Request* sendRequest = nullptr;
77 MPI_Request* receiveRequest = nullptr;
78
79 std::vector<T> receiveBuffer; // no pointers here
80 if (numberOfReceivedMessages.getValue() > 0) {
81 receiveRequest = new MPI_Request();
82 receiveBuffer.resize(numberOfReceivedMessages.getValue());
83 MPI_Irecv(
84 receiveBuffer.data(),
85 numberOfReceivedMessages.getValue(),
86 T::getGlobalCommunciationDatatype(),
87 rank,
88 _SieveReductionTag,
90 receiveRequest
91 );
92 }
93
94 if (numberOfParticlesToSend > 0) {
95 sendRequest = new MPI_Request();
96 MPI_Isend(
97 sendBuffer.data(),
98 numberOfParticlesToSend, // this is important
99 T::getGlobalCommunciationDatatype(),
100 rank,
101 _SieveReductionTag,
103 sendRequest
104 );
105 }
106
107 logDebug("exchangeSieveListsGlobally()", "issued my sends and receives");
108 int flag = 0;
111 while (not flag) {
112 int sendFlag = 1;
113 int receiveFlag = 1;
114 if (sendRequest != nullptr)
115 MPI_Test(sendRequest, &sendFlag, MPI_STATUS_IGNORE);
116 if (receiveRequest != nullptr)
117 MPI_Test(receiveRequest, &receiveFlag, MPI_STATUS_IGNORE);
118 flag = sendFlag and receiveFlag;
119
120 tarch::mpi::Rank::getInstance().writeTimeOutWarning("toolbox::particles::ParticleSet", "exchangeSieveListsGlobally()", rank, _SieveReductionTag);
121 tarch::mpi::Rank::getInstance().triggerDeadlockTimeOut("toolbox::particles::ParticleSet", "exchangeSieveListsGlobally()", rank, _SieveReductionTag);
123 }
124
125 logDebug("exchangeSieveListsGlobally()", "append " << receiveBuffer.size() << " messages to local sieve particle list");
126 for (int i = 0; i < numberOfReceivedMessages.getValue(); i++) {
127 _particlesThatHaveToBeSieved.push_back(new T(receiveBuffer[i]));
128 }
129
130 if (sendRequest != nullptr)
131 delete sendRequest;
132 if (receiveRequest != nullptr)
133 delete receiveRequest;
134 }
135 }
136#endif
137
138 _particlesThatHaveToBeSieved.insert(
139 _particlesThatHaveToBeSieved.end(), _particlesThatCanNotBeLiftedWithinTheirTree.begin(), _particlesThatCanNotBeLiftedWithinTheirTree.end()
140 );
141
142 // shallow clear, as the pointers have already been rolled over into _particlesThatHaveToBeSieved
143 _particlesThatCanNotBeLiftedWithinTheirTree.clear();
144
145 if (periodicBC.any()){
146 for (auto p: _particlesThatHaveToBeSieved){
147 p->setX( toolbox::particles::applyPeriodicBoundaryConditions( p->getX(), domainOffset, domainSize, periodicBC) );
148 }
149 }
150}
151
152
153template <typename T>
155 std::ostringstream msg;
156
157 msg << "(#particles-that-cannot-be-lifted=" << _particlesThatCanNotBeLiftedWithinTheirTree.size()
158 << ",#particles-that-have-to-be-sieved=" << _particlesThatHaveToBeSieved.size()
159 << ")";
160
161 return msg.str();
162}
163
164
165template <typename T>
167 deleteParticles(_particlesThatCanNotBeLiftedWithinTheirTree);
168 deleteParticles(_particlesThatHaveToBeSieved);
169
170 _particlesThatCanNotBeLiftedWithinTheirTree.clear();
171 _particlesThatHaveToBeSieved.clear();
172}
173
174
175template <typename T>
177 SieveParticles<T> result;
178
179 for (auto p: _particlesThatHaveToBeSieved) {
180 result._particlesThatHaveToBeSieved.push_back( new T(*p) );
181 }
182
183 logDebug( "cloneParticlesToBeSieved()", "created a clone of the particle set: " << this->toString() << "->" << result.toString() );
184
185 return result;
186}
187
188
189template <typename T>
191 logDebug( "addParticleThatCanNotBeLiftedWithinItsTree(T* p)", "particle cannot be lifted: " << p->toString() );
192 _particlesThatCanNotBeLiftedWithinTheirTree.push_back(p);
193}
194
195
196template <typename T>
198 return _particlesThatHaveToBeSieved.size();
199}
200
201
202template <typename T>
204 return not _particlesThatHaveToBeSieved.empty();
205}
206
207
208template <typename T>
211 bool removeReturnedParticlesFromSet,
212 bool onlyReturnParticlesThatWillBeLocal,
213 bool lockSemaphore
214) {
215 tarch::multicore::Lock lock(_particlesToBeSievedSemaphore, removeReturnedParticlesFromSet and lockSemaphore);
216
217 ParticleList result;
218 typename ParticleList::iterator p = _particlesThatHaveToBeSieved.begin();
219 while (p != _particlesThatHaveToBeSieved.end()) {
220 bool willBeLocal = toolbox::particles::particleAssignedToVertexWillBeLocal( (*p)->getX(), marker );
221 if (
223 and
224 (willBeLocal or not onlyReturnParticlesThatWillBeLocal)
225 ) {
226 logDebug("getParticlesToBeSievedIntoVertex(...)", "drop particle " << (*p)->toString() << " from global sieve list into vertex " << marker.toString());
227
228 (*p)->setCellH(marker.h());
229
230 result.push_back(*p);
231 if (removeReturnedParticlesFromSet) {
232 p = _particlesThatHaveToBeSieved.erase(p);
233 }
234 else {
235 p++;
236 }
237 } else {
238 p++;
239 }
240 }
241 return result;
242}
#define logDebug(methodName, logMacroMessageStream)
Definition Log.h:50
std::bitset< Dimensions > periodicBC
Definition main.cpp:19
Log Device.
Definition Log.h:516
int getNumberOfRanks() const
Definition Rank.cpp:552
void triggerDeadlockTimeOut(const std::string &className, const std::string &methodName, int communicationPartnerRank, int tag, int numberOfExpectedMessages=1, const std::string &comment="")
Triggers a time out and shuts down the cluster if a timeout is violated.
Definition Rank.cpp:124
void setDeadlockWarningTimeStamp()
Memorise global timeout.
Definition Rank.cpp:193
void writeTimeOutWarning(const std::string &className, const std::string &methodName, int communicationPartnerRank, int tag, int numberOfExpectedMessages=1)
Writes a warning if relevant.
Definition Rank.cpp:148
void setDeadlockTimeOutTimeStamp()
Definition Rank.cpp:198
static Rank & getInstance()
This operation returns the singleton instance.
Definition Rank.cpp:539
int getRank() const
Return rank of this node.
Definition Rank.cpp:529
static int reserveFreeTag(const std::string &fullQualifiedMessageName, int numberOfTags=1)
Return a Free Tag.
Definition Rank.cpp:39
MPI_Comm getCommunicator() const
Definition Rank.cpp:545
Create a lock around a boolean semaphore region.
Definition Lock.h:19
virtual void receiveDanglingMessages() override
Answer to MPI Messages.
static ServiceRepository & getInstance()
Utility class for global sorting for all flavours of particle sets.
SieveParticles< T > cloneParticlesToBeSieved()
Clone object, but let it contain only the delivering part, i.e.
ParticleList getParticlesToBeSievedIntoVertex(const peano4::datamanagement::VertexMarker &marker, bool removeReturnedParticlesFromSet, bool onlyReturnParticlesThatWillBeLocal, bool lockSemaphore)
Get particles that are to be sieved into one vertex.
void addParticleThatCanNotBeLiftedWithinItsTree(T *)
Add a particle to the list of particles which cannot be lifted.
int getNumberOfParticlesThatHaveBeSievedIntoVertices() const
hasParticlesToBeSievedIntoVertices() is equivalent to checking if this routine returns something grea...
void exchangeSieveListsGlobally(const tarch::la::Vector< Dimensions, double > domainOffset, const tarch::la::Vector< Dimensions, double > domainSize, const std::bitset< Dimensions > periodicBC)
Get all the global sieve data consistent.
bool hasParticlesToBeSievedIntoVertices() const
Fine out how many particles still to sieve.
static tarch::logging::Log _log
ParticleList _particlesThatHaveToBeSieved
Particles that should be sieved.
std::string toString(Filter filter)
Definition convert.cpp:170
bool sieveParticle(const Particle &particle, const peano4::datamanagement::VertexMarker &marker)
A particle is to be sieved into a vertex if.
bool particleAssignedToVertexWillBeLocal(const tarch::la::Vector< Dimensions, double > &x, const peano4::datamanagement::VertexMarker &marker)
Definition particles.cpp:7
tarch::la::Vector< Dimensions, double > applyPeriodicBoundaryConditions(const tarch::la::Vector< Dimensions, double > &x, const tarch::la::Vector< Dimensions, double > domainOffset, const tarch::la::Vector< Dimensions, double > domainSize, const std::bitset< Dimensions > periodicBC)
Applies the periodic boundary condition on particle coordinates x.
Definition particles.cpp:45
Vertex marker to provide information about selected vertex.
Simple vector class.
Definition Vector.h:150
static void sendAndPollDanglingMessages(const tarch::mpi::IntegerMessage &message, int destination, int tag, MPI_Comm communicator=tarch::mpi::Rank::getInstance().getCommunicator())
static void receiveAndPollDanglingMessages(tarch::mpi::IntegerMessage &message, int source, int tag, MPI_Comm communicator=tarch::mpi::Rank::getInstance().getCommunicator())