Domain.h
Go to the documentation of this file.
1 //Copyright (c) 2013-2023, The MercuryDPM Developers Team. All rights reserved.
2 //For the list of developers, see <http://www.MercuryDPM.org/Team>.
3 //
4 //Redistribution and use in source and binary forms, with or without
5 //modification, are permitted provided that the following conditions are met:
6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above copyright
9 // notice, this list of conditions and the following disclaimer in the
10 // documentation and/or other materials provided with the distribution.
11 // * Neither the name MercuryDPM nor the
12 // names of its contributors may be used to endorse or promote products
13 // derived from this software without specific prior written permission.
14 //
15 //THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
16 //ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17 //WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18 //DISCLAIMED. IN NO EVENT SHALL THE MERCURYDPM DEVELOPERS TEAM BE LIABLE FOR ANY
19 //DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20 //(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21 //LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22 //ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 //(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24 //SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 
26 
32 #ifndef Domain_H
33 #define Domain_H
34 
35 #include "BaseObject.h"
36 #include "MpiContainer.h"
37 #include "Math/Vector.h"
38 #include "ParticleHandler.h"
39 #include <vector>
40 #include <set>
41 
42 class DPMBase;
43 
44 class DomainHandler;
45 
46 class BaseParticle;
47 
48 class MPIParticle;
49 
51 
53 
54 class MPIParticleForce;
55 
63 class Domain final : public BaseObject
64 {
65 public:
69  Domain();
70 
74  explicit Domain(std::vector<unsigned> globalMeshIndex);
75 
80  Domain(const Domain& d);
81 
85  ~Domain() override;
86 
90  void constructor();
91 
96  virtual Domain* copy() const;
97 
101  void read(std::istream& is) override;
102 
106  void write(std::ostream& os) const override;
107 
111  std::string getName() const override;
112 
116  void setRange(Direction direction, Mdouble min, Mdouble max);
117 
121  void setBounds(std::vector<double> domainLeft, std::vector<double> domainRight, bool computeMiddle);
122 
126  std::vector<double> getDomainMin();
127 
131  std::vector<double> getDomainMax();
132 
136  int getRank();
137 
141  void setRank(int rank);
142 
146  void setHandler(DomainHandler* handler);
147 
151  DomainHandler* getHandler() const;
152 
156  int getGlobalIndex();
157 
161  std::vector<unsigned> getGlobalMeshIndex();
162 
166  void setGlobalMeshIndex(std::vector<unsigned> globalMeshIndex);
167 
171  void disableBoundary(unsigned localIndex);
172 
176  void disableBoundaries();
177 
181  std::vector<bool> getActiveBoundaryList();
182 
186  bool containsParticle(BaseParticle* particle, Mdouble offset = 0.0);
187 
192  bool isInGreaterDomain(BaseParticle* particle);
193 
197  bool isInInnerDomain(BaseParticle* particle);
198 
202  bool isInCommunicationZone(BaseParticle* particle);
203 
207  void createLookUpTable();
208 
212  int getLocalIndex(int i, int j, int k);
213 
217  int getLocalIndex(std::vector<int> localMeshIndex);
218 
222  std::vector<int> getLocalIndexInverse(int localMeshIndex);
223 
227  BaseParticle* findParticleInList(unsigned int identification, std::vector<BaseParticle*> particleList);
228 
232  std::vector<int> findNearbyBoundaries(BaseParticle* particle, Mdouble offset = 0);
233 
237  bool inBoundary(BaseParticle* particle, int localIndex);
238 
242  void addParticlesToLists(BaseParticle* particle, std::vector<std::vector<BaseParticle*> >& list);
243 
247  void findNewMPIParticles(const ParticleHandler& particleHandler);
248 
252  void findNewMPIParticle(BaseParticle* particle);
253 
254  /*
255  * Checks whether a particle is in the list of new particles received by this thread
256  */
257  bool isInNewBoundaryParticleList(BaseParticle* object,int localIndex) const;
261  void findNewMPIInteractions();
262 
266  void collectBoundaryParticleData(int localIndex);
267 
271  void collectInteractionData(int localIndex);
272 
276  void processReceivedBoundaryParticleData(unsigned index, std::vector<BaseParticle*>& newParticles);
277 
281  void processSentBoundaryParticles(unsigned index);
282 
286  void processReceivedInteractionData(unsigned index, std::vector<BaseParticle*>& newParticles);
287 
288  /*
289  * Writes a list of all MPI particles on each thread to the logger.
290  */
291  void debugInformation();
292 
296  void
297  sendAndReceiveCount(MercuryMPITag tag, unsigned& countReceive, unsigned& countSend, unsigned localIndexNeighbour);
298 
303 
308 
313 
318 
322  void updateParticles(std::set<BaseParticle*>& ghostParticlesToBeDeleted);
323 
327  void updateParticlePosition(int localIndex);
328 
332  void updateParticleVelocity(int localIndex);
333 
339 
343  void finalisePositionAndVelocityUpdate(std::set<BaseParticle*>& ghostParticlesToBeDeleted);
344 
348  void prepareVelocityUpdate();
349 
353  void finaliseVelocityUpdate();
354 
368  template<typename T>
370  T* receiveData, unsigned receiveCount,
371  T* sendData, unsigned sendCount, unsigned localIndexNeighbour)
372  {
373  int globalIndexNeighbour = localIndexToGlobalIndexTable_[localIndexNeighbour];
374  int processor = localIndexToProcessorList_[localIndexNeighbour];
375  int tagReceive = globalIndexNeighbour * MAX_PROC + globalIndex_ * 10 + tag;
376  int tagSend = globalIndex_ * MAX_PROC + globalIndexNeighbour * 10 + tag;
377 
378  //Communicate the requests
379  if (receiveCount != 0)
380  {
381  MPIContainer::Instance().receive(receiveData, type, receiveCount, processor, tagReceive);
382  }
383  if (sendCount != 0)
384  {
385  MPIContainer::Instance().send(sendData, type, sendCount, processor, tagSend);
386  }
387  }
388 
392  void addNewParticles();
393 
397  void addParticle(BaseParticle* particle);
398 
402  void updateStatus(std::set<BaseParticle*>& ghostParticlesToBeDeleted);
403 
407  void updateVelocity();
408 
412  unsigned int getNumberOfMPIParticles();
413 
417  unsigned int getNumberOfTrueMPIParticles();
418 
422  void flushParticles(std::set<BaseParticle*>& toBeDeletedList);
423 
427  void flushParticlesFromList(std::vector<BaseParticle*>& list, std::set<BaseParticle*>& toBeDeletedList);
428 
432  Vec3D getMiddle() const ;
433 
438 
442  void cleanCommunicationList(std::vector<BaseParticle*>& list);
443 
444 private:
449 
453  std::vector<double> domainMin_;
454 
458  std::vector<double> domainMax_;
459 
464 
470 
474  std::vector<unsigned> globalMeshIndex_;
475 
481 
486  std::vector<int> localIndexToProcessorList_;
487 
491  std::vector<bool> activeBoundaryList_;
492 
497  std::vector<int> boundaryList_;
498 
502  std::vector<std::vector<BaseParticle*> > boundaryParticleList_;
503 
507  std::vector<std::vector<BaseParticle*> > boundaryParticleListNeighbour_;
508 
512  std::vector<std::vector<BaseParticle*> > newBoundaryParticleList_;
513 
517  std::vector<std::vector<BaseInteraction*> > newInteractionList_;
518 
522  std::vector<unsigned> numberOfParticlesSend_;
523 
527  std::vector<unsigned> numberOfParticlesReceive_;
528 
532  std::vector<unsigned> numNewInteractionsSend_;
533 
537  std::vector<unsigned> numNewInteractionsReceive_;
538 
542  std::vector<std::vector<MPIParticle> > boundaryParticleDataSend_;
543 
547  std::vector<std::vector<MPIParticle> > boundaryParticleDataReceive_;
548 
552  std::vector<std::vector<MPIParticlePosition> > updatePositionDataSend_;
553 
557  std::vector<std::vector<MPIParticlePosition> > updatePositionDataReceive_;
558 
562  std::vector<std::vector<MPIParticleVelocity> > updateVelocityDataSend_;
563 
567  std::vector<std::vector<MPIParticleVelocity> > updateVelocityDataReceive_;
568 
572  std::vector<void*> interactionDataSend_;
573 
577  std::vector<void*> interactionDataReceive_;
578 
582  int rank_;
583 };
584 
585 #endif
Direction
An enum that indicates the direction in Cartesian coordinates.
Definition: GeneralDefine.h:77
#define MAX_PROC
Definition: GeneralDefine.h:51
MercuryMPITag
An enum that facilitates the creation of unique communication tags in the parallel code.
Definition: MpiContainer.h:77
MercuryMPIType
An enum that indicates what type of data is being send over MPI.
Definition: MpiContainer.h:66
It is an abstract base class due to the purely virtual functions declared below. Even if the function...
Definition: BaseObject.h:51
Definition: BaseParticle.h:54
The DPMBase header includes quite a few header files, defining all the handlers, which are essential....
Definition: DPMBase.h:77
Container to store all Domain.
Definition: DomainHandler.h:47
The simulation can be subdivided into Domain's used in parallel code.
Definition: Domain.h:64
void updateStatus(std::set< BaseParticle * > &ghostParticlesToBeDeleted)
Updates particles that are not in the current domain and communicates newly added particles.
Definition: Domain.cc:1633
void debugInformation()
Definition: Domain.cc:1096
void processReceivedBoundaryParticleData(unsigned index, std::vector< BaseParticle * > &newParticles)
Function that copies the mpi data format of a base particle to a real particle and adds it to the par...
Definition: Domain.cc:941
void performBoundaryDataTransmission()
Collects data to be transmitted and then performs the transmission of the data.
Definition: Domain.cc:1221
std::vector< unsigned > numberOfParticlesReceive_
Counter that keeps track of the number of particles that are being received by this domain.
Definition: Domain.h:527
void createLookUpTable()
Create a look up table between local index system to global index system.
Definition: Domain.cc:451
void disableBoundaries()
disables all domain boundaries that have no neighbour
Definition: Domain.cc:597
void write(std::ostream &os) const override
This function does nothing.
Definition: Domain.cc:197
std::vector< int > getLocalIndexInverse(int localMeshIndex)
Definition: Domain.cc:515
void disableBoundary(unsigned localIndex)
Disables a boundary of the domain with a neighbouring domain.
Definition: Domain.cc:378
unsigned int getNumberOfMPIParticles()
Obtains the number of particles in the particleHandler that are MPIParticles.
Definition: Domain.cc:1664
std::vector< void * > interactionDataReceive_
Container that keeps a void array of all the interaction data that is being received by this domain,...
Definition: Domain.h:577
void prepareVelocityUpdate()
Function that sends particle velocity data for ghost particles.
Definition: Domain.cc:1529
std::vector< unsigned > getGlobalMeshIndex()
Gets the global mesh index of the domain.
Definition: Domain.cc:355
void updateParticles(std::set< BaseParticle * > &ghostParticlesToBeDeleted)
This step updates all communication lists and particles in the communication zone.
Definition: Domain.cc:1308
BaseParticle * findParticleInList(unsigned int identification, std::vector< BaseParticle * > particleList)
Searches for a particle with a specific id in a list of particles.
Definition: Domain.cc:529
std::vector< double > getDomainMax()
Gets the maximum domain bounds.
Definition: Domain.cc:319
std::vector< unsigned > numNewInteractionsSend_
Counter that keeps track of the number of interactions that are being send to other domains.
Definition: Domain.h:532
std::vector< bool > activeBoundaryList_
A list of flags corresponding to an inactive or active boundary.
Definition: Domain.h:491
void finaliseVelocityUpdate()
Processes particle velocity data for ghost particles.
Definition: Domain.cc:1557
std::vector< double > getDomainMin()
Gets the minimum domain bounds.
Definition: Domain.cc:310
~Domain() override
Destructor, destroys the domain.
Definition: Domain.cc:121
void processReceivedInteractionData(unsigned index, std::vector< BaseParticle * > &newParticles)
Processes the received interactions from newly added mpi particles
Definition: Domain.cc:999
DomainHandler * domainHandler_
Pointer to the domain's DomainHandler container.
Definition: Domain.h:448
void sendAndReceiveMPIData(MercuryMPITag tag, MercuryMPIType type, T *receiveData, unsigned receiveCount, T *sendData, unsigned sendCount, unsigned localIndexNeighbour)
Function that sends transmissionData/positionData/velocityData to other processors.
Definition: Domain.h:369
Vec3D getMiddle() const
Gives the middle of the domain.
Definition: Domain.cc:1733
int globalIndex_
Global index of the domain in the mesh.
Definition: Domain.h:469
std::vector< std::vector< MPIParticle > > boundaryParticleDataSend_
Container that keeps a list of MPIParticles that are being send to other domains.
Definition: Domain.h:542
std::vector< std::vector< BaseInteraction * > > newInteractionList_
Array that queues interactions that need to be transmitted.
Definition: Domain.h:517
int getGlobalIndex()
Gets the global index of the domain.
Definition: Domain.cc:346
void setBounds(std::vector< double > domainLeft, std::vector< double > domainRight, bool computeMiddle)
Sets the domain bounds.
Definition: Domain.cc:268
std::vector< std::vector< MPIParticle > > boundaryParticleDataReceive_
Container that keeps a list of MPIParticles that are being received by this domain.
Definition: Domain.h:547
std::vector< std::vector< BaseParticle * > > boundaryParticleListNeighbour_
a list of ghost particles on the current domain, which are real on the neighbour domain
Definition: Domain.h:507
std::vector< int > findNearbyBoundaries(BaseParticle *particle, Mdouble offset=0)
This function finds if a given particle is close to a given boundary.
Definition: Domain.cc:554
std::vector< std::vector< BaseParticle * > > boundaryParticleList_
A list of boundary particles in the communication zone that are ghost particles on other domains.
Definition: Domain.h:502
void collectBoundaryParticleData(int localIndex)
collects the data of a particle that has to be communicated to other processors
Definition: Domain.cc:909
void finalisePositionAndVelocityUpdate(std::set< BaseParticle * > &ghostParticlesToBeDeleted)
processes position and velocity data for ghost particles
Definition: Domain.cc:1501
std::vector< unsigned > globalMeshIndex_
Vector containing the global mesh indices i,j,k.
Definition: Domain.h:474
void setRange(Direction direction, Mdouble min, Mdouble max)
Sets the domain range in a given direction.
Definition: Domain.cc:219
bool isInInnerDomain(BaseParticle *particle)
Check if the particle is in the current domain but not in the communication zone.
Definition: Domain.cc:430
void addNewParticles()
Initialises the MPIParticles by communicating newly found particles.
Definition: Domain.cc:1588
Domain()
Default Domain constructor.
Definition: Domain.cc:48
void cleanCommunicationLists()
Removes nullptrs from boundaryParticleList_ and boundaryParticleListNeighbour_.
Definition: Domain.cc:1742
int rank_
Rank of the domain which identifies to which processor it belongs.
Definition: Domain.h:582
std::vector< unsigned > numberOfParticlesSend_
Counter that keeps track of the number of particles that are being send to other domains.
Definition: Domain.h:522
std::vector< double > domainMin_
Minimum domain bounds in the x,y and z direction.
Definition: Domain.h:453
void addParticlesToLists(BaseParticle *particle, std::vector< std::vector< BaseParticle * > > &list)
Function that adds the particles to the approriate boundary list.
Definition: Domain.cc:701
void read(std::istream &is) override
This function does nothing.
Definition: Domain.cc:186
void collectInteractionData(int localIndex)
Collects the data of an interaction that has to be communicated to other processors.
Definition: Domain.cc:924
void setGlobalMeshIndex(std::vector< unsigned > globalMeshIndex)
Sets the global mesh index of theh domain.
Definition: Domain.cc:365
void setHandler(DomainHandler *handler)
Sets the domainHandler.
Definition: Domain.cc:337
void processSentBoundaryParticles(unsigned index)
Bookkeep the newly send particles.
Definition: Domain.cc:977
std::vector< int > localIndexToProcessorList_
look-up table to get the processor of the domain given a local domain index
Definition: Domain.h:486
void cleanCommunicationList(std::vector< BaseParticle * > &list)
Removes nullptr's from a given particle list.
Definition: Domain.cc:1757
void preparePositionAndVelocityUpdate()
Function that sends particle position and velocity data for ghost particles to other processors.
Definition: Domain.cc:1460
void prepareBoundaryDataTransmission()
Prepares the MPI transmission of particle and interaction data from particles in particleHandler.
Definition: Domain.cc:1146
std::vector< std::vector< MPIParticlePosition > > updatePositionDataReceive_
Container that keeps a list of MPIParticlePositions that are being received by this domain.
Definition: Domain.h:557
std::vector< double > domainMax_
Maximum domain bounds in the x,y and z direction.
Definition: Domain.h:458
std::vector< std::vector< MPIParticleVelocity > > updateVelocityDataSend_
Container that keeps a list of MPIParticleVelocities that are being send to other domains.
Definition: Domain.h:562
bool containsParticle(BaseParticle *particle, Mdouble offset=0.0)
Check to see if a given particle is within the current domain.
Definition: Domain.cc:400
void constructor()
contructor of a domain
Definition: Domain.cc:133
bool inBoundary(BaseParticle *particle, int localIndex)
Definition: Domain.cc:578
std::vector< int > localIndexToGlobalIndexTable_
look-up table to get the global index given a local domain index
Definition: Domain.h:480
Vec3D middle_
Middle of the closed domain.
Definition: Domain.h:463
int getRank()
Gets the rank associated with the assigned processorID.
Definition: Domain.cc:328
void setRank(int rank)
Sets the rank associated with the assigned processorID.
Definition: Domain.cc:301
void updateParticlePosition(int localIndex)
Updates the position of particles which are flagged as MPIParticles.
Definition: Domain.cc:1412
void sendAndReceiveCount(MercuryMPITag tag, unsigned &countReceive, unsigned &countSend, unsigned localIndexNeighbour)
A symmetric communication between two domains exchanging a send/recieve count.
Definition: Domain.cc:1119
void findNewMPIInteractions()
Finds interactions that have to be send over to another domain.
Definition: Domain.cc:824
bool isInNewBoundaryParticleList(BaseParticle *object, int localIndex) const
Definition: Domain.cc:809
void findNewMPIParticle(BaseParticle *particle)
Function that check if a given particle should be added to the communication lists.
Definition: Domain.cc:800
void flushParticles(std::set< BaseParticle * > &toBeDeletedList)
Particles that are going to be deleted from the simulation are flushed out of the communication bound...
Definition: Domain.cc:1698
std::vector< unsigned > numNewInteractionsReceive_
Counter that keeps track of the number of interactions that are being received by this domain.
Definition: Domain.h:537
std::vector< void * > interactionDataSend_
Container that keeps a void array of all the interaction data that are being send to other domains,...
Definition: Domain.h:572
int getLocalIndex(int i, int j, int k)
return the local index of a domain given local mesh indices i,j and k
Definition: Domain.cc:498
void updateParticleVelocity(int localIndex)
Updates the velocity of particles which are flagged as MPIParticles.
Definition: Domain.cc:1441
bool isInGreaterDomain(BaseParticle *particle)
Check to see if a given particle is in the current domain or in neighbouring communication zones.
Definition: Domain.cc:420
std::string getName() const override
Returns the name of the object.
Definition: Domain.cc:207
void findNewMPIParticles(const ParticleHandler &particleHandler)
Function that finds new particles in the particle handler that should be added to the communication l...
Definition: Domain.cc:786
std::vector< bool > getActiveBoundaryList()
Returns a list of boundaries that are active in mpi communication.
Definition: Domain.cc:387
void updateVelocity()
Updates MPI particle velocity at the half-time step.
Definition: Domain.cc:1648
unsigned int getNumberOfTrueMPIParticles()
Obtains the number of particles in the particleHandler that are MPIParticles, but NOT periodic partic...
Definition: Domain.cc:1679
std::vector< std::vector< MPIParticleVelocity > > updateVelocityDataReceive_
Container that keeps a list of MPIParticleVelocities that are being received by this domain.
Definition: Domain.h:567
std::vector< std::vector< BaseParticle * > > newBoundaryParticleList_
Array that queues particles that need to be transmitted.
Definition: Domain.h:512
DomainHandler * getHandler() const
Gets the domainHandler.
Definition: Domain.cc:1578
void flushParticlesFromList(std::vector< BaseParticle * > &list, std::set< BaseParticle * > &toBeDeletedList)
Particles that are going to be deleted from the simulation are flushed out of a give communcation bou...
Definition: Domain.cc:1708
virtual Domain * copy() const
Function that creates a copy of this current domain, using the copy constructor.
Definition: Domain.cc:175
void finaliseBoundaryDataTransmission()
This function processes the transmitted data.
Definition: Domain.cc:1262
std::vector< std::vector< MPIParticlePosition > > updatePositionDataSend_
Container that keeps a list of MPIParticlePositions that are being send to other domains.
Definition: Domain.h:552
std::vector< int > boundaryList_
A list of indices of all the active boundaries.
Definition: Domain.h:497
void addParticle(BaseParticle *particle)
Initialises a single particle which is added during the simulation.
Definition: Domain.cc:1610
bool isInCommunicationZone(BaseParticle *particle)
Check if the particle is in the communication zone of the current domain.
Definition: Domain.cc:441
std::enable_if< std::is_scalar< T >::value, void >::type receive(T &t, int from, int tag)
asynchronously receive a scalar from some other processor.
Definition: MpiContainer.h:221
static MPIContainer & Instance()
fetch the instance to be used for communication
Definition: MpiContainer.h:134
std::enable_if< std::is_scalar< T >::value, void >::type send(T &t, int to, int tag)
Asynchronously send a scalar to some other processor.
Definition: MpiContainer.h:171
Data class to send a particle force over MPI.
Definition: MpiDataClass.h:114
Data class to send a particle position over MPI.
Definition: MpiDataClass.h:90
Data class to send a particle velocity over MPI.
Definition: MpiDataClass.h:103
Data class to send a particle over MPI.
Definition: MpiDataClass.h:81
Container to store all BaseParticle.
Definition: ParticleHandler.h:48
Definition: Vector.h:51
const std::complex< Mdouble > i
Definition: ExtendedMath.h:51