52 logger(
DEBUG,
"ParticleHandler::ParticleHandler() finished");
74 logger(
DEBUG,
"ParticleHandler::ParticleHandler(const ParticleHandler &PH) finished");
97 logger(
DEBUG,
"ParticleHandler::operator = (const ParticleHandler& rhs) finished");
110 logger(
DEBUG,
"ParticleHandler::~ParticleHandler() finished");
133 logger(
WARN,
"WARNING: The particle with ID % that is added in ParticleHandler::addObject does not have a "
134 "species yet. Please make sure that you have "
135 "set the species somewhere in the driver code.", P->
getId());
173 logger(
WARN,
"WARNING: The particle with ID % that is added in "
174 "ParticleHandler::addObject does not have a species yet. "
175 "Please make sure that you have "
176 "set the species somewhere in the driver code.", P->
getId());
178 #ifdef MERCURY_USE_MPI
183 insertParticle =
true;
216 #ifdef MERCURY_USE_MPI
251 #ifdef MERCURY_USE_MPI
268 logger(
WARN,
"Function addObject(int fromProcessor, BaseParticle* p) should not be used in serial code");
284 #ifdef MERCURY_USE_MPI
286 if (fromProcessor == toProcessor)
332 "Function addGhostObject(int fromProcessor, int toProcessor, BaseParticle* p) should not be used in serial code");
345 #ifdef MERCURY_USE_MPI
348 logger(
WARN,
"[ParticleHandler::adGhostObject(BaseParticle*)] "
349 "WARNING: The particle with ID % that is added in "
350 "ParticleHandler::addObject does not have a species yet."
351 " Please make sure that you have "
352 "set the species somewhere in the driver code.", P->
getId());
376 "Function ParticleHandler::mpiAddObject(BaseParticle* P) should only be called when compiling with parallel build on");
391 #ifdef MERCURY_USE_MPI
395 logger(
WARN,
"[ParticleHandler::removeObject(const unsigned int)] Using the function removeObject in parallel could lead to out-of-sync communication, Instead use deletion boundaries");
398 #ifdef CONTACT_LIST_HGRID
419 #ifdef MERCURY_USE_MPI
420 #ifdef CONTACT_LIST_HGRID
428 logger(
ERROR,
"This function should only be used interally for mpi routines");
438 #ifdef CONTACT_LIST_HGRID
449 logger(
DEBUG,
"No particles, so cannot compute the smallest particle.");
454 Mdouble min = std::numeric_limits<Mdouble>::max();
460 if (particle->getMaxInteractionRadius() < min)
473 logger(
DEBUG,
"No particles, so cannot compute the largest particle.");
477 Mdouble max = -std::numeric_limits<Mdouble>::max();
483 if (particle->getMaxInteractionRadius() > max)
507 #ifdef MERCURY_USE_MPI
508 logger(
WARN,
"getSmallestParticle should not be used in parallel; use getSmallestInteractionRadius or "
509 "ParticleSpecies::getSmallestParticleMass instead");
530 #ifdef MERCURY_USE_MPIO
531 logger(
WARN,
"getLargestParticle() should not be used in parallel; use getLargestInteractionRadius instead");
543 if (!(p->isMPIParticle() || p->isPeriodicGhostParticle()))
545 ene += p->getKineticEnergy();
553 #ifdef MERCURY_USE_MPI
555 Mdouble kineticEnergyGlobal = 0.0;
559 communicator.allReduce(kineticEnergyLocal, kineticEnergyGlobal, MPI_SUM);
561 return kineticEnergyGlobal;
572 if (!(p->isMPIParticle() || p->isPeriodicGhostParticle()))
574 ene += p->getRotationalEnergy();
582 #ifdef MERCURY_USE_MPI
584 Mdouble rotationalEnergyGlobal = 0.0;
588 communicator.allReduce(rotationalEnergyLocal, rotationalEnergyGlobal, MPI_SUM);
590 return rotationalEnergyGlobal;
600 if (!(p->isFixed() || p->isMPIParticle() || p->isPeriodicGhostParticle()))
607 #ifdef MERCURY_USE_MPI
613 communicator.allReduce(massLocal, massGlobal, MPI_SUM);
623 Vec3D com = {0, 0, 0};
625 if (!(p->isFixed() || p->isMPIParticle() || p->isPeriodicGhostParticle()))
626 com += p->getMass() * p->getPosition();
632 #ifdef MERCURY_USE_MPI
634 Vec3D massTimesPositionGlobal = {0.0, 0.0, 0.0};
638 communicator.allReduce(massTimesPositionLocal.
X, massTimesPositionGlobal.
X, MPI_SUM);
639 communicator.allReduce(massTimesPositionLocal.
Y, massTimesPositionGlobal.
Y, MPI_SUM);
640 communicator.allReduce(massTimesPositionLocal.
Z, massTimesPositionGlobal.
Z, MPI_SUM);
642 return massTimesPositionGlobal;
662 Vec3D momentum = {0, 0, 0};
664 if (!(p->isFixed() || p->isMPIParticle() || p->isPeriodicGhostParticle()))
665 momentum += p->getMomentum();
671 Vec3D momentum = {0, 0, 0};
673 if (!(p->isFixed() || p->isMPIParticle() || p->isPeriodicGhostParticle()))
674 momentum += p->getAngularMomentum();
685 logger(
WARN,
"No particles to set getFastestParticle()");
689 Mdouble maxSpeed = -std::numeric_limits<Mdouble>::max();
692 if (!(pLoop->isMPIParticle() || pLoop->isPeriodicGhostParticle()))
694 if ((pLoop->getVelocity().getLength()) > maxSpeed)
696 maxSpeed = pLoop->getVelocity().getLength();
706 #ifdef MERCURY_USE_MPI
707 logger(
ERROR,
"This function should not be used in parallel");
732 #ifdef MERCURY_USE_MPI
735 Mdouble smallestInteractionRadiusGlobal = 0.0;
739 communicator.allReduce(smallestInteractionRadiusLocal, smallestInteractionRadiusGlobal, MPI_MIN);
741 return smallestInteractionRadiusGlobal;
768 #ifdef MERCURY_USE_MPI
770 Mdouble largestInteractionRadiusGlobal = 0.0;
774 communicator.allReduce(largestInteractionRadiusLocal, largestInteractionRadiusGlobal, MPI_MAX);
776 return largestInteractionRadiusGlobal;
790 if (!(p->isMPIParticle() || p->isPeriodicGhostParticle()))
792 sumRadius += p->getRadius();
800 #ifdef MERCURY_USE_MPI
805 unsigned numberOfRealParticlesGlobal = 0;
809 communicator.allReduce(sumRadiusLocal, sumRadiusGlobal, MPI_SUM);
810 communicator.allReduce(numberOfRealParticlesLocal, numberOfRealParticlesGlobal, MPI_SUM);
812 return sumRadiusGlobal/numberOfRealParticlesGlobal;
825 #ifdef MERCURY_USE_MPI
826 logger(
ERROR,
"getLowestPositionComponentParticle() not implemented yet in parallel");
830 logger(
WARN,
"No getLowestPositionComponentParticle(const int i) since there are no particles.");
834 Mdouble min = std::numeric_limits<Mdouble>::max();
837 if (!(pLoop->isMPIParticle() || pLoop->isPeriodicGhostParticle()))
839 if (pLoop->getPosition().getComponent(i) < min)
841 min = pLoop->getPosition().getComponent(i);
851 #ifdef MERCURY_USE_MPI
852 logger(
ERROR,
"This function should not be used in parallel");
866 logger(
WARN,
"No getHighestPositionComponentParticle(const int i) since there are no particles.");
870 Mdouble max = -std::numeric_limits<Mdouble>::max();
873 if (!(pLoop->isMPIParticle() || pLoop->isPeriodicGhostParticle()))
875 if (pLoop->getPosition().getComponent(i) > max)
877 max = pLoop->getPosition().getComponent(i);
888 #ifdef MERCURY_USE_MPI
889 logger(
ERROR,
"This function should not be used in parallel");
903 logger(
WARN,
"No getLowestVelocityComponentParticle(const int i) since there are no particles");
907 Mdouble min = std::numeric_limits<Mdouble>::max();
910 if (!(pLoop->isMPIParticle() || pLoop->isPeriodicGhostParticle()))
912 if (pLoop->getVelocity().getComponent(i) < min)
914 min = pLoop->getVelocity().getComponent(i);
924 #ifdef MERCURY_USE_MPI
925 logger(
ERROR,
"This function should not be used in parallel");
939 logger(
WARN,
"No getHighestVelocityComponentParticle(const int i) since there are no particles");
943 Mdouble max = -std::numeric_limits<Mdouble>::max();
946 if (!(pLoop->isMPIParticle() || pLoop->isPeriodicGhostParticle()))
948 if (pLoop->getVelocity().getComponent(i) > max)
950 max = pLoop->getVelocity().getComponent(i);
960 #ifdef MERCURY_USE_MPI
961 logger(
ERROR,
"This function should not be used in parallel");
986 std::function<Mdouble(BaseParticle*)> particleAttribute = [](
BaseParticle* p) {
return p->getPosition().X; };
991 return positionXGlobal;
1015 if (type ==
"BaseParticle") {
1019 else if (type ==
"SphericalParticle")
1023 else if (type ==
"LiquidFilmParticle")
1027 else if (type ==
"SuperQuadricParticle")
1031 else if (type ==
"ThermalParticle")
1037 logger(
WARN,
"Particle type % not understood in restart file. Particle will not be read.", type);
1052 logger(
DEBUG,
"ParticleHandler::readAndCreateObject(is): type %", type);
1060 logger(
DEBUG,
"ParticleHandler::readAndCreateObject(is): type %", type);
1128 #ifdef MERCURY_USE_MPI
1134 os << (*it) <<
'\n';
1138 os <<
"Particles " <<
getSize() <<
'\n';
1141 os << (*it) <<
'\n';
1197 if (particle->getIndSpecies() == indSpecies)
1199 particle->getSpecies()->computeMass(particle);
1208 particle->getSpecies()->computeMass(particle);
1227 return "ParticleHandler";
1233 for (
auto p : *
this)
1235 if (!(p->isFixed() || p->isPeriodicGhostParticle() || p->isMPIParticle()))
1236 volume += p->getVolume();
1243 #ifdef MERCURY_USE_MPI
1249 communicator.allReduce(volumeLocal, volumeGlobal, MPI_SUM);
1251 return volumeGlobal;
1263 #ifdef MERCURY_USE_MPI
1267 unsigned int numberOfFakeParticles = 0;
1270 logger.assert_debug(numberOfFakeParticles <=
getSize(),
"More fake particles than getSize()");
1271 return (
getSize() - numberOfFakeParticles);
1284 #ifdef MERCURY_USE_MPI
1290 communicator.reduce(numberOfRealParticles, MPI_SUM);
1293 communicator.
broadcast(numberOfRealParticles);
1294 return numberOfRealParticles;
1322 unsigned int numberOfFixedParticles = 0;
1327 numberOfFixedParticles++;
1330 return numberOfFixedParticles;
1338 #ifdef MERCURY_USE_MPI
1340 unsigned int numberOfFixedParticles = 0;
1343 communicator.allReduce(numberOfFixedParticlesLocal, numberOfFixedParticles, MPI_SUM);
1344 return numberOfFixedParticles;
1354 i->actionsAfterTimeStep();
1359 double liquidVolume = 0;
Mdouble getVolume() const
This class contains all information and functions required for communication between processors...
void read(std::istream &is) override
Particle read function, which accepts an std::istream as input.
void copyDataFromParticleToMPIParticle(BaseParticle *p)
BaseParticle * getLargestParticle() const
Returns the pointer of the largest particle in the particle handler. When mercury is running in paral...
virtual void handleParticleRemoval(unsigned int id)
Handles the removal of particles from the particleHandler.
unsigned int getId() const
Returns the unique identifier of any particular object.
virtual void hGridUpdateParticle(BaseParticle *obj UNUSED)
void checkExtremaOnDelete(BaseParticle *P)
Checks if the extrema of this ParticleHandler needs updating when a particle is deleted.
void write(std::ostream &os) const
virtual void hGridInsertParticle(BaseParticle *obj UNUSED)
static MPIContainer & Instance()
fetch the instance to be used for communication
Mdouble X
the vector components
void removeObject(unsigned int index) override
Removes a BaseParticle from the ParticleHandler.
A spherical particle is the most simple particle used in MercuryDPM.
void addObject(BaseParticle *P) override
Adds a BaseParticle to the ParticleHandler.
unsigned int getSize() const
Gets the size of the particleHandler (including mpi and periodic particles)
virtual bool isSphericalParticle() const
bool mpiInsertParticleCheck(BaseParticle *P)
Function that checks if the mpi particle should really be inserted by the current domain...
Logger< MERCURY_LOGLEVEL > logger("MercuryKernel")
Definition of different loggers with certain modules. A user can define its own custom logger here...
const ParticleSpecies * getSpecies() const
Returns a pointer to the species of this BaseInteractable.
unsigned int getNumberOfObjects() const override
Returns the number of objects in the container. In parallel code this practice is forbidden to avoid ...
void checkExtrema(BaseParticle *P)
Checks if the extrema of this ParticleHandler needs updating.
std::string getName() const override
Returns the name of the handler, namely the string "ParticleHandler".
Mdouble getMaxInteractionRadius() const
Returns the particle's interaction radius, which might be different from radius_ (e.g., when dealing with wet particles)
void setDPMBase(DPMBase *DPMBase)
Sets the problem that is solved using this handler.
const std::complex< Mdouble > i
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.
void setHandler(ParticleHandler *handler)
Sets the pointer to the particle's ParticleHandler.
void addGhostObject(int fromPrcessor, int toProcessor, BaseParticle *p)
Adds a ghost particle located at fromProcessor to toProcessor.
virtual void addGhostObject(T *O)
Adds a new Object to the BaseHandler. called by the to avoid increasing the id.
BaseParticle * getHighestVelocityComponentParticleLocal(int i) const
Gets a pointer to the particle with the highest velocity in direction i in this ParticleHandler.
Mdouble getLargestInteractionRadiusLocal() const
Returns the largest interaction radius of the current domain.
Mdouble getSmallestInteractionRadius() const
Returns the smallest interaction radius.
std::size_t getNumberOfProcessors() const
Get the total number of processors participating in this simulation.
Mdouble getSumRadiusLocal() const
void computeMass(BaseParticle *p) const
Compute Particle mass function, which required a reference to the Species vector. It computes the Par...
void computeAllMasses()
Computes the mass for all BaseParticle in this ParticleHandler.
virtual void handleParticleAddition(unsigned int id, BaseParticle *p)
BaseParticle * getHighestPositionComponentParticle(int i) const
Gets a pointer to the particle with the highest coordinates in direction i in this ParticleHandler...
DomainHandler domainHandler
An object of the class DomainHandler which deals with parallel code.
void setSpecies(const ParticleSpecies *species)
unsigned int getNumberOfFixedParticles() const
Gets the number of particles that are fixed.
void clear() override
Empties the whole ParticleHandler by removing all BaseParticle.
BaseParticle * smallestParticle_
A pointer to the smallest BaseParticle (by interactionRadius) in this ParticleHandler.
void removeLastObject()
Removes the last Object from the BaseHandler.
void removedFixedParticle()
Decrement of the number of fixed particles.
void updateGhostGrid(BaseParticle *P)
Checks if the Domain/periodic interaction distance needs to be updated and updates it accordingly...
unsigned int getNumberOfTrueMPIParticles()
Obtains the number of particles in the particleHandler that are MPIParticles, but NOT periodic partic...
unsigned int getNumberOfRealObjects() const
Returns the number of real objects (on all processors)
void copyDataFromMPIParticleToParticle(MPIParticle *bP, BaseParticle *p, ParticleHandler *particleHandler)
Copies data from an MPIParticle class to a BaseParticle and sets the particleHandler and species...
std::size_t getProcessorID()
Reduces a scalar on all processors to one scalar on a target processor.
virtual void addExistingObject(T *O)
Adds an existing object to the BaseHandler without changing the id of the object. ...
BaseParticle * getHighestVelocityComponentParticle(int i) const
Gets a pointer to the particle with the highest velocity in direction i in this ParticleHandler.
BaseParticle * getSmallestParticle() const
Gets a pointer to the smallest BaseParticle (by interactionRadius) in this ParticleHandler of the loc...
Vec3D getMassTimesPosition() const
Mdouble getSmallestInteractionRadiusLocal() const
Returns the smallest interaction radius of the current domain.
PeriodicBoundaryHandler periodicBoundaryHandler
Internal handler that deals with periodic boundaries, especially in a parallel build.
unsigned int getNumberOfPeriodicGhostParticles()
Returns the number of particles that are flagged is periodicGhostParticle.
BaseParticle * getFastestParticleLocal() const
Gets a pointer to the fastest BaseParticle in this ParticleHandler.
virtual void removeObject(unsigned const int index)
Removes an Object from the BaseHandler.
void removeLastObject()
Removes the last BaseParticle from the ParticleHandler.
void addedFixedParticle()
Increment of the number of fixed particles.
double getLiquidFilmVolume() const
BaseParticle * getObject(const unsigned int id)
Gets a pointer to the Object at the specified index in the BaseHandler.
Data class to send a particle over MPI.
void readAndAddObject(std::istream &is) override
Create a new particle, based on the information from old-style restart data.
ParticleHandler()
Default constructor, it creates an empty ParticleHandler.
BaseParticle * largestParticle_
A pointer to the largest BaseParticle (by interactionRadius) in this ParticleHandler.
BaseParticle * getLowestVelocityComponentParticleLocal(int i) const
Gets a pointer to the particle with the lowest velocity in direction i in this ParticleHandler.
Vec3D getMPISum(Vec3D &val)
Sums the values over all processors using MPI_reduce.
Mdouble getKineticEnergy() const
std::vector< BaseParticle * > objects_
The actual list of Object pointers.
BaseParticle * getHighestPositionComponentParticleLocal(int i) const
Gets a pointer to the particle with the highest coordinates in direction i in this ParticleHandler...
Container to store the pointers to all objects that one creates in a simulation.
unsigned int getNumberOfRealObjectsLocal() const
Returns the number of real objects on a local domain. MPI particles and periodic particles are neglec...
void removeGhostObject(unsigned int index)
Removes a BaseParticle from the ParticleHandler without a global check, this is only to be done for m...
bool isFixed() const override
Is fixed Particle function. It returns whether a Particle is fixed or not, by checking its inverse Ma...
unsigned int getNumberOfFixedObjects() const
Computes the number of fixed particles in the whole simulation.
unsigned int getNumberOfFixedObjectsLocal() const
Computes the number of Fixed particles on a local domain.
Mdouble getHighestPositionX() const
Function returns the highest position in the x-direction.
unsigned int NFixedParticles_
Number of fixed particles.
Vec3D getAngularMomentum() const
bool isPeriodicGhostParticle() const
Indicates if this particle is a ghost in the periodic boundary.
Container to store all BaseParticle.
#define NUMBER_OF_PROCESSORS
For the MPI communication routines this quantity is often required. defining this macro makes the cod...
BaseParticle * getSmallestParticleLocal() const
Gets a pointer to the smallest BaseParticle (by interactionRadius) in this ParticleHandler of the loc...
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.
Vec3D getMassTimesPositionLocal() const
virtual void hGridRemoveParticle(BaseParticle *obj UNUSED)
Mdouble getLiquidVolume() const
void sync()
Process all pending asynchronous communication requests before continuing.
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.
~ParticleHandler() override
Destructor, it destructs the ParticleHandler and all BaseParticle it contains.
Mdouble getKineticEnergyLocal() const
void computeSmallestParticle()
Computes the smallest particle (by interaction radius) and sets it in smallestParticle_.
Domain * getCurrentDomain()
Gets the domain assigned to the processor.
BaseParticle * getLowestPositionComponentParticle(int i) const
Gets a pointer to the particle with the lowest coordinates in direction i in this ParticleHandler...
void setPeriodicComplexity(std::vector< int > complexity)
Set the periodic communication complexity of the particle.
BaseParticle * getLowestVelocityComponentParticle(int i) const
Gets a pointer to the particle with the lowest velocity in direction i in this ParticleHandler.
void insertGhostParticle(BaseParticle *P)
This function inserts a particle in the mpi communication boundaries.
bool isMPIParticle() const
Indicates if this particle is a ghost in the MPI domain.
void computeLargestParticle()
Computes the largest particle (by interaction radius) and sets it in largestParticle_.
Mdouble getMeanRadius() const
virtual void addObject(T *object)
Adds a new Object to the BaseHandler.
Mdouble getRotationalEnergyLocal() const
BaseParticle * getLowestPositionComponentParticleLocal(int i) const
Gets a pointer to the particle with the lowest coordinates in direction i in this ParticleHandler...
void setRotation(bool rotation)
Sets whether particle rotation is enabled or disabled.
Mdouble getMassLocal() const
Vec3D getMomentum() const
unsigned int getIndSpecies() const
Returns the index of the species associated with the interactable object.
BaseParticle * getLastObject()
Gets a pointer to the last Object in this BaseHandler.
static BaseParticle * createObject(const std::string &type)
Reads BaseParticle into the ParticleHandler from restart data.
unsigned int getStorageCapacity() const
Gets the storage capacity of this BaseHandler.
void copyContentsFromOtherHandler(const BaseHandler< BaseParticle > &BH)
Function that copies the contents (vector of pointers, maxObject_, nextId_, DPMBase_) from one handle...
Mdouble getVolumeLocal() const
DPMBase * getDPMBase()
Gets the problem that is solved using this handler.
ParticleHandler & operator=(const ParticleHandler &rhs)
Assignment operator.
unsigned int getNumberOfUnfixedParticles() const
Gets the number of particles that are not fixed.
BaseParticle * getLargestParticleLocal() const
Gets a pointer to the largest BaseParticle (by interactionRadius) in the ParticleHandler of the local...
Mdouble getRotationalEnergy() const
Vec3D getCentreOfMass() const
void actionsAfterTimeStep()
void addExistingObject(BaseParticle *P) override
Adds a BaseParticle to the ParticleHandler.
Mdouble getLargestInteractionRadius() const
Returns the largest interaction radius.
virtual void clear()
Empties the whole BaseHandler by removing all Objects and setting all other variables to 0...
BaseParticle * readAndCreateObject(std::istream &is)
Create a new particle, based on the information provided in a restart file.
BaseParticle * getFastestParticle() const