PeriodicBoundaryHandler Class Referencefinal

Container to store pointers to all BasePeriodicBoundary objects. More...

#include <PeriodicBoundaryHandler.h>

+ Inheritance diagram for PeriodicBoundaryHandler:

Public Member Functions

 PeriodicBoundaryHandler ()
 Default constructor, it creates an empty PeriodicBoundaryHandler. More...
 
 PeriodicBoundaryHandler (const PeriodicBoundaryHandler &BH)
 Constructor that copies all BasePeriodicBoundary it contains and sets the other variables to 0/nullptr. More...
 
PeriodicBoundaryHandler operator= (const PeriodicBoundaryHandler &rhs)
 Assignment operator, copies only the vector of BasePeriodicBoundary and sets the other variables to 0/nullptr. More...
 
 ~PeriodicBoundaryHandler () override
 Destructor, it destructs the PeriodicBoundaryHandler and all BasePeriodicBoundary it contains. More...
 
void addObject (BasePeriodicBoundary *P) override
 Adds a BasePeriodicBoundary to the PeriodicBoundaryHandler. More...
 
void readAndAddObject (std::istream &is) override
 Pure virtual function needs implementation, but it does nothing for the periodicBoudnaryHandler. More...
 
std::string getName () const override
 Returns the name of the handler, namely the string "PeriodicBoundaryHandler". More...
 
void setInteractionDistance (Mdouble interactionDistance)
 Sets the interaction distance. More...
 
Mdouble getInteractionDistance ()
 Returns the interaction distance. More...
 
void updateStatus (std::set< BaseParticle * > &ghostParticlesToBeDeleted)
 Updates the positions/velocity of ghost particles and accordingly the status of these particles. More...
 
void shiftParticle (BaseParticle *particle)
 Shifts the position of the particle based on its current periodic complexity. More...
 
void shiftParticle (BaseParticle *particle, const std::vector< int > &complexity)
 Shifts the position of the particle based on a given periodic complexity. More...
 
std::vector< int > computePeriodicComplexity (Vec3D position)
 Computes the periodic complexity based on a given position. More...
 
void computePeriodicComplexity (std::vector< int > &periodicComplexity, int &totalPeriodicComplexity, Vec3D position)
 Computes the periodic complexity and total periodic complexity based on a given position. More...
 
void addNewParticles ()
 Adds new particles to the periodic particle lists. More...
 
void addNewParticle (BaseParticle *particle)
 Adds a new particle to the periodic list. More...
 
unsigned int getNumberOfPeriodicGhostParticles ()
 Returns the number of particles that are flagged is periodicGhostParticle. More...
 
Mdouble getNumberOfTruePeriodicGhostParticles ()
 Returns the number of particles that are flagged as periodicGhostParticles, but not as MPIParticles. More...
 
void getMPIFlags (BaseParticle *particle, bool &isInMPIDomain, bool &isMPIParticle)
 Determines if a given particle is in the MPI domain and if it is an MPI Particle. More...
 
void setMPIFlags (BaseParticle *particle)
 Sets the MPIParticle and isMPIParticle flags of a given particle. More...
 
void generateGhosts (std::vector< std::vector< int > > &list, std::vector< int > periodicComplexity, std::vector< int > &complexity, int level)
 generates a list of periodic complexities corresponding to a give real particle. More...
 
void collectGhostParticleData ()
 Collects ghost particle data that needs to be be sent to other processors. More...
 
void collectInteractionData ()
 Collects interaction data into an MPI data structure. More...
 
void processReceivedGhostParticleData (int targetIndex, std::vector< BaseParticle * > &newParticles)
 Processes the received ghost data, creates a ghost particle and does some book keeping. More...
 
void processReceivedInteractionData (int targetIndex, std::vector< BaseParticle * > &newParticles)
 Process the received interaction data. More...
 
void processLocalInteractionData (std::vector< BaseParticle * > &newParticles)
 Process the interaction data for local ghosts. More...
 
void processPeriodicParticles ()
 Creates a periodioc particle ID for book keeping and moves the ID to the correct list. More...
 
void processLocalGhostParticles (std::vector< BaseParticle * > &newParticles)
 Creates ghost particles of periodic particles that are located on the same processor. More...
 
void updateParticles ()
 Updates position/velocity and periodic complexity of ghost particles. More...
 
bool checkIsReal (std::vector< int > complexity)
 checks if a periodic complexity is real More...
 
bool checkChanged (std::vector< int > previousComplexity, std::vector< int > complexity)
 checks of two periodic complexities differ More...
 
void updateParticleStatus (std::set< BaseParticle * > &particlesToBeDeleted)
 Updates the status of periodic particles and ghost particles. More...
 
int findTargetProcessor (const std::vector< int > &complexity)
 For a given complexity this function returns the target processor. More...
 
void findNewParticle (BaseParticle *particle)
 Checks if a particle is in the periodic domain, but are not flagged as being in the periodic domain. More...
 
bool checkIfAddNewParticle (BaseParticle *particle)
 
void findNewParticles ()
 Loops over all particles in the simulation to check if they need to be added to the periodic lists. More...
 
void findNewInteractions ()
 Finds interactions that accompany future ghost particles. More...
 
void communicateTargetDomains ()
 Creats a list of send and receive targets for periodic/ghost particles. More...
 
void communicateNumberOfNewParticlesAndInteractions ()
 Communicate the number of new particles and interactions to target processors. More...
 
void prepareNewParticleTransmission ()
 Initial preparation work for sending ghost particles. More...
 
void performNewParticleTransmission ()
 Collects and sends the ghost particle data. More...
 
void finaliseNewParticleTransmission ()
 creates the ghost particles and performs some bookkeeping to keep track of them More...
 
void preparePositionAndVelocityUpdate ()
 Collects the position and velocity data from periodic boundaries. More...
 
void finalisePositionAndVelocityUpdate ()
 Communicates position and velocity data from periodic boundaries and updates ghost particles. More...
 
void flushParticles (std::set< BaseParticle * > &particlesToBeFlushed)
 Removes particles from the periodiocParticleList_ and periociGhostList_. More...
 
void cleanCommunicationList (std::vector< MpiPeriodicParticleIDBase * > &list)
 Removes the nullptr's from a communication list. More...
 
void cleanCommunicationLists ()
 
void clearCommunicationLists ()
 Removes all ghost particles and bookkeeping for a fresh start. More...
 
void initialise ()
 Initialises the communication list vectors as they can not be determined on compile time. More...
 
void flushPeriodicParticles (std::set< BaseParticle * > &particlesToBeDeleted)
 Flushes periodioc particles that need to be deleted from the periodic lists. More...
 
void performActionsBeforeAddingParticles ()
 Actions that boundaries perform before adding new periodic/ghost particles. More...
 
void updateMaserParticle (BaseParticle *particle)
 Updates the maser flag of particles leaving the maser. More...
 
void findBoundariesToIgnore (BaseParticle *particle, std::vector< int > &periodicComplexity, int &totalPeriodicComplexity)
 Disables boundaries that need to be ignored (i.e. a non-maser particle needs to ignore the maser boundary) More...
 
- Public Member Functions inherited from BaseHandler< BasePeriodicBoundary >
 BaseHandler ()
 Default BaseHandler constructor, it creates an empty BaseHandler and assigns DPMBase_ to a null pointer. More...
 
 BaseHandler (const BaseHandler< BasePeriodicBoundary > &BH)
 Constructor that copies the objects of the given handler into itself and sets other variables to 0/nullptr. More...
 
virtual ~BaseHandler ()
 Destructor, it destructs the BaseHandler and all Object it contains. More...
 
void copyContentsFromOtherHandler (const BaseHandler< BasePeriodicBoundary > &BH)
 Function that copies the contents (vector of pointers, maxObject_, nextId_, DPMBase_) from one handler (container) to the other. More...
 
std::enable_if<!std::is_pointer< U >::value, U * >::type copyAndAddObject (const U &object)
 Creates a copy of a Object and adds it to the BaseHandler. More...
 
std::enable_if< std::is_pointer< U >::value, U >::type copyAndAddObject (const U object)
 Creates a copy of a Object and adds it to the BaseHandler. More...
 
std::enable_if<!std::is_pointer< U >::value, U * >::type copyAndAddGhostObject (const U &object)
 Creates a copy of a Object and adds it to the BaseHandler. This is one locally for inserting mpi particles, they avoid the global check if the particle can actually be inserted, because the mpi domain already knows that is the case. More...
 
std::enable_if< std::is_pointer< U >::value, U >::type copyAndAddGhostObject (const U object)
 Creates a copy of a Object and adds it to the BaseHandler. This is one locally for inserting mpi particles, they avoid the global check if the particle can actually be inserted, because the mpi domain already knows that is the case. More...
 
virtual void addExistingObject (BasePeriodicBoundary *O)
 Adds an existing object to the BaseHandler without changing the id of the object. More...
 
virtual void addObject (BasePeriodicBoundary *object)
 Adds a new Object to the BaseHandler. More...
 
virtual void addGhostObject (BasePeriodicBoundary *O)
 Adds a new Object to the BaseHandler. called by the to avoid increasing the id. More...
 
void removeIf (const std::function< bool(BasePeriodicBoundary *)> cond)
 
virtual void removeObject (unsigned const int index)
 Removes an Object from the BaseHandler. More...
 
void removeLastObject ()
 Removes the last Object from the BaseHandler. More...
 
virtual void clear ()
 Empties the whole BaseHandler by removing all Objects and setting all other variables to 0. More...
 
void read (std::istream &is)
 Reads all objects from restart data. More...
 
BasePeriodicBoundarygetObjectById (const unsigned int id)
 Gets a pointer to the Object at the specified index in the BaseHandler. More...
 
std::vector< BasePeriodicBoundary * > getObjectsById (const unsigned int id)
 Gets a vector of pointers to the objects with the specific id. More...
 
BasePeriodicBoundarygetObject (const unsigned int id)
 Gets a pointer to the Object at the specified index in the BaseHandler.
More...
 
const BasePeriodicBoundarygetObject (const unsigned int id) const
 Gets a constant pointer to the Object at the specified index in the BaseHandler. More...
 
BasePeriodicBoundarygetLastObject ()
 Gets a pointer to the last Object in this BaseHandler. More...
 
const BasePeriodicBoundarygetLastObject () const
 Gets a constant pointer to the last Object in this BaseHandler. More...
 
virtual unsigned int getNumberOfObjects () const
 Gets the number of real Object in this BaseHandler. (i.e. no mpi or periodic particles) More...
 
unsigned int getSize () const
 Gets the size of the particleHandler (including mpi and periodic particles) More...
 
unsigned int getStorageCapacity () const
 Gets the storage capacity of this BaseHandler. More...
 
void setStorageCapacity (const unsigned int N)
 Sets the storage capacity of this BaseHandler. More...
 
void resize (const unsigned int N, const BasePeriodicBoundary &obj)
 Resizes the container to contain N elements. More...
 
const std::vector< BasePeriodicBoundary * >::const_iterator begin () const
 Gets the begin of the const_iterator over all Object in this BaseHandler. More...
 
const std::vector< BasePeriodicBoundary * >::iterator begin ()
 Gets the begin of the iterator over all BaseBoundary in this BaseHandler. More...
 
const std::vector< BasePeriodicBoundary * >::const_iterator end () const
 Gets the end of the const_iterator over all BaseBoundary in this BaseHandler. More...
 
const std::vector< BasePeriodicBoundary * >::iterator end ()
 Gets the end of the iterator over all BaseBoundary in this BaseHandler. More...
 
void setDPMBase (DPMBase *DPMBase)
 Sets the problem that is solved using this handler. More...
 
void setId (BasePeriodicBoundary *object, unsigned int id)
 
void increaseId ()
 
unsigned int getNextId ()
 
void setNextId (unsigned int id)
 
DPMBasegetDPMBase ()
 Gets the problem that is solved using this handler. More...
 
DPMBasegetDPMBase () const
 Gets the problem that is solved using this handler and does not change the class. More...
 
virtual void writeVTK () const
 now empty function for writing VTK files. More...
 
unsigned getNextGroupId ()
 Should be called each time you assign a groupId. Returns the value of nextGroupId_ and increases nextGroupId_ by one. More...
 

Private Attributes

Mdouble interactionDistance_
 The interaction distance between a position and the boundary for which particles start to participate with a boundary or not. More...
 
std::vector< int > receiveTargetList_
 A list that keeps track which target processors the current processor is receiving new particles from. More...
 
std::vector< int > sendTargetList_
 A list that keeps track to which targets this processor is sending new particles to. More...
 
std::vector< int > numberOfNewPeriodicGhostParticlesReceive_
 A vector that stores how many new ghost particles will be received from other processors. More...
 
std::vector< int > numberOfNewPeriodicGhostParticlesSend_
 A vector that stores how many particles are going to be send to other processors. More...
 
std::vector< int > numberOfNewInteractionsSend_
 Stores the number of new interactions to be send to target processor corresponding to sendTargetList_. More...
 
std::vector< int > numberOfNewInteractionsReceive_
 Stores the number of new interactions to be received from target processor corresponding to receiveTargetList_. More...
 
std::vector< std::vector< MPIParticle > > periodicGhostParticleReceive_
 Data container for particles that are being received from other processors. More...
 
std::vector< std::vector< MPIParticle > > periodicGhostParticleSend_
 Data container for particles that are being send to other processors. More...
 
std::vector< std::vector< int > > periodicGhostComplexityReceive_
 Data container for periodic complexity that is being received from other processors. More...
 
std::vector< std::vector< int > > periodicGhostComplexitySend_
 Data container for periodic complexity that is being send to other processors. More...
 
std::vector< std::vector< MPIParticlePosition > > updatePositionDataReceive_
 Data container for position data that is being received from other processors. More...
 
std::vector< std::vector< MPIParticlePosition > > updatePositionDataSend_
 Data container for position data that is being send to other processors. More...
 
std::vector< std::vector< MPIParticleVelocity > > updateVelocityDataReceive_
 Data container for velocity data that is being received from other processors. More...
 
std::vector< std::vector< MPIParticleVelocity > > updateVelocityDataSend_
 Data container for velocity data that is being send to other processors. More...
 
std::vector< void * > interactionDataSend_
 Stores the interaction data that is going to be send. More...
 
std::vector< void * > interactionDataReceive_
 Stores the interaction data that is going to be received. More...
 
std::vector< PeriodicListnewPeriodicParticleList_
 
std::vector< std::vector< BaseInteraction * > > newInteractionList_
 
std::vector< PeriodicListperiodicParticleList_
 A vector the size of the number of processors, each entry containing a vector of periodic particle ID's to keep track of periodic particles and their corresponding ghosts. More...
 
std::vector< PeriodicGhostListperiodicGhostList_
 A vector the size of the number of processors, each entry containing a vector of ghost periodioc particle ID's to keep track of periodic ghost particles and their corresponding real particles. More...
 

Additional Inherited Members

- Protected Attributes inherited from BaseHandler< BasePeriodicBoundary >
std::vector< BasePeriodicBoundary * > objects_
 The actual list of Object pointers. More...
 

Detailed Description

Container to store pointers to all BasePeriodicBoundary objects.

The PeriodicBoundaryHandler is a container to store all BasePeriodicBoundary. It is implemented by a vector of pointers to BasePeriodicBoundary.

Constructor & Destructor Documentation

◆ PeriodicBoundaryHandler() [1/2]

PeriodicBoundaryHandler::PeriodicBoundaryHandler ( )

Default constructor, it creates an empty PeriodicBoundaryHandler.

Constructor of the PeriodicBoundaryHandler class. It creates and empty PeriodicBoundaryHandler.

43 {
45  logger(DEBUG, "PeriodicBoundaryHandler::PeriodicBoundaryHandler() finished");
46 }
Logger< MERCURYDPM_LOGLEVEL > logger("MercuryKernel")
Definition of different loggers with certain modules. A user can define its own custom logger here.
@ DEBUG
Mdouble interactionDistance_
The interaction distance between a position and the boundary for which particles start to participate...
Definition: PeriodicBoundaryHandler.h:314

References DEBUG, interactionDistance_, and logger.

◆ PeriodicBoundaryHandler() [2/2]

PeriodicBoundaryHandler::PeriodicBoundaryHandler ( const PeriodicBoundaryHandler PBH)

Constructor that copies all BasePeriodicBoundary it contains and sets the other variables to 0/nullptr.

Parameters
[in]BHThe PeriodicBoundaryHandler that has to be copied.

This is not a copy constructor! It just copies all BasePeriodicBoundary from the other handler into this handler, and clears all other variables.

54 {
55  objects_.clear();
56  setDPMBase(nullptr);
58  logger(DEBUG, "PeriodicBoundaryHandler::PeriodicBoundaryHandler(const PeriodicBoundaryHandler &BH) finished");
59 }
void setDPMBase(DPMBase *DPMBase)
Sets the problem that is solved using this handler.
Definition: BaseHandler.h:718
std::vector< BasePeriodicBoundary * > objects_
The actual list of Object pointers.
Definition: BaseHandler.h:302

References DEBUG, interactionDistance_, logger, BaseHandler< BasePeriodicBoundary >::objects_, and BaseHandler< BasePeriodicBoundary >::setDPMBase().

◆ ~PeriodicBoundaryHandler()

PeriodicBoundaryHandler::~PeriodicBoundaryHandler ( )
override

Destructor, it destructs the PeriodicBoundaryHandler and all BasePeriodicBoundary it contains.

Default destructor. Note that the delete for all boundaries is done in the BaseHandler.

Todo:
MX: Because the periodicBoundaryHandler contains a pointer to a boundary, which is also in the boundary handler currently we just need to empty the PeriodicBoundaryHandler without destroying the object Otherwise we create a segfault in the BoundaryHandler
79 {
83  objects_.clear();
84 
85  logger(DEBUG, "PeriodicBoundaryHandler::~PeriodicBoundaryHandler() finished");
86 }

References DEBUG, logger, and BaseHandler< BasePeriodicBoundary >::objects_.

Member Function Documentation

◆ addNewParticle()

void PeriodicBoundaryHandler::addNewParticle ( BaseParticle particle)

Adds a new particle to the periodic list.

\detail When a user or an insertion boundary is adding a single new particle to the system, this function will add it to the corresponding lists if required. If this is the case, the particle will be communicated to the receiving processor in a three step process. First the processors communicate which each other to determine who is getting how many particles from who. Secondly the actual data transfer is performed and thirdly the received data is processed into the correct bookkeeping lists.

Parameters
[in]particleThe particle that is (or not) being add to the periodic lists.
334 {
335 #ifdef MERCURYDPM_USE_MPI
336  if (NUMBER_OF_PROCESSORS == 1)
337  {
338  return;
339  }
340  if (getDPMBase()->getCurrentDomain()->containsParticle(particle))
341  {
342  //Step 1: Find if the new particle needs to be added
343  findNewParticle(particle);
344  }
345  //Follow the standard communication routine
349 #endif
350 }
#define NUMBER_OF_PROCESSORS
For the MPI communication routines this quantity is often required. defining this macro makes the cod...
Definition: GeneralDefine.h:62
DPMBase * getDPMBase()
Gets the problem that is solved using this handler.
Definition: BaseHandler.h:725
void prepareNewParticleTransmission()
Initial preparation work for sending ghost particles.
Definition: PeriodicBoundaryHandler.cc:1490
void performNewParticleTransmission()
Collects and sends the ghost particle data.
Definition: PeriodicBoundaryHandler.cc:1505
void finaliseNewParticleTransmission()
creates the ghost particles and performs some bookkeeping to keep track of them
Definition: PeriodicBoundaryHandler.cc:1586
void findNewParticle(BaseParticle *particle)
Checks if a particle is in the periodic domain, but are not flagged as being in the periodic domain.
Definition: PeriodicBoundaryHandler.cc:1271

References finaliseNewParticleTransmission(), findNewParticle(), BaseHandler< BasePeriodicBoundary >::getDPMBase(), NUMBER_OF_PROCESSORS, performNewParticleTransmission(), and prepareNewParticleTransmission().

Referenced by DPMBase::insertGhostParticle().

◆ addNewParticles()

void PeriodicBoundaryHandler::addNewParticles ( )

Adds new particles to the periodic particle lists.

\detail This function adds new particles to the periodiocBoundary lists. Particles that are not yet flagged as periodic(ghost) particles are checked if they entered the interaction distances of periodic boundaries. If this is the case these will be communicated to the other processors in a three step process. First the processors communicate which each other to determine who is getting how many particles from who. Secondly the actual data transfer is performed and thirdly the received data is processed into the correct bookkeeping lists.

301 {
302 #ifdef MERCURYDPM_USE_MPI
303  if (NUMBER_OF_PROCESSORS == 1)
304  {
305  return;
306  }
307  //Step 0: Perform actions before finding new particles. I.e. opening maser boundary
309 
310  //Step 1: Find new particles, such that the target domains can be found
312 
313  //Step 3: Communicate number of particles/interactions to other dommains
315 
316  //Step 4: Perform data transmission
318 
319  //Step 5: Finalise data transmission
321 #endif
322 }
void performActionsBeforeAddingParticles()
Actions that boundaries perform before adding new periodic/ghost particles.
Definition: PeriodicBoundaryHandler.cc:1794
void findNewParticles()
Loops over all particles in the simulation to check if they need to be added to the periodic lists.
Definition: PeriodicBoundaryHandler.cc:1328

References finaliseNewParticleTransmission(), findNewParticles(), NUMBER_OF_PROCESSORS, performActionsBeforeAddingParticles(), performNewParticleTransmission(), and prepareNewParticleTransmission().

Referenced by SubcriticalMaserBoundaryTEST::activateMaser(), addObject(), DPMBase::initialiseSolve(), DPMBase::performGhostParticleUpdate(), DPMBase::read(), and DPMBase::updateGhostGrid().

◆ addObject()

void PeriodicBoundaryHandler::addObject ( BasePeriodicBoundary P)
override

Adds a BasePeriodicBoundary to the PeriodicBoundaryHandler.

Parameters
[in]PA pointer to the BasePeriodicBoundary (or derived class) that has to be added. Add the object and tell the object that this is his handler.
91 {
92 #ifdef MERCURYDPM_USE_MPI
93  if (NUMBER_OF_PROCESSORS == 1)
94  {
95  return;
96  }
97  //Puts the particle in the Particle list
98  objects_.push_back(P);
99  //set the particleHandler pointer
100  P->setPeriodicHandler(this);
101  //Remove all ghost particles
103  //Initialise ghost particles
104  addNewParticles();
105 #endif
106 }
void addNewParticles()
Adds new particles to the periodic particle lists.
Definition: PeriodicBoundaryHandler.cc:300
void clearCommunicationLists()
Removes all ghost particles and bookkeeping for a fresh start.
Definition: PeriodicBoundaryHandler.cc:1807
double P
Uniform pressure.
Definition: TwenteMeshGluing.cpp:73

References addNewParticles(), clearCommunicationLists(), NUMBER_OF_PROCESSORS, BaseHandler< BasePeriodicBoundary >::objects_, and Global_Physical_Variables::P.

Referenced by BoundaryHandler::addObject().

◆ checkChanged()

bool PeriodicBoundaryHandler::checkChanged ( std::vector< int >  previousComplexity,
std::vector< int >  complexity 
)

checks of two periodic complexities differ

\detail A large part of the status update requires on if the periodic complexity of the real particle is changed. This function will check if the previous and current periodic complexity differ. If this is the case it returns true, if they remain the same the function returns false

Parameters
[in]previousPeriodicComplexityA periodioc complexity vector that is used as reference
[in]currentPeriodicComplexityA periodic complexity that is checked for difference against a reference periodic complexity.
Returns
True if the periodic complexity as changed with respect to the reference periodic complexity. returns false if the periodic complexity is exactly the same.
1014 {
1015  bool changed = false;
1016 
1017  for (int i = 0; i < currentComplexity.size(); i++)
1018  {
1019  if (previousComplexity[i] != currentComplexity[i])
1020  {
1021  changed = true;
1022  }
1023  }
1024 
1025  return changed;
1026 }
const std::complex< Mdouble > i
Definition: ExtendedMath.h:51

References constants::i.

Referenced by updateParticleStatus().

◆ checkIfAddNewParticle()

bool PeriodicBoundaryHandler::checkIfAddNewParticle ( BaseParticle particle)
1886 {
1887  if (particle->isPeriodicGhostParticle())
1888  {
1889  return false;
1890  }
1891  if (particle->isInPeriodicDomain())
1892  {
1893  return false;
1894  }
1895  return true;
1896 }
bool isPeriodicGhostParticle() const
Indicates if this particle is a ghost in the periodic boundary.
Definition: BaseParticle.cc:297
bool isInPeriodicDomain() const
Indicates if the particle is in the periodic boundary communication zone.
Definition: BaseParticle.cc:287

References BaseParticle::isInPeriodicDomain(), and BaseParticle::isPeriodicGhostParticle().

Referenced by findNewParticle().

◆ checkIsReal()

bool PeriodicBoundaryHandler::checkIsReal ( std::vector< int >  complexity)

checks if a periodic complexity is real

\detail An important distinction between periodic particles is if they are real or not. This check is generally required for the particle status update. A real particle only has positive periodic complexity values. So the moment a negative value is found it is clear the particle is not real.

Parameters
[in]complexityThe periodic complexity that indicates the status of the periodic particle
Returns
When the particle is real this function returns true, otherwise it will return false.
989 {
990  bool isReal = true;
991  for (int i = 0; i < getSize(); i++)
992  {
993  if (mathsFunc::sign(complexity[i]) == -1)
994  {
995  isReal = false;
996  }
997  }
998 
999  return isReal;
1000 }
unsigned int getSize() const
Gets the size of the particleHandler (including mpi and periodic particles)
Definition: BaseHandler.h:655
int sign(T val)
This is a sign function, it returns -1 for negative numbers, 1 for positive numbers and 0 for 0.
Definition: ExtendedMath.h:97

References BaseHandler< BasePeriodicBoundary >::getSize(), constants::i, and mathsFunc::sign().

Referenced by updateParticleStatus().

◆ cleanCommunicationList()

void PeriodicBoundaryHandler::cleanCommunicationList ( std::vector< MpiPeriodicParticleIDBase * > &  list)

Removes the nullptr's from a communication list.

When a particle is deleted the ID is also removed, but to ensure everything happens in the same order a nullptr is introduced instead. This function removes these nullptr's by adding the last entry of the list on such empty spot and making the list shorter.

Parameters
[in]listA list of MPiPeriodicParticleIDBase's that need to be cleaned from empty entries
1760 {
1761  for (int i = 0; i < list.size(); i++)
1762  {
1763  if (list[i] == nullptr)
1764  {
1765  list[i] = list.back();
1766  list.pop_back();
1767  i--;
1768  }
1769  }
1770 }

References constants::i.

Referenced by cleanCommunicationLists().

◆ cleanCommunicationLists()

void PeriodicBoundaryHandler::cleanCommunicationLists ( )
1773 {
1774  for (int i = 0; i < NUMBER_OF_PROCESSORS; i++)
1775  {
1778  }
1779 }
std::vector< PeriodicList > periodicParticleList_
A vector the size of the number of processors, each entry containing a vector of periodic particle ID...
Definition: PeriodicBoundaryHandler.h:417
void cleanCommunicationList(std::vector< MpiPeriodicParticleIDBase * > &list)
Removes the nullptr's from a communication list.
Definition: PeriodicBoundaryHandler.cc:1759
std::vector< PeriodicGhostList > periodicGhostList_
A vector the size of the number of processors, each entry containing a vector of ghost periodioc part...
Definition: PeriodicBoundaryHandler.h:424

References cleanCommunicationList(), constants::i, NUMBER_OF_PROCESSORS, periodicGhostList_, and periodicParticleList_.

Referenced by DPMBase::checkInteractionWithBoundaries(), and DPMBase::deleteGhostParticles().

◆ clearCommunicationLists()

void PeriodicBoundaryHandler::clearCommunicationLists ( )

Removes all ghost particles and bookkeeping for a fresh start.

This function deletes all periodic/ghost ID's and all corresponding ghosts. starting with a fresh clean periodicBoundaryHandler. Useful when another boundary is added - after - particles already have been added

1808 {
1809  if (NUMBER_OF_PROCESSORS > 1)
1810  {
1811  //Clear ID lists
1812  for (auto& i : periodicParticleList_)
1813  {
1814  //logger(INFO,"Size: %",periodicParticleList_[i].size());
1815  for (int j = 0; j < i.size(); j++)
1816  {
1817  delete i[j];
1818  }
1819  i.clear();
1820  }
1821 
1822  for (auto& i : periodicGhostList_)
1823  {
1824  for (int j = 0; j < i.size(); j++)
1825  {
1826  delete i[j];
1827  }
1828  i.clear();
1829  }
1830 
1831  //Collect all ghost particles and unflag
1833  std::set<BaseParticle*> toBeDeleted; //Set because I am too lazy to implement a vector based flushParticle function
1834  for (BaseParticle* particle : pH)
1835  {
1836  if (particle->isPeriodicGhostParticle())
1837  {
1838  toBeDeleted.insert(particle);
1839  }
1840 
1841  //Unflag its periodicity
1842  particle->setInPeriodicDomain(false);
1843  }
1844 
1845  //Flush from mpi boundary and clean the lists
1846  getDPMBase()->getCurrentDomain()->flushParticles(toBeDeleted);
1848 
1849  //Delete particles
1850  for (BaseParticle* particle : toBeDeleted)
1851  {
1852  pH.removeGhostObject(particle->getIndex());
1853  }
1854  }
1855 }
Definition: BaseParticle.h:54
Domain * getCurrentDomain()
Function that returns a pointer to the domain corresponding to the processor.
Definition: DPMBase.cc:5289
ParticleHandler particleHandler
An object of the class ParticleHandler, contains the pointers to all the particles created.
Definition: DPMBase.h:1437
void cleanCommunicationLists()
Removes nullptrs from boundaryParticleList_ and boundaryParticleListNeighbour_.
Definition: Domain.cc:1742
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
Container to store all BaseParticle.
Definition: ParticleHandler.h:48

References Domain::cleanCommunicationLists(), Domain::flushParticles(), DPMBase::getCurrentDomain(), BaseHandler< BasePeriodicBoundary >::getDPMBase(), constants::i, NUMBER_OF_PROCESSORS, DPMBase::particleHandler, periodicGhostList_, periodicParticleList_, and ParticleHandler::removeGhostObject().

Referenced by SubcriticalMaserBoundaryTEST::activateMaser(), and addObject().

◆ collectGhostParticleData()

void PeriodicBoundaryHandler::collectGhostParticleData ( )

Collects ghost particle data that needs to be be sent to other processors.

Sending ghosts to other processors is done in an non-blocking communication way and hence the data needs to be stored somewhere. This function collects and stores the data in a convenient format.

498 {
499  //For all new target lists
500  unsigned long numberOfTargets = sendTargetList_.size();
501  periodicGhostParticleSend_.resize(numberOfTargets);
502  periodicGhostComplexitySend_.resize(numberOfTargets);
503  for (int i = 0; i < numberOfTargets; i++)
504  {
506  {
507  //For all new ghost particles copy particle data and periodic complexity
508  for (int j = 0; j < numberOfNewPeriodicGhostParticlesSend_[i]; j++)
509  {
511  BaseParticle* particle = ppid->particle;
513  for (int k = 0; k < getSize(); k++)
514  {
516  }
517  }
518  }
519  }
520 }
#define PROCESSOR_ID
Definition: GeneralDefine.h:63
MPIParticle copyDataFromParticleToMPIParticle(BaseParticle *p)
Copies data from a NonSphericalParticle to an MPIParticle class and returns this.
Definition: MpiDataClass.cc:124
Definition: MpiDataClass.h:148
std::vector< int > targetPeriodicComplexity
Definition: MpiDataClass.h:160
BaseParticle * particle
Definition: MpiDataClass.h:150
std::vector< int > numberOfNewPeriodicGhostParticlesSend_
A vector that stores how many particles are going to be send to other processors.
Definition: PeriodicBoundaryHandler.h:338
std::vector< PeriodicList > newPeriodicParticleList_
Definition: PeriodicBoundaryHandler.h:405
std::vector< std::vector< MPIParticle > > periodicGhostParticleSend_
Data container for particles that are being send to other processors.
Definition: PeriodicBoundaryHandler.h:358
std::vector< std::vector< int > > periodicGhostComplexitySend_
Data container for periodic complexity that is being send to other processors.
Definition: PeriodicBoundaryHandler.h:368
std::vector< int > sendTargetList_
A list that keeps track to which targets this processor is sending new particles to.
Definition: PeriodicBoundaryHandler.h:326

References copyDataFromParticleToMPIParticle(), BaseHandler< BasePeriodicBoundary >::getSize(), constants::i, newPeriodicParticleList_, numberOfNewPeriodicGhostParticlesSend_, MpiPeriodicParticleIDBase::particle, periodicGhostComplexitySend_, periodicGhostParticleSend_, PROCESSOR_ID, sendTargetList_, and MpiPeriodicParticleIDBase::targetPeriodicComplexity.

Referenced by performNewParticleTransmission().

◆ collectInteractionData()

void PeriodicBoundaryHandler::collectInteractionData ( )

Collects interaction data into an MPI data structure.

Not only particles need to be copied to other ghosts, also their interactions with their surroundings, because these interactions contain history parameters. This function collects the basic interaction data and history data into a useful MPI structure

529 {
530  //For all send target lists
532  unsigned long numberOfTargets = sendTargetList_.size();
533  interactionDataSend_.resize(numberOfTargets);
534  for (int i = 0; i < numberOfTargets; i++)
535  {
536  //Allocate enough space
538 
539  //Fill in the vector
540  unsigned int indexInteraction = 0;
541  for (BaseInteraction* interaction : newInteractionList_[i])
542  {
543  interaction->getMPIInteraction(interactionDataSend_[i], indexInteraction);
544  indexInteraction++;
545  }
546  }
547 }
Stores information about interactions between two interactable objects; often particles but could be ...
Definition: BaseInteraction.h:60
InteractionHandler interactionHandler
An object of the class InteractionHandler.
Definition: DPMBase.h:1467
Container to store Interaction objects.
Definition: InteractionHandler.h:45
void * createMPIInteractionDataArray(unsigned int numberOfInteractions) const
creates an empty MPIInteractionDataArray
Definition: InteractionHandler.cc:211
std::vector< void * > interactionDataSend_
Stores the interaction data that is going to be send.
Definition: PeriodicBoundaryHandler.h:393
std::vector< std::vector< BaseInteraction * > > newInteractionList_
Definition: PeriodicBoundaryHandler.h:410
std::vector< int > numberOfNewInteractionsSend_
Stores the number of new interactions to be send to target processor corresponding to sendTargetList_...
Definition: PeriodicBoundaryHandler.h:343

References InteractionHandler::createMPIInteractionDataArray(), BaseHandler< BasePeriodicBoundary >::getDPMBase(), constants::i, interactionDataSend_, DPMBase::interactionHandler, newInteractionList_, numberOfNewInteractionsSend_, and sendTargetList_.

Referenced by performNewParticleTransmission().

◆ communicateNumberOfNewParticlesAndInteractions()

void PeriodicBoundaryHandler::communicateNumberOfNewParticlesAndInteractions ( )

Communicate the number of new particles and interactions to target processors.

Every receiving target that will receive ghost particle data will need to know how many particles are coming their way. This function performs that communication step. The same for interactions, not every ghost particle receives the same number of interactions and hence that step is done seperately.

1449 {
1450  MPIContainer& communicator = MPIContainer::Instance();
1451  //Communicate to how many particles the target domains receive
1452  int tagSend;
1453  for (int i = 0; i < sendTargetList_.size(); i++)
1454  {
1455  if (sendTargetList_[i] != PROCESSOR_ID)
1456  {
1459 
1461  communicator.send(numberOfNewInteractionsSend_[i], sendTargetList_[i], tagSend);
1462  }
1463  }
1464 
1465  //Perform the receive routines
1468  int tagReceive;
1469  for (int i = 0; i < receiveTargetList_.size(); i++)
1470  {
1472  {
1475 
1477  communicator.receive(numberOfNewInteractionsReceive_[i], receiveTargetList_[i], tagReceive);
1478  }
1479  }
1480 }
#define MAX_PROC
Definition: GeneralDefine.h:51
@ INTERACTION_COUNT
Definition: MpiContainer.h:83
@ PARTICLE_COUNT
Definition: MpiContainer.h:78
This class contains all information and functions required for communication between processors.
Definition: MpiContainer.h:130
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
std::vector< int > numberOfNewPeriodicGhostParticlesReceive_
A vector that stores how many new ghost particles will be received from other processors.
Definition: PeriodicBoundaryHandler.h:332
std::vector< int > receiveTargetList_
A list that keeps track which target processors the current processor is receiving new particles from...
Definition: PeriodicBoundaryHandler.h:320
std::vector< int > numberOfNewInteractionsReceive_
Stores the number of new interactions to be received from target processor corresponding to receiveTa...
Definition: PeriodicBoundaryHandler.h:348

References constants::i, MPIContainer::Instance(), INTERACTION_COUNT, MAX_PROC, numberOfNewInteractionsReceive_, numberOfNewInteractionsSend_, numberOfNewPeriodicGhostParticlesReceive_, numberOfNewPeriodicGhostParticlesSend_, PARTICLE_COUNT, PROCESSOR_ID, MPIContainer::receive(), receiveTargetList_, MPIContainer::send(), and sendTargetList_.

Referenced by prepareNewParticleTransmission().

◆ communicateTargetDomains()

void PeriodicBoundaryHandler::communicateTargetDomains ( )

Creats a list of send and receive targets for periodic/ghost particles.

When communicating ghost particles from periodic boundaries in paralell, it is not clear from the start which processor is sending to which processor. First all processors check to how many domains the processor is sending. A second communication step is then performed to tell all other processors which domains the processor is sending to. After this function has completed every processor has a list of targets that the processor sends data to and a list of targets the processor receives data from.

1395 {
1396 #ifdef MERCURYDPM_USE_MPI
1397  //Step 1: Check to how many domains this domain has to send particles
1398  int numberOfTargetDomainsLocal = 0;
1399  for (int index = 0; index < NUMBER_OF_PROCESSORS; index++)
1400  {
1401  if (newPeriodicParticleList_[index].size() > 0)
1402  {
1403  numberOfTargetDomainsLocal++;
1404  sendTargetList_.push_back(index);
1406  }
1407  }
1408 
1409  //Communicate with other domains to how many domains this domain is sending
1410  std::vector<int> numberOfTargetDomains(NUMBER_OF_PROCESSORS);
1411  MPIContainer::Instance().allGather(numberOfTargetDomainsLocal,1,numberOfTargetDomains,1);
1412 
1413  //Step 2: Communicate to other domains what the target domains are
1414  std::vector<int> receiveTargetList;
1415  for (int index = 0; index < NUMBER_OF_PROCESSORS; index++)
1416  {
1417  if (numberOfTargetDomains[index] > 0)
1418  {
1419  if (index == PROCESSOR_ID)
1420  {
1421  MPIContainer::Instance().broadcast(sendTargetList_.data(), numberOfTargetDomainsLocal, index);
1422  }
1423  else
1424  {
1425  receiveTargetList.resize(numberOfTargetDomains[index], 0);
1426  MPIContainer::Instance().broadcast(receiveTargetList.data(),numberOfTargetDomains[index],index);
1427  }
1428 
1429  //If this domain is a target, flag it.
1430  for (int i = 0; i < receiveTargetList.size(); i++)
1431  {
1432  if (receiveTargetList[i] == PROCESSOR_ID)
1433  {
1434  receiveTargetList_.push_back(index);
1435  }
1436  }
1437  }
1438  }
1439 #endif
1440 }
std::enable_if< std::is_scalar< T >::value, void >::type broadcast(T &t, int fromProcessor=0)
Broadcasts a scalar from the root to all other processors.
Definition: MpiContainer.h:441

References MPIContainer::broadcast(), constants::i, MPIContainer::Instance(), newPeriodicParticleList_, NUMBER_OF_PROCESSORS, numberOfNewPeriodicGhostParticlesSend_, PROCESSOR_ID, receiveTargetList_, and sendTargetList_.

Referenced by prepareNewParticleTransmission().

◆ computePeriodicComplexity() [1/2]

void PeriodicBoundaryHandler::computePeriodicComplexity ( std::vector< int > &  periodicComplexity,
int &  totalPeriodicComplexity,
Vec3D  position 
)

Computes the periodic complexity and total periodic complexity based on a given position.

\detail This function computes the periodic complexity, a vector of intergers that indicate how this particle is related to the periodic boundaries. Every boundary has a status value following: [2] = Real particle, not in the proximity of the boundary [1] = Real particle, in the proximity of the boundary [-1] = ghost particle, in the proximity of the boundary [-2] = ghost particle, not in the proximity of the boundary In addition to the periodic complexity it also computes the totalPeriodicComplexity that indicates with how many boundaries this position is in close proximity

Parameters
[in,out]periodicComplexityThe periodic complexity indicating how a given position is related to the periodic boundaries.
[in,out]totalPeriodicComplexityThe number of boundaries the position is in close proximity with.
[in]positionThe input position for which the relation to the boundaries are determined.
213 {
214  //Compute the new position
215  periodicComplexity.resize(this->getSize());
216  totalPeriodicComplexity = 0;
217  int index = 0;
218  for (BasePeriodicBoundary* boundary : *this)
219  {
220  Mdouble distance = boundary->getDistance(position);
221  if (std::abs(distance) <= interactionDistance_)
222  {
223  if (distance > 0)
224  {
225  //real particle
226  periodicComplexity[index] = 1;
227  totalPeriodicComplexity++;
228  }
229  else if (distance < 0)
230  {
231  //ghost particle
232  periodicComplexity[index] = -1;
233  }
234  else //distance == 0 In extremely rare cases (test cases mostly)
235  {
236  //Check if on left or right side of boundary
237  if (boundary->isClosestToLeftBoundary(position))
238  {
239  //ghost particle on the left side
240  periodicComplexity[index] = -1;
241  }
242  else
243  {
244  //real particle on the right side
245  periodicComplexity[index] = 1;
246  totalPeriodicComplexity++;
247  }
248  }
249  }
250  else
251  {
252  if (distance < 0)
253  {
254  periodicComplexity[index] = -2;
255  }
256  else
257  {
258  periodicComplexity[index] = 2;
259  }
260  }
261  index++;
262  }
263 /*
264  //Modify periodic complexity in case of maser
265  for (int b = 0; b < getSize(); b++)
266  {
267  objects_[b]->modifyPeriodicComplexity(periodicComplexity, position, b);
268  }
269 */
270 }
double Mdouble
Definition: GeneralDefine.h:34
Definition: BasePeriodicBoundary.h:41
virtual Mdouble getDistance(const BaseParticle &particle) const =0
Returns the distance between a particle and the closest boundary, required for any periodic boundary.
virtual bool isClosestToLeftBoundary(const Vec3D &position) const =0
Returns true if it is closer to the left boundary than the right boundary.

References BasePeriodicBoundary::getDistance(), BaseHandler< BasePeriodicBoundary >::getSize(), interactionDistance_, and BasePeriodicBoundary::isClosestToLeftBoundary().

◆ computePeriodicComplexity() [2/2]

std::vector< int > PeriodicBoundaryHandler::computePeriodicComplexity ( Vec3D  position)

Computes the periodic complexity based on a given position.

\detail This function computes the periodic complexity, a vector of intergers that indicate how this particle is related to the periodic boundaries. Every boundary has a status value following: [2] = Real particle, not in the proximity of the boundary [1] = Real particle, in the proximity of the boundary [-1] = ghost particle, in the proximity of the boundary [-2] = ghost particle, not in the proximity of the boundary

Parameters
[in]positionThe input position for which the relation to the boundaries are determined.
Returns
Periodic complexity of the given position
283 {
284  std::vector<int> periodicComplexity;
285  int totalPeriodicComplexity;
286 
287  computePeriodicComplexity(periodicComplexity, totalPeriodicComplexity, position);
288 
289  return periodicComplexity;
290 }
std::vector< int > computePeriodicComplexity(Vec3D position)
Computes the periodic complexity based on a given position.
Definition: PeriodicBoundaryHandler.cc:282

Referenced by findNewParticle(), processReceivedGhostParticleData(), updateParticles(), and updateParticleStatus().

◆ finaliseNewParticleTransmission()

void PeriodicBoundaryHandler::finaliseNewParticleTransmission ( )

creates the ghost particles and performs some bookkeeping to keep track of them

1587 {
1588  //Process the global received data
1589  for (int i = 0; i < receiveTargetList_.size(); i++)
1590  {
1591  std::vector<BaseParticle*> newGhostParticles;
1592  processReceivedGhostParticleData(i, newGhostParticles);
1593  processReceivedInteractionData(i, newGhostParticles);
1594  }
1595 
1596  //Process the local data
1597  std::vector<BaseParticle*> newGhostParticles;
1598  processLocalGhostParticles(newGhostParticles);
1599  processLocalInteractionData(newGhostParticles);
1600 
1601  //Process the periodic particles;
1603 
1604  //Clear lists
1605  receiveTargetList_.clear();
1606  sendTargetList_.clear();
1615  interactionDataSend_.clear();
1616  interactionDataReceive_.clear();
1617  newInteractionList_.clear();
1618  for (auto& i : newPeriodicParticleList_)
1619  {
1620  i.clear();
1621  }
1622  for (auto& i : newPeriodicParticleList_)
1623  {
1624  i.clear();
1625  }
1626 }
void processLocalInteractionData(std::vector< BaseParticle * > &newParticles)
Process the interaction data for local ghosts.
Definition: PeriodicBoundaryHandler.cc:692
void processPeriodicParticles()
Creates a periodioc particle ID for book keeping and moves the ID to the correct list.
Definition: PeriodicBoundaryHandler.cc:782
std::vector< void * > interactionDataReceive_
Stores the interaction data that is going to be received.
Definition: PeriodicBoundaryHandler.h:398
void processReceivedInteractionData(int targetIndex, std::vector< BaseParticle * > &newParticles)
Process the received interaction data.
Definition: PeriodicBoundaryHandler.cc:615
std::vector< std::vector< int > > periodicGhostComplexityReceive_
Data container for periodic complexity that is being received from other processors.
Definition: PeriodicBoundaryHandler.h:363
void processReceivedGhostParticleData(int targetIndex, std::vector< BaseParticle * > &newParticles)
Processes the received ghost data, creates a ghost particle and does some book keeping.
Definition: PeriodicBoundaryHandler.cc:560
void processLocalGhostParticles(std::vector< BaseParticle * > &newParticles)
Creates ghost particles of periodic particles that are located on the same processor.
Definition: PeriodicBoundaryHandler.cc:805
std::vector< std::vector< MPIParticle > > periodicGhostParticleReceive_
Data container for particles that are being received from other processors.
Definition: PeriodicBoundaryHandler.h:353

References constants::i, interactionDataReceive_, interactionDataSend_, newInteractionList_, newPeriodicParticleList_, numberOfNewInteractionsReceive_, numberOfNewInteractionsSend_, numberOfNewPeriodicGhostParticlesReceive_, numberOfNewPeriodicGhostParticlesSend_, periodicGhostComplexityReceive_, periodicGhostComplexitySend_, periodicGhostParticleReceive_, periodicGhostParticleSend_, processLocalGhostParticles(), processLocalInteractionData(), processPeriodicParticles(), processReceivedGhostParticleData(), processReceivedInteractionData(), receiveTargetList_, and sendTargetList_.

Referenced by addNewParticle(), and addNewParticles().

◆ finalisePositionAndVelocityUpdate()

void PeriodicBoundaryHandler::finalisePositionAndVelocityUpdate ( )

Communicates position and velocity data from periodic boundaries and updates ghost particles.

1693 {
1694  //Update the positions, velocities and periodic complexities of particles
1695  updateParticles();
1696 
1697  //Delete vectors
1698  updatePositionDataSend_.clear();
1700  updateVelocityDataSend_.clear();
1702 }
std::vector< std::vector< MPIParticlePosition > > updatePositionDataReceive_
Data container for position data that is being received from other processors.
Definition: PeriodicBoundaryHandler.h:373
std::vector< std::vector< MPIParticlePosition > > updatePositionDataSend_
Data container for position data that is being send to other processors.
Definition: PeriodicBoundaryHandler.h:378
void updateParticles()
Updates position/velocity and periodic complexity of ghost particles.
Definition: PeriodicBoundaryHandler.cc:860
std::vector< std::vector< MPIParticleVelocity > > updateVelocityDataReceive_
Data container for velocity data that is being received from other processors.
Definition: PeriodicBoundaryHandler.h:383
std::vector< std::vector< MPIParticleVelocity > > updateVelocityDataSend_
Data container for velocity data that is being send to other processors.
Definition: PeriodicBoundaryHandler.h:388

References updateParticles(), updatePositionDataReceive_, updatePositionDataSend_, updateVelocityDataReceive_, and updateVelocityDataSend_.

Referenced by updateStatus().

◆ findBoundariesToIgnore()

void PeriodicBoundaryHandler::findBoundariesToIgnore ( BaseParticle particle,
std::vector< int > &  periodicComplexity,
int &  totalPeriodicComplexity 
)

Disables boundaries that need to be ignored (i.e. a non-maser particle needs to ignore the maser boundary)

◆ findNewInteractions()

void PeriodicBoundaryHandler::findNewInteractions ( )

Finds interactions that accompany future ghost particles.

Ghost particles have interactions with history parameters. These interactions also need to be copied to the other processor. This function finds these interactions and stores them.

1344 {
1345  //Check all new particle lists
1346  newInteractionList_.resize(sendTargetList_.size());
1347  for (int i = 0; i < sendTargetList_.size(); i++)
1348  {
1349  for (int p = 0; p < newPeriodicParticleList_[sendTargetList_[i]].size(); p++)
1350  {
1351  BaseParticle* particle = newPeriodicParticleList_[sendTargetList_[i]][p]->particle;
1352 
1353  //Loop over all its interactions
1354  std::vector<BaseInteraction*> interactions = particle->getInteractions();
1355  for (BaseInteraction* interaction : interactions)
1356  {
1357  //Find out what the new particle is interacting with
1358  BaseParticle* particleP = dynamic_cast<BaseParticle*>(interaction->getP());
1359  BaseParticle* objectI = dynamic_cast<BaseParticle*>(interaction->getI());
1360 
1361  //If the P in the interaction structure is the new particle, find I
1362  if (particle == particleP)
1363  {
1364  //Check if the new particle is interacting with a wall
1365  if (!objectI)
1366  {
1367  newInteractionList_[i].push_back(interaction);
1368  }
1369  else //is I a particle
1370  {
1371  newInteractionList_[i].push_back(interaction);
1372  }
1373  }
1374  else //newBoundaryParticle is I in the interaction, P can only be a particle
1375  {
1376  newInteractionList_[i].push_back(interaction);
1377  }
1378  }
1379  }
1380 
1381  //Store the number of interactions
1383  }
1384 }
const std::vector< BaseInteraction * > & getInteractions() const
Returns a list of interactions which belong to this interactable.
Definition: BaseInteractable.h:277

References BaseInteractable::getInteractions(), constants::i, newInteractionList_, newPeriodicParticleList_, numberOfNewInteractionsSend_, and sendTargetList_.

Referenced by prepareNewParticleTransmission().

◆ findNewParticle()

void PeriodicBoundaryHandler::findNewParticle ( BaseParticle particle)

Checks if a particle is in the periodic domain, but are not flagged as being in the periodic domain.

Particles that are located close to a periodic boundary, but not flagged as being in the periodic domain will be added to a list by this function. If they indeed have to be added a periodic ID will be created that stores some basic information required to setup a ghost particle.

Parameters
[in]particleA particle that is considered to be added to the periodic boundary lists
1272 {
1273  //Skip the ghost particles
1274  if (checkIfAddNewParticle(particle))
1275  {
1276  //If the particle was not yet flagged to be in the periodic domain, check if it is in the domain
1277  //if(!particle->isInPeriodicDomain())
1278  {
1279  int totalPeriodicComplexity;
1280  std::vector<int> periodicComplexity;
1281  computePeriodicComplexity(periodicComplexity, totalPeriodicComplexity, particle->getPosition());
1282 
1283  //Modify periodic complexity tailored to specific boundary requirements
1284  for (int b = 0; b < getSize(); b++)
1285  {
1286  objects_[b]->modifyPeriodicComplexity(periodicComplexity, totalPeriodicComplexity, particle, b);
1287  }
1288 
1289  //Set periodicComplexity
1290  particle->setPeriodicComplexity(periodicComplexity);
1291 
1292  //Create ghost particle ID's
1293  std::vector<std::vector<int> > list(0);
1294  if (totalPeriodicComplexity > 0)
1295  {
1296  periodicComplexity = particle->getPeriodicComplexity();
1297 
1298  //Generating all possible complexities.
1299  generateGhosts(list, periodicComplexity, periodicComplexity, getSize());
1300  //logger(VERBOSE,"New ghost particles: %",list.size() - 1);
1301 
1302  //Note: the first one in the list is the real particle such that we skip it
1303  for (int i = 1; i < list.size(); i++)
1304  {
1305  //Compute target domain
1306  //logger(VERBOSE,"Particle position: %",particle->getPosition());
1307  int targetProcessor = findTargetProcessor(list[i]);
1308 
1309  //Create periodic particle ID
1311  ppid->particle = particle;
1312  ppid->periodicComplexity = periodicComplexity;
1313  ppid->targetPeriodicComplexity = list[i];
1314  ppid->targetProcessor = targetProcessor;
1315  newPeriodicParticleList_[targetProcessor].push_back(ppid);
1316  logger(VERBOSE, "Adding a periodic particle with id % and real particle position: %",
1317  particle->getId(), particle->getPosition());
1318  }
1319  }
1320  }
1321  }
1322 }
@ VERBOSE
MpiPeriodicParticleIDBase MpiPeriodicParticleID
Definition: MpiDataClass.h:166
const Vec3D & getPosition() const
Returns the position of this BaseInteractable.
Definition: BaseInteractable.h:218
unsigned int getId() const
Returns the unique identifier of any particular object.
Definition: BaseObject.h:125
void setPeriodicComplexity(std::vector< int > complexity)
Set the periodic communication complexity of the particle.
Definition: BaseParticle.cc:206
const std::vector< int > & getPeriodicComplexity()
Obtains the periodic communication complexity of the particle.
Definition: BaseParticle.cc:231
std::vector< int > periodicComplexity
Definition: MpiDataClass.h:159
int targetProcessor
Definition: MpiDataClass.h:154
void generateGhosts(std::vector< std::vector< int > > &list, std::vector< int > periodicComplexity, std::vector< int > &complexity, int level)
generates a list of periodic complexities corresponding to a give real particle.
Definition: PeriodicBoundaryHandler.cc:465
bool checkIfAddNewParticle(BaseParticle *particle)
Definition: PeriodicBoundaryHandler.cc:1885
int findTargetProcessor(const std::vector< int > &complexity)
For a given complexity this function returns the target processor.
Definition: PeriodicBoundaryHandler.cc:1250

References checkIfAddNewParticle(), computePeriodicComplexity(), findTargetProcessor(), generateGhosts(), BaseObject::getId(), BaseParticle::getPeriodicComplexity(), BaseInteractable::getPosition(), BaseHandler< BasePeriodicBoundary >::getSize(), constants::i, logger, newPeriodicParticleList_, BaseHandler< BasePeriodicBoundary >::objects_, MpiPeriodicParticleIDBase::particle, MpiPeriodicParticleIDBase::periodicComplexity, BaseParticle::setPeriodicComplexity(), MpiPeriodicParticleIDBase::targetPeriodicComplexity, MpiPeriodicParticleIDBase::targetProcessor, and VERBOSE.

Referenced by addNewParticle(), and findNewParticles().

◆ findNewParticles()

void PeriodicBoundaryHandler::findNewParticles ( )

Loops over all particles in the simulation to check if they need to be added to the periodic lists.

Loops over all base particles in the domain to see if they have to be added to the periodic domain lists

1329 {
1330  //Check for all particles if there are unassigned periodic particles
1331  for (auto particle_it = getDPMBase()->particleHandler.begin();
1332  particle_it != getDPMBase()->particleHandler.end(); particle_it++)
1333  {
1334  findNewParticle(*particle_it);
1335  }
1336 
1337 }

References findNewParticle(), and BaseHandler< BasePeriodicBoundary >::getDPMBase().

Referenced by addNewParticles().

◆ findTargetProcessor()

int PeriodicBoundaryHandler::findTargetProcessor ( const std::vector< int > &  complexity)

For a given complexity this function returns the target processor.

A given complexity can be turned into a particle position, somewhere in the simulation domain. This position belongs to a specific processor and this function computes which processor this actually is. Note: When an PMG particle is in the periodic domain, it needs to be copied into a PG"MG" particle. A particle that is in the MG domain, but is not updated by the M boundaries. The position of this MG particle is not in the actual domain to where it has to be copied, but slightly outside. For that reason the position is shifted to the middle of the domain the official particle is found on, and that position is used to determine the actual domain the particle has to go to. Note that currently this only works for a structured grid with equal domain sizes

Parameters
[in]complexityA complexity vector which determines the location of a ghost particle
Returns
The processor ID of the ghost particle location
1251 {
1252  //Find the middle of this domain (or any valid point anyway)
1253  Vec3D middlePosition = getDPMBase()->domainHandler.getCurrentDomain()->getMiddle();
1254 
1255  //Create the particle with a target position
1256  SphericalParticle particle;
1257  particle.setPosition(middlePosition);
1258  shiftParticle(&particle, complexity);
1259 
1260  //Obtain target domain
1261  int targetGlobalIndex = getDPMBase()->domainHandler.getParticleDomainGlobalIndex(&particle);
1262  return getDPMBase()->domainHandler.getParticleProcessor(targetGlobalIndex);
1263 }
virtual void setPosition(const Vec3D &position)
Sets the position of this BaseInteractable.
Definition: BaseInteractable.h:239
DomainHandler domainHandler
An object of the class DomainHandler which deals with parallel code.
Definition: DPMBase.h:1462
int getParticleDomainGlobalIndex(BaseParticle *particle)
Definition: DomainHandler.cc:330
Domain * getCurrentDomain()
Gets the domain assigned to the processor.
Definition: DomainHandler.cc:250
int getParticleProcessor(int globalIndex)
Definition: DomainHandler.cc:409
Vec3D getMiddle() const
Gives the middle of the domain.
Definition: Domain.cc:1733
void shiftParticle(BaseParticle *particle)
Shifts the position of the particle based on its current periodic complexity.
Definition: PeriodicBoundaryHandler.cc:170
A spherical particle is the most simple particle used in MercuryDPM.
Definition: SphericalParticle.h:37
Definition: Vector.h:51

References DPMBase::domainHandler, DomainHandler::getCurrentDomain(), BaseHandler< BasePeriodicBoundary >::getDPMBase(), Domain::getMiddle(), DomainHandler::getParticleDomainGlobalIndex(), DomainHandler::getParticleProcessor(), BaseInteractable::setPosition(), and shiftParticle().

Referenced by findNewParticle().

◆ flushParticles()

void PeriodicBoundaryHandler::flushParticles ( std::set< BaseParticle * > &  particlesToBeFlushed)

Removes particles from the periodiocParticleList_ and periociGhostList_.

Todo:
This function uses a brute force method to flush the particles, this can be done in a smarter way if profiling shows that this is a bottleneck.
1706 {
1711  std::set<MpiPeriodicParticleIDBase*> toBeDeleted;
1712  for (auto p_it : particlesToBeFlushed)
1713  {
1714  for (int i = 0; i < NUMBER_OF_PROCESSORS; i++)
1715  {
1716  for (auto& p : periodicParticleList_[i])
1717  {
1718  if (p != nullptr)
1719  {
1720  if (p_it == p->particle)
1721  {
1722  toBeDeleted.insert(p);
1723  p = nullptr;
1724  }
1725  }
1726  }
1727  }
1728 
1729  for (int i = 0; i < NUMBER_OF_PROCESSORS; i++)
1730  {
1731  for (auto& p : periodicGhostList_[i])
1732  {
1733  if (p != nullptr)
1734  {
1735  if (p_it == p->particle)
1736  {
1737  toBeDeleted.insert(p);
1738  p = nullptr;
1739  }
1740  }
1741  }
1742  }
1743  }
1744 
1745  //Delete ID's
1746  for (auto id_it : toBeDeleted)
1747  {
1748  delete id_it;
1749  }
1750 
1751 }

References constants::i, NUMBER_OF_PROCESSORS, periodicGhostList_, and periodicParticleList_.

Referenced by DPMBase::checkInteractionWithBoundaries(), and DPMBase::deleteGhostParticles().

◆ flushPeriodicParticles()

void PeriodicBoundaryHandler::flushPeriodicParticles ( std::set< BaseParticle * > &  particlesToBeDeleted)

Flushes periodioc particles that need to be deleted from the periodic lists.

◆ generateGhosts()

void PeriodicBoundaryHandler::generateGhosts ( std::vector< std::vector< int > > &  list,
std::vector< int >  periodicComplexity,
std::vector< int > &  complexity,
int  level 
)

generates a list of periodic complexities corresponding to a give real particle.

Given a real particle that interacts with periodic boundaries, ghosts need to be generated. Depending on the number of boundaries this particle is interacting the number of ghosts differs. A recursive function makes sure that all possibilities of the periodic complexity of the real particle are generated. Note that the first periodic complexity in the list returned by this function is always the periodic complexity of the real particle.

Parameters
[in,out]listA list containing all possible ghost periodic complexities for a given periodic complexity
[in]periodicComplexityA periodic complexity of a real particle that is used to determine all its possible ghost periodic complexities
[in,out]complexityOne of the possible permutations of the ghost periodic complexity
[in]levelIndicator at which level the recursive function is
467 {
468  //Add the complexity to the list
469  if (level == 0)
470  {
471  //logger(VERBOSE,"complexity: [%, %, %]",complexity[0], complexity[1], complexity[2]);
472  list.push_back(complexity);
473  }
474  else
475  {
476  //Vary complexity values of level
477  if (periodicComplexity[level - 1] == 1)
478  {
479  complexity[level - 1] = 1;
480  generateGhosts(list, periodicComplexity, complexity, level - 1);
481 
482  complexity[level - 1] = -1;
483  generateGhosts(list, periodicComplexity, complexity, level - 1);
484  }
485  else
486  {
487  generateGhosts(list, periodicComplexity, complexity, level - 1);
488  }
489  }
490 }

Referenced by findNewParticle().

◆ getInteractionDistance()

Mdouble PeriodicBoundaryHandler::getInteractionDistance ( )

Returns the interaction distance.

This distance determines when a particle starts to interact with a periodic boundary.

Returns
The interaction distance.
138 {
139  return interactionDistance_;
140 }

References interactionDistance_.

◆ getMPIFlags()

void PeriodicBoundaryHandler::getMPIFlags ( BaseParticle particle,
bool isInMPIDomain,
bool isMPIParticle 
)

Determines if a given particle is in the MPI domain and if it is an MPI Particle.

Mixed particles that are both a interacting with a periodic boundary and also in an mpi boundary are special cases that need to be handled with care. As example a real particle that moves to another domain will be removed by the mpi boundaries. To avoid segmentation faults the particle needs to be flushed from the periodic boundaries as well. This function determines if a particle is in the MPI domain and if it is a MPIParticle or not.

Parameters
[in]particleThe particle for which the MPI flags are being computed
[in,out]isInMPIDomainA check to see if the particle is in the MPI domain (true) or not (false)
[in,out]isMPIParticleA bool to see if the particle is a ghost in the MPI domain (true) or not (false)
402 {
403  //Check if the particle is actually in this domain. If not the case it is an "MG"-particle
405  if (domain->containsParticle(particle))
406  {
407  //If the particle is in the inner domain, it is not in the mpi doamin
408  if (domain->isInInnerDomain(particle))
409  {
410  isInMPIDomain = false;
411  isMPIParticle = false;
412  }
413  else
414  {
415  isInMPIDomain = true;
416  isMPIParticle = false;
417  }
418  }
419  else
420  {
421  //If the particle is outside the communication zone it is not in the mpi domain
422  if (domain->isInGreaterDomain(particle))
423  {
424  isInMPIDomain = true;
425  isMPIParticle = true;
426  }
427  else
428  {
429  isInMPIDomain = false;
430  isMPIParticle = true;
431  }
432  }
433 }
The simulation can be subdivided into Domain's used in parallel code.
Definition: Domain.h:64
bool isInInnerDomain(BaseParticle *particle)
Check if the particle is in the current domain but not in the communication zone.
Definition: Domain.cc:430
bool containsParticle(BaseParticle *particle, Mdouble offset=0.0)
Check to see if a given particle is within the current domain.
Definition: Domain.cc:400
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

References Domain::containsParticle(), DPMBase::domainHandler, DomainHandler::getCurrentDomain(), BaseHandler< BasePeriodicBoundary >::getDPMBase(), Domain::isInGreaterDomain(), and Domain::isInInnerDomain().

Referenced by setMPIFlags(), and updateParticleStatus().

◆ getName()

std::string PeriodicBoundaryHandler::getName ( ) const
overridevirtual

Returns the name of the handler, namely the string "PeriodicBoundaryHandler".

This determines the unique name of the current class

Returns
The string "PeriodicBoundaryHandler"

Implements BaseHandler< BasePeriodicBoundary >.

118 {
119  return "PeriodicBoundaryHandler";
120 }

◆ getNumberOfPeriodicGhostParticles()

unsigned int PeriodicBoundaryHandler::getNumberOfPeriodicGhostParticles ( )

Returns the number of particles that are flagged is periodicGhostParticle.

Counts the number of periodic ghost particles by simply checking how many entries there are in the periodicGhostLists.

Returns
The number of particles that have isPeriodicGhostParticle() == true
358 {
359  unsigned int sum = 0;
360  for (auto& index : periodicGhostList_)
361  {
362  sum += index.size();
363  }
364  return sum;
365 }

References periodicGhostList_.

Referenced by ParticleHandler::getNumberOfRealObjectsLocal().

◆ getNumberOfTruePeriodicGhostParticles()

Mdouble PeriodicBoundaryHandler::getNumberOfTruePeriodicGhostParticles ( )

Returns the number of particles that are flagged as periodicGhostParticles, but not as MPIParticles.

Counts the number of true periodic ghost particles by checking how many entries there are in the periodiocGhostLists, but ignores mixed ghost particles that additionally have the flay isMPIParticle() == true.

Returns
The number of periodic particles that are not also MPIParticles
374 {
375  int sum = 0;
376  for (auto& index : periodicGhostList_)
377  {
378  int numberOfMPIParticles = 0;
379  for (int pIndex = 0; pIndex < index.size(); pIndex++)
380  {
381  if (index[pIndex]->particle->isMPIParticle() == true)
382  {
383  numberOfMPIParticles++;
384  }
385  }
386  sum += (index.size() - numberOfMPIParticles);
387  }
388  return sum;
389 }

References periodicGhostList_.

◆ initialise()

void PeriodicBoundaryHandler::initialise ( )

Initialises the communication list vectors as they can not be determined on compile time.

On compile time it is not clear how many processors will be used when running the simulation and therefore the basic periodioc lists can't be initialised /bi the constructor. This function initialises the vectors to avoid segmentationfaults.

1788 {
1789  newPeriodicParticleList_ = std::vector<PeriodicList>(NUMBER_OF_PROCESSORS, PeriodicList(0));
1790  periodicParticleList_ = std::vector<PeriodicList>(NUMBER_OF_PROCESSORS, PeriodicList(0));
1791  periodicGhostList_ = std::vector<PeriodicGhostList>(NUMBER_OF_PROCESSORS, PeriodicGhostList(0));
1792 }
std::vector< MpiPeriodicParticleID * > PeriodicList
Definition: PeriodicBoundaryHandler.h:36
std::vector< MpiPeriodicGhostParticleID * > PeriodicGhostList
Definition: PeriodicBoundaryHandler.h:37

References newPeriodicParticleList_, NUMBER_OF_PROCESSORS, periodicGhostList_, and periodicParticleList_.

Referenced by DPMBase::constructor(), and DPMBase::DPMBase().

◆ operator=()

PeriodicBoundaryHandler PeriodicBoundaryHandler::operator= ( const PeriodicBoundaryHandler rhs)

Assignment operator, copies only the vector of BasePeriodicBoundary and sets the other variables to 0/nullptr.

Parameters
[in]rhsThe PeriodicBoundaryHandler on the right hand side of the assignment.

This is not a copy assignment operator! It just copies all BaseBoundary from the other handler into this handler, and clears all other variables.

67 {
68  if (this != &rhs)
69  {
70  objects_.clear();
72  }
73  logger(DEBUG, "PeriodicBoundaryHandler PeriodicBoundaryHandler::operator =(const BoundaryHandler& rhs)");
74  return *this;
75 }

References DEBUG, interactionDistance_, logger, and BaseHandler< BasePeriodicBoundary >::objects_.

◆ performActionsBeforeAddingParticles()

void PeriodicBoundaryHandler::performActionsBeforeAddingParticles ( )

Actions that boundaries perform before adding new periodic/ghost particles.

1795 {
1796  for (BasePeriodicBoundary* boundary : *this)
1797  {
1799  }
1800 }
virtual void performActionsBeforeAddingParticles()
Actions that need to be performed before adding new ghost particles.
Definition: BasePeriodicBoundary.cc:138

References BasePeriodicBoundary::performActionsBeforeAddingParticles().

Referenced by addNewParticles().

◆ performNewParticleTransmission()

void PeriodicBoundaryHandler::performNewParticleTransmission ( )

Collects and sends the ghost particle data.

1506 {
1507  MPIContainer& communicator = MPIContainer::Instance();
1508  int numberOfTargetsReceive = receiveTargetList_.size();
1509  int numberOfTargetsSend = sendTargetList_.size();
1510 
1511  //Make sure that the receiving vectors have the correct length
1512  periodicGhostParticleReceive_.resize(numberOfTargetsReceive);
1513  periodicGhostComplexityReceive_.resize(numberOfTargetsReceive);
1514  interactionDataReceive_.resize(numberOfTargetsReceive);
1516  for (int i = 0; i < numberOfTargetsReceive; i++)
1517  {
1521  }
1522 
1523  //Collect data for sending
1526 
1527  //Send particle and interaction data
1528  for (int i = 0; i < numberOfTargetsSend; i++)
1529  {
1530  if (sendTargetList_[i] != PROCESSOR_ID)
1531  {
1532  //Send particle data
1533  int sendCount = numberOfNewPeriodicGhostParticlesSend_[i];
1534  int processor = sendTargetList_[i];
1536  communicator.send(periodicGhostParticleSend_[i].data(), MercuryMPIType::PARTICLE, sendCount, processor,
1537  tagSend);
1538 
1539  //Send complexity
1542  communicator.send(periodicGhostComplexitySend_[i].data(), sendCount, processor, tagSend);
1543 
1544  //Send interactions
1546  sendCount = numberOfNewInteractionsSend_[i];
1547  if (sendCount > 0)
1548  {
1549  communicator.send(interactionDataSend_[i], MercuryMPIType::INTERACTION, sendCount, processor, tagSend);
1550  }
1551  }
1552  }
1553 
1554  //Receive data
1555  for (int i = 0; i < numberOfTargetsReceive; i++)
1556  {
1558  {
1559  //Receive particle data
1560  int receiveCount = numberOfNewPeriodicGhostParticlesReceive_[i];
1561  int processor = receiveTargetList_[i];
1564  receiveCount, processor, tagReceive);
1565 
1566  //Receive complexity
1569  communicator.receive(periodicGhostComplexityReceive_[i].data(), receiveCount, processor, tagReceive);
1570 
1571  //Send interactions
1573  receiveCount = numberOfNewInteractionsReceive_[i];
1574  if (receiveCount > 0)
1575  {
1576  communicator.receive(interactionDataReceive_[i], MercuryMPIType::INTERACTION, receiveCount, processor,
1577  tagReceive);
1578  }
1579  }
1580  }
1581 
1582  //Synchronise the communications
1583  communicator.sync();
1584 }
@ INTERACTION_DATA
Definition: MpiContainer.h:84
@ PARTICLE_DATA
Definition: MpiContainer.h:79
@ PERIODIC_COMPLEXITY
Definition: MpiContainer.h:85
@ INTERACTION
Definition: MpiContainer.h:67
@ PARTICLE
Definition: MpiContainer.h:67
void sync()
Process all pending asynchronous communication requests before continuing.
Definition: MpiContainer.h:152
void collectInteractionData()
Collects interaction data into an MPI data structure.
Definition: PeriodicBoundaryHandler.cc:528
void collectGhostParticleData()
Collects ghost particle data that needs to be be sent to other processors.
Definition: PeriodicBoundaryHandler.cc:497

References collectGhostParticleData(), collectInteractionData(), InteractionHandler::createMPIInteractionDataArray(), BaseHandler< BasePeriodicBoundary >::getDPMBase(), BaseHandler< BasePeriodicBoundary >::getSize(), constants::i, MPIContainer::Instance(), INTERACTION, INTERACTION_DATA, interactionDataReceive_, interactionDataSend_, DPMBase::interactionHandler, MAX_PROC, numberOfNewInteractionsReceive_, numberOfNewInteractionsSend_, numberOfNewPeriodicGhostParticlesReceive_, numberOfNewPeriodicGhostParticlesSend_, PARTICLE, PARTICLE_DATA, PERIODIC_COMPLEXITY, periodicGhostComplexityReceive_, periodicGhostComplexitySend_, periodicGhostParticleReceive_, periodicGhostParticleSend_, PROCESSOR_ID, MPIContainer::receive(), receiveTargetList_, MPIContainer::send(), sendTargetList_, and MPIContainer::sync().

Referenced by addNewParticle(), and addNewParticles().

◆ prepareNewParticleTransmission()

void PeriodicBoundaryHandler::prepareNewParticleTransmission ( )

Initial preparation work for sending ghost particles.

The first step in adding new particles is the prepare step. First the target domains are determined such that every processors knows where particles are coming from. This step includes finding new particles. The second step is to find the interactions that have to be send with the new particles. The receiving targets need to know how many particles and interactions they receive which is the third step. Finally a communication synchronisation is performed to actually perform the communications which were pending in the MPIContainer.

1491 {
1492  //Communicate which domains send and which domains receive particles
1494 
1495  //Find new interactions
1497 
1498  //Communicate the number of particles and interactions send to the other domains
1500 
1501  //Synchronise the communications
1503 }
void communicateTargetDomains()
Creats a list of send and receive targets for periodic/ghost particles.
Definition: PeriodicBoundaryHandler.cc:1394
void communicateNumberOfNewParticlesAndInteractions()
Communicate the number of new particles and interactions to target processors.
Definition: PeriodicBoundaryHandler.cc:1448
void findNewInteractions()
Finds interactions that accompany future ghost particles.
Definition: PeriodicBoundaryHandler.cc:1343

References communicateNumberOfNewParticlesAndInteractions(), communicateTargetDomains(), findNewInteractions(), MPIContainer::Instance(), and MPIContainer::sync().

Referenced by addNewParticle(), and addNewParticles().

◆ preparePositionAndVelocityUpdate()

void PeriodicBoundaryHandler::preparePositionAndVelocityUpdate ( )

Collects the position and velocity data from periodic boundaries.

1629 {
1630  MPIContainer& communicator = MPIContainer::Instance();
1631  unsigned int numberOfProcessors = communicator.getNumberOfProcessors();
1632  unsigned int processorID = communicator.getProcessorID();
1633 
1634  //For all lists that contain periodic particles
1635  for (unsigned int i = 0; i < numberOfProcessors; i++)
1636  {
1637  unsigned int numberOfParticles = periodicParticleList_[i].size();
1638  if (numberOfParticles > 0 && i != processorID)
1639  {
1640  //Increase the vector size;
1641  updatePositionDataSend_.emplace_back(0);
1642  updateVelocityDataSend_.emplace_back(0);
1643 
1644  //Collect the data
1645  for (unsigned int p = 0; p < numberOfParticles; p++)
1646  {
1647  BaseParticle* particle = periodicParticleList_[i][p]->particle;
1648  updatePositionDataSend_.back().push_back(copyPositionFrom(particle));
1649  updateVelocityDataSend_.back().push_back(copyVelocityFrom(particle));
1650  }
1651 
1652  //Send position data
1653  unsigned int count = numberOfParticles;
1654  unsigned int processor = i;
1655  unsigned int tag = processorID * MAX_PROC + processor * 10 + MercuryMPITag::POSITION_DATA;
1656  communicator.send(updatePositionDataSend_.back().data(), MercuryMPIType::POSITION, count, processor, tag);
1657 
1658  //Send velocity data
1659  tag = processorID * MAX_PROC + processor * 10 + MercuryMPITag::VELOCITY_DATA;
1660  communicator.send(updateVelocityDataSend_.back().data(), MercuryMPIType::VELOCITY, count, processor, tag);
1661  }
1662  }
1663 
1664  //For all lists that contain ghost particles
1665  for (int i = 0; i < numberOfProcessors; i++)
1666  {
1667  unsigned int numberOfParticles = periodicGhostList_[i].size();
1668  if (numberOfParticles > 0 && i != processorID)
1669  {
1670  //Increase the vector size
1671  updatePositionDataReceive_.emplace_back(numberOfParticles);
1672  updateVelocityDataReceive_.emplace_back(numberOfParticles);
1673 
1674  //Receive position data
1675  int count = numberOfParticles;
1676  int processor = i;
1677  int tag = processor * MAX_PROC + processorID * 10 + MercuryMPITag::POSITION_DATA;
1678  communicator.receive(updatePositionDataReceive_.back().data(), MercuryMPIType::POSITION, count, processor,
1679  tag);
1680 
1681  //Receive velocity data
1682  tag = processor * MAX_PROC + processorID * 10 + MercuryMPITag::VELOCITY_DATA;
1683  communicator.receive(updateVelocityDataReceive_.back().data(), MercuryMPIType::POSITION, count, processor,
1684  tag);
1685  }
1686  }
1687 
1688  //Synchronise all the requests
1689  communicator.sync();
1690 }
@ VELOCITY_DATA
Definition: MpiContainer.h:82
@ POSITION_DATA
Definition: MpiContainer.h:80
@ VELOCITY
Definition: MpiContainer.h:67
@ POSITION
Definition: MpiContainer.h:67
MPIParticlePosition copyPositionFrom(BaseParticle *particle)
Copies the position from a particle to an MPIParticlePosition class.
Definition: MpiDataClass.cc:174
MPIParticleVelocity copyVelocityFrom(BaseParticle *particle)
Copies the velocity from a particle to an MPIParticleVelocity class.
Definition: MpiDataClass.cc:190
std::size_t getNumberOfProcessors() const
Get the total number of processors participating in this simulation.
Definition: MpiContainer.cc:104
std::size_t getProcessorID()
Reduces a scalar on all processors to one scalar on a target processor.
Definition: MpiContainer.cc:113

References copyPositionFrom(), copyVelocityFrom(), MPIContainer::getNumberOfProcessors(), MPIContainer::getProcessorID(), constants::i, MPIContainer::Instance(), MAX_PROC, periodicGhostList_, periodicParticleList_, POSITION, POSITION_DATA, MPIContainer::receive(), MPIContainer::send(), MPIContainer::sync(), updatePositionDataReceive_, updatePositionDataSend_, updateVelocityDataReceive_, updateVelocityDataSend_, VELOCITY, and VELOCITY_DATA.

Referenced by updateStatus().

◆ processLocalGhostParticles()

void PeriodicBoundaryHandler::processLocalGhostParticles ( std::vector< BaseParticle * > &  newParticles)

Creates ghost particles of periodic particles that are located on the same processor.

Ghost particles sometimes are located on the same processor as the original periodic particle. These particles are processed in this function. Firstly the ghost is created with the correct position, periodic complexity and flags and is added to the particleHandler. Secondly ID's are made for both ghost and periodic particles to keep track of their movements. Periodic particles are flaged now as being in the periodic domain.

806 {
807  for (int i = 0; i < sendTargetList_.size(); i++)
808  {
809  //Check if the processor is sending ghosts to itself
811  {
812  for (int j = 0; j < numberOfNewPeriodicGhostParticlesSend_[i]; j++)
813  {
815  BaseParticle* particle = ppid->particle;
816 
817  //Create ghost particle
818  BaseParticle* pGhost = particle->copy();
819 
820  //Obtain and set the ghost periodic complexity
822 
823  //Shift the particle
824  shiftParticle(pGhost);
825 
826  //Set the correct flags
827  pGhost->setPeriodicGhostParticle(true);
828  pGhost->setInPeriodicDomain(true);
829  //Note: mpi flags dont have to be set for local particles
830  //these flags are copied from the original particle
831  logger(VERBOSE, "Adding a ghost with id % at position %", pGhost->getId(), pGhost->getPosition());
832 
833  //Finally add it to the particle handler
835 
836  //Do some bookkeeping
838  gpid->particle = pGhost;
839  gpid->otherParticle = particle;
840  gpid->realPeriodicComplexity = particle->getPeriodicComplexity();
841  periodicGhostList_[PROCESSOR_ID].push_back(gpid);
842 
843  //Flag real particle and do some bookkeeping
844  particle->setInPeriodicDomain(true);
845  ppid->otherParticle = pGhost;
846 
847  //Add to the new particle list for an interaction update
848  newParticles.push_back(pGhost);
849  }
850  }
851  }
852 }
MpiPeriodicParticleIDBase MpiPeriodicGhostParticleID
Definition: MpiDataClass.h:167
void setInPeriodicDomain(bool flag)
Flags the status of the particle whether it is in the periodic communication zone or not.
Definition: BaseParticle.cc:292
virtual BaseParticle * copy() const =0
Particle copy method. It calls to copy constructor of this Particle, useful for polymorphism.
void setPeriodicGhostParticle(bool flag)
Flags the status of the particle to be a ghost in periodic boundary or not.
Definition: BaseParticle.cc:302
std::vector< int > realPeriodicComplexity
Definition: MpiDataClass.h:161
BaseParticle * otherParticle
Definition: MpiDataClass.h:151
void addGhostObject(int fromProcessor, int toProcessor, BaseParticle *p)
Adds a ghost particle located at fromProcessor to toProcessor.
Definition: ParticleHandler.cc:287

References ParticleHandler::addGhostObject(), BaseParticle::copy(), BaseHandler< BasePeriodicBoundary >::getDPMBase(), BaseObject::getId(), BaseParticle::getPeriodicComplexity(), BaseInteractable::getPosition(), constants::i, logger, newPeriodicParticleList_, numberOfNewPeriodicGhostParticlesSend_, MpiPeriodicParticleIDBase::otherParticle, MpiPeriodicParticleIDBase::particle, DPMBase::particleHandler, periodicGhostList_, PROCESSOR_ID, MpiPeriodicParticleIDBase::realPeriodicComplexity, sendTargetList_, BaseParticle::setInPeriodicDomain(), BaseParticle::setPeriodicComplexity(), BaseParticle::setPeriodicGhostParticle(), shiftParticle(), MpiPeriodicParticleIDBase::targetPeriodicComplexity, and VERBOSE.

Referenced by finaliseNewParticleTransmission().

◆ processLocalInteractionData()

void PeriodicBoundaryHandler::processLocalInteractionData ( std::vector< BaseParticle * > &  newParticles)

Process the interaction data for local ghosts.

Newly added ghost particles also need their interactions. This function adds the interactions to the correct ghost particles. The interaction data send over MPI only contains the ID's of the particles so a search has to be performed to obtain the particle pointers. For the ghost particles we use the newParticle list that contains all newly added ghost particles. For the other particle an hgrid search is performed. Finally when the two interactables are found the data is copied from the data vector. Note: because these ghost particles are local, the data is actually never send.

Parameters
[in]newParticlesA list containing the newly added ghost particles
693 {
695  for (int i = 0; i < sendTargetList_.size(); i++)
696  {
698  {
699  for (int l = 0; l < numberOfNewInteractionsSend_[i]; l++)
700  {
701  unsigned int identificationP;
702  unsigned int identificationI;
703  bool isWallInteraction;
704  unsigned timeStamp;
705 
706  //Get the general information required to setup a new interaction
707  iH.getInteractionDetails(interactionDataSend_[i], l, identificationP, identificationI,
708  isWallInteraction, timeStamp);
709 
710  //Obtain the particle pointer of the ghost
711  BaseParticle* pGhost;
712  int idOther;
713  //Check if the particle is P
714  for (BaseParticle* particle : newParticles)
715  {
716  if (particle->getId() == identificationP)
717  {
718  pGhost = particle;
719  idOther = identificationI;
720  break;
721  }
722 
723  if (particle->getId() == identificationI)
724  {
725  pGhost = particle;
726  idOther = identificationP;
727  break;
728  }
729  }
730 
731  //If it is a wall interaction, do stuff
732  if (isWallInteraction)
733  {
734  BaseWall* I = getDPMBase()->wallHandler.getObjectById(identificationI);
735  //Create interactions
736  BaseInteraction* j = I->getInteractionWith(pGhost, timeStamp, &iH);
737  if (j!= nullptr) j->setMPIInteraction(interactionDataSend_[i], l, false);
738  logger(VERBOSE, "Wall interaction added!");
739  }
740  else
741  {
742  //Obtain potential interaction particles
743  std::vector<BaseParticle*> interactingParticleList;
744  getDPMBase()->hGridGetInteractingParticleList(pGhost, interactingParticleList);
745 
746  if (interactingParticleList.empty())
747  {
748  logger(VERBOSE, "Failed in creating an interaction :(");
749  }
750 
751  //Find the other interacting particle
752  BaseParticle* otherParticle = nullptr;
753  for (BaseParticle* p2 : interactingParticleList)
754  {
755  if (p2->getId() == idOther)
756  {
757  otherParticle = p2;
758  break;
759  }
760  }
761  if (otherParticle == nullptr)
762  {
763  //The interacting object can't be found
764  continue;
765  }
766 
767  //Add the interaction
768  BaseInteraction* j = pGhost->getInteractionWith(otherParticle, timeStamp, &iH);
769  if (j!= nullptr) j->setMPIInteraction(interactionDataSend_[i], l, false);
770  }
771  }
772  }
773  }
774 }
T * getObjectById(const unsigned int id)
Gets a pointer to the Object at the specified index in the BaseHandler.
Definition: BaseHandler.h:565
virtual void setMPIInteraction(void *interactionDataArray, unsigned int index, bool resetPointers)
Definition: BaseInteraction.cc:907
BaseInteraction * getInteractionWith(BaseParticle *P, unsigned timeStamp, InteractionHandler *interactionHandler) override
Checks if particle is in interaction with given particle P, and if so, returns vector of pointer to t...
Definition: BaseParticle.cc:690
Basic class for walls.
Definition: BaseWall.h:49
BaseInteraction * getInteractionWith(BaseParticle *p, unsigned timeStamp, InteractionHandler *interactionHandler) override
Returns the interaction between this wall and a given particle, nullptr if there is no interaction.
Definition: BaseWall.cc:367
virtual void hGridGetInteractingParticleList(BaseParticle *obj, std::vector< BaseParticle * > &list)
Creates a list of neighbour particles obtained from the hgrid.
Definition: DPMBase.h:1000
WallHandler wallHandler
An object of the class WallHandler. Contains pointers to all the walls created.
Definition: DPMBase.h:1447
void getInteractionDetails(void *interactionData, unsigned int index, unsigned int &identificationP, unsigned int &identificationI, bool &isWallInteraction, unsigned &timeStamp)
reads the basic interaction details from an MPIInteractionDataArray
Definition: InteractionHandler.cc:245

References BaseHandler< BasePeriodicBoundary >::getDPMBase(), InteractionHandler::getInteractionDetails(), BaseParticle::getInteractionWith(), BaseWall::getInteractionWith(), BaseHandler< T >::getObjectById(), DPMBase::hGridGetInteractingParticleList(), constants::i, interactionDataSend_, DPMBase::interactionHandler, logger, numberOfNewInteractionsSend_, PROCESSOR_ID, sendTargetList_, BaseInteraction::setMPIInteraction(), VERBOSE, and DPMBase::wallHandler.

Referenced by finaliseNewParticleTransmission().

◆ processPeriodicParticles()

void PeriodicBoundaryHandler::processPeriodicParticles ( )

Creates a periodioc particle ID for book keeping and moves the ID to the correct list.

Periodic particles that have a copy somewhere else create an ID for book keeping This function also flags the particle being in the periodic domain such that it is ignored when finding new periodic particles.

783 {
784  for (int i : sendTargetList_)
785  {
786  for (int j = 0; j < newPeriodicParticleList_[i].size(); j++)
787  {
788  //Update the particle status
790  ppid->particle->setInPeriodicDomain(true);
791 
792  //make new entry in the list
793  periodicParticleList_[i].push_back(ppid);
794  }
795  }
796 }

References constants::i, newPeriodicParticleList_, MpiPeriodicParticleIDBase::particle, periodicParticleList_, sendTargetList_, and BaseParticle::setInPeriodicDomain().

Referenced by finaliseNewParticleTransmission().

◆ processReceivedGhostParticleData()

void PeriodicBoundaryHandler::processReceivedGhostParticleData ( int  targetIndex,
std::vector< BaseParticle * > &  newParticles 
)

Processes the received ghost data, creates a ghost particle and does some book keeping.

When processors have received new ghost particle data they have to be processed. First the periodic complexity of the ghost is determined. Secondly the ghost is created and given the correct flags and position and is added to the simulation. Thirdly a periodicGhost ID is created for book keeping purposes. A newParticle list is tracking the newly added ghost particles for a later step, processing the interactions.

Parameters
[in]targetIndexThe index in the receiveTargetList which indicates where the data is coming from
[in]newParticlesA list to which new ghost particles are added.
561 {
562  for (int j = 0; j < numberOfNewPeriodicGhostParticlesReceive_[targetIndex]; j++)
563  {
564  //Create the ghost particle and copy basic information
567  particle, &(getDPMBase()->particleHandler));
568 
569  //Obtain real periodic complexity
570  std::vector<int> realPeriodicComplexity = computePeriodicComplexity(particle->getPosition());
571 
572  //Obtain and set the ghost periodic complexity
573  std::vector<int> ghostPeriodicComplexity(getSize());
574  for (int k = 0; k < getSize(); k++)
575  {
576  ghostPeriodicComplexity[k] = periodicGhostComplexityReceive_[targetIndex][getSize() * j + k];
577  }
578  particle->setPeriodicComplexity(ghostPeriodicComplexity);
579 
580  //Shift the ghost particle to it's correct positions and velocities
581  shiftParticle(particle, ghostPeriodicComplexity);
582 
583  //Add particle to simulation
584  logger(VERBOSE, "Adding a ghost at position %", particle->getPosition());
586 
587  //Set the correct flags
589  pGhost->setPeriodicGhostParticle(true);
590  pGhost->setInPeriodicDomain(true);
591  //Give the correct mpi flags
592  setMPIFlags(pGhost);
593 
594  //Create the periodic ID
596  gpid->realPeriodicComplexity = realPeriodicComplexity;
597  gpid->particle = pGhost;
598  periodicGhostList_[receiveTargetList_[targetIndex]].push_back(gpid);
599 
600  //Add to the newParticle list used for possible interactions
601  newParticles.push_back(pGhost);
602  }
603 }
void copyDataFromMPIParticleToParticle(MPIParticle *bP, BaseParticle *p, ParticleHandler *particleHandler)
Copies data from an MPIParticle class to a BaseParticle and sets the particleHandler and species.
Definition: MpiDataClass.cc:105
T * getLastObject()
Gets a pointer to the last Object in this BaseHandler.
Definition: BaseHandler.h:634
static BaseParticle * newParticle()
Definition: MpiDataClass.cc:157
void setMPIFlags(BaseParticle *particle)
Sets the MPIParticle and isMPIParticle flags of a given particle.
Definition: PeriodicBoundaryHandler.cc:443

References ParticleHandler::addGhostObject(), computePeriodicComplexity(), copyDataFromMPIParticleToParticle(), BaseHandler< BasePeriodicBoundary >::getDPMBase(), BaseHandler< T >::getLastObject(), BaseInteractable::getPosition(), BaseHandler< BasePeriodicBoundary >::getSize(), logger, MPISphericalParticle::newParticle(), numberOfNewPeriodicGhostParticlesReceive_, MpiPeriodicParticleIDBase::particle, DPMBase::particleHandler, periodicGhostComplexityReceive_, periodicGhostList_, periodicGhostParticleReceive_, MpiPeriodicParticleIDBase::realPeriodicComplexity, receiveTargetList_, BaseParticle::setInPeriodicDomain(), setMPIFlags(), BaseParticle::setPeriodicComplexity(), BaseParticle::setPeriodicGhostParticle(), shiftParticle(), and VERBOSE.

Referenced by finaliseNewParticleTransmission().

◆ processReceivedInteractionData()

void PeriodicBoundaryHandler::processReceivedInteractionData ( int  targetIndex,
std::vector< BaseParticle * > &  newParticles 
)

Process the received interaction data.

Newly added ghost particles also need their interactions. This function adds the interactions to the correct ghost particles. The interaction data send over MPI only contains the ID's of the particles so a search has to be performed to obtain the particle pointers. For the ghost particles we use the newParticle list that contains all newly added ghost particles. For the other particle an hgrid search is performed. Finally when the two interactables are found the data is copied from the data vector.

Parameters
[in]targetIndexThe index in the receiveTargetList which indicates where the data is coming from
[in]newParticlesA list containing the newly added ghost particles
616 {
618  for (int l = 0; l < numberOfNewInteractionsReceive_[targetIndex]; l++)
619  {
620  unsigned int identificationP;
621  unsigned int identificationI;
622  bool isWallInteraction;
623  unsigned timeStamp;
624 
625  //Get the general information required to setup a new interaction
626  iH.getInteractionDetails(interactionDataReceive_[targetIndex], l, identificationP, identificationI,
627  isWallInteraction, timeStamp);
628 
629  //Obtain the particle pointer of the ghost
630  BaseParticle* pGhost;
631  int idOther;
632  //Check if the particle is P
633  for (BaseParticle* particle : newParticles)
634  {
635  if (particle->getId() == identificationP)
636  {
637  pGhost = particle;
638  idOther = identificationI;
639  break;
640  }
641 
642  if (particle->getId() == identificationI)
643  {
644  pGhost = particle;
645  idOther = identificationP;
646  break;
647  }
648  }
649 
650  //If it is a wall interaction, do stuff
651  if (isWallInteraction)
652  {
653  BaseInteractable* I = getDPMBase()->wallHandler.getObjectById(identificationI);
654  //Create interactions
655  BaseInteraction* i = I->getInteractionWith(pGhost, timeStamp, &iH);
656  if (i!= nullptr) i->setMPIInteraction(interactionDataReceive_[targetIndex], l, false);
657  }
658  else
659  {
660  //Obtain potential interaction particles
661  std::vector<BaseParticle*> interactingParticleList;
662  getDPMBase()->hGridGetInteractingParticleList(pGhost, interactingParticleList);
663 
664  //Find the other interacting particle
665  BaseParticle* otherParticle;
666  for (BaseParticle* p2 : interactingParticleList)
667  {
668  if (p2->getId() == idOther)
669  {
670  otherParticle = p2;
671  break;
672  }
673  }
674 
675  //Add the interaction
676  BaseInteraction* i = pGhost->getInteractionWith(otherParticle, timeStamp, &iH);
677  if (i!= nullptr) i->setMPIInteraction(interactionDataReceive_[targetIndex], l, false);
678  }
679  }
680 }
Defines the basic properties that a interactable object can have.
Definition: BaseInteractable.h:55
virtual BaseInteraction * getInteractionWith(BaseParticle *P, unsigned timeStamp, InteractionHandler *interactionHandler)=0
Returns the interaction between this object and a given BaseParticle.

References BaseHandler< BasePeriodicBoundary >::getDPMBase(), InteractionHandler::getInteractionDetails(), BaseParticle::getInteractionWith(), BaseInteractable::getInteractionWith(), BaseHandler< T >::getObjectById(), DPMBase::hGridGetInteractingParticleList(), constants::i, interactionDataReceive_, DPMBase::interactionHandler, numberOfNewInteractionsReceive_, and DPMBase::wallHandler.

Referenced by finaliseNewParticleTransmission().

◆ readAndAddObject()

void PeriodicBoundaryHandler::readAndAddObject ( std::istream &  is)
overridevirtual

Pure virtual function needs implementation, but it does nothing for the periodicBoudnaryHandler.

The periodic boundary handler does not need to read anything, it will be reconstructed.

Implements BaseHandler< BasePeriodicBoundary >.

110 {
111 }

◆ setInteractionDistance()

void PeriodicBoundaryHandler::setInteractionDistance ( Mdouble  interactionDistance)

Sets the interaction distance.

This distance determines when a particle starts to interact with a periodic boundary

Parameters
[in]interactionDistanceThe distance from a boundary when a particle starts to interact with it.
129 {
130  interactionDistance_ = interactionDistance;
131 }

References interactionDistance_.

Referenced by DPMBase::read(), and DPMBase::updateGhostGrid().

◆ setMPIFlags()

void PeriodicBoundaryHandler::setMPIFlags ( BaseParticle particle)

Sets the MPIParticle and isMPIParticle flags of a given particle.

Mixed particles that are in periodic and mpi domains, PM-particles can create ghosts of themselves PGM and PMG and additionally PGMG-particles. These last particles can't be created both by the periodic routines and the paralle routines and therefore the design choice is that these fully depend on the periodic routines. The update of their MPI flags such as isInMPIDomain and isMPIParticle is handled by this function.

Parameters
[in]particleA particle that receives the correct MPI flags
444 {
445  bool isInMPIDomain;
446  bool isMPIParticle;
447  getMPIFlags(particle, isInMPIDomain, isMPIParticle);
448  particle->setInMPIDomain(isInMPIDomain);
449  particle->setMPIParticle(isMPIParticle);
450 }
void setInMPIDomain(bool flag)
Flags the status of the particle if wether it is in the communication zone or not.
Definition: BaseParticle.cc:281
void setMPIParticle(bool flag)
Flags the mpi particle status.
Definition: BaseParticle.cc:191
void getMPIFlags(BaseParticle *particle, bool &isInMPIDomain, bool &isMPIParticle)
Determines if a given particle is in the MPI domain and if it is an MPI Particle.
Definition: PeriodicBoundaryHandler.cc:401

References getMPIFlags(), BaseParticle::setInMPIDomain(), and BaseParticle::setMPIParticle().

Referenced by processReceivedGhostParticleData(), and updateParticleStatus().

◆ shiftParticle() [1/2]

void PeriodicBoundaryHandler::shiftParticle ( BaseParticle particle)

Shifts the position of the particle based on its current periodic complexity.

\detail This function shifts the position of the particle with respect to the periodic boundaries based on the periodic complexity it currently has. Note that some boundaries such as the angular periodic boundary do not only shift the position, but also the velocity. In that sense this function name is a bit of a misnomer.

Parameters
[in]particleThe particle that shifts position (and possibly other properties)
171 {
172  shiftParticle(particle, particle->getPeriodicComplexity());
173 }

References BaseParticle::getPeriodicComplexity().

Referenced by findTargetProcessor(), processLocalGhostParticles(), processReceivedGhostParticleData(), and updateParticles().

◆ shiftParticle() [2/2]

void PeriodicBoundaryHandler::shiftParticle ( BaseParticle particle,
const std::vector< int > &  complexity 
)

Shifts the position of the particle based on a given periodic complexity.

\detail This function shifts the position of the particle with respect to the periodic boundaries based on a given periodic complexity. Note that some boundaries such as the angular periodic boundary do not only shift the position, but also the velocity. In that sense this function name is a bit of a misnomer.

Parameters
[in]particleThe particle that shifts position (and possibly other properties)
[in]complexityThe periodic complexity that determines how the particle is shifted
184 {
185  int boundaryIndex = 0;
186  for (BasePeriodicBoundary* boundary : *this)
187  {
188  if (complexity[boundaryIndex] == -1)
189  {
190  boundary->shiftPosition(particle);
191  }
192  boundaryIndex++;
193  }
194 }
virtual void shiftPosition(BaseParticle *particle) const =0
Shifts the position (and velocity) of to the ghost particle.

References BasePeriodicBoundary::shiftPosition().

◆ updateMaserParticle()

void PeriodicBoundaryHandler::updateMaserParticle ( BaseParticle particle)

Updates the maser flag of particles leaving the maser.

When a periodic particle changes complexity and remains real, there is a possibility the particle moved over a maser boundary. If that is indeed the case then flag the particle as being not a maser particle

Parameters
[in,out]particleThe particle that needs to check the isMaserParticle flag
Bug:
This only works if all insertions happen on the root if there is a maser present, as the ID is increased locally
1865 {
1866  if (particle->isMaserParticle())
1867  {
1868  for (int b = 0; b < getSize(); b++)
1869  {
1870  if (particle->getPeriodicComplexity(b) == 3)
1871  {
1872  particle->setMaserParticle(false);
1873 
1874  logger(VERBOSE, "particle % with position % goes into outflow domain, new ID = %", particle->getId(),
1875  particle->getPosition(), getDPMBase()->particleHandler.getNextId());
1876  const unsigned int newID = getDPMBase()->particleHandler.getNextId();
1877  logger(VERBOSE, "new id % position X %", newID, particle->getPosition().X);
1878  particle->setId(newID);
1880  }
1881  }
1882  }
1883 }
unsigned int getNextId()
Definition: BaseHandler.h:256
void increaseId()
Definition: BaseHandler.h:251
void setId(unsigned long id)
Assigns a unique identifier to each object in the handler (container) which remains constant even aft...
Definition: BaseObject.cc:72
bool isMaserParticle() const
Indicates if this particle belongs to the maser boundary.
Definition: BaseParticle.cc:307
void setMaserParticle(bool flag)
Flags the status of the particle if it belongs to the maser boundary or not.
Definition: BaseParticle.cc:312
Mdouble X
the vector components
Definition: Vector.h:66

References BaseHandler< BasePeriodicBoundary >::getDPMBase(), BaseObject::getId(), BaseHandler< T >::getNextId(), BaseParticle::getPeriodicComplexity(), BaseInteractable::getPosition(), BaseHandler< BasePeriodicBoundary >::getSize(), BaseHandler< T >::increaseId(), BaseParticle::isMaserParticle(), logger, DPMBase::particleHandler, BaseObject::setId(), BaseParticle::setMaserParticle(), VERBOSE, and Vec3D::X.

Referenced by updateParticleStatus().

◆ updateParticles()

void PeriodicBoundaryHandler::updateParticles ( )

Updates position/velocity and periodic complexity of ghost particles.

This function updates the position/velocity and periodic complexity of ghost particles. There are two versions of update, a local and a global one. The local one can update the particles through pointers, as the periodic particle is located ont he same processor as the ghost. The local version has received data from other processors which is stored in the corresponding vectors

861 {
862  //For all lists that contain ghost particles
863  //The variable dataIndex indicates which index in update<...>Receive_ the data is located
864  int dataIndex = -1;
865  for (int i = 0; i < NUMBER_OF_PROCESSORS; i++)
866  {
867  unsigned long numberOfParticles = periodicGhostList_[i].size();
868  bool global;
869  if (numberOfParticles > 0)
870  {
871  //Check if the update is global or from the current processor
872  if (i != PROCESSOR_ID)
873  {
874  global = true;
875  dataIndex++;
876  }
877  else
878  {
879  global = false;
880  }
881 
882  //Update all particles
883  for (int p = 0; p < numberOfParticles; p++)
884  {
886  BaseParticle* pGhost = pgid->particle;
887 
888  //Depending on where the particle is located the data is stored in a different place
889  if (global)
890  {
891  //logger(VERBOSE,"i: %, numberOfParticles: %, dataIndex: %",i,numberOfParticles, dataIndex);
892  //Check if this particle really belongs to the data that is send
893  logger.assert_debug(pGhost->getId() == updatePositionDataReceive_[dataIndex][p].id,
894  "Periodic particle lists are not in syc");
895 
896  //Add the real position and velocity of the particles
897  //Note: The before updating the position is the position of the ghost
898  //Note: The received position and velocity values are of the real particle
899  //Note: It will be shifted to the correct values after the complexity is computed
900  pGhost->setPreviousPosition(pGhost->getPosition());
901  pGhost->setPosition(updatePositionDataReceive_[dataIndex][p].position);
902  pGhost->setOrientation(updatePositionDataReceive_[dataIndex][p].orientation);
903  pGhost->setVelocity(updateVelocityDataReceive_[dataIndex][p].velocity);
904  pGhost->setAngularVelocity(updateVelocityDataReceive_[dataIndex][p].angularVelocity);
905 
906  }
907  else
908  {
909  //MpiPeriodicGhostParticleID * pgip = periodicGhostList_[i][p];
910  pGhost->setPreviousPosition(pGhost->getPosition());
911  pGhost->setPosition(pgid->otherParticle->getPosition());
912  pGhost->setOrientation(pgid->otherParticle->getOrientation());
913  pGhost->setVelocity(pgid->otherParticle->getVelocity());
915  }
916 
917  //Move current periodic complexity to previous periodic complexity
919 
920  //Compute the new realPeriodicComplexity
921  std::vector<int> previousRealPeriodicComplexity = periodicGhostList_[i][p]->realPeriodicComplexity;
922  //The ghost particle has the real position at the moment, so compute the real periodic complexity here
923  std::vector<int> realPeriodicComplexity = computePeriodicComplexity(pGhost->getPosition());
924  std::vector<int> periodicComplexity(getSize());
925  for (int b = 0; b < getSize(); b++)
926  {
927  int sign = mathsFunc::sign(previousRealPeriodicComplexity[b]
928  * realPeriodicComplexity[b]
929  * pGhost->getPreviousPeriodicComplexity()[b]);
930  periodicComplexity[b] = sign * abs(realPeriodicComplexity[b]);
931  //The maser boundary needs this correction
932  if (periodicComplexity[b] == -3)
933  {
934  periodicComplexity[b] = 1;
935  }
936 
937  }
938  pGhost->setPeriodicComplexity(periodicComplexity);
939 
940  for (int b = 0; b < getSize(); b++)
941  {
942  objects_[b]->modifyGhostAfterCreation(pGhost, b);
943  }
944  //Shift the particle to correct position
945  //Note: If the real particle changed complexity this position will be calculated incorrectly
946  //Hence the previous complexity is used.
947  shiftParticle(pGhost, pGhost->getPreviousPeriodicComplexity());
948 
949  //Update hGrid
950  Vec3D displacement = pGhost->getPreviousPosition() - pGhost->getPosition();
951  getDPMBase()->hGridUpdateMove(pGhost, displacement.getLengthSquared());
952 
953  //Do some book keeping
954  periodicGhostList_[i][p]->realPeriodicComplexity = realPeriodicComplexity;
955 
956  }
957  }
958  }
959 
960  //Update periodic complexity of periodic particles
961  for (BaseParticle* particle : getDPMBase()->particleHandler)
962  {
963  if ((particle->isInPeriodicDomain()) && !(particle->isPeriodicGhostParticle()))
964  {
965  //Update the periodicComplexity of the real particles
966  particle->setPreviousPeriodicComplexity(particle->getPeriodicComplexity());
967  std::vector<int> periodicComplexity;
968  int totalPeriodicComplexity;
969  computePeriodicComplexity(periodicComplexity, totalPeriodicComplexity, particle->getPosition());
970  //Modify periodic complexity tailored to specific boundary requirements
971  for (int b = 0; b < getSize(); b++)
972  {
973  objects_[b]->modifyPeriodicComplexity(periodicComplexity, totalPeriodicComplexity, particle, b);
974  }
975  particle->setPeriodicComplexity(periodicComplexity);
976  }
977  }
978 }
const Quaternion & getOrientation() const
Returns the orientation of this BaseInteractable.
Definition: BaseInteractable.h:230
virtual const Vec3D & getAngularVelocity() const
Returns the angular velocity of this interactable.
Definition: BaseInteractable.cc:341
virtual void setOrientation(const Quaternion &orientation)
Sets the orientation of this BaseInteractable.
Definition: BaseInteractable.h:260
void setAngularVelocity(const Vec3D &angularVelocity)
set the angular velocity of the BaseInteractble.
Definition: BaseInteractable.cc:360
virtual const Vec3D & getVelocity() const
Returns the velocity of this interactable.
Definition: BaseInteractable.cc:329
void setVelocity(const Vec3D &velocity)
set the velocity of the BaseInteractable.
Definition: BaseInteractable.cc:350
void setPreviousPosition(const Vec3D &pos)
Sets the particle's position in the previous time step.
Definition: BaseParticle.cc:614
const std::vector< int > & getPreviousPeriodicComplexity() const
Sets the previous periodic communication complexity of the particle.
Definition: BaseParticle.cc:271
void setPreviousPeriodicComplexity(std::vector< int > complexity)
Set the previous periodic communication complexity of the paritcle.
Definition: BaseParticle.cc:266
const Vec3D & getPreviousPosition() const
Returns the particle's position in the previous time step.
Definition: BaseParticle.h:403
virtual void hGridUpdateMove(BaseParticle *, Mdouble)
Definition: DPMBase.cc:1933
static Mdouble getLengthSquared(const Vec3D &a)
Calculates the squared length of a Vec3D: .
Definition: Vector.h:332

References computePeriodicComplexity(), BaseInteractable::getAngularVelocity(), BaseHandler< BasePeriodicBoundary >::getDPMBase(), BaseObject::getId(), Vec3D::getLengthSquared(), BaseInteractable::getOrientation(), BaseParticle::getPeriodicComplexity(), BaseInteractable::getPosition(), BaseParticle::getPreviousPeriodicComplexity(), BaseParticle::getPreviousPosition(), BaseHandler< BasePeriodicBoundary >::getSize(), BaseInteractable::getVelocity(), DPMBase::hGridUpdateMove(), constants::i, logger, NUMBER_OF_PROCESSORS, BaseHandler< BasePeriodicBoundary >::objects_, MpiPeriodicParticleIDBase::otherParticle, MpiPeriodicParticleIDBase::particle, periodicGhostList_, PROCESSOR_ID, BaseInteractable::setAngularVelocity(), BaseInteractable::setOrientation(), BaseParticle::setPeriodicComplexity(), BaseInteractable::setPosition(), BaseParticle::setPreviousPeriodicComplexity(), BaseParticle::setPreviousPosition(), BaseInteractable::setVelocity(), shiftParticle(), mathsFunc::sign(), updatePositionDataReceive_, and updateVelocityDataReceive_.

Referenced by finalisePositionAndVelocityUpdate().

◆ updateParticleStatus()

void PeriodicBoundaryHandler::updateParticleStatus ( std::set< BaseParticle * > &  particlesToBeDeleted)

Updates the status of periodic particles and ghost particles.

This function updates the status of the particles based on the periodic complexity of the particles. this is beneficial as no round-off errors are made due to the shift in position. If a particle changes it's periodic complexity it is either removed or turned into a real particle. The real particle will be re-introduced in a later step. Particles that need to be deleted will be stored in a vector as these particles might also need to be flushed from the Domain.h lists.

Parameters
[in,out]particlesToBeDeletedList of particles that will need to be removed from the simulation
1037 {
1038  MPIContainer& communicator = MPIContainer::Instance();
1039  int numberOfProcessors = communicator.getNumberOfProcessors();
1040  std::set<MpiPeriodicParticleID*> deletePeriodicIDList;
1041  std::set<MpiPeriodicGhostParticleID*> deletePeriodicGhostIDList;
1042  std::set<BaseParticle*> specialUpdateParticleList;
1043 
1044  //For all domains
1045  for (int i = 0; i < numberOfProcessors; i++)
1046  {
1047  int numberOfPeriodicParticles = periodicParticleList_[i].size();
1048  int numberOfPeriodicGhostParticles = periodicGhostList_[i].size();
1049 
1050  //Loop over all periodic particles to see if their complexity changed
1051  for (int p = 0; p < numberOfPeriodicParticles; p++)
1052  {
1054  BaseParticle* particle = ppid->particle;
1055 
1056  //Check particle status
1057  bool isReal = checkIsReal(particle->getPeriodicComplexity());
1058  bool changed = checkChanged(particle->getPreviousPeriodicComplexity(), particle->getPeriodicComplexity());
1059 
1060  //Only if the particle changed we need to undertake action
1061  if (changed)
1062  {
1063  if (isReal)
1064  {
1065  //Flag this particle as normal, it will be re-introduced when finding new periodic particles
1066  logger(VERBOSE, "Real particle % changed complexity at: %", particle->getId(),
1067  particle->getPosition());
1068  particle->setInPeriodicDomain(false);
1069  //Incase of a special flag 3, perform update action
1070  updateMaserParticle(particle);
1071  }
1072  else
1073  {
1074  //Oh noes, the particle became a ghost. Kill it with balefire!!... if it is necessary
1075  logger(VERBOSE, "Real particle % changed to ghost at: %", particle->getId(),
1076  particle->getPosition());
1077  particlesToBeDeleted.insert(particle);
1078  }
1079 
1080  //Delete the ID
1081  deletePeriodicIDList.insert(ppid);
1082  periodicParticleList_[i][p] = nullptr;
1083  }
1084 
1085 
1086  //If a PM particle changes from to PMG it will need to be deleted.
1087  //The deletion will be done by the M boundary, but it still needs to be flushed from the periodic lists
1088  if (particle->isInMPIDomain())
1089  {
1090  //Store old values and compute new to see if the status has changed
1091  bool isMPIParticleOld = particle->isMPIParticle();
1092  bool isMPIParticle;
1093  bool isInMPIDomain;
1094  getMPIFlags(particle, isInMPIDomain, isMPIParticle);
1095 
1096  //Particle needs to be removed from lists if it becomes an MG particle
1097  if (isMPIParticleOld != isMPIParticle)
1098  {
1099  logger(VERBOSE, "PM to PMG: Flush from boundary");
1100  deletePeriodicIDList.insert(ppid);
1101  periodicParticleList_[i][p] = nullptr;
1102  }
1103 
1104  //MG particle needs to be removed from lists if it moves to another domain
1105  if (!isInMPIDomain)
1106  {
1107  if (particle->isMPIParticle())
1108  {
1109  logger(VERBOSE, "PMG leaves domain: Flush from boundary");
1110  deletePeriodicIDList.insert(ppid);
1111  periodicParticleList_[i][p] = nullptr;
1112  }
1113  }
1114  }
1115  }
1116 
1117  //Loop over all periodic ghost particles to see if their complexity changed
1118  for (int p = 0; p < numberOfPeriodicGhostParticles; p++)
1119  {
1121  BaseParticle* pGhost = pgid->particle;
1122 
1123  //Check particle status
1124  bool isReal = checkIsReal(pGhost->getPeriodicComplexity());
1125  bool changed = checkChanged(pGhost->getPreviousPeriodicComplexity(), pGhost->getPeriodicComplexity());
1126 
1127  //Update mixed particles, particles that also are in the mpi domain also need an update
1128  //Note that these particles are not listed in the domain lists, they are taken care here.
1129  //Store old values and update status of pGhost
1130  bool isInMPIDomainOld = pGhost->isInMPIDomain();
1131  bool isMPIParticleOld = pGhost->isMPIParticle();
1132  setMPIFlags(pGhost);
1133  if (isInMPIDomainOld)
1134  {
1135 
1136  //Case 1: pGhost changed from real to mpi particle
1137  if (isMPIParticleOld != pGhost->isMPIParticle())
1138  {
1139  //Case 1: turned from M ghost to M
1140  //The correct flags have been set above already
1141 
1142  //Case 2: Turned from M to M ghost
1143  if (pGhost->isMPIParticle())
1144  {
1145  logger(VERBOSE, "PGM to PGMG: Deleting particle.");
1146  particlesToBeDeleted.insert(pGhost);
1147  deletePeriodicGhostIDList.insert(pgid);
1148  periodicGhostList_[i][p] = nullptr;
1149  }
1150 
1151  }
1152 
1153  //Case 2: pGhost left the mpi domain
1154  if (pGhost->isInMPIDomain() != isInMPIDomainOld)
1155  {
1156  //Case 1: Moved inside the current domain
1157  //The correct flags have been set above already
1158 
1159  //Case 2: Moved to a neighbour domain
1160  if (pGhost->isMPIParticle())
1161  {
1162  logger(VERBOSE, "PGMG moved out of domain: Deleting particle.");
1163  particlesToBeDeleted.insert(pGhost);
1164  deletePeriodicGhostIDList.insert(pgid);
1165  periodicGhostList_[i][p] = nullptr;
1166  }
1167  }
1168  }
1169 
1170  //Check if the particles need to be deleted based on their periodic complexity
1171  if (changed)
1172  {
1173  if (isReal)
1174  {
1175  //Check if the complexity of the particle is truely real based on it's current position
1176  std::vector<int> pc = computePeriodicComplexity(pGhost->getPosition());
1177  int tpc = 0;
1178  for (int b = 0; b < getSize(); b++)
1179  {
1180  objects_[b]->modifyPeriodicComplexity(pc, tpc, pGhost, b);
1181  }
1182  if (!checkIsReal(pc))
1183  {
1184  logger(ERROR, "Round-off error detected.");
1185  //logger(WARN,"Round-off error corrected, phew!");
1186  }
1187 
1188  //There are two cases
1189  //Case 1: PGMG particles turning PMG; These are still not real
1190  //Case 2: PGM particles turning PG; These are truely real
1191  if (pGhost->isMPIParticle())
1192  {
1193  logger(VERBOSE, "PGMG turned PMG: delete it");
1194  particlesToBeDeleted.insert(pGhost);
1195  }
1196  else
1197  {
1198  //Turn the particle real
1199  logger(VERBOSE, "Ghost particle changed to real at position: %", pGhost->getPosition());
1200  pGhost->setInPeriodicDomain(false);
1201  pGhost->setPeriodicGhostParticle(false);
1202  //Make sure this particle can be detected now by the parallel boundaries
1203  pGhost->setInMPIDomain(false);
1204  }
1205  }
1206  else
1207  {
1208  //Delete the particle
1209  logger(VERBOSE, "Ghost particle changed complexity at position: %", pGhost->getPosition());
1210  particlesToBeDeleted.insert(pGhost);
1211  }
1212 
1213  //Delete the ID
1214  deletePeriodicGhostIDList.insert(pgid);
1215  periodicGhostList_[i][p] = nullptr;
1216  }
1217  }
1218 
1219  }
1220 
1221  //Delete IDs
1222  for (auto ppid_it : deletePeriodicIDList)
1223  {
1224  delete ppid_it;
1225  }
1226 
1227  for (auto pgid_it : deletePeriodicGhostIDList)
1228  {
1229  delete pgid_it;
1230  }
1231  unsigned int nextId = getDPMBase()->particleHandler.getNextId();
1232  communicator.broadcast(nextId);
1234 }
@ ERROR
void setNextId(unsigned int id)
Definition: BaseHandler.h:261
bool isInMPIDomain()
Indicates if the particle is in the communication zone of the mpi domain.
Definition: BaseParticle.cc:276
bool isMPIParticle() const
Indicates if this particle is a ghost in the MPI domain.
Definition: BaseParticle.cc:181
void updateMaserParticle(BaseParticle *particle)
Updates the maser flag of particles leaving the maser.
Definition: PeriodicBoundaryHandler.cc:1864
bool checkChanged(std::vector< int > previousComplexity, std::vector< int > complexity)
checks of two periodic complexities differ
Definition: PeriodicBoundaryHandler.cc:1012
bool checkIsReal(std::vector< int > complexity)
checks if a periodic complexity is real
Definition: PeriodicBoundaryHandler.cc:988

References MPIContainer::broadcast(), checkChanged(), checkIsReal(), computePeriodicComplexity(), ERROR, BaseHandler< BasePeriodicBoundary >::getDPMBase(), BaseObject::getId(), getMPIFlags(), BaseHandler< T >::getNextId(), MPIContainer::getNumberOfProcessors(), BaseParticle::getPeriodicComplexity(), BaseInteractable::getPosition(), BaseParticle::getPreviousPeriodicComplexity(), BaseHandler< BasePeriodicBoundary >::getSize(), constants::i, MPIContainer::Instance(), BaseParticle::isInMPIDomain(), BaseParticle::isMPIParticle(), logger, BaseHandler< BasePeriodicBoundary >::objects_, MpiPeriodicParticleIDBase::particle, DPMBase::particleHandler, periodicGhostList_, periodicParticleList_, BaseParticle::setInMPIDomain(), BaseParticle::setInPeriodicDomain(), setMPIFlags(), BaseHandler< T >::setNextId(), BaseParticle::setPeriodicGhostParticle(), updateMaserParticle(), and VERBOSE.

Referenced by updateStatus().

◆ updateStatus()

void PeriodicBoundaryHandler::updateStatus ( std::set< BaseParticle * > &  particlesToBeDeleted)

Updates the positions/velocity of ghost particles and accordingly the status of these particles.

\detail This function updates the status of periodic particles and periodic ghost particles. This is done in two steps. The first step is to update the ghost particles with the position of their corresponding real particles. Based on this new position their status will be updated. Occasionally a particle needs to be removed and because this particle might also be listed in the communication boundaries, it will be deleted after those lists have been flushed.

Parameters
[in]particlesToBeDeletedA list of particles that need to be deleted, but can't yet be deleted to avoid segmentation faults
152 {
153  //Step 1: collect position and velocity data of the real particle and send the data
155 
156  //Step 2: finalise the data transision
158 
159  //Step 3: Update the status of the ghost and real particles
160  updateParticleStatus(particlesToBeDeleted);
161 }
void preparePositionAndVelocityUpdate()
Collects the position and velocity data from periodic boundaries.
Definition: PeriodicBoundaryHandler.cc:1628
void updateParticleStatus(std::set< BaseParticle * > &particlesToBeDeleted)
Updates the status of periodic particles and ghost particles.
Definition: PeriodicBoundaryHandler.cc:1036
void finalisePositionAndVelocityUpdate()
Communicates position and velocity data from periodic boundaries and updates ghost particles.
Definition: PeriodicBoundaryHandler.cc:1692

References finalisePositionAndVelocityUpdate(), preparePositionAndVelocityUpdate(), and updateParticleStatus().

Referenced by DPMBase::performGhostParticleUpdate().

Member Data Documentation

◆ interactionDataReceive_

std::vector<void*> PeriodicBoundaryHandler::interactionDataReceive_
private

Stores the interaction data that is going to be received.

Referenced by finaliseNewParticleTransmission(), performNewParticleTransmission(), and processReceivedInteractionData().

◆ interactionDataSend_

std::vector<void*> PeriodicBoundaryHandler::interactionDataSend_
private

Stores the interaction data that is going to be send.

Referenced by collectInteractionData(), finaliseNewParticleTransmission(), performNewParticleTransmission(), and processLocalInteractionData().

◆ interactionDistance_

Mdouble PeriodicBoundaryHandler::interactionDistance_
private

The interaction distance between a position and the boundary for which particles start to participate with a boundary or not.

Referenced by computePeriodicComplexity(), getInteractionDistance(), operator=(), PeriodicBoundaryHandler(), and setInteractionDistance().

◆ newInteractionList_

std::vector<std::vector<BaseInteraction*> > PeriodicBoundaryHandler::newInteractionList_
private

A list that stores the new interactions that have to be send to target processor, corresponding to sendTargetList_

Referenced by collectInteractionData(), finaliseNewParticleTransmission(), and findNewInteractions().

◆ newPeriodicParticleList_

std::vector<PeriodicList> PeriodicBoundaryHandler::newPeriodicParticleList_
private

A vector the size of the number of processors, each entry containing a vector of newly found periodic particles that need to be send to other processors

Referenced by collectGhostParticleData(), communicateTargetDomains(), finaliseNewParticleTransmission(), findNewInteractions(), findNewParticle(), initialise(), processLocalGhostParticles(), and processPeriodicParticles().

◆ numberOfNewInteractionsReceive_

std::vector<int> PeriodicBoundaryHandler::numberOfNewInteractionsReceive_
private

Stores the number of new interactions to be received from target processor corresponding to receiveTargetList_.

Referenced by communicateNumberOfNewParticlesAndInteractions(), finaliseNewParticleTransmission(), performNewParticleTransmission(), and processReceivedInteractionData().

◆ numberOfNewInteractionsSend_

std::vector<int> PeriodicBoundaryHandler::numberOfNewInteractionsSend_
private

Stores the number of new interactions to be send to target processor corresponding to sendTargetList_.

Referenced by collectInteractionData(), communicateNumberOfNewParticlesAndInteractions(), finaliseNewParticleTransmission(), findNewInteractions(), performNewParticleTransmission(), and processLocalInteractionData().

◆ numberOfNewPeriodicGhostParticlesReceive_

std::vector<int> PeriodicBoundaryHandler::numberOfNewPeriodicGhostParticlesReceive_
private

A vector that stores how many new ghost particles will be received from other processors.

Referenced by communicateNumberOfNewParticlesAndInteractions(), finaliseNewParticleTransmission(), performNewParticleTransmission(), and processReceivedGhostParticleData().

◆ numberOfNewPeriodicGhostParticlesSend_

std::vector<int> PeriodicBoundaryHandler::numberOfNewPeriodicGhostParticlesSend_
private

◆ periodicGhostComplexityReceive_

std::vector<std::vector<int> > PeriodicBoundaryHandler::periodicGhostComplexityReceive_
private

Data container for periodic complexity that is being received from other processors.

Referenced by finaliseNewParticleTransmission(), performNewParticleTransmission(), and processReceivedGhostParticleData().

◆ periodicGhostComplexitySend_

std::vector<std::vector<int> > PeriodicBoundaryHandler::periodicGhostComplexitySend_
private

Data container for periodic complexity that is being send to other processors.

Referenced by collectGhostParticleData(), finaliseNewParticleTransmission(), and performNewParticleTransmission().

◆ periodicGhostList_

std::vector<PeriodicGhostList> PeriodicBoundaryHandler::periodicGhostList_
private

A vector the size of the number of processors, each entry containing a vector of ghost periodioc particle ID's to keep track of periodic ghost particles and their corresponding real particles.

Referenced by cleanCommunicationLists(), clearCommunicationLists(), flushParticles(), getNumberOfPeriodicGhostParticles(), getNumberOfTruePeriodicGhostParticles(), initialise(), preparePositionAndVelocityUpdate(), processLocalGhostParticles(), processReceivedGhostParticleData(), updateParticles(), and updateParticleStatus().

◆ periodicGhostParticleReceive_

std::vector<std::vector<MPIParticle> > PeriodicBoundaryHandler::periodicGhostParticleReceive_
private

Data container for particles that are being received from other processors.

Referenced by finaliseNewParticleTransmission(), performNewParticleTransmission(), and processReceivedGhostParticleData().

◆ periodicGhostParticleSend_

std::vector<std::vector<MPIParticle> > PeriodicBoundaryHandler::periodicGhostParticleSend_
private

Data container for particles that are being send to other processors.

Referenced by collectGhostParticleData(), finaliseNewParticleTransmission(), and performNewParticleTransmission().

◆ periodicParticleList_

std::vector<PeriodicList> PeriodicBoundaryHandler::periodicParticleList_
private

A vector the size of the number of processors, each entry containing a vector of periodic particle ID's to keep track of periodic particles and their corresponding ghosts.

Referenced by cleanCommunicationLists(), clearCommunicationLists(), flushParticles(), initialise(), preparePositionAndVelocityUpdate(), processPeriodicParticles(), and updateParticleStatus().

◆ receiveTargetList_

std::vector<int> PeriodicBoundaryHandler::receiveTargetList_
private

A list that keeps track which target processors the current processor is receiving new particles from.

Referenced by communicateNumberOfNewParticlesAndInteractions(), communicateTargetDomains(), finaliseNewParticleTransmission(), performNewParticleTransmission(), and processReceivedGhostParticleData().

◆ sendTargetList_

◆ updatePositionDataReceive_

std::vector<std::vector<MPIParticlePosition> > PeriodicBoundaryHandler::updatePositionDataReceive_
private

Data container for position data that is being received from other processors.

Referenced by finalisePositionAndVelocityUpdate(), preparePositionAndVelocityUpdate(), and updateParticles().

◆ updatePositionDataSend_

std::vector<std::vector<MPIParticlePosition> > PeriodicBoundaryHandler::updatePositionDataSend_
private

Data container for position data that is being send to other processors.

Referenced by finalisePositionAndVelocityUpdate(), and preparePositionAndVelocityUpdate().

◆ updateVelocityDataReceive_

std::vector<std::vector<MPIParticleVelocity> > PeriodicBoundaryHandler::updateVelocityDataReceive_
private

Data container for velocity data that is being received from other processors.

Referenced by finalisePositionAndVelocityUpdate(), preparePositionAndVelocityUpdate(), and updateParticles().

◆ updateVelocityDataSend_

std::vector<std::vector<MPIParticleVelocity> > PeriodicBoundaryHandler::updateVelocityDataSend_
private

Data container for velocity data that is being send to other processors.

Referenced by finalisePositionAndVelocityUpdate(), and preparePositionAndVelocityUpdate().


The documentation for this class was generated from the following files: