BaseHandler.h
Go to the documentation of this file.
1 // This file is part of the MercuryDPM project (https://www.mercurydpm.org).
2 // Copyright (c), The MercuryDPM Developers Team. All rights reserved.
3 // License: BSD 3-Clause License; see the LICENSE file in the root directory.
4 
10 #ifndef BASEHANDLER_H
11 #define BASEHANDLER_H
12 
13 #include <vector>
14 #include <type_traits>
15 #include "Math/Helpers.h"
16 #include "Logger.h"
17 
18 class DPMBase;
19 
28 template<typename T>
30 {
31 public:
37 
42 
46  virtual ~BaseHandler();
47 
53 
57  template<typename U>
59  copyAndAddObject(const U& object);
60 
64  template<typename U>
66  copyAndAddObject(const U object);
67 
74  template<typename U>
76  copyAndAddGhostObject(const U& object);
77 
84  template<typename U>
86  copyAndAddGhostObject(const U object);
87 
92  virtual void addExistingObject(T* O);
93 
97  virtual void addObject(T* object);
98 
103  virtual void addGhostObject(T* O);
104 
105  void removeIf(const std::function<bool(T*)> cond);
106 
110  virtual void removeObject(unsigned const int index);
111 
112  virtual void removeObjects(std::vector<unsigned int> indices);
113 
118 
122  virtual void clear();
123 
128  virtual void readAndAddObject(std::istream& is) = 0;
129 
133  void read(std::istream& is);
134 
138  T* getObjectById(const unsigned int id);
139 
143  std::vector<T*> getObjectsById(const unsigned int id);
144 
148  T* getObject(const unsigned int id);
149 
153  const T* getObject(const unsigned int id) const;
154 
159 
163  const T* getLastObject() const;
164 
168  virtual unsigned int getNumberOfObjects() const;
169 
173  unsigned int getSize() const;
174 
178  unsigned int getStorageCapacity() const;
179 
183  void setStorageCapacity(const unsigned int N);
184 
188  void resize(const unsigned int N, const T& obj);
189 
193  const typename std::vector<T*>::const_iterator begin() const;
194 
198  const typename std::vector<T*>::iterator begin();
199 
203  const typename std::vector<T*>::const_iterator end() const;
204 
208  const typename std::vector<T*>::iterator end();
209 
215 
219  void setId(T* object, unsigned int id)
220  {
221  object->setId(id);
222  if (nextId_ <= id)
223  {
224  nextId_ = id + 1;
225  }
226  }
227 
228  /*
229  * \brief This function updates the iD counter by one
230  * \details Function used in parallel to keep the Id's unique over all processors
231  */
232  void increaseId()
233  {
234  nextId_++;
235  }
236 
237  unsigned int getNextId()
238  {
239  return nextId_;
240  }
241 
242  void setNextId(unsigned int id)
243  {
244  nextId_ = id;
245  }
246 
251 
255  DPMBase* getDPMBase() const;
256 
260  virtual std::string getName() const = 0;
261 
266  [[deprecated]]
267  virtual void writeVTK() const
268  {};
269 
274  unsigned getNextGroupId() { return nextGroupId_++; }
275 
276 protected:
283  std::vector<T*> objects_;
284 
285 private:
289  unsigned int maxObjects_;
290 
294  unsigned int nextId_;
295 
301  unsigned nextGroupId_ = 1;
302 
310 };
311 
315 template<typename T>
317 {
318  DPMBase_ = nullptr;
319  clear();
320  logger(DEBUG, "BaseHandler<T>::BaseHandler() finished");
321 }
322 
330 template<typename T>
332 {
333  DPMBase_ = nullptr;
334  clear();
335  copyContentsFromOtherHandler(BH);
336  logger(DEBUG, "BaseHandler<T>::BaseHandler(const BaseHandler &BH) finished");
337 }
338 
339 template<typename T>
341 {
342  clear();
343  logger(DEBUG, "BaseHandler<T>::~BaseHandler() finished");
344 }
345 
347 template<typename T>
349 {
350  for (const T* const obj : BH.objects_)
351  {
352  addObject(obj->copy());
353  }
354 }
355 
357 template<typename T>
358 template<typename U>
361 {
362  U* oCopy = object.copy();
363  addObject(oCopy);
364  return oCopy;
365 }
366 
368 template<typename T>
369 template<typename U>
372 {
373  return copyAndAddObject(*object);
374 }
375 
377 template<class T>
378 template<class U>
381 {
382  U* oCopy = object.copy();
383  addGhostObject(oCopy);
384  return oCopy;
385 }
386 
388 template<class T>
389 template<class U>
392 {
393  return copyAndAddGhostObject(*object);
394 }
395 
397 template<class T>
399 {
400  objects_.push_back(O);
401  //Set the index of the particle
402  getLastObject()->setIndex(getSize() - 1);
403  //Adjust the nextId_ value
404  if (O->getId() + 1 > nextId_)
405  {
406  nextId_ = O->getId() + 1;
407  }
408 }
409 
411 template<class T>
413 {
414  objects_.push_back(object);
415  //Set the index of the particle
416  getLastObject()->setIndex(getSize() - 1);
417  //set the non changing particle identifier
418  getLastObject()->setId(nextId_);
419  //Update Id for next particle
420  nextId_++;
421 }
422 
424 template<class T>
426 {
427  objects_.push_back(O);
428  //Set the index of the particle
429  getLastObject()->setIndex(getSize() - 1);
430 }
431 
432 //\todo should this function ever be used?
433 template<class T>
434 void BaseHandler<T>::removeIf(const std::function<bool(T*)> cond)
435 {
436  for (int i = 0; i < objects_.size(); ++i) {
437  if (cond(objects_[i]))
438  {
439  //objects_(i)->actionsOnErase();
440  removeObject(i);
441  --i;
442  }
443  }
444 }
445 
452 template<typename T>
453 void BaseHandler<T>::removeObject(const unsigned int index)
454 {
455  logger.assert_debug(index < getSize(),
456  "In: void %::removeObject(const unsigned int index) const, "
457  "no object exists with index %, number of objects is %",
458  getName(), index, getSize());
459 
460  //Removing a particle within the list is not efficient.
461  //Swap with last element and then perform the deletion
462  const unsigned int lastIndex = objects_.size() - 1;
463 
464  T* const objectToDelete = objects_[index];
465 
466  //No swapping required if it is the last object
467  if (index != lastIndex)
468  {
469 
470  T* const objectToMove = objects_[lastIndex];
471 
472  objects_[index] = objectToMove; //place it back
473  objects_[lastIndex] = objectToDelete; //Just to make sure.
474 
475  //and notify it of the change.
476  objects_[index]->moveInHandler(index);
477  //Even though we are going to delete this particle,
478  //we still need to keep it consistent.
479  objects_[lastIndex]->moveInHandler(lastIndex);
480  }
481 
482 
483  //And clear it from the backing container.
484  objects_.pop_back();
485  //And _NOW_ we delete it.
486 
487  delete objectToDelete;
488 }
489 
497 template<typename T>
498 void BaseHandler<T>::removeObjects(std::vector<unsigned int> indices)
499 {
500  if (indices.empty())
501  {
502  logger(DEBUG, "no objects could be removed due to an empty indices vector, please specify the"
503  "indices of objects to delete.");
504  return;
505  }
506  // Sort in descending order for safe deletion
507  std::sort(indices.begin(), indices.end(), std::greater<unsigned int>());
508  // Remove duplicates
509  indices.erase(std::unique(indices.begin(), indices.end()), indices.end());
510 
511  // Perform deletion
512  for (unsigned const int index : indices)
513  {
514  removeObject(index);
515  }
516 }
517 
518 template<typename T>
520 {
521  if (getSize() == 0)
522  {
523  logger(WARN, "In: void %::removeLastObject, no Object exists in this BaseHandler.", getName());
524  return;
525  }
526  T* const object = objects_.back();
527  //Remove the (now double) reference to that last Object
528  objects_.pop_back();
529  //Physically removes Object
530  delete object;
531 }
532 
535 template<typename T>
537 {
538 
539  for (T* const obj : objects_)
540  {
541  delete obj;
542  }
543  objects_.clear();
544 
545  nextId_ = 0;
546  maxObjects_ = 0;
547 }
548 
550 template<typename T>
551 void BaseHandler<T>::read(std::istream& is)
552 {
553  clear();
554  unsigned int N;
555  std::string dummy;
556  is >> dummy;
557  std::stringstream line;
559  line >> N;
560  logger(VERBOSE, "In %::read(is): reading in % objects.", getName(), N);
561  setStorageCapacity(N);
562  for (unsigned int i = 0; i < N; i++)
563  {
564  readAndAddObject(is);
565  }
566 }
567 
572 template<typename T>
573 T* BaseHandler<T>::getObjectById(const unsigned int id)
574 {
575  // Usually, the id and the index into the backing storage matches
576  // So check this position first!
577  // dducks: Can't we guarantee more? That should speed up searches.
578  if (id < objects_.size() && objects_[id]->getId() == id)
579  {
580  return objects_[id]; //There is a hit, return early
581  }
582 
583  for (T* obj : objects_) //Search for the correct id, since it wasn't where
584  { // we expected it. Just use a linear search..
585  if (obj->getId() == id) //Found it, so return!
586  return obj;
587  }
588 #ifndef MERCURYDPM_USE_MPI
589  logger(ERROR, "[BaseHandler::getObjectById()] in Object* %: Object with ID % could not be found.", getName(), id);
590 #endif
591  return nullptr;
592 }
593 
600 template<typename T>
601 std::vector<T*> BaseHandler<T>::getObjectsById(const unsigned int id)
602 {
603  std::vector<T*> list;
604  for (T* obj : objects_)
605  {
606  if (obj->getId() == id)
607  {
608  list.push_back(obj);
609  }
610  }
611 #ifndef MERCURYDPM_USE_MPI
612  logger(ERROR, "[BaseHandler::getObjectById()] in Object* %: Object with ID % could not be found.", getName(), id);
613 #endif
614  return list;
615 
616 }
617 
620 template<typename T>
621 T* BaseHandler<T>::getObject(const unsigned int index)
622 {
623  logger.assert_debug(index < getSize(),
624  "[%::getObject()] Object couldn't be found because index (%) is higher than number of objects (%).",
625  getName(), index, getSize());
626  return objects_[index];
627 }
628 
631 template<typename T>
632 const T* BaseHandler<T>::getObject(const unsigned int index) const
633 {
634  logger.assert_debug(index < getSize(),
635  "[%::getObject() const] Object couldn't be found because index (%) is higher than number of objects (%).",
636  getName(), index, getSize());
637  return objects_[index];
638 }
639 
641 template<typename T>
643 {
644  return objects_.back();
645 }
646 
648 template<typename T>
650 {
651  return objects_.back();
652 }
653 
655 template<typename T>
657 {
658  return objects_.size();
659 }
660 
662 template<class T>
663 unsigned int BaseHandler<T>::getSize() const
664 {
665  return objects_.size();
666 }
667 
669 template<typename T>
671 {
672  return objects_.capacity();
673 }
674 
676 template<typename T>
677 void BaseHandler<T>::setStorageCapacity(const unsigned int N)
678 {
679  objects_.reserve(N);
680 }
681 
686 template<class T>
687 void BaseHandler<T>::resize(const unsigned int N, const T& obj)
688 {
689  //objects_.resize(N,obj); //doesn't work because the handler stores pointers only (data needs to be allocated);
690  while (getSize() < N)
691  copyAndAddObject(obj);
692  while (getSize() > N)
693  removeLastObject();
694 }
695 
697 template<typename T>
698 const typename std::vector<T*>::const_iterator BaseHandler<T>::begin() const
699 {
700  return objects_.begin();
701 }
702 
704 template<typename T>
705 const typename std::vector<T*>::iterator BaseHandler<T>::begin()
706 {
707  return objects_.begin();
708 }
709 
711 template<typename T>
712 const typename std::vector<T*>::const_iterator BaseHandler<T>::end() const
713 {
714  return objects_.end();
715 }
716 
718 template<typename T>
719 const typename std::vector<T*>::iterator BaseHandler<T>::end()
720 {
721  return objects_.end();
722 }
723 
725 template<typename T>
727 {
728  DPMBase_ = DPMBase;
729 }
730 
732 template<typename T>
734 {
735  return DPMBase_;
736 }
737 
739 template<typename T>
741 {
742  return DPMBase_;
743 }
744 
745 #endif
746 
int i
Definition: BiCGSTAB_step_by_step.cpp:9
std::string getName(int argc, char *argv[])
Definition: CombineParallelDataFiles.cpp:16
LL< Log::VERBOSE > VERBOSE
Verbose information.
Definition: Logger.cc:36
Logger< MERCURYDPM_LOGLEVEL > logger("MercuryKernel")
Definition of different loggers with certain modules. A user can define its own custom logger here.
LL< Log::ERROR > ERROR
Error log level.
Definition: Logger.cc:32
LL< Log::WARN > WARN
Warning log level.
Definition: Logger.cc:33
void addObject(CGHandler &cg, std::string coordinate)
Definition: MercuryCG.cpp:22
Container to store the pointers to all objects that one creates in a simulation.
Definition: BaseHandler.h:30
virtual void removeObject(unsigned const int index)
Removes an Object from the BaseHandler.
Definition: BaseHandler.h:453
DPMBase * DPMBase_
A pointer back to the DPMBase class.
Definition: BaseHandler.h:309
BaseHandler()
Default BaseHandler constructor, it creates an empty BaseHandler and assigns DPMBase_ to a null point...
Definition: BaseHandler.h:316
void setDPMBase(DPMBase *DPMBase)
Sets the problem that is solved using this handler.
Definition: BaseHandler.h:726
void read(std::istream &is)
Reads all objects from restart data.
Definition: BaseHandler.h:551
const std::vector< T * >::iterator end()
Gets the end of the iterator over all BaseBoundary in this BaseHandler.
Definition: BaseHandler.h:719
const T * getObject(const unsigned int id) const
Gets a constant pointer to the Object at the specified index in the BaseHandler.
Definition: BaseHandler.h:632
const T * getLastObject() const
Gets a constant pointer to the last Object in this BaseHandler.
Definition: BaseHandler.h:649
unsigned nextGroupId_
value of the next BaseObject::groupId_. Value increased by one each time a groupId is assigned....
Definition: BaseHandler.h:301
virtual unsigned int getNumberOfObjects() const
Gets the number of real Object in this BaseHandler. (i.e. no mpi or periodic particles)
Definition: BaseHandler.h:656
virtual std::string getName() const =0
Gets the name of this handler.
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 part...
Definition: BaseHandler.h:380
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.
Definition: BaseHandler.h:371
std::vector< T * > objects_
The actual list of Object pointers.
Definition: BaseHandler.h:283
virtual void writeVTK() const
now empty function for writing VTK files.
Definition: BaseHandler.h:267
unsigned getNextGroupId()
Should be called each time you assign a groupId. Returns the value of nextGroupId_ and increases next...
Definition: BaseHandler.h:274
DPMBase * getDPMBase() const
Gets the problem that is solved using this handler and does not change the class.
Definition: BaseHandler.h:740
virtual void clear()
Empties the whole BaseHandler by removing all Objects and setting all other variables to 0.
Definition: BaseHandler.h:536
virtual void readAndAddObject(std::istream &is)=0
Reads Object into the BaseHandler from restart data.
void setStorageCapacity(const unsigned int N)
Sets the storage capacity of this BaseHandler.
Definition: BaseHandler.h:677
virtual void addObject(T *object)
Adds a new Object to the BaseHandler.
Definition: BaseHandler.h:412
unsigned int getNextId()
Definition: BaseHandler.h:237
const std::vector< T * >::const_iterator begin() const
Gets the begin of the const_iterator over all Object in this BaseHandler.
Definition: BaseHandler.h:698
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.
Definition: BaseHandler.h:360
unsigned int getStorageCapacity() const
Gets the storage capacity of this BaseHandler.
Definition: BaseHandler.h:670
const std::vector< T * >::const_iterator end() const
Gets the end of the const_iterator over all BaseBoundary in this BaseHandler.
Definition: BaseHandler.h:712
void setId(T *object, unsigned int id)
Definition: BaseHandler.h:219
unsigned int getSize() const
Gets the size of the particleHandler (including mpi and periodic particles)
Definition: BaseHandler.h:663
void resize(const unsigned int N, const T &obj)
Resizes the container to contain N elements.
Definition: BaseHandler.h:687
void setNextId(unsigned int id)
Definition: BaseHandler.h:242
DPMBase * getDPMBase()
Gets the problem that is solved using this handler.
Definition: BaseHandler.h:733
void removeIf(const std::function< bool(T *)> cond)
Definition: BaseHandler.h:434
BaseHandler(const BaseHandler< T > &BH)
Constructor that copies the objects of the given handler into itself and sets other variables to 0/nu...
Definition: BaseHandler.h:331
const std::vector< T * >::iterator begin()
Gets the begin of the iterator over all BaseBoundary in this BaseHandler.
Definition: BaseHandler.h:705
unsigned int maxObjects_
An integer to keep track of the largest number of objects ever stored in this BaseHandler.
Definition: BaseHandler.h:289
std::vector< T * > getObjectsById(const unsigned int id)
Gets a vector of pointers to the objects with the specific id.
Definition: BaseHandler.h:601
virtual void addGhostObject(T *O)
Adds a new Object to the BaseHandler. called by the to avoid increasing the id.
Definition: BaseHandler.h:425
void copyContentsFromOtherHandler(const BaseHandler< T > &BH)
Function that copies the contents (vector of pointers, maxObject_, nextId_, DPMBase_) from one handle...
Definition: BaseHandler.h:348
void increaseId()
Definition: BaseHandler.h:232
unsigned int nextId_
identifier for next object created
Definition: BaseHandler.h:294
T * getObject(const unsigned int id)
Gets a pointer to the Object at the specified index in the BaseHandler.
Definition: BaseHandler.h:621
virtual ~BaseHandler()
Destructor, it destructs the BaseHandler and all Object it contains.
Definition: BaseHandler.h:340
T * getObjectById(const unsigned int id)
Gets a pointer to the Object at the specified index in the BaseHandler.
Definition: BaseHandler.h:573
void removeLastObject()
Removes the last Object from the BaseHandler.
Definition: BaseHandler.h:519
virtual void addExistingObject(T *O)
Adds an existing object to the BaseHandler without changing the id of the object.
Definition: BaseHandler.h:398
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 part...
Definition: BaseHandler.h:391
T * getLastObject()
Gets a pointer to the last Object in this BaseHandler.
Definition: BaseHandler.h:642
virtual void removeObjects(std::vector< unsigned int > indices)
Definition: BaseHandler.h:498
The DPMBase header includes quite a few header files, defining all the handlers, which are essential....
Definition: DPMBase.h:56
@ N
Definition: constructor.cpp:22
#define DEBUG
Definition: main.h:181
squared absolute value
Definition: GlobalFunctions.h:87
double U
Swimming speed.
Definition: two_d_variable_diff_adapt.cc:53
line
Definition: calibrate.py:103
type
Definition: compute_granudrum_aor.py:141
void getLineFromStringStream(std::istream &in, std::stringstream &out)
Reads a line from one stringstream into another, and prepares the latter for reading in.
Definition: StringHelpers.cc:41
std::string string(const unsigned &i)
Definition: oomph_definitions.cc:286