MercuryDPM  Beta
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
ParticleHandler.cc
Go to the documentation of this file.
1 //Copyright (c) 2013-2014, The MercuryDPM Developers Team. All rights reserved.
2 //For the list of developers, see <http://www.MercuryDPM.org/Team>.
3 //
4 //Redistribution and use in source and binary forms, with or without
5 //modification, are permitted provided that the following conditions are met:
6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above copyright
9 // notice, this list of conditions and the following disclaimer in the
10 // documentation and/or other materials provided with the distribution.
11 // * Neither the name MercuryDPM nor the
12 // names of its contributors may be used to endorse or promote products
13 // derived from this software without specific prior written permission.
14 //
15 //THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
16 //ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17 //WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18 //DISCLAIMED. IN NO EVENT SHALL THE MERCURYDPM DEVELOPERS TEAM BE LIABLE FOR ANY
19 //DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20 //(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21 //LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22 //ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 //(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24 //SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 
26 
27 #include <limits>
28 #include <Math/Helpers.h>
29 #include "ParticleHandler.h"
30 #include "DPMBase.h"
31 #include "SpeciesHandler.h"
33 
34 
40 {
41  largestParticle_ = nullptr;
42  smallestParticle_ = nullptr;
43  logger(DEBUG, "ParticleHandler::ParticleHandler() finished");
44 }
45 
54 {
55  clear();
56  setDPMBase(PH.getDPMBase());
57  largestParticle_ = nullptr;
58  smallestParticle_ = nullptr;
60  if (objects_.size() != 0)
61  {
64  }
65  logger(DEBUG, "ParticleHandler::ParticleHandler(const ParticleHandler &PH) finished");
66 }
67 
75 {
76  if (this != &rhs)
77  {
78  clear();
79  largestParticle_ = nullptr;
80  smallestParticle_ = nullptr;
82  if (objects_.size() != 0)
83  {
86  }
87  }
88  logger(DEBUG, "ParticleHandler::operator = (const ParticleHandler& rhs) finished");
89  return *this;
90 }
91 
97 {
98  //First reset the pointers, such that they are not checked twice when removing particles
99  largestParticle_ = nullptr;
100  smallestParticle_ = nullptr;
101  logger(DEBUG, "ParticleHandler::~ParticleHandler() finished");
102 }
103 
118 {
119  //\todo I diasbled the MERCURY_DEPRECATED attribute until we actually fixed the deprecation issue. This will scare users away.
120  // if (P->getSpecies() == nullptr)
121  // {
122  // logger(WARN, "WARNING: The particle with ID % that is added in "
123  // "ParticleHandler::addObject does not have a species yet. "
124  // "Please make sure that you have "
125  // "set the species somewhere in the driver code.", P->getId());
126  // }
127  //Puts the particle in the Particle list
129  if (getDPMBase() != nullptr)
130  {
131  //This places the particle in this grid
133  //This computes where the particle currently is in the grid
135  }
136  //set the particleHandler pointer
137  P->setHandler(this);
138  //compute mass of the particle
139  P->getSpecies()->computeMass(P) ;
140  //Check if this particle has new extrema
141  checkExtrema(P);
142 }
143 
151 void ParticleHandler::removeObject(unsigned const int id)
152 {
153 #ifdef CONTACT_LIST_HGRID
154  getDPMBase()->getPossibleContactList().remove_ParticlePosibleContacts(getObject(id));
155 #endif
158 }
159 
165 {
166 #ifdef CONTACT_LIST_HGRID
167  getDPMBase()->getPossibleContactList().remove_ParticlePosibleContacts(getLastObject());
168 #endif
171 }
172 
174 {
175  if (getNumberOfObjects() == 0)
176  {
177  logger(WARN, "No particles, so cannot compute the smallest particle.");
178  return;
179  }
180  Mdouble min = std::numeric_limits<Mdouble>::max();
181  smallestParticle_ = nullptr;
182  for (BaseParticle* const particle : objects_)
183  {
184  if (particle->getInteractionRadius() < min)
185  {
186  min = particle->getInteractionRadius();
187  smallestParticle_ = particle;
188  }
189  }
190 }
191 
193 {
194  if (getNumberOfObjects() == 0)
195  {
196  logger(WARN, "No particles, so cannot compute the largest particle.");
197  return;
198  }
199  Mdouble max = -std::numeric_limits<Mdouble>::max();
200  largestParticle_ = nullptr;
201  for (BaseParticle* const particle : objects_)
202  {
203  if (particle->getInteractionRadius() > max)
204  {
205  max = particle->getInteractionRadius();
206  largestParticle_ = particle;
207  }
208  }
209 }
210 
216 {
217  if (smallestParticle_ == nullptr)
218  {
219  logger(WARN, "No particles to return in getSmallestParticle()");
220  }
221  return smallestParticle_;
222 }
223 
229 {
230  if (largestParticle_ == nullptr)
231  {
232  logger(WARN, "No particles to set get_LargestParticle()");
233  }
234  return largestParticle_;
235 }
236 
241 {
242  if (getNumberOfObjects() == 0)
243  {
244  logger(WARN, "No particles to set getFastestParticle()" );
245  return nullptr;
246  }
247  BaseParticle* p = nullptr;
248  Mdouble maxSpeed = -std::numeric_limits<Mdouble>::max();
249  for (BaseParticle* const pLoop : objects_)
250  {
251  if ((pLoop->getVelocity().getLength()) > maxSpeed)
252  {
253  maxSpeed = pLoop->getVelocity().getLength();
254  p = pLoop;
255  }
256  }
257  return p;
258 }
259 
266 {
267  if (getNumberOfObjects() == 0)
268  {
269  logger(WARN, "No getLowestPositionComponentParticle(const int i) since there are no particles.");
270  return nullptr;
271  }
272  BaseParticle* p = nullptr;
273  Mdouble min = std::numeric_limits<Mdouble>::max();
274  for (BaseParticle* const pLoop : objects_)
275  {
276  if (pLoop->getPosition().getComponent(i) < min)
277  {
278  min = pLoop->getPosition().getComponent(i);
279  p = pLoop;
280  }
281  }
282  return p;
283 }
284 
291 {
292  if (getNumberOfObjects() == 0)
293  {
294  logger(WARN, "No getHighestPositionComponentParticle(const int i) since there are no particles.");
295  return nullptr;
296  }
297  BaseParticle* p = nullptr;
298  Mdouble max = -std::numeric_limits<Mdouble>::max();
299  for (BaseParticle* const pLoop : objects_)
300  {
301  if (pLoop->getPosition().getComponent(i) > max)
302  {
303  max = pLoop->getPosition().getComponent(i);
304  p = pLoop;
305  }
306  }
307 
308  return p;
309 }
310 
317 {
318  if (getNumberOfObjects() == 0)
319  {
320  logger(WARN, "No getLowestVelocityComponentParticle(const int i) since there are no particles");
321  return nullptr;
322  }
323  BaseParticle* p = nullptr;
324  Mdouble min = std::numeric_limits<Mdouble>::max();
325  for (BaseParticle* const pLoop : objects_)
326  {
327  if (pLoop->getVelocity().getComponent(i) < min)
328  {
329  min = pLoop->getVelocity().getComponent(i);
330  p = pLoop;
331  }
332  }
333  return p;
334 }
335 
342 {
343  if (!getNumberOfObjects())
344  {
345  logger(WARN, "No getHighestVelocityComponentParticle(const int i) since there are no particles");
346  return nullptr;
347  }
348  BaseParticle* p = nullptr;
349  Mdouble max = -std::numeric_limits<Mdouble>::max();
350  for (BaseParticle* const pLoop : objects_)
351  {
352  if (pLoop->getVelocity().getComponent(i) > max)
353  {
354  max = pLoop->getVelocity().getComponent(i);
355  p = pLoop;
356  }
357  }
358  return p;
359 }
360 
365 {
366  if (getNumberOfObjects() == 0)
367  {
368  logger(WARN, "No particles to set getLightestParticle()");
369  return nullptr;
370  }
371  BaseParticle* p = nullptr;
372  Mdouble minMass = std::numeric_limits<Mdouble>::max();
373  for (BaseParticle* const pLoop : objects_)
374  {
375  if (pLoop->getMass() < minMass)
376  {
377  minMass = pLoop->getMass();
378  p = pLoop;
379  }
380  }
381  return p;
382 }
383 
390 {
391  smallestParticle_ = nullptr;
392  largestParticle_ = nullptr;
394 }
395 
399 void ParticleHandler::readObject(std::istream& is)
400 {
401  std::string type;
402  is >> type;
403  if (type == "BaseParticle")
404  {
405  BaseParticle baseParticle;
406  is >> baseParticle;
407  copyAndAddObject(baseParticle);
408  getLastObject()->setId(baseParticle.getId()); //to ensure old id
410  }
412  else if (type == "BP")
413  {
414  BaseParticle baseParticle;
415  baseParticle.oldRead(is);
416  copyAndAddObject(baseParticle);
417  getLastObject()->setId(baseParticle.getId()); //to ensure old id
418  }
419  else if (isdigit(type[0]))
420  {
421  readOldObject(type, is);
422  }
423  else
424  {
425  logger(ERROR, "Particle type % not understood in restart file. Particle has not been read.", type);
426  return;
427  }
428 }
429 
439 void ParticleHandler::readOldObject(std::string type, std::istream& is)
440 {
441  //read in next line
442  std::stringstream line(std::stringstream::in | std::stringstream::out);
444  logger(VERBOSE, line.str());
445  //std::cout << line.str() << std::endl;
446 
447  BaseParticle particle;
448 
449  //Declare all properties of the particle
450  unsigned int indSpecies;
451  Mdouble radius, inverseMass, inverseInertia;
452  Vec3D position, velocity, orientation, angularVelocity;
453 
454  //Read all values
455  position.X = atof(type.c_str());
456 
457  line >> position.Y >> position.Z >> velocity >> radius >> orientation >> angularVelocity >> inverseMass >> inverseInertia >> indSpecies;
458 
459  //Put the values in the particle
460  particle.setIndSpecies(indSpecies);
461  particle.setPosition(position);
462  particle.setVelocity(velocity);
463  particle.setRadius(radius);
464  particle.setOrientation(orientation);
465  particle.setAngularVelocity(angularVelocity);
466  if (inverseMass == 0.0)
467  particle.fixParticle();
468  else
469  {
470  particle.setInertia(1./inverseInertia);
471  }
472 
473  //Put the particle in the handler
474  copyAndAddObject(particle);
475 }
476 
477 void ParticleHandler::write(std::ostream& os) const
478 {
479  os << "Particles " << getNumberOfObjects() << std::endl;
480  for (BaseParticle* it : *this)
481  os << (*it) << std::endl;
482 }
483 
489 {
490  if (P == largestParticle_)
491  {
492  //if the properties of the largest particle changes
494  }
496  {
497  largestParticle_ = P;
498  }
499 
500  if (P == smallestParticle_)
501  {
502  //if the properties of the smallest particle changes
504  }
506  {
507  smallestParticle_ = P;
508  }
509 }
510 
515 {
516  if (P == largestParticle_)
517  {
519  }
520  if (P == smallestParticle_)
521  {
523  }
524 }
525 
530 void ParticleHandler::computeAllMasses(unsigned int indSpecies)
531 {
532  for (BaseParticle* particle : objects_)
533  {
534  if (particle->getIndSpecies() == indSpecies)
535  {
536  particle->getSpecies()->computeMass(particle);
537  }
538  }
539 }
540 
542 {
543  for (BaseParticle* particle : objects_)
544  {
545  particle->getSpecies()->computeMass(particle);
546  }
547 }
548 
552 std::string ParticleHandler::getName() const
553 {
554  return "ParticleHandler";
555 }
BaseParticle * getLargestParticle() const
Gets a pointer to the largest BaseParticle (by interactionRadius) in this ParticleHandler.
unsigned int getId() const
Returns the unique identifier of any particular object.
Definition: BaseObject.cc:113
virtual void hGridUpdateParticle(BaseParticle *obj UNUSED)
no implementation but can be overidden in its derived classes.
Definition: DPMBase.cc:633
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)
no implementation but can be overidden in its derived classes.
Definition: DPMBase.cc:626
Mdouble X
the vector components
Definition: Vector.h:52
Logger< MERCURY_LOGLEVEL > logger("MercuryKernel")
void checkExtrema(BaseParticle *P)
Checks if the extrema of this ParticleHandler needs updating.
void setDPMBase(DPMBase *DPMBase)
Sets the problem that is solved using this handler.
BaseParticle * getLowestVelocityComponentParticle(const int i) const
Gets a pointer to the particle with the lowest velocity in direction i in this ParticleHandler.
const ParticleSpecies * getSpecies() const
Returns a pointer to the species of this BaseInteractable.
std::string getName() const
Returns the name of the handler, namely the string "ParticleHandler".
void setHandler(ParticleHandler *handler)
Sets the pointer to the particle's ParticleHandler.
double Mdouble
BaseParticle * getLightestParticle() const
Gets a pointer to the lightest BaseParticle (by mass) in this ParticleHandler.
virtual 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.
void readObject(std::istream &is)
Reads BaseParticle into the ParticleHandler from restart data.
BaseParticle * smallestParticle_
A pointer to the smallest BaseParticle (by interactionRadius) in this ParticleHandler.
void removeLastObject()
Removes the last Object from the BaseHandler.
Definition: BaseHandler.h:345
void clear()
Empties the whole ParticleHandler by removing all BaseParticle.
void setId(const unsigned int id)
Assigns a unique identifier to each object in the handler (container) which remains constant even aft...
Definition: BaseObject.cc:98
BaseParticle * getSmallestParticle() const
Gets a pointer to the smallest BaseParticle (by interactionRadius) in this ParticleHandler.
U * copyAndAddObject(const U &O)
Creates a copy of a Object and adds it to the BaseHandler.
void getLineFromStringStream(std::istream &in, std::stringstream &out)
Reads a line from one stringstream into another, and prepares the latter for reading in...
Definition: Helpers.cc:389
virtual void removeObject(unsigned const int id)
Removes an Object from the BaseHandler.
Definition: BaseHandler.h:303
void removeLastObject()
Removes the last BaseParticle from the ParticleHandler.
BaseParticle * getObject(const unsigned int id)
Gets a pointer to the Object at the specified index in the BaseHandler.
virtual void addObject(BaseParticle *P)
Adds a BaseParticle to the ParticleHandler.
void readOldObject(std::string type, std::istream &is)
Reads BaseParticle into the ParticleHandler 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.
~ParticleHandler()
Destructor, it destructs the ParticleHandler and all BaseParticle it contains.
BaseParticle * getHighestVelocityComponentParticle(const int i) const
Gets a pointer to the particle with the highest velocity in direction i in this ParticleHandler.
virtual void addObject(T *O)
Adds a new Object to the BaseHandler.
Definition: BaseHandler.h:284
std::vector< BaseParticle * > objects_
The actual list of Object pointers.
Definition: BaseHandler.h:205
Container to store the pointers to all objects that one creates in a simulation.
Definition: BaseHandler.h:50
unsigned int getNumberOfObjects() const
Gets the number of Object in this BaseHandler.
Container to store all BaseParticle.
Mdouble Y
Definition: Vector.h:52
virtual void hGridRemoveParticle(BaseParticle *obj UNUSED)
no implementation but can be overidden in its derived classes.
Definition: DPMBase.cc:640
void computeSmallestParticle()
Computes the smallest particle (by interaction radius) and sets it in smallestParticle_.
BaseParticle * getHighestPositionComponentParticle(const int i) const
Gets a pointer to the particle with the highest coordinates in direction i in this ParticleHandler...
virtual MERCURY_DEPRECATED void oldRead(std::istream &is)
deprecated version of the read function.
void computeLargestParticle()
Computes the largest particle (by interaction radius) and sets it in largestParticle_.
BaseParticle * getLastObject()
Gets a pointer to the last Object in this BaseHandler.
void copyContentsFromOtherHandler(const BaseHandler< BaseParticle > &BH)
Function that copies the contents (vector of pointers, maxObject_, nextId_, DPMBase_) from one handle...
Implementation of a 3D vector (by Vitaliy).
Definition: Vector.h:45
DPMBase * getDPMBase()
Gets the problem that is solved using this handler.
Definition: BaseHandler.h:512
BaseParticle * getLowestPositionComponentParticle(const int i) const
Gets a pointer to the particle with the lowest coordinates in direction i in this ParticleHandler...
Mdouble Z
Definition: Vector.h:52
Mdouble getInteractionRadius() const
Returns the particle's interaction radius, which might be different from radius_ (e.g., when dealing with wet particles)
virtual void removeObject(unsigned const int id)
Removes a BaseParticle from the ParticleHandler.
ParticleHandler operator=(const ParticleHandler &rhs)
Assignment operator.
void clear()
Empties the whole BaseHandler by removing all Objects and setting all other variables to 0...
Definition: BaseHandler.h:360
BaseParticle * getFastestParticle() const
Gets a pointer to the fastest BaseParticle in this ParticleHandler.