MercuryDPM  Alpha
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
BaseHandler.h
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 
31 #ifndef BASEHANDLER_H
32 #define BASEHANDLER_H
33 
34 #include <iostream>
35 #include <vector>
36 #include <type_traits>
37 #include "Math/Helpers.h"
38 #include "Logger.h"
39 
40 class DPMBase;
41 
50 template<typename T>
52 {
53 public:
58  BaseHandler();
59 
63  BaseHandler(const BaseHandler<T>& BH);
64 
68  virtual ~BaseHandler();
69 
75 
79  template<typename U>
80  typename std::enable_if<!std::is_pointer<U>::value,U*>::type
81  copyAndAddObject(const U& object);
82 
86  template<typename U>
87  typename std::enable_if<std::is_pointer<U>::value,U>::type
88  copyAndAddObject(const U object);
89 
93  virtual void addObject(T* object);
94 
98  virtual void removeObject(unsigned const int id);
99 
103  void removeLastObject();
104 
108  void clear();
109 
114  virtual void readObject(std::istream& is) = 0;
115 
119  void read(std::istream& is);
120 
124  T* getObjectById(const unsigned int id);
125 
129  T* getObject(const unsigned int id);
130 
134  const T* getObject(const unsigned int id) const;
135 
139  T* getLastObject();
140 
144  const T* getLastObject() const;
145 
149  unsigned int getNumberOfObjects() const;
150 
154  unsigned int getStorageCapacity() const;
155 
159  void setStorageCapacity(const unsigned int N);
160 
164  const typename std::vector<T*>::const_iterator begin() const;
165 
169  const typename std::vector<T*>::iterator begin();
170 
174  const typename std::vector<T*>::const_iterator end() const;
175 
179  const typename std::vector<T*>::iterator end();
180 
184  void setDPMBase(DPMBase* DPMBase);
185 
189  void setId(T* object,unsigned int id)
190  {
191  object->setId(id);
192  if (nextId_<=id)
193  {
194  nextId_ = id+1;
195  }
196  }
197 
201  DPMBase* getDPMBase();
202 
206  DPMBase* getDPMBase() const;
207 
211  virtual std::string getName() const = 0;
212 
216  virtual void writeVTK(){};
217 
218 protected:
225  std::vector<T*> objects_;
226 
227 private:
231  unsigned int maxObjects_;
232 
236  unsigned int nextId_;
237 
244  DPMBase* DPMBase_;
245 };
246 
250 template<typename T>
252 {
253  DPMBase_ = nullptr;
254  clear();
255  logger(DEBUG, "Basehandler<T>::BaseHandler() finished");
256 }
257 
265 template<typename T>
267 {
268  DPMBase_ = nullptr;
269  clear();
270  copyContentsFromOtherHandler(BH);
271  logger(DEBUG,"BaseHandler<T>::BaseHandler(const BaseHandler &BH) finished");
272 }
273 
274 template<typename T>
276 {
277  clear();
278  logger(DEBUG, "BaseHandler<T>::~BaseHandler() finished");
279 }
280 
282 template<typename T>
284 {
285  for (const T* const obj : BH.objects_)
286  {
287  addObject(obj->copy());
288  }
289 }
290 
292 template<typename T>
293 template<typename U>
294 typename std::enable_if<!std::is_pointer<U>::value,U*>::type
296 {
297  U* oCopy = object.copy();
298  addObject(oCopy);
299  return oCopy;
300 }
301 
303 template<typename T>
304 template<typename U>
305 typename std::enable_if<std::is_pointer<U>::value,U>::type
307 {
308  return copyAndAddObject(*object);
309 }
310 
312 template<typename T>
314 {
315  objects_.push_back(object);
316  //Set the index of the particle
317  getLastObject()->setIndex(getNumberOfObjects() - 1);
318  //set the non changing particle identifier
319  getLastObject()->setId(nextId_);
320  //Update Id for next particle
321  nextId_++;
322  //Update the maximum number of Particles
323  if (getNumberOfObjects() > maxObjects_)
324  maxObjects_ = getNumberOfObjects();
325 }
326 
332 template<typename T>
333 void BaseHandler<T>::removeObject(const unsigned int index)
334 {
335  logger.assert_always(index < getNumberOfObjects(),
336  "In: void %::removeOject(const unsigned int index) const, "
337  "no object exists with index %, number of objects is %",
338  getName(), index, getNumberOfObjects());
339 
340  //Okay, this function deletes the particle. Now, the problem is that
341  //particles store their position in the handler (@dducks: do they?)
342  //which means that we would absolutely destroy performance if we took
343  //something out in the middle. Now, what we'll do is swap our particle
344  //with the last one (in case it already is, it is invariant); then
345  //remove the last one.
346  //So, we want the last index.
347  const unsigned int lastIndex = objects_.size() - 1;
348 
349  //So, step one, retrieve the pointer
350  T* const objectToDelete = objects_[index];
351 
352  if (index != lastIndex) //Are we not the last object?
353  {
354  //well.. let's swap.
355  T* const objectToMove = objects_[lastIndex];
356 
357  objects_[index] = objectToMove; //place it back
358  objects_[lastIndex] = objectToDelete; //Just to make sure.
359 
360  //and notify it of the change.
361  objects_[index]->moveInHandler(index);
362  //Even though we are going to delete this particle,
363  //we still need to keep it consistent.
364  objects_[lastIndex]->moveInHandler(lastIndex);
365  }
366 
367  //And clear it from the backing container.
368  objects_.pop_back();
369  //And _NOW_ we delete it.
370  delete objectToDelete;
371 
372 }
373 
374 template<typename T>
376 {
377  if (getNumberOfObjects() == 0)
378  {
379  logger(WARN, "In: void %::removeLastObject, no Object exists in this BaseHandler.", getName());
380  return;
381  }
382  T* const object = objects_.back();
383  //Remove the (now double) reference to that last Object
384  objects_.pop_back();
385  //Physically removes Object
386  delete object;
387 }
388 
391 template<typename T>
393 {
394 
395  for (T* const obj : objects_)
396  {
397  delete obj;
398  }
399  objects_.clear();
400 
401  nextId_ = 0;
402  maxObjects_ = 0;
403 }
404 
406 template<typename T>
407 void BaseHandler<T>::read(std::istream& is)
408 {
409  clear();
410  unsigned int N;
411  std::string dummy;
412  is >> dummy;
413  std::stringstream line(std::stringstream::in | std::stringstream::out);
415  line >> N;
416  logger(VERBOSE, "In %::read(is): reading in % objects.", getName(), N);
417  setStorageCapacity(N);
418  for (unsigned int i = 0; i < N; i++)
419  {
420  readObject(is);
421  }
422 }
423 
428 template<typename T>
429 T* BaseHandler<T>::getObjectById(const unsigned int id)
430 {
431  // Usually, the id and the index into the backing storage matches
432  // So check this position first!
433  // dducks: Can't we guarantee more? That should speed up searches.
434  if (id < objects_.size() && objects_[id]->getId() == id)
435  {
436  return objects_[id]; //There is a hit, return early
437  }
438 
439  for (T* obj : objects_ ) //Search for the correct id, since it wasn't where
440  { // we expected it. Just use a linear search..
441  if (obj->getId() == id) //Found it, so return!
442  return obj;
443  }
444  logger(ERROR, "[BaseHandler::getObjectById()] in Object* %: Object with ID % could not be found.", getName(), id);
445  return nullptr;
446 }
447 
450 template<typename T>
451 T* BaseHandler<T>::getObject(const unsigned int index)
452 {
453  logger.assert(index < getNumberOfObjects(),
454  "[%::getObject()] Object couldn't be found because index (%) is higher than number of objects (%).",
455  getName(), index, getNumberOfObjects());
456 
457  return objects_[index];
458 }
459 
462 template<typename T>
463 const T* BaseHandler<T>::getObject(const unsigned int index) const
464 {
465  logger.assert(index < getNumberOfObjects(),
466  "[%::getObject() const] Object couldn't be found because index (%) is higher than number of objects (%).",
467  getName(), index, getNumberOfObjects());
468  return objects_[index];
469 }
470 
472 template<typename T>
474 {
475  return objects_.back();
476 }
477 
479 template<typename T>
481 {
482  return objects_.back();
483 }
484 
486 template<typename T>
488 {
489  return objects_.size();
490 }
491 
493 template<typename T>
495 {
496  return objects_.capacity();
497 }
498 
500 template<typename T>
501 void BaseHandler<T>::setStorageCapacity(const unsigned int N)
502 {
503  objects_.reserve(N);
504 }
505 
507 template<typename T>
508 const typename std::vector<T*>::const_iterator BaseHandler<T>::begin() const
509 {
510  return objects_.begin();
511 }
512 
514 template<typename T>
515 const typename std::vector<T*>::iterator BaseHandler<T>::begin()
516 {
517  return objects_.begin();
518 }
519 
521 template<typename T>
522 const typename std::vector<T*>::const_iterator BaseHandler<T>::end() const
523 {
524  return objects_.end();
525 }
526 
528 template<typename T>
529 const typename std::vector<T*>::iterator BaseHandler<T>::end()
530 {
531  return objects_.end();
532 }
533 
535 template<typename T>
537 {
538  DPMBase_ = DPMBase;
539 }
540 
542 template<typename T>
544 {
545  logger.assert(DPMBase_!= nullptr,"[BaseHandler::getDPMBase()] in Object* %: pointer to DPMBase class is not set.", getName());
546  return DPMBase_;
547 }
548 
550 template<typename T>
552 {
553  logger.assert(DPMBase_!= nullptr, "[BaseHandler::getDPMBase() const] in Object* %: pointer to DPMBase class is not set.", getName());
554  return DPMBase_;
555 }
556 #endif
557 
The DPMBase header includes quite a few header files, defining all the handlers, which are essential...
Definition: DPMBase.h:65
virtual void readObject(std::istream &is)=0
Reads Object into the BaseHandler from restart data.
LL< Log::DEBUG > DEBUG
Debug information.
Definition: Logger.cc:56
Logger< MERCURY_LOGLEVEL > logger("MercuryKernel")
void setDPMBase(DPMBase *DPMBase)
Sets the problem that is solved using this handler.
Definition: BaseHandler.h:536
void setStorageCapacity(const unsigned int N)
Sets the storage capacity of this BaseHandler.
Definition: BaseHandler.h:501
T * getObjectById(const unsigned int id)
Gets a pointer to the Object at the specified index in the BaseHandler.
Definition: BaseHandler.h:429
virtual void writeVTK()
Over written in WallHandler and ParticleHandler.
Definition: BaseHandler.h:216
unsigned int nextId_
identifier for next object created
Definition: BaseHandler.h:236
const std::vector< T * >::const_iterator end() const
Gets the end of the const_iterator over all BaseBoundary in this BaseHandler.
Definition: BaseHandler.h:522
void read(std::istream &is)
Reads all objects from restart data.
Definition: BaseHandler.h:407
LL< Log::ERROR > ERROR
Error log level.
Definition: Logger.cc:51
BaseHandler()
Default BaseHandler constructor, it creates an empty BaseHandler and assigns DPMBase_ to a null point...
Definition: BaseHandler.h:251
void removeLastObject()
Removes the last Object from the BaseHandler.
Definition: BaseHandler.h:375
const std::vector< T * >::const_iterator begin() const
Gets the begin of the const_iterator over all Object in this BaseHandler.
Definition: BaseHandler.h:508
LL< Log::WARN > WARN
Warning log level.
Definition: Logger.cc:52
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:396
virtual void removeObject(unsigned const int id)
Removes an Object from the BaseHandler.
Definition: BaseHandler.h:333
T * getObject(const unsigned int id)
Gets a pointer to the Object at the specified index in the BaseHandler.
Definition: BaseHandler.h:451
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:295
virtual std::string getName() const =0
Gets the name of this handler.
std::vector< T * > objects_
The actual list of Object pointers.
Definition: BaseHandler.h:216
Container to store the pointers to all objects that one creates in a simulation.
Definition: BaseHandler.h:51
LL< Log::VERBOSE > VERBOSE
Verbose information.
Definition: Logger.cc:55
unsigned int getNumberOfObjects() const
Gets the number of Object in this BaseHandler.
Definition: BaseHandler.h:487
void setId(T *object, unsigned int id)
This function sets the id and ensures that nextId is a bigger value than id.
Definition: BaseHandler.h:189
DPMBase * DPMBase_
A pointer back to the DPMBase class.
Definition: BaseHandler.h:244
virtual void addObject(T *object)
Adds a new Object to the BaseHandler.
Definition: BaseHandler.h:313
T * getLastObject()
Gets a pointer to the last Object in this BaseHandler.
Definition: BaseHandler.h:473
unsigned int getStorageCapacity() const
Gets the storage capacity of this BaseHandler.
Definition: BaseHandler.h:494
virtual ~BaseHandler()
Destructor, it destructs the BaseHandler and all Object it contains.
Definition: BaseHandler.h:275
void copyContentsFromOtherHandler(const BaseHandler< T > &BH)
Function that copies the contents (vector of pointers, maxObject_, nextId_, DPMBase_) from one handle...
Definition: BaseHandler.h:283
DPMBase * getDPMBase()
Gets the problem that is solved using this handler.
Definition: BaseHandler.h:543
unsigned int maxObjects_
An integer to keep track of the largest number of objects ever stored in this BaseHandler.
Definition: BaseHandler.h:231
void clear()
Empties the whole BaseHandler by removing all Objects and setting all other variables to 0...
Definition: BaseHandler.h:392