MercuryDPM  Beta
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
InteractionHandler.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 #include <iostream>
26 #include <iomanip>
27 #include <string>
28 #include <stdlib.h>
29 #include "Particles/BaseParticle.h"
30 #include "InteractionHandler.h"
31 #include "SpeciesHandler.h"
32 #include "Species/BaseSpecies.h"
34 #include "DPMBase.h"
35 
40 {
41  logger(DEBUG, "InteractionHandler::InteractionHandler() finished");
42 }
43 
52 {
53  //By default interactions are not copied.
54  logger(DEBUG, "InteractionHandler::InteractionHandler(const "
55  "InteractionHandler &IH) finished, please note that no interactions"
56  " have been copied.");
57 }
58 
63 {
64  if (this != &rhs)
65  {
66  clear();
67  }
68  logger(DEBUG, "InteractionHandler::operator =(const InteractionHandler& rhs) finished.");
69  return *this;
70 }
71 
73 {
74  logger(DEBUG, "InteractionHandler::~InteractionHandler() finished");
75 }
76 
81 {
82  //Puts the particle in the Particle list
84  //set the particleHandler pointer
85  I->setHandler(this);
86 }
87 
94 {
95  //for particle-particle collision it is assumed BaseInteractable P has a lower index then I, so we only have to check for I, not P
96  for (std::list<BaseInteraction*>::const_iterator it = P->getInteractions().begin(); it != P->getInteractions().end(); ++it)
97  {
98  if ((*it)->getI() == I)
99  {
100  return *it;
101  }
102  }
103  return nullptr;
104 }
105 
115 {
117 
118  //std::cout << "Trying to reconnect to BaseInteraction between P=" << P->getId() << " and " << I->getId() << std::endl;
120  if (!C)
121  {
122  C = species->getNewInteraction(P, I, timeStamp);
123  addObject(C);
124  //std::cout << "Creating new interaction with index=" << getLastObject()->getIndex() << " id=" << getLastObject()->getId() << std::endl;
125  }
126 
127  //set timeStamp
128  C->setTimeStamp(timeStamp);
129 
130  //set species of collision
131  C->setSpecies(species);
132 
133  return C;
134 }
135 
155 {
156  BaseInteraction* iMain = getObject(id);
157 
158  BaseParticle* P = dynamic_cast<BaseParticle*>(iMain->getP());
159  BaseParticle* I = dynamic_cast<BaseParticle*>(iMain->getI());
160  if (P && I)
161  {
162  //std::cout<<"Both are particles"<<std::endl;
164  if (realI && !P->getPeriodicFromParticle())
165  {
166  //std::cout << "P is normal and I periodic P=" << P->getId() << " I=" << I->getId() << " I real=" << I->getPeriodicFromParticle()->getId() << std::endl;
167  if (P->getIndex() < realI->getIndex())
168  {
169  //std::cout << "Reconnecting to spring" << std::endl;
170  BaseInteraction* iOther = getExistingInteraction(P, realI);
171  if (iOther)
172  {
173  //Here we decide which of the two interactions should be kept:
174  //the interaction between the two real particles (iMain), or
175  //the interaction between the real and a ghost particle (iOther).
176  //It picks the one for which a collision has happened,
177  //i.e. the one with the newer timeStamp.
179  if (iOther->getTimeStamp() < iMain->getTimeStamp())
180  {
181  //std::cout << "Switching" << std::endl;
182  iMain->setI(realI);
183  removeObject(iOther->getIndex());
184  return;
185  }
186  else
187  {
188  //std::cout << "Not switching" << std::endl;
190  return;
191  }
192  }
193  else
194  {
195  //std::cout << "Not found, so just move" << std::endl;
196  iMain->setI(realI);
197  return;
198  }
199  }
200  }
201  }
203 }
204 
213 {
214  //std::cout<<"void InteractionHandler::eraseOldInteractions(Mdouble lastTimeStep)"<<std::endl;
215  //std::cout<<"Current interactions="<<getNumberOfObjects()<<std::endl;
216  //Remove_if reconstructs the vector with only elements passing the check_spring_time function
217  //Erase removes the end of the vector
219  for (unsigned int id = 0; id < getNumberOfObjects(); id++)
220  {
221  if (getObject(id)->getTimeStamp() < lastTimeStep)
222  {
223  removeObject(id);
224  --id;
225  }
226  }
227 }
228 
232 std::string InteractionHandler::getName() const
233 {
234  return "InteractionHandler";
235 }
236 
241 void InteractionHandler::write(std::ostream& os) const
242 {
243  os << "Interactions " << getNumberOfObjects() << std::endl;
244  for (BaseInteraction* i : *this)
245  os << (*i) << std::endl;
246 }
247 
251 void InteractionHandler::readObject(std::istream& is)
252 {
253  std::string type, dummy, idType;
254  unsigned int id0, id1;
255  Mdouble timeStamp;
256 
257  std::stringstream line(std::stringstream::in | std::stringstream::out);
259  line >> type >> idType >> id0 >> id1 >> dummy >> timeStamp;
261  BaseInteraction* C;
262  if (idType.compare("particleIds") == 0)
264  else
265  C = getInteraction(getDPMBase()->particleHandler.getObjectById(id0), getDPMBase()->wallHandler.getObjectById(id1), timeStamp);
266  line >> (*C);
267 }
unsigned int getIndex() const
Returns the index of the object in the handler.
Definition: BaseObject.cc:106
BaseSpecies is the class from which all other species are derived.
Definition: BaseSpecies.h:44
void write(std::ostream &os) const
Writes the InteractionHandler to an output stream, for example a restart file.
Logger< MERCURY_LOGLEVEL > logger("MercuryKernel")
virtual BaseInteraction * getNewInteraction(BaseInteractable *P, BaseInteractable *I, Mdouble timeStamp)=0
returns new Interaction object.
T * getObjectById(const unsigned int id)
Gets a pointer to the Object at the specified index in the BaseHandler.
Definition: BaseHandler.h:394
void setI(BaseInteractable *I)
Sets the second object involved in the interaction (often particle or wall).
BaseInteraction * getInteraction(BaseInteractable *P, BaseInteractable *I, Mdouble timeStamp)
Returns the Interaction between the BaseInteractable's P and I.
double Mdouble
InteractionHandler()
Default constructor, it creates an empty InteractionHandler.
~InteractionHandler()
Destructor, it destructs the InteractionHandler and all BaseInteraction it contains.
Mdouble getTimeStamp() const
Returns an Mdouble which is the time stamp of the interaction.
void setSpecies(BaseSpecies *species)
Set the Species of the interaction; note this can either be a Species or MixedSpecies.
Stores information about interactions between two interactable objects; often particles but could be ...
void eraseOldInteractions(Mdouble lastTimeStep)
erases interactions which have an old timestamp.
BaseParticle * getPeriodicFromParticle() const
Returns the 'original' particle this one's a periodic copy of.
void setTimeStamp(Mdouble timeStamp)
Updates the time step of the interacting. Note, timesteps used to find completed interactions.
BaseInteraction * getExistingInteraction(BaseInteractable *P, BaseInteractable *I)
Returns the Interaction between the BaseInteractable's P and I if it exists, otherwise returns a null...
void removeObjectKeepingPeriodics(unsigned const int id)
Removes interactions of periodic particles when the periodic particles get deleted (see DPMBase::remo...
InteractionHandler operator=(const InteractionHandler &rhs)
Assignment operator.
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.
ParticleHandler particleHandler
An object of the class ParticleHandler, contains the pointers to all the particles created...
Definition: DPMBase.h:878
Container to store Interaction objects.
BaseInteraction * getObject(const unsigned int id)
Gets a pointer to the Object at the specified index in the BaseHandler.
void setHandler(InteractionHandler *handler)
Sets the pointer to the interaction hander which is storing this interaction.
std::string getName() const
Returns the name of the object.
#define UNUSED
Definition: GeneralDefine.h:37
virtual void addObject(T *O)
Adds a new Object to the BaseHandler.
Definition: BaseHandler.h:284
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.
SpeciesHandler speciesHandler
A handler to that stores the species type i.e. elastic, linear visco-elastic... et cetera...
Definition: DPMBase.h:868
U::MixedSpeciesType * getMixedObject(const U *S, const U *T)
WallHandler wallHandler
An object of the class WallHandler. Contains pointers to all the walls created.
Definition: DPMBase.h:883
BaseInteractable * getI()
Defines the basic properties that a interactable object can have.
void readObject(std::istream &is)
Reads an Interaction into the InteractionHandler from restart data.
const std::list< BaseInteraction * > & getInteractions() const
Returns a reference to the list of interactions in this BaseInteractable.
unsigned int getIndSpecies() const
Returns the index of the Species of this BaseInteractable.
BaseInteractable * getP()
Returns a pointer to first object involved in the interaction (normally a particle).
DPMBase * getDPMBase()
Gets the problem that is solved using this handler.
void addObject(BaseInteraction *I)
Adds an Interaction to the InteractionHandler.
void clear()
Empties the whole BaseHandler by removing all Objects and setting all other variables to 0...