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< intcomputePeriodicComplexity (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...
 
virtual void removeObjects (std::vector< unsigned int > indices)
 
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< intreceiveTargetList_
 A list that keeps track which target processors the current processor is receiving new particles from. More...
 
std::vector< intsendTargetList_
 A list that keeps track to which targets this processor is sending new particles to. More...
 
std::vector< intnumberOfNewPeriodicGhostParticlesReceive_
 A vector that stores how many new ghost particles will be received from other processors. More...
 
std::vector< intnumberOfNewPeriodicGhostParticlesSend_
 A vector that stores how many particles are going to be send to other processors. More...
 
std::vector< intnumberOfNewInteractionsSend_
 Stores the number of new interactions to be send to target processor corresponding to sendTargetList_. More...
 
std::vector< intnumberOfNewInteractionsReceive_
 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.

21 {
23  logger(DEBUG, "PeriodicBoundaryHandler::PeriodicBoundaryHandler() finished");
24 }
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:292

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.

32 {
33  objects_.clear();
34  setDPMBase(nullptr);
36  logger(DEBUG, "PeriodicBoundaryHandler::PeriodicBoundaryHandler(const PeriodicBoundaryHandler &BH) finished");
37 }
void setDPMBase(DPMBase *DPMBase)
Sets the problem that is solved using this handler.
Definition: BaseHandler.h:726
std::vector< BasePeriodicBoundary * > objects_
The actual list of Object pointers.
Definition: BaseHandler.h:283

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
57 {
61  objects_.clear();
62 
63  logger(DEBUG, "PeriodicBoundaryHandler::~PeriodicBoundaryHandler() finished");
64 }

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

Member Function Documentation

◆ addNewParticle()

void PeriodicBoundaryHandler::addNewParticle ( BaseParticle particle)

Adds a new particle to the periodic list.

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.
312 {
313 #ifdef MERCURYDPM_USE_MPI
314  if (NUMBER_OF_PROCESSORS == 1)
315  {
316  return;
317  }
318  if (getDPMBase()->getCurrentDomain()->containsParticle(particle))
319  {
320  //Step 1: Find if the new particle needs to be added
321  findNewParticle(particle);
322  }
323  //Follow the standard communication routine
327 #endif
328 }
#define NUMBER_OF_PROCESSORS
For the MPI communication routines this quantity is often required. defining this macro makes the cod...
Definition: GeneralDefine.h:41
DPMBase * getDPMBase()
Gets the problem that is solved using this handler.
Definition: BaseHandler.h:733
void prepareNewParticleTransmission()
Initial preparation work for sending ghost particles.
Definition: PeriodicBoundaryHandler.cc:1468
void performNewParticleTransmission()
Collects and sends the ghost particle data.
Definition: PeriodicBoundaryHandler.cc:1483
void finaliseNewParticleTransmission()
creates the ghost particles and performs some bookkeeping to keep track of them
Definition: PeriodicBoundaryHandler.cc:1564
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:1249

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.

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.

279 {
280 #ifdef MERCURYDPM_USE_MPI
281  if (NUMBER_OF_PROCESSORS == 1)
282  {
283  return;
284  }
285  //Step 0: Perform actions before finding new particles. I.e. opening maser boundary
287 
288  //Step 1: Find new particles, such that the target domains can be found
290 
291  //Step 3: Communicate number of particles/interactions to other dommains
293 
294  //Step 4: Perform data transmission
296 
297  //Step 5: Finalise data transmission
299 #endif
300 }
void performActionsBeforeAddingParticles()
Actions that boundaries perform before adding new periodic/ghost particles.
Definition: PeriodicBoundaryHandler.cc:1772
void findNewParticles()
Loops over all particles in the simulation to check if they need to be added to the periodic lists.
Definition: PeriodicBoundaryHandler.cc:1306

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

Referenced by SubcriticalMaserBoundaryTEST::activateMaser(), addObject(), 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.
69 {
70 #ifdef MERCURYDPM_USE_MPI
71  if (NUMBER_OF_PROCESSORS == 1)
72  {
73  return;
74  }
75  //Puts the particle in the Particle list
76  objects_.push_back(P);
77  //set the particleHandler pointer
78  P->setPeriodicHandler(this);
79  //Remove all ghost particles
81  //Initialise ghost particles
83 #endif
84 }
void addNewParticles()
Adds new particles to the periodic particle lists.
Definition: PeriodicBoundaryHandler.cc:278
void clearCommunicationLists()
Removes all ghost particles and bookkeeping for a fresh start.
Definition: PeriodicBoundaryHandler.cc:1785
double P
Uniform pressure.
Definition: TwenteMeshGluing.cpp:77

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

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.
992 {
993  bool changed = false;
994 
995  for (int i = 0; i < currentComplexity.size(); i++)
996  {
997  if (previousComplexity[i] != currentComplexity[i])
998  {
999  changed = true;
1000  }
1001  }
1002 
1003  return changed;
1004 }
int i
Definition: BiCGSTAB_step_by_step.cpp:9

References i.

Referenced by updateParticleStatus().

◆ checkIfAddNewParticle()

bool PeriodicBoundaryHandler::checkIfAddNewParticle ( BaseParticle particle)
1864 {
1865  if (particle->isPeriodicGhostParticle())
1866  {
1867  return false;
1868  }
1869  if (particle->isInPeriodicDomain())
1870  {
1871  return false;
1872  }
1873  return true;
1874 }
bool isPeriodicGhostParticle() const
Indicates if this particle is a ghost in the periodic boundary.
Definition: BaseParticle.cc:280
bool isInPeriodicDomain() const
Indicates if the particle is in the periodic boundary communication zone.
Definition: BaseParticle.cc:270

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

Referenced by findNewParticle().

◆ checkIsReal()

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

checks if a periodic complexity is real

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.
967 {
968  bool isReal = true;
969  for (int i = 0; i < getSize(); i++)
970  {
971  if (mathsFunc::sign(complexity[i]) == -1)
972  {
973  isReal = false;
974  }
975  }
976 
977  return isReal;
978 }
unsigned int getSize() const
Gets the size of the particleHandler (including mpi and periodic particles)
Definition: BaseHandler.h:663
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:77

References BaseHandler< BasePeriodicBoundary >::getSize(), 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
1738 {
1739  for (int i = 0; i < list.size(); i++)
1740  {
1741  if (list[i] == nullptr)
1742  {
1743  list[i] = list.back();
1744  list.pop_back();
1745  i--;
1746  }
1747  }
1748 }

References i.

Referenced by cleanCommunicationLists().

◆ cleanCommunicationLists()

void PeriodicBoundaryHandler::cleanCommunicationLists ( )
1751 {
1752  for (int i = 0; i < NUMBER_OF_PROCESSORS; i++)
1753  {
1756  }
1757 }
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:395
void cleanCommunicationList(std::vector< MpiPeriodicParticleIDBase * > &list)
Removes the nullptr's from a communication list.
Definition: PeriodicBoundaryHandler.cc:1737
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:402

References cleanCommunicationList(), 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

1786 {
1787  if (NUMBER_OF_PROCESSORS > 1)
1788  {
1789  //Clear ID lists
1790  for (auto& i : periodicParticleList_)
1791  {
1792  //logger(INFO,"Size: %",periodicParticleList_[i].size());
1793  for (int j = 0; j < i.size(); j++)
1794  {
1795  delete i[j];
1796  }
1797  i.clear();
1798  }
1799 
1800  for (auto& i : periodicGhostList_)
1801  {
1802  for (int j = 0; j < i.size(); j++)
1803  {
1804  delete i[j];
1805  }
1806  i.clear();
1807  }
1808 
1809  //Collect all ghost particles and unflag
1811  std::set<BaseParticle*> toBeDeleted; //Set because I am too lazy to implement a vector based flushParticle function
1812  for (BaseParticle* particle : pH)
1813  {
1814  if (particle->isPeriodicGhostParticle())
1815  {
1816  toBeDeleted.insert(particle);
1817  }
1818 
1819  //Unflag its periodicity
1820  particle->setInPeriodicDomain(false);
1821  }
1822 
1823  //Flush from mpi boundary and clean the lists
1824  getDPMBase()->getCurrentDomain()->flushParticles(toBeDeleted);
1826 
1827  //Delete particles
1828  for (BaseParticle* particle : toBeDeleted)
1829  {
1830  pH.removeGhostObject(particle->getIndex());
1831  }
1832  }
1833 }
Definition: BaseParticle.h:33
Domain * getCurrentDomain()
Function that returns a pointer to the domain corresponding to the processor.
Definition: DPMBase.cc:5378
ParticleHandler particleHandler
An object of the class ParticleHandler, contains the pointers to all the particles created.
Definition: DPMBase.h:1443
void cleanCommunicationLists()
Removes nullptrs from boundaryParticleList_ and boundaryParticleListNeighbour_.
Definition: Domain.cc:1721
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:1677
Container to store pointers to all particles.
Definition: ParticleHandler.h:28
std::ptrdiff_t j
Definition: tut_arithmetic_redux_minmax.cpp:2

References Domain::cleanCommunicationLists(), Domain::flushParticles(), DPMBase::getCurrentDomain(), BaseHandler< BasePeriodicBoundary >::getDPMBase(), i, j, 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.

476 {
477  //For all new target lists
478  unsigned long numberOfTargets = sendTargetList_.size();
479  periodicGhostParticleSend_.resize(numberOfTargets);
480  periodicGhostComplexitySend_.resize(numberOfTargets);
481  for (int i = 0; i < numberOfTargets; i++)
482  {
484  {
485  //For all new ghost particles copy particle data and periodic complexity
486  for (int j = 0; j < numberOfNewPeriodicGhostParticlesSend_[i]; j++)
487  {
489  BaseParticle* particle = ppid->particle;
491  for (int k = 0; k < getSize(); k++)
492  {
494  }
495  }
496  }
497  }
498 }
#define PROCESSOR_ID
Definition: GeneralDefine.h:42
MPIParticle copyDataFromParticleToMPIParticle(BaseParticle *p)
Copies data from a NonSphericalParticle to an MPIParticle class and returns this.
Definition: MpiDataClass.cc:103
Definition: MpiDataClass.h:127
std::vector< int > targetPeriodicComplexity
Definition: MpiDataClass.h:139
BaseParticle * particle
Definition: MpiDataClass.h:129
std::vector< int > numberOfNewPeriodicGhostParticlesSend_
A vector that stores how many particles are going to be send to other processors.
Definition: PeriodicBoundaryHandler.h:316
std::vector< PeriodicList > newPeriodicParticleList_
Definition: PeriodicBoundaryHandler.h:383
std::vector< std::vector< MPIParticle > > periodicGhostParticleSend_
Data container for particles that are being send to other processors.
Definition: PeriodicBoundaryHandler.h:336
std::vector< std::vector< int > > periodicGhostComplexitySend_
Data container for periodic complexity that is being send to other processors.
Definition: PeriodicBoundaryHandler.h:346
std::vector< int > sendTargetList_
A list that keeps track to which targets this processor is sending new particles to.
Definition: PeriodicBoundaryHandler.h:304
char char char int int * k
Definition: level2_impl.h:374

References copyDataFromParticleToMPIParticle(), BaseHandler< BasePeriodicBoundary >::getSize(), i, j, k, 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

507 {
508  //For all send target lists
510  unsigned long numberOfTargets = sendTargetList_.size();
511  interactionDataSend_.resize(numberOfTargets);
512  for (int i = 0; i < numberOfTargets; i++)
513  {
514  //Allocate enough space
516 
517  //Fill in the vector
518  unsigned int indexInteraction = 0;
519  for (BaseInteraction* interaction : newInteractionList_[i])
520  {
521  interaction->getMPIInteraction(interactionDataSend_[i], indexInteraction);
522  indexInteraction++;
523  }
524  }
525 }
Stores information about interactions between two interactable objects; often particles but could be ...
Definition: BaseInteraction.h:39
InteractionHandler interactionHandler
An object of the class InteractionHandler.
Definition: DPMBase.h:1473
Container to store Interaction objects.
Definition: InteractionHandler.h:25
void * createMPIInteractionDataArray(unsigned int numberOfInteractions) const
creates an empty MPIInteractionDataArray
Definition: InteractionHandler.cc:191
std::vector< void * > interactionDataSend_
Stores the interaction data that is going to be send.
Definition: PeriodicBoundaryHandler.h:371
std::vector< std::vector< BaseInteraction * > > newInteractionList_
Definition: PeriodicBoundaryHandler.h:388
std::vector< int > numberOfNewInteractionsSend_
Stores the number of new interactions to be send to target processor corresponding to sendTargetList_...
Definition: PeriodicBoundaryHandler.h:321

References InteractionHandler::createMPIInteractionDataArray(), BaseHandler< BasePeriodicBoundary >::getDPMBase(), 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.

1427 {
1428  MPIContainer& communicator = MPIContainer::Instance();
1429  //Communicate to how many particles the target domains receive
1430  int tagSend;
1431  for (int i = 0; i < sendTargetList_.size(); i++)
1432  {
1433  if (sendTargetList_[i] != PROCESSOR_ID)
1434  {
1437 
1439  communicator.send(numberOfNewInteractionsSend_[i], sendTargetList_[i], tagSend);
1440  }
1441  }
1442 
1443  //Perform the receive routines
1446  int tagReceive;
1447  for (int i = 0; i < receiveTargetList_.size(); i++)
1448  {
1450  {
1453 
1455  communicator.receive(numberOfNewInteractionsReceive_[i], receiveTargetList_[i], tagReceive);
1456  }
1457  }
1458 }
#define MAX_PROC
Definition: GeneralDefine.h:30
@ INTERACTION_COUNT
Definition: MpiContainer.h:62
@ PARTICLE_COUNT
Definition: MpiContainer.h:57
This class contains all information and functions required for communication between processors.
Definition: MpiContainer.h:109
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:200
static MPIContainer & Instance()
fetch the instance to be used for communication
Definition: MpiContainer.h:113
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:150
std::vector< int > numberOfNewPeriodicGhostParticlesReceive_
A vector that stores how many new ghost particles will be received from other processors.
Definition: PeriodicBoundaryHandler.h:310
std::vector< int > receiveTargetList_
A list that keeps track which target processors the current processor is receiving new particles from...
Definition: PeriodicBoundaryHandler.h:298
std::vector< int > numberOfNewInteractionsReceive_
Stores the number of new interactions to be received from target processor corresponding to receiveTa...
Definition: PeriodicBoundaryHandler.h:326

References 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.

1373 {
1374 #ifdef MERCURYDPM_USE_MPI
1375  //Step 1: Check to how many domains this domain has to send particles
1376  int numberOfTargetDomainsLocal = 0;
1377  for (int index = 0; index < NUMBER_OF_PROCESSORS; index++)
1378  {
1379  if (newPeriodicParticleList_[index].size() > 0)
1380  {
1381  numberOfTargetDomainsLocal++;
1382  sendTargetList_.push_back(index);
1384  }
1385  }
1386 
1387  //Communicate with other domains to how many domains this domain is sending
1388  std::vector<int> numberOfTargetDomains(NUMBER_OF_PROCESSORS);
1389  MPIContainer::Instance().allGather(numberOfTargetDomainsLocal,1,numberOfTargetDomains,1);
1390 
1391  //Step 2: Communicate to other domains what the target domains are
1392  std::vector<int> receiveTargetList;
1393  for (int index = 0; index < NUMBER_OF_PROCESSORS; index++)
1394  {
1395  if (numberOfTargetDomains[index] > 0)
1396  {
1397  if (index == PROCESSOR_ID)
1398  {
1399  MPIContainer::Instance().broadcast(sendTargetList_.data(), numberOfTargetDomainsLocal, index);
1400  }
1401  else
1402  {
1403  receiveTargetList.resize(numberOfTargetDomains[index], 0);
1404  MPIContainer::Instance().broadcast(receiveTargetList.data(),numberOfTargetDomains[index],index);
1405  }
1406 
1407  //If this domain is a target, flag it.
1408  for (int i = 0; i < receiveTargetList.size(); i++)
1409  {
1410  if (receiveTargetList[i] == PROCESSOR_ID)
1411  {
1412  receiveTargetList_.push_back(index);
1413  }
1414  }
1415  }
1416  }
1417 #endif
1418 }
Scalar Scalar int size
Definition: benchVecAdd.cpp:17
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:420

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

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.

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.
191 {
192  //Compute the new position
193  periodicComplexity.resize(this->getSize());
194  totalPeriodicComplexity = 0;
195  int index = 0;
196  for (BasePeriodicBoundary* boundary : *this)
197  {
198  Mdouble distance = boundary->getDistance(position);
199  if (std::abs(distance) <= interactionDistance_)
200  {
201  if (distance > 0)
202  {
203  //real particle
204  periodicComplexity[index] = 1;
205  totalPeriodicComplexity++;
206  }
207  else if (distance < 0)
208  {
209  //ghost particle
210  periodicComplexity[index] = -1;
211  }
212  else //distance == 0 In extremely rare cases (test cases mostly)
213  {
214  //Check if on left or right side of boundary
215  if (boundary->isClosestToLeftBoundary(position))
216  {
217  //ghost particle on the left side
218  periodicComplexity[index] = -1;
219  }
220  else
221  {
222  //real particle on the right side
223  periodicComplexity[index] = 1;
224  totalPeriodicComplexity++;
225  }
226  }
227  }
228  else
229  {
230  if (distance < 0)
231  {
232  periodicComplexity[index] = -2;
233  }
234  else
235  {
236  periodicComplexity[index] = 2;
237  }
238  }
239  index++;
240  }
241 /*
242  //Modify periodic complexity in case of maser
243  for (int b = 0; b < getSize(); b++)
244  {
245  objects_[b]->modifyPeriodicComplexity(periodicComplexity, position, b);
246  }
247 */
248 }
AnnoyingScalar abs(const AnnoyingScalar &x)
Definition: AnnoyingScalar.h:135
Definition: BasePeriodicBoundary.h:20
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 abs(), 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.

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
261 {
262  std::vector<int> periodicComplexity;
263  int totalPeriodicComplexity;
264 
265  computePeriodicComplexity(periodicComplexity, totalPeriodicComplexity, position);
266 
267  return periodicComplexity;
268 }
std::vector< int > computePeriodicComplexity(Vec3D position)
Computes the periodic complexity based on a given position.
Definition: PeriodicBoundaryHandler.cc:260

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

◆ finaliseNewParticleTransmission()

void PeriodicBoundaryHandler::finaliseNewParticleTransmission ( )

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

1565 {
1566  //Process the global received data
1567  for (int i = 0; i < receiveTargetList_.size(); i++)
1568  {
1569  std::vector<BaseParticle*> newGhostParticles;
1570  processReceivedGhostParticleData(i, newGhostParticles);
1571  processReceivedInteractionData(i, newGhostParticles);
1572  }
1573 
1574  //Process the local data
1575  std::vector<BaseParticle*> newGhostParticles;
1576  processLocalGhostParticles(newGhostParticles);
1577  processLocalInteractionData(newGhostParticles);
1578 
1579  //Process the periodic particles;
1581 
1582  //Clear lists
1583  receiveTargetList_.clear();
1584  sendTargetList_.clear();
1593  interactionDataSend_.clear();
1594  interactionDataReceive_.clear();
1595  newInteractionList_.clear();
1596  for (auto& i : newPeriodicParticleList_)
1597  {
1598  i.clear();
1599  }
1600  for (auto& i : newPeriodicParticleList_)
1601  {
1602  i.clear();
1603  }
1604 }
void processLocalInteractionData(std::vector< BaseParticle * > &newParticles)
Process the interaction data for local ghosts.
Definition: PeriodicBoundaryHandler.cc:670
void processPeriodicParticles()
Creates a periodioc particle ID for book keeping and moves the ID to the correct list.
Definition: PeriodicBoundaryHandler.cc:760
std::vector< void * > interactionDataReceive_
Stores the interaction data that is going to be received.
Definition: PeriodicBoundaryHandler.h:376
void processReceivedInteractionData(int targetIndex, std::vector< BaseParticle * > &newParticles)
Process the received interaction data.
Definition: PeriodicBoundaryHandler.cc:593
std::vector< std::vector< int > > periodicGhostComplexityReceive_
Data container for periodic complexity that is being received from other processors.
Definition: PeriodicBoundaryHandler.h:341
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:538
void processLocalGhostParticles(std::vector< BaseParticle * > &newParticles)
Creates ghost particles of periodic particles that are located on the same processor.
Definition: PeriodicBoundaryHandler.cc:783
std::vector< std::vector< MPIParticle > > periodicGhostParticleReceive_
Data container for particles that are being received from other processors.
Definition: PeriodicBoundaryHandler.h:331

References 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.

1671 {
1672  //Update the positions, velocities and periodic complexities of particles
1673  updateParticles();
1674 
1675  //Delete vectors
1676  updatePositionDataSend_.clear();
1678  updateVelocityDataSend_.clear();
1680 }
std::vector< std::vector< MPIParticlePosition > > updatePositionDataReceive_
Data container for position data that is being received from other processors.
Definition: PeriodicBoundaryHandler.h:351
std::vector< std::vector< MPIParticlePosition > > updatePositionDataSend_
Data container for position data that is being send to other processors.
Definition: PeriodicBoundaryHandler.h:356
void updateParticles()
Updates position/velocity and periodic complexity of ghost particles.
Definition: PeriodicBoundaryHandler.cc:838
std::vector< std::vector< MPIParticleVelocity > > updateVelocityDataReceive_
Data container for velocity data that is being received from other processors.
Definition: PeriodicBoundaryHandler.h:361
std::vector< std::vector< MPIParticleVelocity > > updateVelocityDataSend_
Data container for velocity data that is being send to other processors.
Definition: PeriodicBoundaryHandler.h:366

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.

1322 {
1323  //Check all new particle lists
1324  newInteractionList_.resize(sendTargetList_.size());
1325  for (int i = 0; i < sendTargetList_.size(); i++)
1326  {
1327  for (int p = 0; p < newPeriodicParticleList_[sendTargetList_[i]].size(); p++)
1328  {
1329  BaseParticle* particle = newPeriodicParticleList_[sendTargetList_[i]][p]->particle;
1330 
1331  //Loop over all its interactions
1332  std::vector<BaseInteraction*> interactions = particle->getInteractions();
1333  for (BaseInteraction* interaction : interactions)
1334  {
1335  //Find out what the new particle is interacting with
1336  BaseParticle* particleP = dynamic_cast<BaseParticle*>(interaction->getP());
1337  BaseParticle* objectI = dynamic_cast<BaseParticle*>(interaction->getI());
1338 
1339  //If the P in the interaction structure is the new particle, find I
1340  if (particle == particleP)
1341  {
1342  //Check if the new particle is interacting with a wall
1343  if (!objectI)
1344  {
1345  newInteractionList_[i].push_back(interaction);
1346  }
1347  else //is I a particle
1348  {
1349  newInteractionList_[i].push_back(interaction);
1350  }
1351  }
1352  else //newBoundaryParticle is I in the interaction, P can only be a particle
1353  {
1354  newInteractionList_[i].push_back(interaction);
1355  }
1356  }
1357  }
1358 
1359  //Store the number of interactions
1361  }
1362 }
float * p
Definition: Tutorial_Map_using.cpp:9
const std::vector< BaseInteraction * > & getInteractions() const
Returns a list of interactions which belong to this interactable.
Definition: BaseInteractable.h:256

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

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
1250 {
1251  //Skip the ghost particles
1252  if (checkIfAddNewParticle(particle))
1253  {
1254  //If the particle was not yet flagged to be in the periodic domain, check if it is in the domain
1255  //if(!particle->isInPeriodicDomain())
1256  {
1257  int totalPeriodicComplexity;
1258  std::vector<int> periodicComplexity;
1259  computePeriodicComplexity(periodicComplexity, totalPeriodicComplexity, particle->getPosition());
1260 
1261  //Modify periodic complexity tailored to specific boundary requirements
1262  for (int b = 0; b < getSize(); b++)
1263  {
1264  objects_[b]->modifyPeriodicComplexity(periodicComplexity, totalPeriodicComplexity, particle, b);
1265  }
1266 
1267  //Set periodicComplexity
1268  particle->setPeriodicComplexity(periodicComplexity);
1269 
1270  //Create ghost particle ID's
1271  std::vector<std::vector<int> > list(0);
1272  if (totalPeriodicComplexity > 0)
1273  {
1274  periodicComplexity = particle->getPeriodicComplexity();
1275 
1276  //Generating all possible complexities.
1277  generateGhosts(list, periodicComplexity, periodicComplexity, getSize());
1278  //logger(VERBOSE,"New ghost particles: %",list.size() - 1);
1279 
1280  //Note: the first one in the list is the real particle such that we skip it
1281  for (int i = 1; i < list.size(); i++)
1282  {
1283  //Compute target domain
1284  //logger(VERBOSE,"Particle position: %",particle->getPosition());
1285  int targetProcessor = findTargetProcessor(list[i]);
1286 
1287  //Create periodic particle ID
1289  ppid->particle = particle;
1290  ppid->periodicComplexity = periodicComplexity;
1291  ppid->targetPeriodicComplexity = list[i];
1292  ppid->targetProcessor = targetProcessor;
1293  newPeriodicParticleList_[targetProcessor].push_back(ppid);
1294  logger(VERBOSE, "Adding a periodic particle with id % and real particle position: %",
1295  particle->getId(), particle->getPosition());
1296  }
1297  }
1298  }
1299  }
1300 }
@ VERBOSE
MpiPeriodicParticleIDBase MpiPeriodicParticleID
Definition: MpiDataClass.h:145
Scalar * b
Definition: benchVecAdd.cpp:17
const Vec3D & getPosition() const
Returns the position of this BaseInteractable.
Definition: BaseInteractable.h:197
unsigned int getId() const
Returns the unique identifier of any particular object.
Definition: BaseObject.h:104
void setPeriodicComplexity(std::vector< int > complexity)
Set the periodic communication complexity of the particle.
Definition: BaseParticle.cc:189
const std::vector< int > & getPeriodicComplexity()
Obtains the periodic communication complexity of the particle.
Definition: BaseParticle.cc:214
std::vector< int > periodicComplexity
Definition: MpiDataClass.h:138
int targetProcessor
Definition: MpiDataClass.h:133
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:443
bool checkIfAddNewParticle(BaseParticle *particle)
Definition: PeriodicBoundaryHandler.cc:1863
int findTargetProcessor(const std::vector< int > &complexity)
For a given complexity this function returns the target processor.
Definition: PeriodicBoundaryHandler.cc:1228

References b, checkIfAddNewParticle(), computePeriodicComplexity(), findTargetProcessor(), generateGhosts(), BaseObject::getId(), BaseParticle::getPeriodicComplexity(), BaseInteractable::getPosition(), BaseHandler< BasePeriodicBoundary >::getSize(), 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

1307 {
1308  //Check for all particles if there are unassigned periodic particles
1309  for (auto particle_it = getDPMBase()->particleHandler.begin();
1310  particle_it != getDPMBase()->particleHandler.end(); particle_it++)
1311  {
1312  findNewParticle(*particle_it);
1313  }
1314 
1315 }

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
1229 {
1230  //Find the middle of this domain (or any valid point anyway)
1231  Vec3D middlePosition = getDPMBase()->domainHandler.getCurrentDomain()->getMiddle();
1232 
1233  //Create the particle with a target position
1234  SphericalParticle particle;
1235  particle.setPosition(middlePosition);
1236  shiftParticle(&particle, complexity);
1237 
1238  //Obtain target domain
1239  int targetGlobalIndex = getDPMBase()->domainHandler.getParticleDomainGlobalIndex(&particle);
1240  return getDPMBase()->domainHandler.getParticleProcessor(targetGlobalIndex);
1241 }
virtual void setPosition(const Vec3D &position)
Sets the position of this BaseInteractable.
Definition: BaseInteractable.h:218
DomainHandler domainHandler
An object of the class DomainHandler which deals with parallel code.
Definition: DPMBase.h:1468
int getParticleDomainGlobalIndex(BaseParticle *particle)
Definition: DomainHandler.cc:308
Domain * getCurrentDomain()
Gets the domain assigned to the processor.
Definition: DomainHandler.cc:228
int getParticleProcessor(int globalIndex)
Definition: DomainHandler.cc:387
Vec3D getMiddle() const
Gives the middle of the domain.
Definition: Domain.cc:1712
void shiftParticle(BaseParticle *particle)
Shifts the position of the particle based on its current periodic complexity.
Definition: PeriodicBoundaryHandler.cc:148
A spherical particle is the most simple particle used in MercuryDPM.
Definition: SphericalParticle.h:16
Definition: Kernel/Math/Vector.h:30

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.
1684 {
1689  std::set<MpiPeriodicParticleIDBase*> toBeDeleted;
1690  for (auto p_it : particlesToBeFlushed)
1691  {
1692  for (int i = 0; i < NUMBER_OF_PROCESSORS; i++)
1693  {
1694  for (auto& p : periodicParticleList_[i])
1695  {
1696  if (p != nullptr)
1697  {
1698  if (p_it == p->particle)
1699  {
1700  toBeDeleted.insert(p);
1701  p = nullptr;
1702  }
1703  }
1704  }
1705  }
1706 
1707  for (int i = 0; i < NUMBER_OF_PROCESSORS; i++)
1708  {
1709  for (auto& p : periodicGhostList_[i])
1710  {
1711  if (p != nullptr)
1712  {
1713  if (p_it == p->particle)
1714  {
1715  toBeDeleted.insert(p);
1716  p = nullptr;
1717  }
1718  }
1719  }
1720  }
1721  }
1722 
1723  //Delete ID's
1724  for (auto id_it : toBeDeleted)
1725  {
1726  delete id_it;
1727  }
1728 
1729 }

References i, NUMBER_OF_PROCESSORS, p, 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
445 {
446  //Add the complexity to the list
447  if (level == 0)
448  {
449  //logger(VERBOSE,"complexity: [%, %, %]",complexity[0], complexity[1], complexity[2]);
450  list.push_back(complexity);
451  }
452  else
453  {
454  //Vary complexity values of level
455  if (periodicComplexity[level - 1] == 1)
456  {
457  complexity[level - 1] = 1;
458  generateGhosts(list, periodicComplexity, complexity, level - 1);
459 
460  complexity[level - 1] = -1;
461  generateGhosts(list, periodicComplexity, complexity, level - 1);
462  }
463  else
464  {
465  generateGhosts(list, periodicComplexity, complexity, level - 1);
466  }
467  }
468 }

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.
116 {
117  return interactionDistance_;
118 }

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)
380 {
381  //Check if the particle is actually in this domain. If not the case it is an "MG"-particle
383  if (domain->containsParticle(particle))
384  {
385  //If the particle is in the inner domain, it is not in the mpi doamin
386  if (domain->isInInnerDomain(particle))
387  {
388  isInMPIDomain = false;
389  isMPIParticle = false;
390  }
391  else
392  {
393  isInMPIDomain = true;
394  isMPIParticle = false;
395  }
396  }
397  else
398  {
399  //If the particle is outside the communication zone it is not in the mpi domain
400  if (domain->isInGreaterDomain(particle))
401  {
402  isInMPIDomain = true;
403  isMPIParticle = true;
404  }
405  else
406  {
407  isInMPIDomain = false;
408  isMPIParticle = true;
409  }
410  }
411 }
The simulation can be subdivided into Domain's used in parallel code.
Definition: Domain.h:42
SteadyAxisymAdvectionDiffusion problem on rectangular domain
Definition: steady_axisym_advection_diffusion.cc:151

References domain, DPMBase::domainHandler, DomainHandler::getCurrentDomain(), and BaseHandler< BasePeriodicBoundary >::getDPMBase().

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 >.

96 {
97  return "PeriodicBoundaryHandler";
98 }

◆ 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
336 {
337  unsigned int sum = 0;
338  for (auto& index : periodicGhostList_)
339  {
340  sum += index.size();
341  }
342  return sum;
343 }

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
352 {
353  int sum = 0;
354  for (auto& index : periodicGhostList_)
355  {
356  int numberOfMPIParticles = 0;
357  for (int pIndex = 0; pIndex < index.size(); pIndex++)
358  {
359  if (index[pIndex]->particle->isMPIParticle() == true)
360  {
361  numberOfMPIParticles++;
362  }
363  }
364  sum += (index.size() - numberOfMPIParticles);
365  }
366  return sum;
367 }

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.

1766 {
1767  newPeriodicParticleList_ = std::vector<PeriodicList>(NUMBER_OF_PROCESSORS, PeriodicList(0));
1768  periodicParticleList_ = std::vector<PeriodicList>(NUMBER_OF_PROCESSORS, PeriodicList(0));
1769  periodicGhostList_ = std::vector<PeriodicGhostList>(NUMBER_OF_PROCESSORS, PeriodicGhostList(0));
1770 }
std::vector< MpiPeriodicParticleID * > PeriodicList
Definition: PeriodicBoundaryHandler.h:14
std::vector< MpiPeriodicGhostParticleID * > PeriodicGhostList
Definition: PeriodicBoundaryHandler.h:15

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.

45 {
46  if (this != &rhs)
47  {
48  objects_.clear();
50  }
51  logger(DEBUG, "PeriodicBoundaryHandler PeriodicBoundaryHandler::operator =(const BoundaryHandler& rhs)");
52  return *this;
53 }

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

◆ performActionsBeforeAddingParticles()

void PeriodicBoundaryHandler::performActionsBeforeAddingParticles ( )

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

1773 {
1774  for (BasePeriodicBoundary* boundary : *this)
1775  {
1777  }
1778 }
virtual void performActionsBeforeAddingParticles()
Actions that need to be performed before adding new ghost particles.
Definition: BasePeriodicBoundary.cc:117

References BasePeriodicBoundary::performActionsBeforeAddingParticles().

Referenced by addNewParticles().

◆ performNewParticleTransmission()

void PeriodicBoundaryHandler::performNewParticleTransmission ( )

Collects and sends the ghost particle data.

1484 {
1485  MPIContainer& communicator = MPIContainer::Instance();
1486  int numberOfTargetsReceive = receiveTargetList_.size();
1487  int numberOfTargetsSend = sendTargetList_.size();
1488 
1489  //Make sure that the receiving vectors have the correct length
1490  periodicGhostParticleReceive_.resize(numberOfTargetsReceive);
1491  periodicGhostComplexityReceive_.resize(numberOfTargetsReceive);
1492  interactionDataReceive_.resize(numberOfTargetsReceive);
1494  for (int i = 0; i < numberOfTargetsReceive; i++)
1495  {
1499  }
1500 
1501  //Collect data for sending
1504 
1505  //Send particle and interaction data
1506  for (int i = 0; i < numberOfTargetsSend; i++)
1507  {
1508  if (sendTargetList_[i] != PROCESSOR_ID)
1509  {
1510  //Send particle data
1511  int sendCount = numberOfNewPeriodicGhostParticlesSend_[i];
1512  int processor = sendTargetList_[i];
1514  communicator.send(periodicGhostParticleSend_[i].data(), MercuryMPIType::PARTICLE, sendCount, processor,
1515  tagSend);
1516 
1517  //Send complexity
1520  communicator.send(periodicGhostComplexitySend_[i].data(), sendCount, processor, tagSend);
1521 
1522  //Send interactions
1524  sendCount = numberOfNewInteractionsSend_[i];
1525  if (sendCount > 0)
1526  {
1527  communicator.send(interactionDataSend_[i], MercuryMPIType::INTERACTION, sendCount, processor, tagSend);
1528  }
1529  }
1530  }
1531 
1532  //Receive data
1533  for (int i = 0; i < numberOfTargetsReceive; i++)
1534  {
1536  {
1537  //Receive particle data
1538  int receiveCount = numberOfNewPeriodicGhostParticlesReceive_[i];
1539  int processor = receiveTargetList_[i];
1542  receiveCount, processor, tagReceive);
1543 
1544  //Receive complexity
1547  communicator.receive(periodicGhostComplexityReceive_[i].data(), receiveCount, processor, tagReceive);
1548 
1549  //Send interactions
1551  receiveCount = numberOfNewInteractionsReceive_[i];
1552  if (receiveCount > 0)
1553  {
1554  communicator.receive(interactionDataReceive_[i], MercuryMPIType::INTERACTION, receiveCount, processor,
1555  tagReceive);
1556  }
1557  }
1558  }
1559 
1560  //Synchronise the communications
1561  communicator.sync();
1562 }
int data[]
Definition: Map_placement_new.cpp:1
@ INTERACTION_DATA
Definition: MpiContainer.h:63
@ PARTICLE_DATA
Definition: MpiContainer.h:58
@ PERIODIC_COMPLEXITY
Definition: MpiContainer.h:64
@ INTERACTION
Definition: MpiContainer.h:46
@ PARTICLE
Definition: MpiContainer.h:46
void sync()
Process all pending asynchronous communication requests before continuing.
Definition: MpiContainer.h:131
void collectInteractionData()
Collects interaction data into an MPI data structure.
Definition: PeriodicBoundaryHandler.cc:506
void collectGhostParticleData()
Collects ghost particle data that needs to be be sent to other processors.
Definition: PeriodicBoundaryHandler.cc:475

References collectGhostParticleData(), collectInteractionData(), InteractionHandler::createMPIInteractionDataArray(), data, BaseHandler< BasePeriodicBoundary >::getDPMBase(), BaseHandler< BasePeriodicBoundary >::getSize(), 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.

1469 {
1470  //Communicate which domains send and which domains receive particles
1472 
1473  //Find new interactions
1475 
1476  //Communicate the number of particles and interactions send to the other domains
1478 
1479  //Synchronise the communications
1481 }
void communicateTargetDomains()
Creats a list of send and receive targets for periodic/ghost particles.
Definition: PeriodicBoundaryHandler.cc:1372
void communicateNumberOfNewParticlesAndInteractions()
Communicate the number of new particles and interactions to target processors.
Definition: PeriodicBoundaryHandler.cc:1426
void findNewInteractions()
Finds interactions that accompany future ghost particles.
Definition: PeriodicBoundaryHandler.cc:1321

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.

1607 {
1608  MPIContainer& communicator = MPIContainer::Instance();
1609  unsigned int numberOfProcessors = communicator.getNumberOfProcessors();
1610  unsigned int processorID = communicator.getProcessorID();
1611 
1612  //For all lists that contain periodic particles
1613  for (unsigned int i = 0; i < numberOfProcessors; i++)
1614  {
1615  unsigned int numberOfParticles = periodicParticleList_[i].size();
1616  if (numberOfParticles > 0 && i != processorID)
1617  {
1618  //Increase the vector size;
1619  updatePositionDataSend_.emplace_back(0);
1620  updateVelocityDataSend_.emplace_back(0);
1621 
1622  //Collect the data
1623  for (unsigned int p = 0; p < numberOfParticles; p++)
1624  {
1625  BaseParticle* particle = periodicParticleList_[i][p]->particle;
1626  updatePositionDataSend_.back().push_back(copyPositionFrom(particle));
1627  updateVelocityDataSend_.back().push_back(copyVelocityFrom(particle));
1628  }
1629 
1630  //Send position data
1631  unsigned int count = numberOfParticles;
1632  unsigned int processor = i;
1633  unsigned int tag = processorID * MAX_PROC + processor * 10 + MercuryMPITag::POSITION_DATA;
1634  communicator.send(updatePositionDataSend_.back().data(), MercuryMPIType::POSITION, count, processor, tag);
1635 
1636  //Send velocity data
1637  tag = processorID * MAX_PROC + processor * 10 + MercuryMPITag::VELOCITY_DATA;
1638  communicator.send(updateVelocityDataSend_.back().data(), MercuryMPIType::VELOCITY, count, processor, tag);
1639  }
1640  }
1641 
1642  //For all lists that contain ghost particles
1643  for (int i = 0; i < numberOfProcessors; i++)
1644  {
1645  unsigned int numberOfParticles = periodicGhostList_[i].size();
1646  if (numberOfParticles > 0 && i != processorID)
1647  {
1648  //Increase the vector size
1649  updatePositionDataReceive_.emplace_back(numberOfParticles);
1650  updateVelocityDataReceive_.emplace_back(numberOfParticles);
1651 
1652  //Receive position data
1653  int count = numberOfParticles;
1654  int processor = i;
1655  int tag = processor * MAX_PROC + processorID * 10 + MercuryMPITag::POSITION_DATA;
1656  communicator.receive(updatePositionDataReceive_.back().data(), MercuryMPIType::POSITION, count, processor,
1657  tag);
1658 
1659  //Receive velocity data
1660  tag = processor * MAX_PROC + processorID * 10 + MercuryMPITag::VELOCITY_DATA;
1661  communicator.receive(updateVelocityDataReceive_.back().data(), MercuryMPIType::POSITION, count, processor,
1662  tag);
1663  }
1664  }
1665 
1666  //Synchronise all the requests
1667  communicator.sync();
1668 }
@ VELOCITY_DATA
Definition: MpiContainer.h:61
@ POSITION_DATA
Definition: MpiContainer.h:59
@ VELOCITY
Definition: MpiContainer.h:46
@ POSITION
Definition: MpiContainer.h:46
MPIParticlePosition copyPositionFrom(BaseParticle *particle)
Copies the position from a particle to an MPIParticlePosition class.
Definition: MpiDataClass.cc:153
MPIParticleVelocity copyVelocityFrom(BaseParticle *particle)
Copies the velocity from a particle to an MPIParticleVelocity class.
Definition: MpiDataClass.cc:169
std::size_t getNumberOfProcessors() const
Get the total number of processors participating in this simulation.
Definition: MpiContainer.cc:83
std::size_t getProcessorID()
Reduces a scalar on all processors to one scalar on a target processor.
Definition: MpiContainer.cc:92

References copyPositionFrom(), copyVelocityFrom(), MPIContainer::getNumberOfProcessors(), MPIContainer::getProcessorID(), i, MPIContainer::Instance(), MAX_PROC, p, 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.

784 {
785  for (int i = 0; i < sendTargetList_.size(); i++)
786  {
787  //Check if the processor is sending ghosts to itself
789  {
790  for (int j = 0; j < numberOfNewPeriodicGhostParticlesSend_[i]; j++)
791  {
793  BaseParticle* particle = ppid->particle;
794 
795  //Create ghost particle
796  BaseParticle* pGhost = particle->copy();
797 
798  //Obtain and set the ghost periodic complexity
800 
801  //Shift the particle
802  shiftParticle(pGhost);
803 
804  //Set the correct flags
805  pGhost->setPeriodicGhostParticle(true);
806  pGhost->setInPeriodicDomain(true);
807  //Note: mpi flags dont have to be set for local particles
808  //these flags are copied from the original particle
809  logger(VERBOSE, "Adding a ghost with id % at position %", pGhost->getId(), pGhost->getPosition());
810 
811  //Finally add it to the particle handler
813 
814  //Do some bookkeeping
816  gpid->particle = pGhost;
817  gpid->otherParticle = particle;
818  gpid->realPeriodicComplexity = particle->getPeriodicComplexity();
819  periodicGhostList_[PROCESSOR_ID].push_back(gpid);
820 
821  //Flag real particle and do some bookkeeping
822  particle->setInPeriodicDomain(true);
823  ppid->otherParticle = pGhost;
824 
825  //Add to the new particle list for an interaction update
826  newParticles.push_back(pGhost);
827  }
828  }
829  }
830 }
MpiPeriodicParticleIDBase MpiPeriodicGhostParticleID
Definition: MpiDataClass.h:146
void setInPeriodicDomain(bool flag)
Flags the status of the particle whether it is in the periodic communication zone or not.
Definition: BaseParticle.cc:275
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:285
std::vector< int > realPeriodicComplexity
Definition: MpiDataClass.h:140
BaseParticle * otherParticle
Definition: MpiDataClass.h:130
void addGhostObject(int fromProcessor, int toProcessor, BaseParticle *p)
Adds a ghost particle located at fromProcessor to toProcessor.
Definition: ParticleHandler.cc:275

References ParticleHandler::addGhostObject(), BaseParticle::copy(), BaseHandler< BasePeriodicBoundary >::getDPMBase(), BaseObject::getId(), BaseParticle::getPeriodicComplexity(), BaseInteractable::getPosition(), i, j, 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
671 {
673  for (int i = 0; i < sendTargetList_.size(); i++)
674  {
676  {
677  for (int l = 0; l < numberOfNewInteractionsSend_[i]; l++)
678  {
679  unsigned int identificationP;
680  unsigned int identificationI;
681  bool isWallInteraction;
682  unsigned timeStamp;
683 
684  //Get the general information required to setup a new interaction
685  iH.getInteractionDetails(interactionDataSend_[i], l, identificationP, identificationI,
686  isWallInteraction, timeStamp);
687 
688  //Obtain the particle pointer of the ghost
689  BaseParticle* pGhost;
690  int idOther;
691  //Check if the particle is P
692  for (BaseParticle* particle : newParticles)
693  {
694  if (particle->getId() == identificationP)
695  {
696  pGhost = particle;
697  idOther = identificationI;
698  break;
699  }
700 
701  if (particle->getId() == identificationI)
702  {
703  pGhost = particle;
704  idOther = identificationP;
705  break;
706  }
707  }
708 
709  //If it is a wall interaction, do stuff
710  if (isWallInteraction)
711  {
712  BaseWall* I = getDPMBase()->wallHandler.getObjectById(identificationI);
713  //Create interactions
714  BaseInteraction* j = I->getInteractionWith(pGhost, timeStamp, &iH);
715  if (j!= nullptr) j->setMPIInteraction(interactionDataSend_[i], l, false);
716  logger(VERBOSE, "Wall interaction added!");
717  }
718  else
719  {
720  //Obtain potential interaction particles
721  std::vector<BaseParticle*> interactingParticleList;
722  getDPMBase()->hGridGetInteractingParticleList(pGhost, interactingParticleList);
723 
724  if (interactingParticleList.empty())
725  {
726  logger(VERBOSE, "Failed in creating an interaction :(");
727  }
728 
729  //Find the other interacting particle
730  BaseParticle* otherParticle = nullptr;
731  for (BaseParticle* p2 : interactingParticleList)
732  {
733  if (p2->getId() == idOther)
734  {
735  otherParticle = p2;
736  break;
737  }
738  }
739  if (otherParticle == nullptr)
740  {
741  //The interacting object can't be found
742  continue;
743  }
744 
745  //Add the interaction
746  BaseInteraction* j = pGhost->getInteractionWith(otherParticle, timeStamp, &iH);
747  if (j!= nullptr) j->setMPIInteraction(interactionDataSend_[i], l, false);
748  }
749  }
750  }
751  }
752 }
T * getObjectById(const unsigned int id)
Gets a pointer to the Object at the specified index in the BaseHandler.
Definition: BaseHandler.h:573
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:667
Basic class for walls.
Definition: BaseWall.h:28
virtual void hGridGetInteractingParticleList(BaseParticle *obj, std::vector< BaseParticle * > &list)
Creates a list of neighbour particles obtained from the hgrid.
Definition: DPMBase.h:989
WallHandler wallHandler
An object of the class WallHandler. Contains pointers to all the walls created.
Definition: DPMBase.h:1453
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:225
#define I
Definition: main.h:127

References BaseHandler< BasePeriodicBoundary >::getDPMBase(), InteractionHandler::getInteractionDetails(), BaseParticle::getInteractionWith(), BaseHandler< T >::getObjectById(), DPMBase::hGridGetInteractingParticleList(), i, I, interactionDataSend_, DPMBase::interactionHandler, j, logger, numberOfNewInteractionsSend_, PROCESSOR_ID, sendTargetList_, 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.

761 {
762  for (int i : sendTargetList_)
763  {
764  for (int j = 0; j < newPeriodicParticleList_[i].size(); j++)
765  {
766  //Update the particle status
768  ppid->particle->setInPeriodicDomain(true);
769 
770  //make new entry in the list
771  periodicParticleList_[i].push_back(ppid);
772  }
773  }
774 }

References i, j, 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.
539 {
540  for (int j = 0; j < numberOfNewPeriodicGhostParticlesReceive_[targetIndex]; j++)
541  {
542  //Create the ghost particle and copy basic information
545  particle, &(getDPMBase()->particleHandler));
546 
547  //Obtain real periodic complexity
548  std::vector<int> realPeriodicComplexity = computePeriodicComplexity(particle->getPosition());
549 
550  //Obtain and set the ghost periodic complexity
551  std::vector<int> ghostPeriodicComplexity(getSize());
552  for (int k = 0; k < getSize(); k++)
553  {
554  ghostPeriodicComplexity[k] = periodicGhostComplexityReceive_[targetIndex][getSize() * j + k];
555  }
556  particle->setPeriodicComplexity(ghostPeriodicComplexity);
557 
558  //Shift the ghost particle to it's correct positions and velocities
559  shiftParticle(particle, ghostPeriodicComplexity);
560 
561  //Add particle to simulation
562  logger(VERBOSE, "Adding a ghost at position %", particle->getPosition());
564 
565  //Set the correct flags
567  pGhost->setPeriodicGhostParticle(true);
568  pGhost->setInPeriodicDomain(true);
569  //Give the correct mpi flags
570  setMPIFlags(pGhost);
571 
572  //Create the periodic ID
574  gpid->realPeriodicComplexity = realPeriodicComplexity;
575  gpid->particle = pGhost;
576  periodicGhostList_[receiveTargetList_[targetIndex]].push_back(gpid);
577 
578  //Add to the newParticle list used for possible interactions
579  newParticles.push_back(pGhost);
580  }
581 }
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:84
T * getLastObject()
Gets a pointer to the last Object in this BaseHandler.
Definition: BaseHandler.h:642
static BaseParticle * newParticle()
Definition: MpiDataClass.cc:136
void setMPIFlags(BaseParticle *particle)
Sets the MPIParticle and isMPIParticle flags of a given particle.
Definition: PeriodicBoundaryHandler.cc:421

References ParticleHandler::addGhostObject(), computePeriodicComplexity(), copyDataFromMPIParticleToParticle(), BaseHandler< BasePeriodicBoundary >::getDPMBase(), BaseHandler< T >::getLastObject(), BaseInteractable::getPosition(), BaseHandler< BasePeriodicBoundary >::getSize(), j, k, 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
594 {
596  for (int l = 0; l < numberOfNewInteractionsReceive_[targetIndex]; l++)
597  {
598  unsigned int identificationP;
599  unsigned int identificationI;
600  bool isWallInteraction;
601  unsigned timeStamp;
602 
603  //Get the general information required to setup a new interaction
604  iH.getInteractionDetails(interactionDataReceive_[targetIndex], l, identificationP, identificationI,
605  isWallInteraction, timeStamp);
606 
607  //Obtain the particle pointer of the ghost
608  BaseParticle* pGhost;
609  int idOther;
610  //Check if the particle is P
611  for (BaseParticle* particle : newParticles)
612  {
613  if (particle->getId() == identificationP)
614  {
615  pGhost = particle;
616  idOther = identificationI;
617  break;
618  }
619 
620  if (particle->getId() == identificationI)
621  {
622  pGhost = particle;
623  idOther = identificationP;
624  break;
625  }
626  }
627 
628  //If it is a wall interaction, do stuff
629  if (isWallInteraction)
630  {
631  BaseInteractable* I = getDPMBase()->wallHandler.getObjectById(identificationI);
632  //Create interactions
633  BaseInteraction* i = I->getInteractionWith(pGhost, timeStamp, &iH);
634  if (i!= nullptr) i->setMPIInteraction(interactionDataReceive_[targetIndex], l, false);
635  }
636  else
637  {
638  //Obtain potential interaction particles
639  std::vector<BaseParticle*> interactingParticleList;
640  getDPMBase()->hGridGetInteractingParticleList(pGhost, interactingParticleList);
641 
642  //Find the other interacting particle
643  BaseParticle* otherParticle;
644  for (BaseParticle* p2 : interactingParticleList)
645  {
646  if (p2->getId() == idOther)
647  {
648  otherParticle = p2;
649  break;
650  }
651  }
652 
653  //Add the interaction
654  BaseInteraction* i = pGhost->getInteractionWith(otherParticle, timeStamp, &iH);
655  if (i!= nullptr) i->setMPIInteraction(interactionDataReceive_[targetIndex], l, false);
656  }
657  }
658 }
Defines the basic properties that a interactable object can have.
Definition: BaseInteractable.h:34

References BaseHandler< BasePeriodicBoundary >::getDPMBase(), InteractionHandler::getInteractionDetails(), BaseParticle::getInteractionWith(), BaseHandler< T >::getObjectById(), DPMBase::hGridGetInteractingParticleList(), i, 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 >.

88 {
89 }

◆ 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.
107 {
108  interactionDistance_ = interactionDistance;
109 }

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
422 {
423  bool isInMPIDomain;
424  bool isMPIParticle;
425  getMPIFlags(particle, isInMPIDomain, isMPIParticle);
426  particle->setInMPIDomain(isInMPIDomain);
427  particle->setMPIParticle(isMPIParticle);
428 }
void setInMPIDomain(bool flag)
Flags the status of the particle if wether it is in the communication zone or not.
Definition: BaseParticle.cc:264
void setMPIParticle(bool flag)
Flags the mpi particle status.
Definition: BaseParticle.cc:174
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:379

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.

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)
149 {
150  shiftParticle(particle, particle->getPeriodicComplexity());
151 }

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.

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
162 {
163  int boundaryIndex = 0;
164  for (BasePeriodicBoundary* boundary : *this)
165  {
166  if (complexity[boundaryIndex] == -1)
167  {
168  boundary->shiftPosition(particle);
169  }
170  boundaryIndex++;
171  }
172 }
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
1843 {
1844  if (particle->isMaserParticle())
1845  {
1846  for (int b = 0; b < getSize(); b++)
1847  {
1848  if (particle->getPeriodicComplexity(b) == 3)
1849  {
1850  particle->setMaserParticle(false);
1851 
1852  logger(VERBOSE, "particle % with position % goes into outflow domain, new ID = %", particle->getId(),
1853  particle->getPosition(), getDPMBase()->particleHandler.getNextId());
1854  const unsigned int newID = getDPMBase()->particleHandler.getNextId();
1855  logger(VERBOSE, "new id % position X %", newID, particle->getPosition().X);
1856  particle->setId(newID);
1858  }
1859  }
1860  }
1861 }
unsigned int getNextId()
Definition: BaseHandler.h:237
void increaseId()
Definition: BaseHandler.h:232
void setId(unsigned long id)
Assigns a unique identifier to each object in the handler (container) which remains constant even aft...
Definition: BaseObject.cc:50
bool isMaserParticle() const
Indicates if this particle belongs to the maser boundary.
Definition: BaseParticle.cc:290
void setMaserParticle(bool flag)
Flags the status of the particle if it belongs to the maser boundary or not.
Definition: BaseParticle.cc:295
Mdouble X
the vector components
Definition: Kernel/Math/Vector.h:45

References b, 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

839 {
840  //For all lists that contain ghost particles
841  //The variable dataIndex indicates which index in update<...>Receive_ the data is located
842  int dataIndex = -1;
843  for (int i = 0; i < NUMBER_OF_PROCESSORS; i++)
844  {
845  unsigned long numberOfParticles = periodicGhostList_[i].size();
846  bool global;
847  if (numberOfParticles > 0)
848  {
849  //Check if the update is global or from the current processor
850  if (i != PROCESSOR_ID)
851  {
852  global = true;
853  dataIndex++;
854  }
855  else
856  {
857  global = false;
858  }
859 
860  //Update all particles
861  for (int p = 0; p < numberOfParticles; p++)
862  {
864  BaseParticle* pGhost = pgid->particle;
865 
866  //Depending on where the particle is located the data is stored in a different place
867  if (global)
868  {
869  //logger(VERBOSE,"i: %, numberOfParticles: %, dataIndex: %",i,numberOfParticles, dataIndex);
870  //Check if this particle really belongs to the data that is send
871  logger.assert_debug(pGhost->getId() == updatePositionDataReceive_[dataIndex][p].id,
872  "Periodic particle lists are not in syc");
873 
874  //Add the real position and velocity of the particles
875  //Note: The before updating the position is the position of the ghost
876  //Note: The received position and velocity values are of the real particle
877  //Note: It will be shifted to the correct values after the complexity is computed
878  pGhost->setPreviousPosition(pGhost->getPosition());
879  pGhost->setPosition(updatePositionDataReceive_[dataIndex][p].position);
880  pGhost->setOrientation(updatePositionDataReceive_[dataIndex][p].orientation);
881  pGhost->setVelocity(updateVelocityDataReceive_[dataIndex][p].velocity);
882  pGhost->setAngularVelocity(updateVelocityDataReceive_[dataIndex][p].angularVelocity);
883 
884  }
885  else
886  {
887  //MpiPeriodicGhostParticleID * pgip = periodicGhostList_[i][p];
888  pGhost->setPreviousPosition(pGhost->getPosition());
889  pGhost->setPosition(pgid->otherParticle->getPosition());
890  pGhost->setOrientation(pgid->otherParticle->getOrientation());
891  pGhost->setVelocity(pgid->otherParticle->getVelocity());
893  }
894 
895  //Move current periodic complexity to previous periodic complexity
897 
898  //Compute the new realPeriodicComplexity
899  std::vector<int> previousRealPeriodicComplexity = periodicGhostList_[i][p]->realPeriodicComplexity;
900  //The ghost particle has the real position at the moment, so compute the real periodic complexity here
901  std::vector<int> realPeriodicComplexity = computePeriodicComplexity(pGhost->getPosition());
902  std::vector<int> periodicComplexity(getSize());
903  for (int b = 0; b < getSize(); b++)
904  {
905  int sign = mathsFunc::sign(previousRealPeriodicComplexity[b]
906  * realPeriodicComplexity[b]
907  * pGhost->getPreviousPeriodicComplexity()[b]);
908  periodicComplexity[b] = sign * abs(realPeriodicComplexity[b]);
909  //The maser boundary needs this correction
910  if (periodicComplexity[b] == -3)
911  {
912  periodicComplexity[b] = 1;
913  }
914 
915  }
916  pGhost->setPeriodicComplexity(periodicComplexity);
917 
918  for (int b = 0; b < getSize(); b++)
919  {
920  objects_[b]->modifyGhostAfterCreation(pGhost, b);
921  }
922  //Shift the particle to correct position
923  //Note: If the real particle changed complexity this position will be calculated incorrectly
924  //Hence the previous complexity is used.
925  shiftParticle(pGhost, pGhost->getPreviousPeriodicComplexity());
926 
927  //Update hGrid
928  Vec3D displacement = pGhost->getPreviousPosition() - pGhost->getPosition();
929  getDPMBase()->hGridUpdateMove(pGhost, displacement.getLengthSquared());
930 
931  //Do some book keeping
932  periodicGhostList_[i][p]->realPeriodicComplexity = realPeriodicComplexity;
933 
934  }
935  }
936  }
937 
938  //Update periodic complexity of periodic particles
939  for (BaseParticle* particle : getDPMBase()->particleHandler)
940  {
941  if ((particle->isInPeriodicDomain()) && !(particle->isPeriodicGhostParticle()))
942  {
943  //Update the periodicComplexity of the real particles
944  particle->setPreviousPeriodicComplexity(particle->getPeriodicComplexity());
945  std::vector<int> periodicComplexity;
946  int totalPeriodicComplexity;
947  computePeriodicComplexity(periodicComplexity, totalPeriodicComplexity, particle->getPosition());
948  //Modify periodic complexity tailored to specific boundary requirements
949  for (int b = 0; b < getSize(); b++)
950  {
951  objects_[b]->modifyPeriodicComplexity(periodicComplexity, totalPeriodicComplexity, particle, b);
952  }
953  particle->setPeriodicComplexity(periodicComplexity);
954  }
955  }
956 }
const Quaternion & getOrientation() const
Returns the orientation of this BaseInteractable.
Definition: BaseInteractable.h:209
virtual const Vec3D & getAngularVelocity() const
Returns the angular velocity of this interactable.
Definition: BaseInteractable.cc:319
virtual void setOrientation(const Quaternion &orientation)
Sets the orientation of this BaseInteractable.
Definition: BaseInteractable.h:239
void setAngularVelocity(const Vec3D &angularVelocity)
set the angular velocity of the BaseInteractble.
Definition: BaseInteractable.cc:338
virtual const Vec3D & getVelocity() const
Returns the velocity of this interactable.
Definition: BaseInteractable.cc:307
void setVelocity(const Vec3D &velocity)
set the velocity of the BaseInteractable.
Definition: BaseInteractable.cc:328
void setPreviousPosition(const Vec3D &pos)
Sets the particle's position in the previous time step.
Definition: BaseParticle.cc:600
const std::vector< int > & getPreviousPeriodicComplexity() const
Sets the previous periodic communication complexity of the particle.
Definition: BaseParticle.cc:254
void setPreviousPeriodicComplexity(std::vector< int > complexity)
Set the previous periodic communication complexity of the paritcle.
Definition: BaseParticle.cc:249
const Vec3D & getPreviousPosition() const
Returns the particle's position in the previous time step.
Definition: BaseParticle.h:378
virtual void hGridUpdateMove(BaseParticle *, Mdouble)
Definition: DPMBase.cc:1922
static Mdouble getLengthSquared(const Vec3D &a)
Calculates the squared length of a Vec3D: .
Definition: Kernel/Math/Vector.h:324
double velocity(const double &t)
Angular velocity as function of time t.
Definition: jeffery_orbit.cc:107
T sign(T x)
Definition: cxx11_tensor_builtins_sycl.cpp:172

References abs(), b, 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(), i, logger, NUMBER_OF_PROCESSORS, BaseHandler< BasePeriodicBoundary >::objects_, MpiPeriodicParticleIDBase::otherParticle, p, MpiPeriodicParticleIDBase::particle, periodicGhostList_, PROCESSOR_ID, BaseInteractable::setAngularVelocity(), BaseInteractable::setOrientation(), BaseParticle::setPeriodicComplexity(), BaseInteractable::setPosition(), BaseParticle::setPreviousPeriodicComplexity(), BaseParticle::setPreviousPosition(), BaseInteractable::setVelocity(), shiftParticle(), mathsFunc::sign(), SYCL::sign(), updatePositionDataReceive_, updateVelocityDataReceive_, and Jeffery_Solution::velocity().

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

References b, 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(), i, MPIContainer::Instance(), BaseParticle::isInMPIDomain(), BaseParticle::isMPIParticle(), logger, BaseHandler< BasePeriodicBoundary >::objects_, p, MpiPeriodicParticleIDBase::particle, DPMBase::particleHandler, pc, 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.

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
130 {
131  //Step 1: collect position and velocity data of the real particle and send the data
133 
134  //Step 2: finalise the data transision
136 
137  //Step 3: Update the status of the ghost and real particles
138  updateParticleStatus(particlesToBeDeleted);
139 }
void preparePositionAndVelocityUpdate()
Collects the position and velocity data from periodic boundaries.
Definition: PeriodicBoundaryHandler.cc:1606
void updateParticleStatus(std::set< BaseParticle * > &particlesToBeDeleted)
Updates the status of periodic particles and ghost particles.
Definition: PeriodicBoundaryHandler.cc:1014
void finalisePositionAndVelocityUpdate()
Communicates position and velocity data from periodic boundaries and updates ghost particles.
Definition: PeriodicBoundaryHandler.cc:1670

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: