ParticleHandler Class Reference

Container to store all BaseParticle. More...

#include <ParticleHandler.h>

+ Inheritance diagram for ParticleHandler:

Public Member Functions

 ParticleHandler ()
 Default constructor, it creates an empty ParticleHandler. More...
 
 ParticleHandler (const ParticleHandler &PH)
 Constructor that copies all BaseParticle it contains and then sets the smallest and largest particle. More...
 
ParticleHandleroperator= (const ParticleHandler &rhs)
 Assignment operator. More...
 
 ~ParticleHandler () override
 Destructor, it destructs the ParticleHandler and all BaseParticle it contains. More...
 
void addExistingObject (BaseParticle *P) override
 Adds a BaseParticle to the ParticleHandler. More...
 
void addObject (BaseParticle *P) override
 Adds a BaseParticle to the ParticleHandler. More...
 
void addObject (int fromProcessor, BaseParticle *P)
 Adds a BaseParticle located at processor fromProcessor to toProcessor. More...
 
void addGhostObject (int fromProcessor, int toProcessor, BaseParticle *p)
 Adds a ghost particle located at fromProcessor to toProcessor. More...
 
void addGhostObject (BaseParticle *P) override
 Adds a BaseParticle to the ParticleHandler. More...
 
void removeObject (unsigned int index) override
 Removes a BaseParticle from the ParticleHandler. More...
 
void removeGhostObject (unsigned int index)
 Removes a BaseParticle from the ParticleHandler without a global check, this is only to be done for mpi routines. More...
 
void removeLastObject ()
 Removes the last BaseParticle from the ParticleHandler. More...
 
void computeSmallestParticle ()
 Computes the smallest particle (by interaction radius) and sets it in smallestParticle_. More...
 
void computeLargestParticle ()
 Computes the largest particle (by interaction radius) and sets it in largestParticle_. More...
 
BaseParticlegetSmallestParticleLocal () const
 Gets a pointer to the smallest BaseParticle (by interactionRadius) in this ParticleHandler of the local domain. More...
 
BaseParticlegetSmallestParticle () const
 Gets a pointer to the smallest BaseParticle (by interactionRadius) in this ParticleHandler of the local domain. When mercury is running in parallel this function throws an error since a pointer to another domain is useless. More...
 
BaseParticlegetLargestParticleLocal () const
 Gets a pointer to the largest BaseParticle (by interactionRadius) in the ParticleHandler of the local domain. More...
 
BaseParticlegetLargestParticle () const
 Returns the pointer of the largest particle in the particle handler. When mercury is running in parallel this function throws an error since a pointer to another domain is useless. More...
 
Mdouble getSmallestInteractionRadiusLocal () const
 Returns the smallest interaction radius of the current domain. More...
 
Mdouble getSmallestInteractionRadius () const
 Returns the smallest interaction radius. More...
 
Mdouble getLargestInteractionRadiusLocal () const
 Returns the largest interaction radius of the current domain. More...
 
Mdouble getLargestInteractionRadius () const
 Returns the largest interaction radius. More...
 
BaseParticlegetFastestParticleLocal () const
 Gets a pointer to the fastest BaseParticle in this ParticleHandler. More...
 
BaseParticlegetFastestParticle () const
 
Mdouble getKineticEnergy () const
 
Mdouble getRotationalEnergy () const
 
Mdouble getMass () const
 
Vec3D getMassTimesPosition () const
 
Vec3D getCentreOfMass () const
 
Vec3D getMomentum () const
 
Vec3D getAngularMomentum () const
 
Mdouble getVolume () const
 
Mdouble getMeanRadius () const
 
BaseParticlegetLowestPositionComponentParticleLocal (int i) const
 Gets a pointer to the particle with the lowest coordinates in direction i in this ParticleHandler. More...
 
BaseParticlegetLowestPositionComponentParticle (int i) const
 Gets a pointer to the particle with the lowest coordinates in direction i in this ParticleHandler. More...
 
BaseParticlegetHighestPositionComponentParticleLocal (int i) const
 Gets a pointer to the particle with the highest coordinates in direction i in this ParticleHandler. More...
 
BaseParticlegetHighestPositionComponentParticle (int i) const
 Gets a pointer to the particle with the highest coordinates in direction i in this ParticleHandler. More...
 
BaseParticlegetLowestVelocityComponentParticleLocal (int i) const
 Gets a pointer to the particle with the lowest velocity in direction i in this ParticleHandler. More...
 
BaseParticlegetLowestVelocityComponentParticle (int i) const
 Gets a pointer to the particle with the lowest velocity in direction i in this ParticleHandler. More...
 
BaseParticlegetHighestVelocityComponentParticleLocal (int i) const
 Gets a pointer to the particle with the highest velocity in direction i in this ParticleHandler. More...
 
BaseParticlegetHighestVelocityComponentParticle (int i) const
 Gets a pointer to the particle with the highest velocity in direction i in this ParticleHandler. More...
 
template<typename T >
std::enable_if< std::is_scalar< T >::value, T >::type getParticleAttributeLocal (std::function< T(BaseParticle *)> attribute, AttributeType type) const
 Computes an attribute type (min/max/..) of a particle attribute (position/velocity) in a local domain. More...
 
template<typename T >
std::enable_if< std::is_scalar< T >::value, T >::type getParticleAttribute (std::function< T(BaseParticle *)> attribute, AttributeType type) const
 Computes an attribute type (min/max/..) of a particle attribute(position/velocity) in the global domain. More...
 
Mdouble getHighestPositionX () const
 Function returns the highest position in the x-direction. More...
 
void clear () override
 Empties the whole ParticleHandler by removing all BaseParticle. More...
 
unsigned int getNumberOfFixedParticles () const
 Gets the number of particles that are fixed. More...
 
unsigned int getNumberOfUnfixedParticles () const
 Gets the number of particles that are not fixed. More...
 
BaseParticlereadAndCreateObject (std::istream &is)
 Create a new particle, based on the information provided in a restart file. More...
 
void readAndAddObject (std::istream &is) override
 
void write (std::ostream &os) const
 
void checkExtrema (BaseParticle *P)
 Checks if the extrema of this ParticleHandler needs updating. More...
 
void checkExtremaOnDelete (BaseParticle *P)
 Checks if the extrema of this ParticleHandler needs updating when a particle is deleted. More...
 
void computeAllMasses (unsigned int indSpecies)
 Computes the mass for all BaseParticle of the given species in this ParticleHandler. More...
 
void computeAllMasses ()
 Computes the mass for all BaseParticle in this ParticleHandler. More...
 
void addedFixedParticle ()
 Increment of the number of fixed particles. More...
 
void removedFixedParticle ()
 Decrement of the number of fixed particles. More...
 
std::string getName () const override
 Returns the name of the handler, namely the string "ParticleHandler". More...
 
unsigned int getNumberOfRealObjects () const
 Returns the number of real objects (on all processors) More...
 
unsigned int getNumberOfObjects () const override
 Returns the number of objects in the container. In parallel code this practice is forbidden to avoid confusion with real and fake particles. If the size of the container is wished, call size() More...
 
unsigned int getNumberOfFixedObjectsLocal () const
 Computes the number of Fixed particles on a local domain. More...
 
unsigned int getNumberOfFixedObjects () const
 Computes the number of fixed particles in the whole simulation. More...
 
unsigned int getNumberOfRealObjectsLocal () const
 Returns the number of real objects on a local domain. MPI particles and periodic particles are neglected. More...
 
void actionsAfterTimeStep ()
 
double getLiquidFilmVolume () const
 
void saveNumberPSDtoCSV (std::string csvFileName, std::vector< double > diameterBins={})
 
- Public Member Functions inherited from BaseHandler< BaseParticle >
 BaseHandler ()
 Default BaseHandler constructor, it creates an empty BaseHandler and assigns DPMBase_ to a null pointer. More...
 
 BaseHandler (const BaseHandler< BaseParticle > &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< BaseParticle > &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 (BaseParticle *O)
 Adds an existing object to the BaseHandler without changing the id of the object. More...
 
virtual void addObject (BaseParticle *object)
 Adds a new Object to the BaseHandler. More...
 
virtual void addGhostObject (BaseParticle *O)
 Adds a new Object to the BaseHandler. called by the to avoid increasing the id. More...
 
void removeIf (const std::function< bool(BaseParticle *)> cond)
 
void removeLastObject ()
 Removes the last Object from the BaseHandler. More...
 
void read (std::istream &is)
 Reads all objects from restart data. More...
 
BaseParticlegetObjectById (const unsigned int id)
 Gets a pointer to the Object at the specified index in the BaseHandler. More...
 
std::vector< BaseParticle * > getObjectsById (const unsigned int id)
 Gets a vector of pointers to the objects with the specific id. More...
 
BaseParticlegetObject (const unsigned int id)
 Gets a pointer to the Object at the specified index in the BaseHandler.
More...
 
const BaseParticlegetObject (const unsigned int id) const
 Gets a constant pointer to the Object at the specified index in the BaseHandler. More...
 
BaseParticlegetLastObject ()
 Gets a pointer to the last Object in this BaseHandler. More...
 
const BaseParticlegetLastObject () const
 Gets a constant pointer to the last Object in this BaseHandler. 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 BaseParticle &obj)
 Resizes the container to contain N elements. More...
 
const std::vector< BaseParticle * >::const_iterator begin () const
 Gets the begin of the const_iterator over all Object in this BaseHandler. More...
 
const std::vector< BaseParticle * >::iterator begin ()
 Gets the begin of the iterator over all BaseBoundary in this BaseHandler. More...
 
const std::vector< BaseParticle * >::const_iterator end () const
 Gets the end of the const_iterator over all BaseBoundary in this BaseHandler. More...
 
const std::vector< BaseParticle * >::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 (BaseParticle *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...
 

Static Public Member Functions

static BaseParticlecreateObject (const std::string &type)
 Reads BaseParticle into the ParticleHandler from restart data. More...
 

Private Member Functions

Mdouble getKineticEnergyLocal () const
 
Mdouble getRotationalEnergyLocal () const
 
Mdouble getMassLocal () const
 
Mdouble getVolumeLocal () const
 
Vec3D getMassTimesPositionLocal () const
 
Mdouble getSumRadiusLocal () const
 

Private Attributes

BaseParticlelargestParticle_
 A pointer to the largest BaseParticle (by interactionRadius) in this ParticleHandler. More...
 
BaseParticlesmallestParticle_
 A pointer to the smallest BaseParticle (by interactionRadius) in this ParticleHandler. More...
 
unsigned int NFixedParticles_
 Number of fixed particles. More...
 

Additional Inherited Members

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

Detailed Description

Container to store all BaseParticle.

The ParticleHandler is a container to store all BaseParticle. It is implemented by a vector of pointers to BaseParticle.

Constructor & Destructor Documentation

◆ ParticleHandler() [1/2]

ParticleHandler::ParticleHandler ( )

Default constructor, it creates an empty ParticleHandler.

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

51 {
52  largestParticle_ = nullptr;
53  smallestParticle_ = nullptr;
54  logger(DEBUG, "ParticleHandler::ParticleHandler() finished");
55 }
Logger< MERCURYDPM_LOGLEVEL > logger("MercuryKernel")
Definition of different loggers with certain modules. A user can define its own custom logger here.
@ DEBUG
BaseParticle * smallestParticle_
A pointer to the smallest BaseParticle (by interactionRadius) in this ParticleHandler.
Definition: ParticleHandler.h:471
BaseParticle * largestParticle_
A pointer to the largest BaseParticle (by interactionRadius) in this ParticleHandler.
Definition: ParticleHandler.h:466

References DEBUG, largestParticle_, logger, and smallestParticle_.

◆ ParticleHandler() [2/2]

ParticleHandler::ParticleHandler ( const ParticleHandler PH)

Constructor that copies all BaseParticle it contains and then sets the smallest and largest particle.

Parameters
[in]PHThe ParticleHandler that has to be copied.

This is not a copy constructor! It copies the DPMBase and all BaseParticle, and sets the other variables to 0. After that, it computes the smallest and largest particle in this handler.

65 {
66  clear();
67  setDPMBase(PH.getDPMBase());
68  largestParticle_ = nullptr;
69  smallestParticle_ = nullptr;
71  if (!objects_.empty())
72  {
75  }
76  logger(DEBUG, "ParticleHandler::ParticleHandler(const ParticleHandler &PH) finished");
77 }
void setDPMBase(DPMBase *DPMBase)
Sets the problem that is solved using this handler.
Definition: BaseHandler.h:718
std::vector< BaseParticle * > objects_
The actual list of Object pointers.
Definition: BaseHandler.h:302
DPMBase * getDPMBase()
Gets the problem that is solved using this handler.
Definition: BaseHandler.h:725
void copyContentsFromOtherHandler(const BaseHandler< BaseParticle > &BH)
Function that copies the contents (vector of pointers, maxObject_, nextId_, DPMBase_) from one handle...
Definition: BaseHandler.h:367
void clear() override
Empties the whole ParticleHandler by removing all BaseParticle.
Definition: ParticleHandler.cc:977
void computeSmallestParticle()
Computes the smallest particle (by interaction radius) and sets it in smallestParticle_.
Definition: ParticleHandler.cc:451
void computeLargestParticle()
Computes the largest particle (by interaction radius) and sets it in largestParticle_.
Definition: ParticleHandler.cc:475

References clear(), computeLargestParticle(), computeSmallestParticle(), BaseHandler< BaseParticle >::copyContentsFromOtherHandler(), DEBUG, BaseHandler< T >::getDPMBase(), largestParticle_, logger, BaseHandler< BaseParticle >::objects_, BaseHandler< BaseParticle >::setDPMBase(), and smallestParticle_.

◆ ~ParticleHandler()

ParticleHandler::~ParticleHandler ( )
override

Destructor, it destructs the ParticleHandler and all BaseParticle it contains.

Set the pointers to largestParticle_ and smallestParticle_ to nullptr, all BaseParticle are destroyed by the BaseHandler afterwards.

108 {
109  //First reset the pointers, such that they are not checked twice when removing particles
110  largestParticle_ = nullptr;
111  smallestParticle_ = nullptr;
112  logger(DEBUG, "ParticleHandler::~ParticleHandler() finished");
113 }

References DEBUG, largestParticle_, logger, and smallestParticle_.

Member Function Documentation

◆ actionsAfterTimeStep()

void ParticleHandler::actionsAfterTimeStep ( )
1373 {
1374  for (auto i: *this)
1375  {
1376  i->actionsAfterTimeStep();
1377  }
1378 }
const std::complex< Mdouble > i
Definition: ExtendedMath.h:51

References constants::i.

Referenced by DPMBase::computeOneTimeStep().

◆ addedFixedParticle()

void ParticleHandler::addedFixedParticle ( )

Increment of the number of fixed particles.

Todo:
MX: For Jonny, is this still required, keeping the parallel code in mind?
1235 {
1236  NFixedParticles_++;
1237 }
unsigned int NFixedParticles_
Number of fixed particles.
Definition: ParticleHandler.h:476

References NFixedParticles_.

Referenced by BaseParticle::fixParticle().

◆ addExistingObject()

void ParticleHandler::addExistingObject ( BaseParticle P)
override

Adds a BaseParticle to the ParticleHandler.

Parameters
[in]PA pointer to the BaseParticle that has to be added.

To add a BaseParticle to the ParticleHandler, first check if it has a species, since it is as common bug to use a BaseParticle without species, which leads to a segmentation fault. To help the user with debugging, a warning is given if a particle without species is added. After that, the actions for adding the particle to the BaseHandler are taken, which include adding it to the vector of pointers to all BaseParticle and assigning the correct id and index. Then the particle is added to the HGrid, the particle is told that this is its handler, its mass is computed and finally it is checked if this is the smallest or largest particle in this ParticleHandler. The particle exists, in other words: it has been made before. This implies it already got an id Attached to it and hence we don't want to assign a new ID to it.

132 {
133  if (P->getSpecies() == nullptr)
134  {
135  logger(WARN, "WARNING: The particle with ID % that is added in ParticleHandler::addObject does not have a "
136  "species yet. Please make sure that you have "
137  "set the species somewhere in the driver code.", P->getId());
138  }
139 
140  //Puts the particle in the Particle list
142  if (getDPMBase() != nullptr)
143  {
144  //This places the particle in this grid
146  //This computes where the particle currently is in the grid
148  }
149  //set the particleHandler pointer
150  P->setHandler(this);
151  //compute mass of the particle
152  P->getSpecies()->computeMass(P);
153  //Check if this particle has new extrema
154  checkExtrema(P);
155 }
@ WARN
virtual void addExistingObject(T *O)
Adds an existing object to the BaseHandler without changing the id of the object.
Definition: BaseHandler.h:417
virtual void hGridUpdateParticle(BaseParticle *obj UNUSED)
Definition: DPMBase.cc:1704
virtual void hGridInsertParticle(BaseParticle *obj UNUSED)
Definition: DPMBase.cc:1697
void checkExtrema(BaseParticle *P)
Checks if the extrema of this ParticleHandler needs updating.
Definition: ParticleHandler.cc:1173
double P
Uniform pressure.
Definition: TwenteMeshGluing.cpp:73

References BaseHandler< T >::addExistingObject(), checkExtrema(), BaseHandler< BaseParticle >::getDPMBase(), DPMBase::hGridInsertParticle(), DPMBase::hGridUpdateParticle(), logger, Global_Physical_Variables::P, and WARN.

Referenced by readAndAddObject().

◆ addGhostObject() [1/2]

void ParticleHandler::addGhostObject ( BaseParticle P)
override

Adds a BaseParticle to the ParticleHandler.

This is a special function that is used in the parallel code. The functions differs from the standard parallel implementation as this function does not check if the particle is an mpi particle and the mpi domain is not updated. When the domain adds mpi particles to the simulation these checks are not required. It also doesnt increase the id of the particle

Parameters
[in]Apointer to the BaseParticle that has to be added.
349 {
350 #ifdef MERCURYDPM_USE_MPI
351  if (P->getSpecies() == nullptr)
352  {
353  logger(WARN, "[ParticleHandler::adGhostObject(BaseParticle*)] "
354  "WARNING: The particle with ID % that is added in "
355  "ParticleHandler::addObject does not have a species yet."
356  " Please make sure that you have "
357  "set the species somewhere in the driver code.", P->getId());
358  }
359 
360  MPIContainer& communicator = MPIContainer::Instance();
361  //Puts the particle in the Particle list
363  if (getDPMBase() != nullptr)
364  {
365  //This places the particle in this grid
367  //This computes where the particle currently is in the grid
369 
370  // broadcast particle addition
371  getDPMBase()->handleParticleAddition(P->getId(), P);
372  }
373  //set the particleHandler pointer
374  P->setHandler(this);
375  //compute mass of the particle
376  P->getSpecies()->computeMass(P) ;
377  //Check if this particle has new extrema
378  checkExtrema(P);
379 #else
380  logger(INFO,
381  "Function ParticleHandler::mpiAddObject(BaseParticle* P) should only be called when compiling with parallel build on");
382 #endif
383 }
@ INFO
virtual void addGhostObject(T *O)
Adds a new Object to the BaseHandler. called by the to avoid increasing the id.
Definition: BaseHandler.h:444
virtual void handleParticleAddition(unsigned int id, BaseParticle *p)
Definition: DPMBase.cc:5477
This class contains all information and functions required for communication between processors.
Definition: MpiContainer.h:130
static MPIContainer & Instance()
fetch the instance to be used for communication
Definition: MpiContainer.h:134

References BaseHandler< T >::addGhostObject(), checkExtrema(), BaseHandler< BaseParticle >::getDPMBase(), DPMBase::handleParticleAddition(), DPMBase::hGridInsertParticle(), DPMBase::hGridUpdateParticle(), INFO, MPIContainer::Instance(), logger, Global_Physical_Variables::P, and WARN.

◆ addGhostObject() [2/2]

void ParticleHandler::addGhostObject ( int  fromProcessor,
int  toProcessor,
BaseParticle p 
)

Adds a ghost particle located at fromProcessor to toProcessor.

This function adds a ghost particle from one processor to another processor.

When a periodic ghost particle or a mpi ghost particle is created, the ID should not be updated and hence the addGhostObject needs to be called. Adding a ghost keeps the ID constant. Additionally this function copies the particle information given on processor fromProcessor to all other processors. The target processor then adds the particle.

Parameters
[in]fromProcessorprocessor containing the particle data
[in]toProcessorprocessor that needs to add the particle
[in,out]particlethat contains the data and receives the data
288 {
289 #ifdef MERCURYDPM_USE_MPI
290  MPIContainer& communicator = MPIContainer::Instance();
291  if (fromProcessor == toProcessor)
292  {
293  if (communicator.getProcessorID() == fromProcessor)
294  {
295  addGhostObject(p);
296  }
297 
298  return;
299  }
300 
301  //Create communication information object
303  MPIParticle pInfo;
304  int tag;
305  if (communicator.getProcessorID() == fromProcessor)
306  {
308  tag = fromProcessor*MAX_PROC*10 + toProcessor*10 + MercuryMPITag::PARTICLE_DATA;
309  communicator.send(&pInfo, MercuryMPIType::PARTICLE, 1, toProcessor, tag);
310  }
311 
312  if (communicator.getProcessorID() == toProcessor)
313  {
314  tag = fromProcessor*MAX_PROC*10 + toProcessor*10 + MercuryMPITag::PARTICLE_DATA;
315  communicator.receive(&pInfo, MercuryMPIType::PARTICLE, 1, fromProcessor, tag);
316  }
317 
318  //Sync the communication
319  communicator.sync();
320 
321  //Add the data to the new particle
322  if (communicator.getProcessorID() == toProcessor)
323  {
324  copyDataFromMPIParticleToParticle(&pInfo, p, this);
325  }
326 
327 
328  //Only toProcessor adds the particle, quietly without any check with other processors
329  //IMPORTANT NOTE: When adding a periodic particle in parallel, this is performed just before
330  //finding new particles. For that reason we dont have to add a ghostparticle to the mpi communication lists
331  if (communicator.getProcessorID() == toProcessor)
332  {
333  addGhostObject(p);
334  }
335 #else
336  logger(WARN,
337  "Function addGhostObject(int fromProcessor, int toProcessor, BaseParticle* p) should not be used in serial code");
338 #endif
339 }
#define MAX_PROC
Definition: GeneralDefine.h:51
@ PARTICLE_DATA
Definition: MpiContainer.h:79
@ PARTICLE
Definition: MpiContainer.h:67
void copyDataFromMPIParticleToParticle(MPIParticle *bP, BaseParticle *p, ParticleHandler *particleHandler)
Copies data from an MPIParticle class to a BaseParticle and sets the particleHandler and species.
Definition: MpiDataClass.cc:105
std::enable_if< std::is_scalar< T >::value, void >::type receive(T &t, int from, int tag)
asynchronously receive a scalar from some other processor.
Definition: MpiContainer.h:221
void sync()
Process all pending asynchronous communication requests before continuing.
Definition: MpiContainer.h:152
std::size_t getProcessorID()
Reduces a scalar on all processors to one scalar on a target processor.
Definition: MpiContainer.cc: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:171
Data class to send a particle over MPI.
Definition: MpiDataClass.h:81
void copyDataFromParticleToMPIParticle(BaseParticle *p)
Definition: MpiDataClass.cc:131
void addGhostObject(int fromProcessor, int toProcessor, BaseParticle *p)
Adds a ghost particle located at fromProcessor to toProcessor.
Definition: ParticleHandler.cc:287

References copyDataFromMPIParticleToParticle(), MPISphericalParticle::copyDataFromParticleToMPIParticle(), MPIContainer::getProcessorID(), MPIContainer::Instance(), logger, MAX_PROC, PARTICLE, PARTICLE_DATA, MPIContainer::receive(), MPIContainer::send(), MPIContainer::sync(), and WARN.

Referenced by PeriodicBoundaryHandler::processLocalGhostParticles(), Domain::processReceivedBoundaryParticleData(), and PeriodicBoundaryHandler::processReceivedGhostParticleData().

◆ addObject() [1/2]

void ParticleHandler::addObject ( BaseParticle P)
override

Adds a BaseParticle to the ParticleHandler.

Parameters
[in]PA pointer to the BaseParticle that has to be added.

To add a BaseParticle to the ParticleHandler, first check if it has a species, since it is as common bug to use a BaseParticle without species, which leads to a segmentation fault. To help the user with debugging, a warning is given if a particle without species is added. After that, the actions for adding the particle to the BaseHandler are taken, which include adding it to the vector of pointers to all BaseParticle and assigning the correct id and index. Then the particle is added to the HGrid, the particle is told that this is its handler, its mass is computed and finally it is checked if this is the smallest or largest particle in this ParticleHandler.

172 {
173  if (P->getSpecies() == nullptr)
174  {
175  logger(WARN, "WARNING: The particle with ID % that is added in "
176  "ParticleHandler::addObject does not have a species yet. "
177  "Please make sure that you have "
178  "set the species somewhere in the driver code.", P->getId());
179  }
180 #ifdef MERCURYDPM_USE_MPI
181  bool insertParticle;
182  //Check if the particle P should be added to the current domain
183  if (NUMBER_OF_PROCESSORS == 1)
184  {
185  insertParticle = true;
186  }
187  else
188  {
189  insertParticle = getDPMBase()->mpiInsertParticleCheck(P);
190  }
191 
192  //Add the particle if it is in the mpi domain or if the domain is not yet defined
193  if(insertParticle)
194  {
195 #endif
196  //Puts the particle in the Particle list
198  if (getDPMBase() != nullptr)
199  {
200  //This places the particle in this grid
202  //This computes where the particle currently is in the grid
204 
205  // Broadcasts the existance of a new particle
206  getDPMBase()->handleParticleAddition(P->getId(), P);
207  }
208  //set the particleHandler pointer
209  P->setHandler(this);
210  //compute mass of the particle
211  P->getSpecies()->computeMass(P);
212  //Check if this particle has new extrema
213  checkExtrema(P);
214  if (!P->isSphericalParticle())
215  {
216  getDPMBase()->setRotation(true);
217  }
218 
219  P->actionsAfterAddObject();
220 
221 #ifdef MERCURYDPM_USE_MPI
222  P->setPeriodicComplexity(std::vector<int>(0));
223  }
224  else
225  {
226  logger.assert_debug(!P->isMPIParticle(),"Can't add mpi particle as it does not exist");
227  logger.assert_debug(!P->isPeriodicGhostParticle(),"Can't add mpi particle as it does not exist");
228  //Somehwere a really new particle has been added, so to keep the ID's globally unique, we also update
229  //the unique value on all other processors
231  }
232 
233  //Add the particle to the ghost particle lists
235  //Check if this new particle requires an update in the mpi grid (interactionDistance).
237 
238  //Delete the particle that was supposed to be added (but was not)
239  if(!insertParticle)
240  {
241  delete P;
242  }
243 #endif
244 }
#define NUMBER_OF_PROCESSORS
For the MPI communication routines this quantity is often required. defining this macro makes the cod...
Definition: GeneralDefine.h:62
virtual void addObject(T *object)
Adds a new Object to the BaseHandler.
Definition: BaseHandler.h:431
void increaseId()
Definition: BaseHandler.h:251
void setRotation(bool rotation)
Sets whether particle rotation is enabled or disabled.
Definition: DPMBase.h:563
void insertGhostParticle(BaseParticle *P)
This function inserts a particle in the mpi communication boundaries.
Definition: DPMBase.cc:1811
void updateGhostGrid(BaseParticle *P)
Checks if the Domain/periodic interaction distance needs to be updated and updates it accordingly.
Definition: DPMBase.cc:1837
bool mpiInsertParticleCheck(BaseParticle *P)
Function that checks if the mpi particle should really be inserted by the current domain.
Definition: DPMBase.cc:1732

References BaseHandler< T >::addObject(), checkExtrema(), BaseHandler< BaseParticle >::getDPMBase(), DPMBase::handleParticleAddition(), DPMBase::hGridInsertParticle(), DPMBase::hGridUpdateParticle(), BaseHandler< T >::increaseId(), DPMBase::insertGhostParticle(), logger, DPMBase::mpiInsertParticleCheck(), NUMBER_OF_PROCESSORS, Global_Physical_Variables::P, DPMBase::setRotation(), DPMBase::updateGhostGrid(), and WARN.

Referenced by ChuteWithPeriodicInflow::AddContinuingBottom(), addObject(), CircularPeriodicBoundary::checkBoundaryAfterParticleMoved(), ConstantMassFlowMaserBoundary::checkBoundaryAfterParticleMoved(), SubcriticalMaserBoundary::checkBoundaryAfterParticleMoved(), SubcriticalMaserBoundaryTEST::checkBoundaryAfterParticleMoved(), ChuteWithContraction::ChuteWithContraction(), ChuteWithPeriodicInflowAndContinuingBottom::ChuteWithPeriodicInflowAndContinuingBottom(), ChuteWithPeriodicInflowAndContraction::ChuteWithPeriodicInflowAndContraction(), ChuteWithPeriodicInflowAndVariableBottom::ChuteWithPeriodicInflowAndVariableBottom(), ContractionWithPeriodicInflow::ContractionWithPeriodicInflow(), SubcriticalMaserBoundaryTEST::copyExtraParticles(), CurvyChute::createBottom(), PeriodicBoundary::createGhostParticle(), TimeDependentPeriodicBoundary::createGhostParticle(), LeesEdwardsBoundary::createHorizontalPeriodicParticle(), ShearBoxBoundary::createHorizontalPeriodicParticle(), AngledPeriodicBoundary::createPeriodicParticle(), CircularPeriodicBoundary::createPeriodicParticle(), ConstantMassFlowMaserBoundary::createPeriodicParticle(), SubcriticalMaserBoundary::createPeriodicParticle(), LeesEdwardsBoundary::createVerticalPeriodicParticle(), ShearBoxBoundary::createVerticalPeriodicParticle(), SubcriticalMaserBoundaryTEST::extendBottom(), ChuteWithPeriodicInflow::ExtendInWidth(), ChuteWithPeriodicInflow::integrateBeforeForceComputation(), and ContactDetectionTester::setupParticles().

◆ addObject() [2/2]

void ParticleHandler::addObject ( int  fromProcessor,
BaseParticle p 
)

Adds a BaseParticle located at processor fromProcessor to toProcessor.

This function adds a particle to the simulation where the information of the particle is not available by the target processor.

When a certain processor generates a particle which needs to be inserted in a domain of another processor, this information needs to be transfered before the particle can be actually added

Parameters
[in]fromProcessorprocessor containing the particle data
[in,out]particlethat contains the data and receives the data
255 {
256 #ifdef MERCURYDPM_USE_MPI
257  MPIContainer& communicator = MPIContainer::Instance();
258 
259  //The processor that contains the particle that needs to be copied needs to identify the target, and communicate this
260  MPIParticle pInfo;
261  if (communicator.getProcessorID() == fromProcessor)
262  {
264  }
265 
266  //Broadcast from processor i
267  communicator.broadcast(&pInfo,MercuryMPIType::PARTICLE,fromProcessor);
268  copyDataFromMPIParticleToParticle(&pInfo, p, this);
269 
270  //All processors now know have the same information and we can proceed with the collective add
271  addObject(p);
272 #else
273  logger(WARN, "Function addObject(int fromProcessor, BaseParticle* p) should not be used in serial code");
274 #endif
275 }
std::enable_if< std::is_scalar< T >::value, void >::type broadcast(T &t, int fromProcessor=0)
Broadcasts a scalar from the root to all other processors.
Definition: MpiContainer.h:441
void addObject(BaseParticle *P) override
Adds a BaseParticle to the ParticleHandler.
Definition: ParticleHandler.cc:171

References addObject(), MPIContainer::broadcast(), copyDataFromMPIParticleToParticle(), MPISphericalParticle::copyDataFromParticleToMPIParticle(), MPIContainer::getProcessorID(), MPIContainer::Instance(), logger, PARTICLE, and WARN.

◆ checkExtrema()

void ParticleHandler::checkExtrema ( BaseParticle P)

Checks if the extrema of this ParticleHandler needs updating.

 \param[in] type The first value of the position.
 \param[in] is The input stream from which the information is read.
 \details The old objects did not have their type in the beginning of the line.
          Instead, the first string of the file was the position in x-direction.
          Since we already read the first string of the file, we need to give
          it to this function and convert it to the position in x-direction.
          The rest of the stream is then read in the usual way.
&zwj;/

void ParticleHandler::readAndCreateOldObject(std::istream& is, const std::string& type) { //read in next line std::stringstream line; helpers::getLineFromStringStream(is, line); logger(VERBOSE, line.str()); //stdcout << line.str() << std::endl;

BaseParticle particle;

//Declare all properties of the particle unsigned int indSpecies; Mdouble radius, inverseMass, inverseInertia; Vec3D position, velocity, euler, angularVelocity;

//Read all values position.X = atof(type.c_str());

line >> position.Y >> position.Z >> velocity >> radius >> euler >> angularVelocity >> inverseMass >> inverseInertia >> indSpecies;

//Put the values in the particle particle.setSpecies(getDPMBase()->speciesHandler.getObject(indSpecies)); particle.setPosition(position); particle.setVelocity(velocity); particle.setRadius(radius); Quaternion q; q.setEuler(euler); particle.setOrientation(q); particle.setAngularVelocity(angularVelocity); if (inverseMass == 0.0) particle.fixParticle(); else { particle.setInverseInertia(MatrixSymmetric3D(1,0,0,1,0,1)*inverseInertia); }

//Put the particle in the handler copyAndAddObject(particle); }

void ParticleHandler::write(std::ostream& os) const {

os << "Particles " << getSize() << '\n';
for (BaseParticle* it : *this)
{
    os << (*it) << '\n';
}

os.flush(); }

/*!

Parameters
[in]PA pointer to the particle, which properties have to be checked against the ParticleHandlers extrema.
1174 {
1175  if (P == largestParticle_)
1176  {
1177  //if the properties of the largest particle changes
1179  }
1180  else if (!largestParticle_ || P->getMaxInteractionRadius() > largestParticle_->getMaxInteractionRadius())
1181  {
1182  largestParticle_ = P;
1183  }
1184 
1185  if (P == smallestParticle_)
1186  {
1187  //if the properties of the smallest particle changes
1189  }
1190  else if (!smallestParticle_ || P->getMaxInteractionRadius() < smallestParticle_->getMaxInteractionRadius())
1191  {
1192  smallestParticle_ = P;
1193  }
1194 }
Mdouble getMaxInteractionRadius() const
Returns the particle's interaction radius, which might be different from radius_ (e....
Definition: BaseParticle.h:362

References computeLargestParticle(), computeSmallestParticle(), BaseParticle::getMaxInteractionRadius(), largestParticle_, Global_Physical_Variables::P, and smallestParticle_.

Referenced by addExistingObject(), addGhostObject(), addObject(), and BaseParticle::setRadius().

◆ checkExtremaOnDelete()

void ParticleHandler::checkExtremaOnDelete ( BaseParticle P)

Checks if the extrema of this ParticleHandler needs updating when a particle is deleted.

Parameters
[in]PA pointer to the particle, which is going to get deleted.
1200 {
1201  if (P == largestParticle_)
1202  {
1204  }
1205  if (P == smallestParticle_)
1206  {
1208  }
1209 }

References computeLargestParticle(), computeSmallestParticle(), largestParticle_, Global_Physical_Variables::P, and smallestParticle_.

Referenced by BaseParticle::~BaseParticle(), and SuperQuadricParticle::~SuperQuadricParticle().

◆ clear()

void ParticleHandler::clear ( )
overridevirtual

Empties the whole ParticleHandler by removing all BaseParticle.

Note that the pointers to smallestParticle_ and largestParticle_ are set to nullptr since these particles don't exist anymore after calling this function.

Reimplemented from BaseHandler< BaseParticle >.

978 {
979  smallestParticle_ = nullptr;
980  largestParticle_ = nullptr;
981 
982  for (auto p0: *this)
983  {
984  getDPMBase()->handleParticleRemoval(p0->getId());
985  }
986 
988 }
virtual void clear()
Empties the whole BaseHandler by removing all Objects and setting all other variables to 0.
Definition: BaseHandler.h:528
virtual void handleParticleRemoval(unsigned int id)
Handles the removal of particles from the particleHandler.
Definition: DPMBase.cc:5462

References BaseHandler< T >::clear(), BaseHandler< BaseParticle >::getDPMBase(), DPMBase::handleParticleRemoval(), largestParticle_, and smallestParticle_.

Referenced by NautaMixer::addParticles(), NautaMixer::addParticlesAtWall(), CGHandler::evaluateRestartFiles(), HorizontalMixer::introduceParticlesAtWall(), HorizontalMixer::introduceParticlesInDomain(), HorizontalMixer::introduceSingleParticle(), operator=(), ParticleHandler(), FileReader::read(), DPMBase::read(), DPMBase::readNextDataFile(), HorizontalMixerWalls::setupInitialConditions(), FreeCooling2DinWallsDemo::setupInitialConditions(), FreeCooling3DDemoProblem::setupInitialConditions(), FreeCooling3DinWallsDemo::setupInitialConditions(), FreeCoolingDemoProblem::setupInitialConditions(), CoilSelfTest::setupInitialConditions(), ParticleParticleInteraction::setupInitialConditions(), ParticleParticleInteractionWithPlasticForces::setupInitialConditions(), ParticleWallInteraction::setupInitialConditions(), EnergyUnitTest::setupInitialConditions(), HertzianSinterForceUnitTest::setupInitialConditions(), MD_demo::setupInitialConditions(), PlasticForceUnitTest::setupInitialConditions(), SeparateFilesSelfTest::setupInitialConditions(), SinterForceUnitTest::setupInitialConditions(), and BaseCluster::setupInitialConditions().

◆ computeAllMasses() [1/2]

void ParticleHandler::computeAllMasses ( )

Computes the mass for all BaseParticle in this ParticleHandler.

1227 {
1228  for (BaseParticle* particle : objects_)
1229  {
1230  particle->getSpecies()->computeMass(particle);
1231  }
1232 }
Definition: BaseParticle.h:54

References BaseHandler< BaseParticle >::objects_.

◆ computeAllMasses() [2/2]

void ParticleHandler::computeAllMasses ( unsigned int  indSpecies)

Computes the mass for all BaseParticle of the given species in this ParticleHandler.

Parameters
[in]indSpeciesUnsigned integer with the index of the species for which the masses must be computed.
1216 {
1217  for (BaseParticle* particle : objects_)
1218  {
1219  if (particle->getIndSpecies() == indSpecies)
1220  {
1221  particle->getSpecies()->computeMass(particle);
1222  }
1223  }
1224 }

References BaseHandler< BaseParticle >::objects_.

Referenced by SpeciesHandler::addObject(), DPMBase::initialiseSolve(), DPMBase::readNextDataFile(), ParticleSpecies::setDensity(), and DPMBase::setParticleDimensions().

◆ computeLargestParticle()

void ParticleHandler::computeLargestParticle ( )

Computes the largest particle (by interaction radius) and sets it in largestParticle_.

476 {
477  if (getSize() == 0)
478  {
479  logger(DEBUG, "No particles, so cannot compute the largest particle.");
480  largestParticle_ = nullptr;
481  return;
482  }
483  Mdouble max = -std::numeric_limits<Mdouble>::max();
484  largestParticle_ = nullptr;
485  for (BaseParticle* const particle : objects_)
486  {
487  //if (!(particle->isMPIParticle() || particle->isPeriodicGhostParticle()))
488  {
489  if (particle->getMaxInteractionRadius() > max)
490  {
491  max = particle->getMaxInteractionRadius();
492  largestParticle_ = particle;
493  }
494  }
495  }
496 }
double Mdouble
Definition: GeneralDefine.h:34
unsigned int getSize() const
Gets the size of the particleHandler (including mpi and periodic particles)
Definition: BaseHandler.h:655

References DEBUG, BaseHandler< BaseParticle >::getSize(), largestParticle_, logger, and BaseHandler< BaseParticle >::objects_.

Referenced by DeletionBoundary::checkBoundaryAfterParticleMoved(), checkExtrema(), checkExtremaOnDelete(), operator=(), and ParticleHandler().

◆ computeSmallestParticle()

void ParticleHandler::computeSmallestParticle ( )

Computes the smallest particle (by interaction radius) and sets it in smallestParticle_.

452 {
453  if (getSize() == 0)
454  {
455  logger(DEBUG, "No particles, so cannot compute the smallest particle.");
456 
457  smallestParticle_ = nullptr;
458  return;
459  }
460  Mdouble min = std::numeric_limits<Mdouble>::max();
461  smallestParticle_ = nullptr;
462  for (BaseParticle* const particle : objects_)
463  {
464  //if (!(particle->isMPIParticle() || particle->isPeriodicGhostParticle()))
465  {
466  if (particle->getMaxInteractionRadius() < min)
467  {
468  min = particle->getMaxInteractionRadius();
469  smallestParticle_ = particle;
470  }
471  }
472  }
473 }

References DEBUG, BaseHandler< BaseParticle >::getSize(), logger, BaseHandler< BaseParticle >::objects_, and smallestParticle_.

Referenced by DeletionBoundary::checkBoundaryAfterParticleMoved(), checkExtrema(), checkExtremaOnDelete(), operator=(), and ParticleHandler().

◆ createObject()

BaseParticle * ParticleHandler::createObject ( const std::string &  type)
static

Reads BaseParticle into the ParticleHandler from restart data.

Parameters
[in]isThe input stream from which the information is read.
1026 {
1027  if (type == "BaseParticle") {
1028  //for backwards compatibility
1029  return new SphericalParticle;
1030  }
1031  else if (type == "SphericalParticle")
1032  {
1033  return new SphericalParticle;
1034  }
1035  else if (type == "LiquidFilmParticle")
1036  {
1037  return new LiquidFilmParticle;
1038  }
1039  else if (type == "SuperQuadricParticle")
1040  {
1041  return new SuperQuadricParticle;
1042  }
1043  else if (type == "ThermalParticle")
1044  {
1045  return new ThermalParticle;
1046  }
1047  else if (type == "HeatFluidCoupledParticle")
1048  {
1049  return new HeatFluidCoupledParticle;
1050  }
1051  else if (type == "Clump")
1052  {
1053  return new ClumpParticle;
1054  }
1055  else
1056  {
1057  logger(WARN, "Particle type % not understood in restart file. Particle will not be read.", type);
1058  return nullptr;
1059  }
1060 }
HeatFluidCoupled< SphericalParticle > HeatFluidCoupledParticle
Template specialisation of HeatFluidCoupled<Particle> for spherical particles.
Definition: HeatFluidCoupledParticle.h:134
LiquidFilm< SphericalParticle > LiquidFilmParticle
Definition: LiquidFilmParticle.h:199
Thermal< SphericalParticle > ThermalParticle
Definition: ThermalParticle.h:182
Definition: ClumpParticle.h:41
A spherical particle is the most simple particle used in MercuryDPM.
Definition: SphericalParticle.h:37
Definition: SuperQuadricParticle.h:57

References logger, and WARN.

Referenced by readAndCreateObject().

◆ getAngularMomentum()

Vec3D ParticleHandler::getAngularMomentum ( ) const
676 {
677  Vec3D momentum = {0, 0, 0};
678  for (auto p : *this)
679  if (!(p->isFixed() || p->isMPIParticle() || p->isPeriodicGhostParticle()))
680  momentum += p->getAngularMomentum();
681  return getMPISum(momentum);
682 }
Vec3D getMPISum(Vec3D &val)
Definition: MpiDataClass.cc:199
Definition: Vector.h:51

References getMPISum().

Referenced by main().

◆ getCentreOfMass()

Vec3D ParticleHandler::getCentreOfMass ( ) const
655 {
656  Mdouble m = getMass();
657  if (m == 0)
658  {
660  return nanvec;
661  }
662  else
663  return getMassTimesPosition() / m;
664 }
Vec3D getMassTimesPosition() const
Definition: ParticleHandler.cc:636
Mdouble getMass() const
Definition: ParticleHandler.cc:611
const Mdouble NaN
Definition: GeneralDefine.h:43

References getMass(), getMassTimesPosition(), and constants::NaN.

Referenced by DPMBase::getCentreOfMass(), and RotatingDrumWet::printTime().

◆ getFastestParticle()

BaseParticle * ParticleHandler::getFastestParticle ( ) const
711 {
712 #ifdef MERCURYDPM_USE_MPI
713  logger(ERROR,"This function should not be used in parallel");
714 #endif
715  return getFastestParticleLocal();
716 }
@ ERROR
BaseParticle * getFastestParticleLocal() const
Gets a pointer to the fastest BaseParticle in this ParticleHandler.
Definition: ParticleHandler.cc:687

References ERROR, getFastestParticleLocal(), and logger.

◆ getFastestParticleLocal()

BaseParticle * ParticleHandler::getFastestParticleLocal ( ) const

Gets a pointer to the fastest BaseParticle in this ParticleHandler.

Returns
A pointer to the fastest BaseParticle in this ParticleHandler.
688 {
689  if (getSize() == 0)
690  {
691  logger(WARN, "No particles to set getFastestParticle()");
692  return nullptr;
693  }
694  BaseParticle* p = nullptr;
695  Mdouble maxSpeed = -std::numeric_limits<Mdouble>::max();
696  for (BaseParticle* const pLoop : objects_)
697  {
698  if (!(pLoop->isMPIParticle() || pLoop->isPeriodicGhostParticle()))
699  {
700  if ((pLoop->getVelocity().getLength()) > maxSpeed)
701  {
702  maxSpeed = pLoop->getVelocity().getLength();
703  p = pLoop;
704  }
705  }
706  }
707  return p;
708 }

References BaseHandler< BaseParticle >::getSize(), logger, BaseHandler< BaseParticle >::objects_, and WARN.

Referenced by getFastestParticle().

◆ getHighestPositionComponentParticle()

BaseParticle * ParticleHandler::getHighestPositionComponentParticle ( int  i) const

Gets a pointer to the particle with the highest coordinates in direction i in this ParticleHandler.

893 {
894 #ifdef MERCURYDPM_USE_MPI
895  logger(ERROR,"This function should not be used in parallel");
896 #endif
898 }
BaseParticle * getHighestPositionComponentParticleLocal(int i) const
Gets a pointer to the particle with the highest coordinates in direction i in this ParticleHandler.
Definition: ParticleHandler.cc:868

References ERROR, getHighestPositionComponentParticleLocal(), constants::i, and logger.

◆ getHighestPositionComponentParticleLocal()

BaseParticle * ParticleHandler::getHighestPositionComponentParticleLocal ( int  i) const

Gets a pointer to the particle with the highest coordinates in direction i in this ParticleHandler.

Parameters
[in]iDirection for which one wants the particle with highest coordinates.
Returns
A pointer to the particle with the highest coordinates in direction i in this ParticleHandler.
869 {
870  if (getSize() == 0)
871  {
872  logger(WARN, "No getHighestPositionComponentParticle(const int i) since there are no particles.");
873  return nullptr;
874  }
875  BaseParticle* p = nullptr;
876  Mdouble max = -std::numeric_limits<Mdouble>::max();
877  for (BaseParticle* const pLoop : objects_)
878  {
879  if (!(pLoop->isMPIParticle() || pLoop->isPeriodicGhostParticle()))
880  {
881  if (pLoop->getPosition().getComponent(i) > max)
882  {
883  max = pLoop->getPosition().getComponent(i);
884  p = pLoop;
885  }
886  }
887  }
888 
889  return p;
890 }

References BaseHandler< BaseParticle >::getSize(), constants::i, logger, BaseHandler< BaseParticle >::objects_, and WARN.

Referenced by getHighestPositionComponentParticle().

◆ getHighestPositionX()

Mdouble ParticleHandler::getHighestPositionX ( ) const

Function returns the highest position in the x-direction.

This is a prototype example of how to obtain global particle attributes in the parallel code

Returns
Returns the highest x-position value of all particles
996 {
997  //Define the attribute function
998  std::function<Mdouble(BaseParticle*)> particleAttribute = [](BaseParticle* p) { return p->getPosition().X; };
999 
1000  //Obtain the MAX attribute
1001  Mdouble positionXGlobal = getParticleAttribute<Mdouble>(particleAttribute, AttributeType::MAX);
1002 
1003  return positionXGlobal;
1004 }
@ MAX
Definition: ParticleHandler.h:39

References MAX.

◆ getHighestVelocityComponentParticle()

BaseParticle * ParticleHandler::getHighestVelocityComponentParticle ( int  i) const

Gets a pointer to the particle with the highest velocity in direction i in this ParticleHandler.

965 {
966 #ifdef MERCURYDPM_USE_MPI
967  logger(ERROR,"This function should not be used in parallel");
968 #endif
970 }
BaseParticle * getHighestVelocityComponentParticleLocal(int i) const
Gets a pointer to the particle with the highest velocity in direction i in this ParticleHandler.
Definition: ParticleHandler.cc:941

References ERROR, getHighestVelocityComponentParticleLocal(), constants::i, and logger.

◆ getHighestVelocityComponentParticleLocal()

BaseParticle * ParticleHandler::getHighestVelocityComponentParticleLocal ( int  i) const

Gets a pointer to the particle with the highest velocity in direction i in this ParticleHandler.

Parameters
[in]iDirection for which you want the particle with highest velocity.
Returns
A pointer to the particle with the highest velocity in direction i in this ParticleHandler.
942 {
943  if (!getSize())
944  {
945  logger(WARN, "No getHighestVelocityComponentParticle(const int i) since there are no particles");
946  return nullptr;
947  }
948  BaseParticle* p = nullptr;
949  Mdouble max = -std::numeric_limits<Mdouble>::max();
950  for (BaseParticle* const pLoop : objects_)
951  {
952  if (!(pLoop->isMPIParticle() || pLoop->isPeriodicGhostParticle()))
953  {
954  if (pLoop->getVelocity().getComponent(i) > max)
955  {
956  max = pLoop->getVelocity().getComponent(i);
957  p = pLoop;
958  }
959  }
960  }
961  return p;
962 }

References BaseHandler< BaseParticle >::getSize(), constants::i, logger, BaseHandler< BaseParticle >::objects_, and WARN.

Referenced by getHighestVelocityComponentParticle().

◆ getKineticEnergy()

Mdouble ParticleHandler::getKineticEnergy ( ) const
558 {
559 #ifdef MERCURYDPM_USE_MPI
560  Mdouble kineticEnergyLocal = getKineticEnergyLocal();
561  Mdouble kineticEnergyGlobal = 0.0;
562 
563  //sum up over all domains
564  MPIContainer& communicator = MPIContainer::Instance();
565  communicator.allReduce(kineticEnergyLocal, kineticEnergyGlobal, MPI_SUM);
566 
567  return kineticEnergyGlobal;
568 #else
569  return getKineticEnergyLocal();
570 #endif
571 }
Mdouble getKineticEnergyLocal() const
Definition: ParticleHandler.cc:544

References getKineticEnergyLocal(), and MPIContainer::Instance().

Referenced by main(), DPMBase::writeEneTimeStep(), and LawinenBox::writeEneTimeStep().

◆ getKineticEnergyLocal()

Mdouble ParticleHandler::getKineticEnergyLocal ( ) const
private
545 {
546  Mdouble ene = 0;
547  for (auto p : *this)
548  {
549  if (!(p->isMPIParticle() || p->isPeriodicGhostParticle()))
550  {
551  ene += p->getKineticEnergy();
552  }
553  }
554  return ene;
555 }

Referenced by getKineticEnergy().

◆ getLargestInteractionRadius()

Mdouble ParticleHandler::getLargestInteractionRadius ( ) const

Returns the largest interaction radius.

773 {
774 #ifdef MERCURYDPM_USE_MPI
775  Mdouble largestInteractionRadiusLocal = getLargestInteractionRadiusLocal();
776  Mdouble largestInteractionRadiusGlobal = 0.0;
777 
778  //Obtain the global value
779  MPIContainer& communicator = MPIContainer::Instance();
780  communicator.allReduce(largestInteractionRadiusLocal, largestInteractionRadiusGlobal, MPI_MAX);
781 
782  return largestInteractionRadiusGlobal;
783 #else
785 #endif
786 }
Mdouble getLargestInteractionRadiusLocal() const
Returns the largest interaction radius of the current domain.
Definition: ParticleHandler.cc:757

References getLargestInteractionRadiusLocal(), and MPIContainer::Instance().

Referenced by Contact::actionsAfterSolve(), DPMBase::read(), and saveNumberPSDtoCSV().

◆ getLargestInteractionRadiusLocal()

Mdouble ParticleHandler::getLargestInteractionRadiusLocal ( ) const

Returns the largest interaction radius of the current domain.

758 {
759  if (!(getLargestParticleLocal() == nullptr))
760  {
762  }
763  else
764  {
765  return 0.0;
766  }
767 }
BaseParticle * getLargestParticleLocal() const
Gets a pointer to the largest BaseParticle (by interactionRadius) in the ParticleHandler of the local...
Definition: ParticleHandler.cc:526
BaseParticle * getLargestParticle() const
Returns the pointer of the largest particle in the particle handler. When mercury is running in paral...
Definition: ParticleHandler.cc:534

References getLargestParticle(), getLargestParticleLocal(), and BaseParticle::getMaxInteractionRadius().

Referenced by MercuryBase::getHGridTargetMaxInteractionRadius(), and getLargestInteractionRadius().

◆ getLargestParticle()

BaseParticle * ParticleHandler::getLargestParticle ( ) const

◆ getLargestParticleLocal()

BaseParticle * ParticleHandler::getLargestParticleLocal ( ) const

Gets a pointer to the largest BaseParticle (by interactionRadius) in the ParticleHandler of the local domain.

Returns
A pointer to the largest BaseParticle (by interactionRadius) in this ParticleHandler.
527 {
528  return largestParticle_;
529 }

References largestParticle_.

Referenced by ConstantMassFlowMaserBoundary::activateMaser(), ConstantMassFlowMaserBoundary::createPeriodicParticle(), getLargestInteractionRadiusLocal(), getLargestParticle(), RotatingDrum::setupInitialConditions(), and DPMBase::writeFstatHeader().

◆ getLiquidFilmVolume()

double ParticleHandler::getLiquidFilmVolume ( ) const
1381 {
1382  double liquidVolume = 0;
1383  for (auto i : objects_) {
1384  auto j = dynamic_cast<LiquidFilmParticle*>(i);
1385  if (j and !j->isMPIParticle()) liquidVolume += j->getLiquidVolume();
1386  }
1387  return getMPISum(liquidVolume);
1388 };
Definition: LiquidFilmParticle.h:36
Mdouble getLiquidVolume() const
Definition: LiquidFilmParticle.h:103

References getMPISum(), constants::i, and BaseHandler< BaseParticle >::objects_.

Referenced by LiquidMigrationMPI2Test::printTime().

◆ getLowestPositionComponentParticle()

BaseParticle * ParticleHandler::getLowestPositionComponentParticle ( int  i) const

Gets a pointer to the particle with the lowest coordinates in direction i in this ParticleHandler.

856 {
857 #ifdef MERCURYDPM_USE_MPI
858  logger(ERROR,"This function should not be used in parallel");
859 #endif
861 }
BaseParticle * getLowestPositionComponentParticleLocal(int i) const
Gets a pointer to the particle with the lowest coordinates in direction i in this ParticleHandler.
Definition: ParticleHandler.cc:829

References ERROR, getLowestPositionComponentParticleLocal(), constants::i, and logger.

◆ getLowestPositionComponentParticleLocal()

BaseParticle * ParticleHandler::getLowestPositionComponentParticleLocal ( int  i) const

Gets a pointer to the particle with the lowest coordinates in direction i in this ParticleHandler.

Parameters
[in]iDirection for which you want the particle with lowest coordinates.
Returns
A pointer to the particle with the lowest coordinates in the given direction in this ParticleHandler.
830 {
831 #ifdef MERCURYDPM_USE_MPI
832  logger(ERROR,"getLowestPositionComponentParticle() not implemented yet in parallel");
833 #endif
834  if (getSize() == 0)
835  {
836  logger(WARN, "No getLowestPositionComponentParticle(const int i) since there are no particles.");
837  return nullptr;
838  }
839  BaseParticle* p = nullptr;
840  Mdouble min = std::numeric_limits<Mdouble>::max();
841  for (BaseParticle* const pLoop : objects_)
842  {
843  if (!(pLoop->isMPIParticle() || pLoop->isPeriodicGhostParticle()))
844  {
845  if (pLoop->getPosition().getComponent(i) < min)
846  {
847  min = pLoop->getPosition().getComponent(i);
848  p = pLoop;
849  }
850  }
851  }
852  return p;
853 }

References ERROR, BaseHandler< BaseParticle >::getSize(), constants::i, logger, BaseHandler< BaseParticle >::objects_, and WARN.

Referenced by getLowestPositionComponentParticle().

◆ getLowestVelocityComponentParticle()

BaseParticle * ParticleHandler::getLowestVelocityComponentParticle ( int  i) const

Gets a pointer to the particle with the lowest velocity in direction i in this ParticleHandler.

929 {
930 #ifdef MERCURYDPM_USE_MPI
931  logger(ERROR,"This function should not be used in parallel");
932 #endif
934 }
BaseParticle * getLowestVelocityComponentParticleLocal(int i) const
Gets a pointer to the particle with the lowest velocity in direction i in this ParticleHandler.
Definition: ParticleHandler.cc:905

References ERROR, getLowestVelocityComponentParticleLocal(), constants::i, and logger.

◆ getLowestVelocityComponentParticleLocal()

BaseParticle * ParticleHandler::getLowestVelocityComponentParticleLocal ( int  i) const

Gets a pointer to the particle with the lowest velocity in direction i in this ParticleHandler.

Parameters
[in]iDirection for which you want the particle with lowest velocity.
Returns
A pointer to the particle with the lowest velocity in direction i in this ParticleHandler.
906 {
907  if (getSize() == 0)
908  {
909  logger(WARN, "No getLowestVelocityComponentParticle(const int i) since there are no particles");
910  return nullptr;
911  }
912  BaseParticle* p = nullptr;
913  Mdouble min = std::numeric_limits<Mdouble>::max();
914  for (BaseParticle* const pLoop : objects_)
915  {
916  if (!(pLoop->isMPIParticle() || pLoop->isPeriodicGhostParticle()))
917  {
918  if (pLoop->getVelocity().getComponent(i) < min)
919  {
920  min = pLoop->getVelocity().getComponent(i);
921  p = pLoop;
922  }
923  }
924  }
925  return p;
926 }

References BaseHandler< BaseParticle >::getSize(), constants::i, logger, BaseHandler< BaseParticle >::objects_, and WARN.

Referenced by getLowestVelocityComponentParticle().

◆ getMass()

Mdouble ParticleHandler::getMass ( ) const
612 {
613 #ifdef MERCURYDPM_USE_MPI
614  Mdouble massLocal = getMassLocal();
615  Mdouble massGlobal = 0.0;
616 
617  //Sum up over all domains
618  MPIContainer& communicator = MPIContainer::Instance();
619  communicator.allReduce(massLocal, massGlobal, MPI_SUM);
620 
621  return massGlobal;
622 #else
623  return getMassLocal();
624 #endif
625 }
Mdouble getMassLocal() const
Definition: ParticleHandler.cc:602

References getMassLocal(), and MPIContainer::Instance().

Referenced by BoundariesSelfTest::actionsAfterTimeStep(), FluxAndPeriodicBoundarySelfTest::actionsAfterTimeStep(), FluxBoundarySelfTest::actionsAfterTimeStep(), FixedClusterInsertionBoundary::checkBoundaryBeforeTimeStep(), RandomClusterInsertionBoundary::checkBoundaryBeforeTimeStep(), getCentreOfMass(), DPMBase::getTotalMass(), HeaterBoundaryTest::setupInitialConditions(), DPMBase::writeEneTimeStep(), and LawinenBox::writeEneTimeStep().

◆ getMassLocal()

Mdouble ParticleHandler::getMassLocal ( ) const
private
603 {
604  Mdouble m = 0;
605  for (auto p : *this)
606  if (!(p->isFixed() || p->isMPIParticle() || p->isPeriodicGhostParticle()))
607  m += p->getMass();
608  return m;
609 }

Referenced by getMass().

◆ getMassTimesPosition()

Vec3D ParticleHandler::getMassTimesPosition ( ) const
637 {
638 #ifdef MERCURYDPM_USE_MPI
639  Vec3D massTimesPositionLocal = getMassTimesPositionLocal();
640  Vec3D massTimesPositionGlobal = {0.0, 0.0, 0.0};
641 
642  // Sum up over all domains
643  MPIContainer& communicator = MPIContainer::Instance();
644  communicator.allReduce(massTimesPositionLocal.X, massTimesPositionGlobal.X, MPI_SUM);
645  communicator.allReduce(massTimesPositionLocal.Y, massTimesPositionGlobal.Y, MPI_SUM);
646  communicator.allReduce(massTimesPositionLocal.Z, massTimesPositionGlobal.Z, MPI_SUM);
647 
648  return massTimesPositionGlobal;
649 #else
650  return getMassTimesPositionLocal();
651 #endif
652 }
Vec3D getMassTimesPositionLocal() const
Definition: ParticleHandler.cc:627
Mdouble Y
Definition: Vector.h:66
Mdouble Z
Definition: Vector.h:66
Mdouble X
the vector components
Definition: Vector.h:66

References getMassTimesPositionLocal(), MPIContainer::Instance(), Vec3D::X, Vec3D::Y, and Vec3D::Z.

Referenced by getCentreOfMass(), and DPMBase::writeEneTimeStep().

◆ getMassTimesPositionLocal()

Vec3D ParticleHandler::getMassTimesPositionLocal ( ) const
private
628 {
629  Vec3D com = {0, 0, 0};
630  for (auto p : *this)
631  if (!(p->isFixed() || p->isMPIParticle() || p->isPeriodicGhostParticle()))
632  com += p->getMass() * p->getPosition();
633  return com;
634 }

Referenced by getMassTimesPosition().

◆ getMeanRadius()

Mdouble ParticleHandler::getMeanRadius ( ) const
805 {
806 #ifdef MERCURYDPM_USE_MPI
807  Mdouble sumRadiusLocal = getSumRadiusLocal();
808  unsigned numberOfRealParticlesLocal = getNumberOfRealObjectsLocal();
809 
810  Mdouble sumRadiusGlobal = 0.0;
811  unsigned numberOfRealParticlesGlobal = 0;
812 
813  //Sum up over all domains
814  MPIContainer& communicator = MPIContainer::Instance();
815  communicator.allReduce(sumRadiusLocal, sumRadiusGlobal, MPI_SUM);
816  communicator.allReduce(numberOfRealParticlesLocal, numberOfRealParticlesGlobal, MPI_SUM);
817 
818  return sumRadiusGlobal/numberOfRealParticlesGlobal;
819 #else
820  return getSumRadiusLocal() / getSize();
821 #endif
822 }
unsigned int getNumberOfRealObjectsLocal() const
Returns the number of real objects on a local domain. MPI particles and periodic particles are neglec...
Definition: ParticleHandler.cc:1283
Mdouble getSumRadiusLocal() const
Definition: ParticleHandler.cc:791

References getNumberOfRealObjectsLocal(), BaseHandler< BaseParticle >::getSize(), getSumRadiusLocal(), and MPIContainer::Instance().

Referenced by InitialConditions< SpeciesType >::getMeanRelativeContactRadius(), Sintering::getMeanRelativeContactRadius(), regimeForceUnitTest::getMeanRelativeContactRadius(), main(), GranuDrum::printTime(), Drum::printTime(), RotatingDrumWet::printTime(), regimeForceUnitTest::printTime(), and SingleParticle< SpeciesType >::writeEneTimeStep().

◆ getMomentum()

Vec3D ParticleHandler::getMomentum ( ) const
667 {
668  Vec3D momentum = {0, 0, 0};
669  for (auto p : *this)
670  if (!(p->isFixed() || p->isMPIParticle() || p->isPeriodicGhostParticle()))
671  momentum += p->getMomentum();
672  return getMPISum(momentum);
673 }

References getMPISum().

Referenced by DPMBase::getTotalMomentum(), main(), ParticleBeam::printTime(), and LawinenBox::writeEneTimeStep().

◆ getName()

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

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

Returns
The string "ParticleHandler".

Implements BaseHandler< BaseParticle >.

1248 {
1249  return "ParticleHandler";
1250 }

◆ getNumberOfFixedObjects()

unsigned int ParticleHandler::getNumberOfFixedObjects ( ) const

Computes the number of fixed particles in the whole simulation.

1359 {
1360 #ifdef MERCURYDPM_USE_MPI
1361  unsigned int numberOfFixedParticlesLocal = getNumberOfFixedObjectsLocal();
1362  unsigned int numberOfFixedParticles = 0;
1363 
1364  MPIContainer& communicator = MPIContainer::Instance();
1365  communicator.allReduce(numberOfFixedParticlesLocal, numberOfFixedParticles, MPI_SUM);
1366  return numberOfFixedParticles;
1367 #else
1369 #endif
1370 }
unsigned int getNumberOfFixedObjectsLocal() const
Computes the number of Fixed particles on a local domain.
Definition: ParticleHandler.cc:1342

References getNumberOfFixedObjectsLocal(), and MPIContainer::Instance().

Referenced by LawinenBox::setupInitialConditions().

◆ getNumberOfFixedObjectsLocal()

unsigned int ParticleHandler::getNumberOfFixedObjectsLocal ( ) const

Computes the number of Fixed particles on a local domain.

Loops over all particles to check if the particle is fixed or not, in a local domain.

Returns
the number of fixed particles in a local domain
1343 {
1344  unsigned int numberOfFixedParticles = 0;
1345  for (BaseParticle* particle : *this)
1346  {
1347  if (particle->isFixed())
1348  {
1349  numberOfFixedParticles++;
1350  }
1351  }
1352  return numberOfFixedParticles;
1353 }
bool isFixed() const override
Is fixed Particle function. It returns whether a Particle is fixed or not, by checking its inverse Ma...
Definition: BaseParticle.h:93

References BaseParticle::isFixed().

Referenced by getNumberOfFixedObjects().

◆ getNumberOfFixedParticles()

unsigned int ParticleHandler::getNumberOfFixedParticles ( ) const

Gets the number of particles that are fixed.

1010 {
1011  return NFixedParticles_;
1012 }

References NFixedParticles_.

◆ getNumberOfObjects()

unsigned int ParticleHandler::getNumberOfObjects ( ) const
overridevirtual

Returns the number of objects in the container. In parallel code this practice is forbidden to avoid confusion with real and fake particles. If the size of the container is wished, call size()

Reimplemented from BaseHandler< BaseParticle >.

1326 {
1327 //#ifdef MERCURYDPM_USE_MPI
1328 // MPIContainer& communicator = MPIContainer::Instance();
1329 // if (communicator.getNumberOfProcessors() > 1)
1330 // {
1331 // logger(WARN,"When compiling with MPI please do not use getNumberOfObjects(). Instead use: getNumberOfRealObjectsLocal(), getNumberOfRealObjects() or getSize()");
1332 // }
1333 //#endif
1334  return getSize();
1335 }

References BaseHandler< BaseParticle >::getSize().

Referenced by Contact::actionsAfterSolve(), TwoByTwoMPIDomainMPI4Test::actionsAfterTimeStep(), GranularCollapse::actionsAfterTimeStep(), MercuryProblem::actionsAfterTimeStep(), LawinenBox::actionsBeforeTimeStep(), SmoothChute::actionsBeforeTimeStep(), AngleOfRepose::actionsBeforeTimeStep(), Chutebelt::actionsBeforeTimeStep(), ChutePeriodic::add_flow_particles(), SilbertPeriodic::add_flow_particles(), ChuteWithPeriodicInflow::AddContinuingBottom(), Chute::addFlowParticlesCompactly(), NautaMixer::addParticles(), statistics_while_running< T >::auto_set_domain(), statistics_while_running< T >::auto_set_z(), Mercury3Dclump::checkClumpForInteractionPeriodic(), DPMBase::checkParticleForInteractionLocalPeriodic(), ChuteWithContraction::ChuteWithContraction(), ChuteWithPeriodicInflowAndContinuingBottom::ChuteWithPeriodicInflowAndContinuingBottom(), ChuteWithPeriodicInflowAndContraction::ChuteWithPeriodicInflowAndContraction(), ChuteWithPeriodicInflowAndVariableBottom::ChuteWithPeriodicInflowAndVariableBottom(), ChuteWithPeriodicInflow::cleanChute(), ChuteWithContraction::cleanChute(), Funnel::cleanChute(), Chute::cleanChute(), ClosedCSCRestart::ClosedCSCRestart(), ClosedCSCRun::ClosedCSCRun(), ContractionWithPeriodicInflow::ContractionWithPeriodicInflow(), Slide::create_rough_wall(), AngleOfRepose::createBaseSpecies(), SilbertPeriodic::createBaseSpecies(), CSCInit::CSCInit(), ChuteWithPeriodicInflow::ExtendInWidth(), SphericalIndenter::getBedHeight(), getNumberOfUnfixedParticles(), InitialConditions< SpeciesType >::InitialConditions(), ChuteWithPeriodicInflow::integrateBeforeForceComputation(), ContactDetectionIntersectionOfWallsTest::introduceParticlesAtWall(), LawinenBox::LawinenBox(), main(), ChuteBottom::makeRoughBottom(), LiquidMigrationSelfTest::outputXBallsData(), SphericalIndenter::outputXBallsData(), LawinenBox::printTime(), GranuDrum::printTime(), GranuHeap::printTime(), ChuteWithPeriodicInflow::printTime(), Drum::printTime(), RotatingDrumWet::printTime(), VerticalMixer::printTime(), SilbertPeriodic::printTime(), vibratedBed::printTime(), Chute::printTime(), readAndCreateObject(), CSCInit::save(), save(), saveNumberPSDtoCSV(), ClosedCSCWalls::saveWalls(), CSCWalls::saveWalls(), MeshTriangle::setHandler(), LawinenBox::setupInitialConditions(), ClosedCSCWalls::setupInitialConditions(), CSCRun::setupInitialConditions(), CSCWalls::setupInitialConditions(), Binary::setupInitialConditions(), FreeCooling2DinWalls::setupInitialConditions(), FreeCooling2DinWallsDemo::setupInitialConditions(), FreeCooling3DDemoProblem::setupInitialConditions(), FreeCooling3DinWallsDemo::setupInitialConditions(), FreeCoolingDemoProblem::setupInitialConditions(), HourGlass2D::setupInitialConditions(), HourGlass::setupInitialConditions(), Cstatic2d::setupInitialConditions(), Cstatic3D::setupInitialConditions(), AngleOfRepose::setupInitialConditions(), SilbertPeriodic::setupInitialConditions(), Chutebelt::setupInitialConditions(), ParticleCreation::setupInitialConditions(), TriangulatedScrewSelfTest::setupInitialConditions(), TriangulatedStepWallSelfTest::setupInitialConditions(), TriangulatedWallSelfTest::setupInitialConditions(), SphericalIndenter::setupInitialConditions(), ScalingTestRun::setupInitialConditions(), GranularCollapse::setupInitialConditions(), Tutorial11::setupInitialConditions(), MD_demo::setupInitialConditions(), ChuteBottom::setupInitialConditions(), and SingleParticleIndenter::SingleParticleIndenter().

◆ getNumberOfRealObjects()

unsigned int ParticleHandler::getNumberOfRealObjects ( ) const

Returns the number of real objects (on all processors)

1305 {
1306 #ifdef MERCURYDPM_USE_MPI
1307  MPIContainer& communicator = MPIContainer::Instance();
1308  unsigned int numberOfRealParticles = getNumberOfRealObjectsLocal();
1309 
1310  // \todo MX: use an allreduce here
1311  //Combine the total number of Particles into one number on processor 0
1312  communicator.reduce(numberOfRealParticles, MPI_SUM);
1313 
1314  //Broadcast new number to all the processorsi
1315  communicator.broadcast(numberOfRealParticles);
1316  return numberOfRealParticles;
1317 #else
1318  return getSize();
1319 #endif
1320 }

References MPIContainer::broadcast(), getNumberOfRealObjectsLocal(), BaseHandler< BaseParticle >::getSize(), and MPIContainer::Instance().

Referenced by Membrane::createVertexParticles(), DPMBase::decompose(), and HourGlass2D::setupInitialConditions().

◆ getNumberOfRealObjectsLocal()

unsigned int ParticleHandler::getNumberOfRealObjectsLocal ( ) const

Returns the number of real objects on a local domain. MPI particles and periodic particles are neglected.

Returns
the number of real particles (neglecting MPI and periodic) on a local domain
Todo:
MX: in future also add the periodic mpi particles
1284 {
1285 #ifdef MERCURYDPM_USE_MPI
1286  const MPIContainer& communicator = MPIContainer::Instance();
1287  if (communicator.getNumberOfProcessors() > 1)
1288  {
1289  unsigned int numberOfFakeParticles = 0;
1290  numberOfFakeParticles += getDPMBase()->domainHandler.getCurrentDomain()->getNumberOfTrueMPIParticles();
1292  logger.assert_debug(numberOfFakeParticles <= getSize(), "More fake particles than getSize()");
1293  return (getSize() - numberOfFakeParticles);
1294  }
1295  else
1296  {
1297  return getSize();
1298  }
1299 #else
1300  return getSize();
1301 #endif
1302 }
PeriodicBoundaryHandler periodicBoundaryHandler
Internal handler that deals with periodic boundaries, especially in a parallel build.
Definition: DPMBase.h:1457
DomainHandler domainHandler
An object of the class DomainHandler which deals with parallel code.
Definition: DPMBase.h:1462
Domain * getCurrentDomain()
Gets the domain assigned to the processor.
Definition: DomainHandler.cc:250
unsigned int getNumberOfTrueMPIParticles()
Obtains the number of particles in the particleHandler that are MPIParticles, but NOT periodic partic...
Definition: Domain.cc:1679
std::size_t getNumberOfProcessors() const
Get the total number of processors participating in this simulation.
Definition: MpiContainer.cc:104
unsigned int getNumberOfPeriodicGhostParticles()
Returns the number of particles that are flagged is periodicGhostParticle.
Definition: PeriodicBoundaryHandler.cc:357

References DPMBase::domainHandler, DomainHandler::getCurrentDomain(), BaseHandler< BaseParticle >::getDPMBase(), PeriodicBoundaryHandler::getNumberOfPeriodicGhostParticles(), MPIContainer::getNumberOfProcessors(), Domain::getNumberOfTrueMPIParticles(), BaseHandler< BaseParticle >::getSize(), MPIContainer::Instance(), logger, and DPMBase::periodicBoundaryHandler.

Referenced by MaserRepeatedOutInMPI2Test::actionsAfterSolve(), TwoByTwoMPIDomainMPI4Test::actionsAfterTimeStep(), getMeanRadius(), getNumberOfRealObjects(), and DPMBase::outputXBallsData().

◆ getNumberOfUnfixedParticles()

unsigned int ParticleHandler::getNumberOfUnfixedParticles ( ) const

Gets the number of particles that are not fixed.

1018 {
1020 }
unsigned int getNumberOfObjects() const override
Returns the number of objects in the container. In parallel code this practice is forbidden to avoid ...
Definition: ParticleHandler.cc:1325

References getNumberOfObjects(), and NFixedParticles_.

◆ getParticleAttribute()

template<typename T >
std::enable_if<std::is_scalar<T>::value, T>::type ParticleHandler::getParticleAttribute ( std::function< T(BaseParticle *)>  attribute,
AttributeType  type 
) const
inline

Computes an attribute type (min/max/..) of a particle attribute(position/velocity) in the global domain.

Many functions the particleHandler return a pointer to a BaseParticle, i.e. the fastest particle, however in parallel this is not useful as pointers can't be send across processes. This function gives the flexibility to find a global particle extremum such as the fastest particle Velocity or lowest particle position.

Parameters
[in]attributeA function that obtains a scalar from a particle. i.e. position or radius
[in]typeAn AttributeType tells this function what to do with the attribute, take the maximum or the minimum
Returns
Returns a scalar value representing the AttributeType of the Attribute: In easier terms returns the max/min/... of a particle attribute such as radius
306  {
307 #ifdef MERCURYDPM_USE_MPI
308  T particleAttributeLocal = getParticleAttributeLocal(attribute, type);
309  T particleAttributeGlobal;
310 
311  //Communicate local to global using the approriate rule
312  MPIContainer& communicator = MPIContainer::Instance();
313  switch(type)
314  {
315  case AttributeType::MIN :
316  communicator.allReduce(particleAttributeLocal,particleAttributeGlobal,MPI_MIN);
317  break;
318  case AttributeType::MAX :
319  communicator.allReduce(particleAttributeLocal,particleAttributeGlobal,MPI_MAX);
320  break;
321  default :
322  logger(ERROR,"Attribute type is not recognised");
323  break;
324  }
325  return particleAttributeGlobal;
326 #else
327  return getParticleAttributeLocal(attribute, type);
328 #endif
329  }
@ MIN
Definition: ParticleHandler.h:39
std::enable_if< std::is_scalar< T >::value, T >::type getParticleAttributeLocal(std::function< T(BaseParticle *)> attribute, AttributeType type) const
Computes an attribute type (min/max/..) of a particle attribute (position/velocity) in a local domain...
Definition: ParticleHandler.h:244

References ERROR, getParticleAttributeLocal(), MPIContainer::Instance(), logger, MAX, and MIN.

◆ getParticleAttributeLocal()

template<typename T >
std::enable_if<std::is_scalar<T>::value, T>::type ParticleHandler::getParticleAttributeLocal ( std::function< T(BaseParticle *)>  attribute,
AttributeType  type 
) const
inline

Computes an attribute type (min/max/..) of a particle attribute (position/velocity) in a local domain.

Computes an attribute type (min/max/..) of a particle attribute (position/velocity) in a local domain

Many functions the particleHandler return a pointer to a BaseParticle, i.e. the fastest particle, however in parallel this is not useful as pointers can't be send across processes. This function gives the flexibility to find a global particle extremum such as the fastest particle Velocity or lowest particle position.

Parameters
[in]attributeA function that obtains a scalar from a particle. i.e. position or radius
[in]typeAn AttributeType tells this function what to do with the attribute, take the maximum or the minimum
Returns
Returns a scalar value representing the AttributeType of the Attribute: In easier terms returns the max/min/... of a particle attribute such as radius
245  {
246  T attributeParticle;
247  T attributeFinal;
248 
249  if ((*this).getSize() == 0)
250  {
251  logger(WARN, "ParticleHandler is empty: returning 0.0");
252  attributeFinal = 0;
253  return 0.0;
254  }
255  else
256  {
257  //Initialise with the first particle found
258  attributeParticle = attribute(objects_[0]);
259  attributeFinal = attributeParticle;
260 
261  //Find the final attribute
262  for (BaseParticle* particle : (*this))
263  {
264  //Obtain the attribute
265  if (!(particle->isMPIParticle() || particle->isPeriodicGhostParticle() || particle->isFixed()))
266  {
267  attributeParticle = attribute(particle);
268  }
269 
270  //Decide what to do with the magnitude of the attribute
271  switch (type)
272  {
273  case AttributeType::MIN :
274  if (attributeParticle < attributeFinal)
275  {
276  attributeFinal = attributeParticle;
277  }
278  break;
279  case AttributeType::MAX :
280  if (attributeParticle > attributeFinal)
281  {
282  attributeFinal = attributeParticle;
283  }
284  break;
285  default :
286  logger(ERROR, "Attribute type is not recognised");
287  break;
288  }
289  }
290  return attributeFinal;
291  }
292  }

References ERROR, logger, MAX, MIN, BaseHandler< BaseParticle >::objects_, and WARN.

Referenced by getParticleAttribute().

◆ getRotationalEnergy()

Mdouble ParticleHandler::getRotationalEnergy ( ) const
587 {
588 #ifdef MERCURYDPM_USE_MPI
589  Mdouble rotationalEnergyLocal = getRotationalEnergyLocal();
590  Mdouble rotationalEnergyGlobal = 0.0;
591 
592  //sum up over all domains
593  MPIContainer& communicator = MPIContainer::Instance();
594  communicator.allReduce(rotationalEnergyLocal, rotationalEnergyGlobal, MPI_SUM);
595 
596  return rotationalEnergyGlobal;
597 #else
598  return getRotationalEnergyLocal();
599 #endif
600 }
Mdouble getRotationalEnergyLocal() const
Definition: ParticleHandler.cc:573

References getRotationalEnergyLocal(), and MPIContainer::Instance().

Referenced by main(), DPMBase::writeEneTimeStep(), and LawinenBox::writeEneTimeStep().

◆ getRotationalEnergyLocal()

Mdouble ParticleHandler::getRotationalEnergyLocal ( ) const
private
574 {
575  Mdouble ene = 0;
576  for (auto p : *this)
577  {
578  if (!(p->isMPIParticle() || p->isPeriodicGhostParticle()))
579  {
580  ene += p->getRotationalEnergy();
581  }
582  }
583  return ene;
584 }

Referenced by getRotationalEnergy().

◆ getSmallestInteractionRadius()

Mdouble ParticleHandler::getSmallestInteractionRadius ( ) const

Returns the smallest interaction radius.

737 {
738 #ifdef MERCURYDPM_USE_MPI
739  //Compute the local value
740  Mdouble smallestInteractionRadiusLocal = getSmallestInteractionRadiusLocal();
741  Mdouble smallestInteractionRadiusGlobal = 0.0;
742 
743  //Obtain the global value
744  MPIContainer& communicator = MPIContainer::Instance();
745  communicator.allReduce(smallestInteractionRadiusLocal, smallestInteractionRadiusGlobal, MPI_MIN);
746 
747  return smallestInteractionRadiusGlobal;
748 
749 #else
751 #endif
752 }
Mdouble getSmallestInteractionRadiusLocal() const
Returns the smallest interaction radius of the current domain.
Definition: ParticleHandler.cc:721

References getSmallestInteractionRadiusLocal(), and MPIContainer::Instance().

Referenced by Contact::actionsAfterSolve(), main(), and saveNumberPSDtoCSV().

◆ getSmallestInteractionRadiusLocal()

Mdouble ParticleHandler::getSmallestInteractionRadiusLocal ( ) const

Returns the smallest interaction radius of the current domain.

722 {
723  if (!(getSmallestParticleLocal() == nullptr))
724  {
726  }
727  else
728  {
729  return 0.0;
730  }
731 }
BaseParticle * getSmallestParticleLocal() const
Gets a pointer to the smallest BaseParticle (by interactionRadius) in this ParticleHandler of the loc...
Definition: ParticleHandler.cc:502

References BaseParticle::getMaxInteractionRadius(), and getSmallestParticleLocal().

Referenced by MercuryBase::getHGridTargetMinInteractionRadius(), and getSmallestInteractionRadius().

◆ getSmallestParticle()

BaseParticle * ParticleHandler::getSmallestParticle ( ) const

Gets a pointer to the smallest BaseParticle (by interactionRadius) in this ParticleHandler of the local domain. When mercury is running in parallel this function throws an error since a pointer to another domain is useless.

Returns
A pointer to the to the smallest BaseParticle (by interactionRadius) in this ParticleHandler.
512 {
513 #ifdef MERCURYDPM_USE_MPI
514  logger(WARN,"getSmallestParticle should not be used in parallel; use getSmallestInteractionRadius or "
515  "ParticleSpecies::getSmallestParticleMass instead");
516  return nullptr;
517 #else
518  return getSmallestParticleLocal();
519 #endif
520 }

References getSmallestParticleLocal(), logger, and WARN.

Referenced by HGridOptimiser::initialise(), and saveNumberPSDtoCSV().

◆ getSmallestParticleLocal()

BaseParticle * ParticleHandler::getSmallestParticleLocal ( ) const

Gets a pointer to the smallest BaseParticle (by interactionRadius) in this ParticleHandler of the local domain.

Returns
A pointer to the to the smallest BaseParticle (by interactionRadius) in this ParticleHandler.
503 {
504  return smallestParticle_;
505 }

References smallestParticle_.

Referenced by getSmallestInteractionRadiusLocal(), getSmallestParticle(), RotatingDrum::setupInitialConditions(), and DPMBase::writeFstatHeader().

◆ getSumRadiusLocal()

Mdouble ParticleHandler::getSumRadiusLocal ( ) const
private
Returns
The sum of all particle radii
792 {
793  Mdouble sumRadius = 0;
794  for (BaseParticle* const p : objects_)
795  {
796  if (!(p->isMPIParticle() || p->isPeriodicGhostParticle()))
797  {
798  sumRadius += p->getRadius();
799  }
800  }
801  return sumRadius;
802 }

References BaseHandler< BaseParticle >::objects_.

Referenced by getMeanRadius().

◆ getVolume()

Mdouble ParticleHandler::getVolume ( ) const
1264 {
1265 #ifdef MERCURYDPM_USE_MPI
1266  Mdouble volumeLocal = getVolumeLocal();
1267  Mdouble volumeGlobal = 0.0;
1268 
1269  // sum up over all domains
1270  MPIContainer& communicator = MPIContainer::Instance();
1271  communicator.allReduce(volumeLocal, volumeGlobal, MPI_SUM);
1272 
1273  return volumeGlobal;
1274 #else
1275  return getVolumeLocal();
1276 #endif
1277 }
Mdouble getVolumeLocal() const
Definition: ParticleHandler.cc:1252

References getVolumeLocal(), and MPIContainer::Instance().

Referenced by PSDManualInsertionSelfTest::actionsAfterSolve(), ShearStage::actionsAfterTimeStep(), LeesEdwardsDemo::actionsAfterTimeStep(), ShiftingConstantMassFlowMaserBoundarySelfTest::actionsAfterTimeStep(), ShiftingMaserBoundarySelfTest::actionsAfterTimeStep(), TimeDependentPeriodicBoundary3DSelfTest::actionsAfterTimeStep(), TimeDependentPeriodicBoundaryTest::actionsAfterTimeStep(), FixedClusterInsertionBoundary::checkBoundaryBeforeTimeStep(), RandomClusterInsertionBoundary::checkBoundaryBeforeTimeStep(), and GranuHeap::GranuHeap().

◆ getVolumeLocal()

Mdouble ParticleHandler::getVolumeLocal ( ) const
private
1253 {
1254  Mdouble volume = 0;
1255  for (auto p : *this)
1256  {
1257  if (!(p->isFixed() || p->isPeriodicGhostParticle() || p->isMPIParticle()))
1258  volume += p->getVolume();
1259  }
1260  return volume;
1261 }

Referenced by getVolume().

◆ operator=()

ParticleHandler & ParticleHandler::operator= ( const ParticleHandler rhs)

Assignment operator.

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

This is not a copy assignment operator! It copies the DPMBase and all BaseParticle, and sets the other variables to 0. After that, it computes the smallest and largest particle in this handler.

86 {
87  if (this != &rhs)
88  {
89  clear();
90  largestParticle_ = nullptr;
91  smallestParticle_ = nullptr;
93  if (!objects_.empty())
94  {
97  }
98  }
99  logger(DEBUG, "ParticleHandler::operator = (const ParticleHandler& rhs) finished");
100  return *this;
101 }

References clear(), computeLargestParticle(), computeSmallestParticle(), BaseHandler< BaseParticle >::copyContentsFromOtherHandler(), DEBUG, largestParticle_, logger, BaseHandler< BaseParticle >::objects_, and smallestParticle_.

◆ readAndAddObject()

void ParticleHandler::readAndAddObject ( std::istream &  is)
overridevirtual
     \brief Create a new particle, based on the information from old-style restart data.
    &zwj;/

void readAndCreateOldObject(std::istream &is, const std::string& type);

/*!
   \brief Create a new particle in the WallHandler, based on the information provided in a restart file.
Parameters
[in]isThe input stream from which the information is read.

Implements BaseHandler< BaseParticle >.

1095 {
1097  addExistingObject(o);
1098 }
void addExistingObject(BaseParticle *P) override
Adds a BaseParticle to the ParticleHandler.
Definition: ParticleHandler.cc:131
BaseParticle * readAndCreateObject(std::istream &is)
Create a new particle, based on the information provided in a restart file.
Definition: ParticleHandler.cc:1065

References addExistingObject(), and readAndCreateObject().

Referenced by DPMBase::read().

◆ readAndCreateObject()

BaseParticle * ParticleHandler::readAndCreateObject ( std::istream &  is)

Create a new particle, based on the information provided in a restart file.

Parameters
[in]isThe input stream from which the information is read.
Todo:
check what is special about this case
1066 {
1067  std::string type;
1068  BaseParticle* particle = nullptr;
1069  if (getNumberOfObjects()>0) logger(DEBUG,"size % % %",getNumberOfObjects(),getLastObject()->getVelocity(),getLastObject()->getRadius());
1070  if (getStorageCapacity() > 0)
1071  {
1072  is >> type;
1073  logger(DEBUG, "ParticleHandler::readAndCreateObject(is): type %", type);
1074  particle = createObject(type);
1075  particle->setHandler(this);
1076  particle->read(is);
1077  }
1078  else //for insertion boundaries
1079  {
1081  is >> type;
1082  logger(DEBUG, "ParticleHandler::readAndCreateObject(is): type %", type);
1083  particle = createObject(type);
1084  particle->setHandler(this);
1085  particle->read(is);
1086  }
1087  particle->setSpecies(getDPMBase()->speciesHandler.getObject(particle->getIndSpecies()));
1088  return particle;
1089 }
unsigned int getStorageCapacity() const
Gets the storage capacity of this BaseHandler.
Definition: BaseHandler.h:662
BaseParticle * getLastObject()
Gets a pointer to the last Object in this BaseHandler.
Definition: BaseHandler.h:634
unsigned int getIndSpecies() const
Returns the index of the species associated with the interactable object.
Definition: BaseInteractable.h:88
void setHandler(ParticleHandler *handler)
Sets the pointer to the particle's ParticleHandler.
Definition: BaseParticle.cc:663
void read(std::istream &is) override
Particle read function, which accepts an std::istream as input.
Definition: BaseParticle.cc:374
void setSpecies(const ParticleSpecies *species)
Definition: BaseParticle.cc:818
static BaseParticle * createObject(const std::string &type)
Reads BaseParticle into the ParticleHandler from restart data.
Definition: ParticleHandler.cc:1025

References createObject(), DEBUG, BaseHandler< BaseParticle >::getDPMBase(), BaseInteractable::getIndSpecies(), BaseHandler< BaseParticle >::getLastObject(), getNumberOfObjects(), BaseHandler< BaseParticle >::getStorageCapacity(), logger, BaseParticle::read(), BaseParticle::setHandler(), and BaseParticle::setSpecies().

Referenced by InsertionBoundary::read(), and readAndAddObject().

◆ removedFixedParticle()

void ParticleHandler::removedFixedParticle ( )

Decrement of the number of fixed particles.

Todo:
MX: For Jonny, is this still required, keeping the parallel code in mind?
1240 {
1241  NFixedParticles_--;
1242 }

References NFixedParticles_.

Referenced by BaseParticle::unfix(), and BaseParticle::~BaseParticle().

◆ removeGhostObject()

void ParticleHandler::removeGhostObject ( unsigned int  index)

Removes a BaseParticle from the ParticleHandler without a global check, this is only to be done for mpi routines.

Parameters
[in]indexThe index of which BaseParticle has to be removed from this ParticleHandler.

The BaseParticle with index is removed and the last BaseParticle in the vector is moved to its position. It also removes the BaseParticle from the HGrid. This function is only called by the parallel routines where we are sure the particles have been flushed out of the communication boundaries.

423 {
424 #ifdef MERCURYDPM_USE_MPI
425 #ifdef CONTACT_LIST_HGRID
426  getDPMBase()->getPossibleContactList().remove_ParticlePosibleContacts(getObject(id));
427 #endif
429  // broadcast the particle removal
430  getDPMBase()->handleParticleRemoval(getObject(index)->getId());
432 #else
433  logger(ERROR, "This function should only be used interally for mpi routines");
434 #endif
435 }
virtual void removeObject(unsigned const int index)
Removes an Object from the BaseHandler.
Definition: BaseHandler.h:472
BaseParticle * getObject(const unsigned int id)
Gets a pointer to the Object at the specified index in the BaseHandler.
Definition: BaseHandler.h:613
virtual void hGridRemoveParticle(BaseParticle *obj UNUSED)
Definition: DPMBase.cc:1711

References ERROR, BaseHandler< BaseParticle >::getDPMBase(), BaseHandler< BaseParticle >::getObject(), DPMBase::handleParticleRemoval(), DPMBase::hGridRemoveParticle(), logger, and BaseHandler< T >::removeObject().

Referenced by DeletionBoundary::checkBoundaryAfterParticleMoved(), DPMBase::checkInteractionWithBoundaries(), PeriodicBoundaryHandler::clearCommunicationLists(), and DPMBase::deleteGhostParticles().

◆ removeLastObject()

void ParticleHandler::removeLastObject ( )

Removes the last BaseParticle from the ParticleHandler.

Function that removes the last object from this ParticleHandler. It also removes the particle from the HGrid.

442 {
443 #ifdef CONTACT_LIST_HGRID
444  getDPMBase()->getPossibleContactList().remove_ParticlePosibleContacts(getLastObject());
445 #endif
449 }
void removeLastObject()
Removes the last Object from the BaseHandler.
Definition: BaseHandler.h:511

References BaseHandler< BaseParticle >::getDPMBase(), BaseHandler< BaseParticle >::getLastObject(), DPMBase::handleParticleRemoval(), DPMBase::hGridRemoveParticle(), and BaseHandler< T >::removeLastObject().

Referenced by Penetration::setupInitialConditions().

◆ removeObject()

void ParticleHandler::removeObject ( unsigned int  index)
overridevirtual

Removes a BaseParticle from the ParticleHandler.

Parameters
[in]indexThe index of which BaseParticle has to be removed from this ParticleHandler.

The BaseParticle with index is removed and the last BaseParticle in the vector is moved to its position. It also removes the BaseParticle from the HGrid. When running this in parallel a warning is thrown that deleting particles might cause havoc in the communication between boundaries, as the deleted particle might still be in one of the boundary lists

Reimplemented from BaseHandler< BaseParticle >.

395 {
396 #ifdef MERCURYDPM_USE_MPI
397  MPIContainer& communicator = MPIContainer::Instance();
398  if (communicator.getNumberOfProcessors() > 1 )
399  {
400  logger(WARN, "[ParticleHandler::removeObject(const unsigned int)] Using the function removeObject in parallel could lead to out-of-sync communication, Instead use deletion boundaries");
401  }
402 #endif
403 #ifdef CONTACT_LIST_HGRID
404  getDPMBase()->getPossibleContactList().remove_ParticlePosibleContacts(getObject(id));
405 #endif
407  // broadcast the particle removal
408  getDPMBase()->handleParticleRemoval(getObject(index)->getId());
410 }

References BaseHandler< BaseParticle >::getDPMBase(), MPIContainer::getNumberOfProcessors(), BaseHandler< BaseParticle >::getObject(), DPMBase::handleParticleRemoval(), DPMBase::hGridRemoveParticle(), MPIContainer::Instance(), logger, BaseHandler< T >::removeObject(), and WARN.

Referenced by AngleOfRepose::actionsBeforeTimeStep(), PeriodicWallsWithSlidingFrictionUnitTest::actionsBeforeTimeStep(), SilbertPeriodic::add_flow_particles(), CircularPeriodicBoundary::checkBoundaryAfterParticleMoved(), ConstantMassFlowMaserBoundary::checkBoundaryAfterParticleMoved(), DeletionBoundary::checkBoundaryAfterParticleMoved(), ChuteWithContraction::ChuteWithContraction(), ChuteWithPeriodicInflowAndContraction::ChuteWithPeriodicInflowAndContraction(), ChuteWithPeriodicInflow::cleanChute(), ChuteWithContraction::cleanChute(), Funnel::cleanChute(), Chute::cleanChute(), ContactDetectionTester::cleanup(), ContractionWithPeriodicInflow::ContractionWithPeriodicInflow(), ChuteBottom::makeRoughBottom(), CurvyChute::recreateBottom(), DPMBase::removeDuplicatePeriodicParticles(), CSCWalls::saveWalls(), and AngleOfRepose::setupInitialConditions().

◆ saveNumberPSDtoCSV()

void ParticleHandler::saveNumberPSDtoCSV ( std::string  csvFileName,
std::vector< double diameterBins = {} 
)
1391 {
1392  //check that there is at least one particle in the handler
1393  if (getNumberOfObjects()==0) {
1394  logger(WARN, "saveNumberPSDtoCSV: No PSD written, as particleHandler is empty.");
1395  }
1396 
1397  // check that the diameter vector is set
1398 #ifdef MERCURYDPM_USE_MPI
1399  double rMin = getSmallestInteractionRadius();
1400  double rMax = getLargestInteractionRadius();
1401 #else
1402  double rMin = getSmallestParticle()->getRadius();
1403  double rMax = getLargestParticle()->getRadius();
1404 #endif
1405  if (diameterBins.empty()) {
1406  size_t n = std::min(100,(int)std::ceil(getNumberOfObjects()/20));
1407  diameterBins.reserve(n);
1408  double dr = (rMax-rMin)/(n-1);
1409  for (size_t i = 0; i<n-1; i++) {
1410  diameterBins.push_back(2.0 * (rMin + i * dr));
1411  }
1412  } else {
1413  // make sure values are in increasing order
1414  std::sort(diameterBins.begin(), diameterBins.end());
1415  }
1416 
1417  // set the last bin to include the largest particle
1418  if (diameterBins.back() < 2.0 * rMax) {
1419  diameterBins.push_back(2.0 * rMax);
1420  }
1421 
1422  // create a psd structure
1423  struct PSD {
1424  double diameter;
1425  double probability;
1426  };
1427  std::vector<PSD> psd;
1428  size_t n = diameterBins.size();
1429  psd.reserve(n);
1430  for (const auto bin : diameterBins) {
1431  psd.push_back({bin,0.0});
1432  }
1433 
1434  for (const auto p : *this) {
1435  double d = 2.0*p->getRadius();
1436  for (auto& bin : psd) {
1437  if (d <= bin.diameter) {
1438  bin.probability += 1./getNumberOfObjects();
1439  break;
1440  }
1441  }
1442  }
1443 
1444  logger(INFO,"Writing PSD to %",csvFileName);
1445  std::ofstream csv(csvFileName);
1446  logger.assert_always(csv.is_open(),"File % could not be opened",csvFileName);
1447  csv << "Diameter" << ',' << "Probability Number Distribution" << '\n';
1448  for (const auto bin : psd) {
1449  csv << bin.diameter << ',' << bin.probability << '\n';
1450  }
1451  csv.close();
1452 }
const unsigned n
Definition: CG3DPackingUnitTest.cpp:32
Mdouble getRadius() const
Returns the particle's radius.
Definition: BaseParticle.h:348
Contains a vector with radii and probabilities of a user defined particle size distribution (PSD)
Definition: PSD.h:65
Mdouble getLargestInteractionRadius() const
Returns the largest interaction radius.
Definition: ParticleHandler.cc:772
Mdouble getSmallestInteractionRadius() const
Returns the smallest interaction radius.
Definition: ParticleHandler.cc:736
BaseParticle * getSmallestParticle() const
Gets a pointer to the smallest BaseParticle (by interactionRadius) in this ParticleHandler of the loc...
Definition: ParticleHandler.cc:511

References getLargestInteractionRadius(), getLargestParticle(), getNumberOfObjects(), BaseParticle::getRadius(), getSmallestInteractionRadius(), getSmallestParticle(), constants::i, INFO, logger, n, and WARN.

Referenced by main().

◆ write()

Member Data Documentation

◆ largestParticle_

BaseParticle* ParticleHandler::largestParticle_
private

A pointer to the largest BaseParticle (by interactionRadius) in this ParticleHandler.

Todo:
TW: note that checkExtrema gets called if a particle gets created and its Species and Radius gets set, even if it's not yet included in the particleHandler! This is necessary to check a not included particle for overlaps before inserting it into the handler. Not sure if this is a sensible structure; to be discussed. Note: these statistic now include mpi and ghost particles as well

Referenced by checkExtrema(), checkExtremaOnDelete(), clear(), computeLargestParticle(), getLargestParticleLocal(), operator=(), ParticleHandler(), and ~ParticleHandler().

◆ NFixedParticles_

unsigned int ParticleHandler::NFixedParticles_
private

◆ smallestParticle_

BaseParticle* ParticleHandler::smallestParticle_
private

A pointer to the smallest BaseParticle (by interactionRadius) in this ParticleHandler.

Referenced by checkExtrema(), checkExtremaOnDelete(), clear(), computeSmallestParticle(), getSmallestParticleLocal(), operator=(), ParticleHandler(), and ~ParticleHandler().


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