InteractionHandler Class Referencefinal

Container to store Interaction objects. More...

#include <InteractionHandler.h>

+ Inheritance diagram for InteractionHandler:

Public Member Functions

 InteractionHandler ()
 Default constructor, it creates an empty InteractionHandler. More...
 
 InteractionHandler (const InteractionHandler &IH UNUSED)
 Copy constructor, but since interactions must not be copied, it creates an empty InteractionHandler. More...
 
InteractionHandleroperator= (const InteractionHandler &rhs)
 Assignment operator. More...
 
 ~InteractionHandler () override
 Destructor, it destructs the InteractionHandler and all BaseInteraction it contains. More...
 
void addObject (BaseInteraction *I) override
 Adds an Interaction to the InteractionHandler. More...
 
void read (std::istream &is)
 
void readAndAddObject (std::istream &is) override
 Reads an Interaction into the InteractionHandler from restart data. More...
 
BaseInteractiongetExistingInteraction (const BaseInteractable *P, const BaseInteractable *I) const
 Returns the Interaction between the BaseInteractable's P and I if it exists, otherwise returns a null pointer. More...
 
BaseInteractionaddInteraction (BaseInteractable *P, BaseInteractable *I, unsigned timeStamp)
 
void resetNewObjectsOMP ()
 
void addNewObjectsOMP ()
 
BaseInteractiongetInteraction (BaseInteractable *P, BaseInteractable *I, unsigned timeStamp)
 Returns the Interaction between the BaseInteractable's P and I. More...
 
BaseInteractioncreateEmptyInteraction () const
 Creates an empty interaction. More...
 
void deleteEmptyInteraction (BaseInteraction *interaction) const
 Deletes an empty interaction. More...
 
void * createMPIInteractionDataArray (unsigned int numberOfInteractions) const
 creates an empty MPIInteractionDataArray More...
 
void deleteMPIInteractionDataArray (void *dataArray)
 deletes an MPIInteractionDataArray More...
 
void getInteractionDetails (void *interactionData, unsigned int index, unsigned int &identificationP, unsigned int &identificationI, bool &isWallInteraction, unsigned &timeStamp)
 reads the basic interaction details from an MPIInteractionDataArray More...
 
BaseInteractiongetInteraction (BaseInteractable *P, BaseInteractable *I, unsigned timeStamp, const Vec3D &normal)
 Returns the Interaction between the BaseInteractable's P and I closest to the contact point (should be used when multiple contacts are possible). More...
 
void removeObjectKeepingPeriodics (unsigned int id)
 Removes interactions of periodic particles when the periodic particles get deleted (see DPMBase::removeDuplicatePeriodicParticles) More...
 
void eraseOldInteractions (unsigned)
 erases interactions which have an old timestamp. More...
 
void actionsAfterTimeStep ()
 
Mdouble getMeanOverlap () const
 The mean overlap of all interactions. More...
 
void write (std::ostream &os) const
 Writes the InteractionHandler to an output stream, for example a restart file. More...
 
void setWriteVTK (FileType f)
 
void setWriteVTK (bool)
 
FileType getWriteVTK () const
 
std::string getName () const override
 Returns the name of the object. More...
 
double getLiquidBridgeVolume () const
 
unsigned getNumberOfLiquidBridges () const
 
- Public Member Functions inherited from BaseHandler< BaseInteraction >
 BaseHandler ()
 Default BaseHandler constructor, it creates an empty BaseHandler and assigns DPMBase_ to a null pointer. More...
 
 BaseHandler (const BaseHandler< BaseInteraction > &BH)
 Constructor that copies the objects of the given handler into itself and sets other variables to 0/nullptr. More...
 
virtual ~BaseHandler ()
 Destructor, it destructs the BaseHandler and all Object it contains. More...
 
void copyContentsFromOtherHandler (const BaseHandler< BaseInteraction > &BH)
 Function that copies the contents (vector of pointers, maxObject_, nextId_, DPMBase_) from one handler (container) to the other. More...
 
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. More...
 
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. More...
 
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 particles, they avoid the global check if the particle can actually be inserted, because the mpi domain already knows that is the case. More...
 
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 particles, they avoid the global check if the particle can actually be inserted, because the mpi domain already knows that is the case. More...
 
virtual void addExistingObject (BaseInteraction *O)
 Adds an existing object to the BaseHandler without changing the id of the object. More...
 
virtual void addObject (BaseInteraction *object)
 Adds a new Object to the BaseHandler. More...
 
virtual void addGhostObject (BaseInteraction *O)
 Adds a new Object to the BaseHandler. called by the to avoid increasing the id. More...
 
void removeIf (const std::function< bool(BaseInteraction *)> cond)
 
virtual void removeObject (unsigned const int index)
 Removes an Object from the BaseHandler. More...
 
void removeLastObject ()
 Removes the last Object from the BaseHandler. More...
 
virtual void clear ()
 Empties the whole BaseHandler by removing all Objects and setting all other variables to 0. More...
 
void read (std::istream &is)
 Reads all objects from restart data. More...
 
BaseInteractiongetObjectById (const unsigned int id)
 Gets a pointer to the Object at the specified index in the BaseHandler. More...
 
std::vector< BaseInteraction * > getObjectsById (const unsigned int id)
 Gets a vector of pointers to the objects with the specific id. More...
 
BaseInteractiongetObject (const unsigned int id)
 Gets a pointer to the Object at the specified index in the BaseHandler.
More...
 
const BaseInteractiongetObject (const unsigned int id) const
 Gets a constant pointer to the Object at the specified index in the BaseHandler. More...
 
BaseInteractiongetLastObject ()
 Gets a pointer to the last Object in this BaseHandler. More...
 
const BaseInteractiongetLastObject () const
 Gets a constant pointer to the last Object in this BaseHandler. More...
 
virtual unsigned int getNumberOfObjects () const
 Gets the number of real Object in this BaseHandler. (i.e. no mpi or periodic particles) More...
 
unsigned int getSize () const
 Gets the size of the particleHandler (including mpi and periodic particles) More...
 
unsigned int getStorageCapacity () const
 Gets the storage capacity of this BaseHandler. More...
 
void setStorageCapacity (const unsigned int N)
 Sets the storage capacity of this BaseHandler. More...
 
void resize (const unsigned int N, const BaseInteraction &obj)
 Resizes the container to contain N elements. More...
 
const std::vector< BaseInteraction * >::const_iterator begin () const
 Gets the begin of the const_iterator over all Object in this BaseHandler. More...
 
const std::vector< BaseInteraction * >::iterator begin ()
 Gets the begin of the iterator over all BaseBoundary in this BaseHandler. More...
 
const std::vector< BaseInteraction * >::const_iterator end () const
 Gets the end of the const_iterator over all BaseBoundary in this BaseHandler. More...
 
const std::vector< BaseInteraction * >::iterator end ()
 Gets the end of the iterator over all BaseBoundary in this BaseHandler. More...
 
void setDPMBase (DPMBase *DPMBase)
 Sets the problem that is solved using this handler. More...
 
void setId (BaseInteraction *object, unsigned int id)
 
void increaseId ()
 
unsigned int getNextId ()
 
void setNextId (unsigned int id)
 
DPMBasegetDPMBase ()
 Gets the problem that is solved using this handler. More...
 
DPMBasegetDPMBase () const
 Gets the problem that is solved using this handler and does not change the class. More...
 
virtual void writeVTK () const
 now empty function for writing VTK files. More...
 
unsigned getNextGroupId ()
 Should be called each time you assign a groupId. Returns the value of nextGroupId_ and increases nextGroupId_ by one. More...
 

Public Attributes

std::vector< std::vector< BaseInteraction * > > newObjects_
 

Private Attributes

FileType writeVTK_
 
std::map< unsigned, BaseParticle * > particleById
 
std::map< unsigned, BaseWall * > wallById
 

Additional Inherited Members

- Protected Attributes inherited from BaseHandler< BaseInteraction >
std::vector< BaseInteraction * > objects_
 The actual list of Object pointers. More...
 

Detailed Description

Container to store Interaction objects.

The InteractionHandler is a container to store all Interaction objects. It is implemented as a vector of BaseInteraction pointers.

Constructor & Destructor Documentation

◆ InteractionHandler() [1/2]

InteractionHandler::InteractionHandler ( )

Default constructor, it creates an empty InteractionHandler.

Constructor of the ParticleHandler class. It creates and empty ParticleHandler.

44 {
46  logger(DEBUG, "InteractionHandler::InteractionHandler() finished");
47 }
@ NO_FILE
file will not be created/read
Logger< MERCURYDPM_LOGLEVEL > logger("MercuryKernel")
Definition of different loggers with certain modules. A user can define its own custom logger here.
@ DEBUG
FileType writeVTK_
Definition: InteractionHandler.h:211

References DEBUG, logger, NO_FILE, and writeVTK_.

◆ InteractionHandler() [2/2]

InteractionHandler::InteractionHandler ( const InteractionHandler &IH  UNUSED)

Copy constructor, but since interactions must not be copied, it creates an empty InteractionHandler.

Parameters
[in]IHThe InteractionHandler that has to be copied.

This is not a copy constructor! It only clears all variables, since by default interactions are not copied.

Todo:
Please check if interactions indeed don't need to be copied.
57 {
58  writeVTK_ = IH.writeVTK_;
59  //By default interactions are not copied.
60  logger(DEBUG, "InteractionHandler::InteractionHandler(const "
61  "InteractionHandler &IH) finished, please note that no interactions"
62  " have been copied.");
63 }

References DEBUG, logger, and writeVTK_.

◆ ~InteractionHandler()

InteractionHandler::~InteractionHandler ( )
override

Destructor, it destructs the InteractionHandler and all BaseInteraction it contains.

80 {
81  logger(DEBUG, "InteractionHandler::~InteractionHandler() finished");
82 }

References DEBUG, and logger.

Member Function Documentation

◆ actionsAfterTimeStep()

void InteractionHandler::actionsAfterTimeStep ( )
396 {
397  for (auto i: *this)
398  {
399  i->actionsAfterTimeStep();
400  }
401 }
const std::complex< Mdouble > i
Definition: ExtendedMath.h:51

References constants::i.

Referenced by DPMBase::computeOneTimeStep(), and DPMBase::initialiseSolve().

◆ addInteraction()

BaseInteraction * InteractionHandler::addInteraction ( BaseInteractable P,
BaseInteractable I,
unsigned  timeStamp 
)
115 {
116  BaseSpecies* species = getDPMBase()->speciesHandler.getMixedObject(P->getIndSpecies(), I->getIndSpecies());
117  BaseInteraction* C = species->getNewInteraction(P, I, timeStamp);
118  addObject(C);
119  return C;
120 }
DPMBase * getDPMBase()
Gets the problem that is solved using this handler.
Definition: BaseHandler.h:725
unsigned int getIndSpecies() const
Returns the index of the species associated with the interactable object.
Definition: BaseInteractable.h:88
Stores information about interactions between two interactable objects; often particles but could be ...
Definition: BaseInteraction.h:60
BaseSpecies is the class from which all other species are derived.
Definition: BaseSpecies.h:50
virtual BaseInteraction * getNewInteraction(BaseInteractable *P, BaseInteractable *I, unsigned timeStamp) const =0
returns new Interaction object.
SpeciesHandler speciesHandler
A handler to that stores the species type i.e. LinearViscoelasticSpecies, etc.
Definition: DPMBase.h:1427
void addObject(BaseInteraction *I) override
Adds an Interaction to the InteractionHandler.
Definition: InteractionHandler.cc:87
std::enable_if<!std::is_pointer< typename U::MixedSpeciesType >::value, typename U::MixedSpeciesType * >::type getMixedObject(const U *S, const U *T)
Definition: SpeciesHandler.h:74
double P
Uniform pressure.
Definition: TwenteMeshGluing.cpp:73

References addObject(), BaseHandler< BaseInteraction >::getDPMBase(), BaseInteractable::getIndSpecies(), SpeciesHandler::getMixedObject(), BaseSpecies::getNewInteraction(), Global_Physical_Variables::P, and DPMBase::speciesHandler.

Referenced by DPMBase::readNextFStatFile().

◆ addNewObjectsOMP()

void InteractionHandler::addNewObjectsOMP ( )
129  {
130  for (auto objects : newObjects_) {
131  for (auto object : objects) {
132  addObject(object);
133  }
134  }
135 }
std::vector< std::vector< BaseInteraction * > > newObjects_
Definition: InteractionHandler.h:203

References addObject(), and newObjects_.

Referenced by DPMBase::computeAllForces().

◆ addObject()

void InteractionHandler::addObject ( BaseInteraction I)
override

Adds an Interaction to the InteractionHandler.

Parameters
[in]PA pointer to the BaseInteraction (or derived class) that has to be added.
88 {
89  //set the particleHandler pointer
90  I->setHandler(this);
91  //Puts the interaction in the Interaction list
93  I->getP()->addInteraction(I);
94  I->getI()->addInteraction(I);
95 }
virtual void addObject(T *object)
Adds a new Object to the BaseHandler.
Definition: BaseHandler.h:431
void addInteraction(BaseInteraction *I)
Adds an interaction to this BaseInteractable.
Definition: BaseInteractable.cc:292
void setHandler(InteractionHandler *handler)
Sets the pointer to the interaction hander which is storing this interaction.
Definition: BaseInteraction.cc:261
BaseInteractable * getI()
Returns a pointer to the second object involved in the interaction (often a wall or a particle).
Definition: BaseInteraction.h:285
BaseInteractable * getP()
Returns a pointer to first object involved in the interaction (normally a particle).
Definition: BaseInteraction.h:274

References BaseInteractable::addInteraction(), BaseHandler< T >::addObject(), BaseInteraction::getI(), BaseInteraction::getP(), and BaseInteraction::setHandler().

Referenced by addInteraction(), addNewObjectsOMP(), BaseInteraction::copySwitchPointer(), and getInteraction().

◆ createEmptyInteraction()

BaseInteraction * InteractionHandler::createEmptyInteraction ( ) const

Creates an empty interaction.

Returns the Interaction between the BaseInteractable's P and I.

Empty interactions are required when dealing with parallel code. it is used a proto type interaction that can handle the MPI interaction data type which is a void array

183 {
184  //NOTE: assuming the interaction type of a species is the same for all species
185  BaseSpecies* species = this->getDPMBase()->speciesHandler.getObject(0);
186  BaseInteraction* emptyInteraction = species->getEmptyInteraction();
187 
188  return emptyInteraction;
189 }
T * getObject(const unsigned int id)
Gets a pointer to the Object at the specified index in the BaseHandler.
Definition: BaseHandler.h:613
virtual BaseInteraction * getEmptyInteraction() const =0

References BaseHandler< BaseInteraction >::getDPMBase(), BaseSpecies::getEmptyInteraction(), BaseHandler< T >::getObject(), and DPMBase::speciesHandler.

Referenced by createMPIInteractionDataArray(), deleteMPIInteractionDataArray(), and getInteractionDetails().

◆ createMPIInteractionDataArray()

void * InteractionHandler::createMPIInteractionDataArray ( unsigned int  numberOfInteractions) const

creates an empty MPIInteractionDataArray

When sending interactions to other processors it is done with a void* array, because interactions come in many different sizes and shapes. The size of an interaction depends on the type f interaction. By creating an emptyInteraction, the size can be determined and an empty vector can be allocated

Parameters
[in]numberOfInteractionsThe number of interactions that are added to the MPIInteractionDataArray
Returns
Returns a void pointer to a block of memory that will contain the interaction data
212 {
213  BaseInteraction* emptyInteraction = this->createEmptyInteraction();
214  //create a vector based on the first interaction. This is to avoid templating the whole class
215  void* historyData = emptyInteraction->createMPIInteractionDataArray(numberOfInteractions);
216  this->deleteEmptyInteraction(emptyInteraction);
217 
218  return historyData;
219 }
virtual void * createMPIInteractionDataArray(unsigned int numberOfInteractions) const
Definition: BaseInteraction.cc:911
BaseInteraction * createEmptyInteraction() const
Creates an empty interaction.
Definition: InteractionHandler.cc:182
void deleteEmptyInteraction(BaseInteraction *interaction) const
Deletes an empty interaction.
Definition: InteractionHandler.cc:197

References createEmptyInteraction(), BaseInteraction::createMPIInteractionDataArray(), and deleteEmptyInteraction().

Referenced by PeriodicBoundaryHandler::collectInteractionData(), Domain::performBoundaryDataTransmission(), and PeriodicBoundaryHandler::performNewParticleTransmission().

◆ deleteEmptyInteraction()

void InteractionHandler::deleteEmptyInteraction ( BaseInteraction interaction) const

Deletes an empty interaction.

When handling the Interaction MPI data type, an empty interaction is created. This function destroys that empty function again

Parameters
[in,out]interactionPointer to a base interaction that needs to be deleted
198 {
199  BaseSpecies* species = this->getDPMBase()->speciesHandler.getObject(0);
200  species->deleteEmptyInteraction(interaction);
201 }
virtual void deleteEmptyInteraction(BaseInteraction *interaction) const =0

References BaseSpecies::deleteEmptyInteraction(), BaseHandler< BaseInteraction >::getDPMBase(), BaseHandler< T >::getObject(), and DPMBase::speciesHandler.

Referenced by createMPIInteractionDataArray(), deleteMPIInteractionDataArray(), and getInteractionDetails().

◆ deleteMPIInteractionDataArray()

void InteractionHandler::deleteMPIInteractionDataArray ( void *  dataArray)

deletes an MPIInteractionDataArray

An empty interaction is created that can recast the data array into an array of the interactions. After the conversion the data of the array is cleaned up

Parameters
[in]dataArrayvoid pointer to a data array
228 {
229  BaseInteraction* emptyInteraction = this->createEmptyInteraction();
230  emptyInteraction->deleteMPIInteractionDataArray(dataArray);
231  this->deleteEmptyInteraction(emptyInteraction);
232 }
virtual void deleteMPIInteractionDataArray(void *dataArray)
Definition: BaseInteraction.cc:917

References createEmptyInteraction(), deleteEmptyInteraction(), and BaseInteraction::deleteMPIInteractionDataArray().

Referenced by Domain::finaliseBoundaryDataTransmission().

◆ eraseOldInteractions()

void InteractionHandler::eraseOldInteractions ( unsigned  currentNTime)

erases interactions which have an old timestamp.

Each interaction contains a time stamp, which stores the last time that an interaction object has been called. Thus, one can see that an interaction has ended by comparing the time stamp with the last value of DPMBase::time_. This function erases all interactions that have ended.

Parameters
[in]lastTimeStepthe last used value of DPMBase::time_.
Todo:
TW: this function has to be sped up with sth like this: erase(remove_if(begin(), end(), bind2nd(checkSpringTime(), lastTimeStep)), end());
378 {
379  //std::cout<<"void InteractionHandler::eraseOldInteractions(Mdouble lastTimeStep)"<<std::endl;
380  //std::cout<<"Current interactions="<<getNumberOfObjects()<<std::endl;
381  //Remove_if reconstructs the vector with only elements passing the check_spring_time function
382  //Erase removes the end of the vector
384  for (unsigned int id = 0; id < getNumberOfObjects(); id++)
385  {
386  if (getObject(id)->getTimeStamp() <= currentNTime)
387  {
388  getObject(id)->actionsOnErase();
389  removeObject(id);
390  --id;
391  }
392  }
393 }
virtual void removeObject(unsigned const int index)
Removes an Object from the BaseHandler.
Definition: BaseHandler.h:472
virtual unsigned int getNumberOfObjects() const
Gets the number of real Object in this BaseHandler. (i.e. no mpi or periodic particles)
Definition: BaseHandler.h:648
Mdouble getTimeStamp() const
Returns an Mdouble which is the time stamp of the interaction.
Definition: BaseInteraction.h:319
virtual void actionsOnErase()
If an interaction needs to do something before it gets erased, add it here. E.g. Liquid bridges ruptu...
Definition: BaseInteraction.h:84

References BaseInteraction::actionsOnErase(), BaseHandler< BaseInteraction >::getNumberOfObjects(), BaseHandler< BaseInteraction >::getObject(), BaseInteraction::getTimeStamp(), and BaseHandler< BaseInteraction >::removeObject().

Referenced by DPMBase::computeOneTimeStep().

◆ getExistingInteraction()

BaseInteraction * InteractionHandler::getExistingInteraction ( const BaseInteractable P,
const BaseInteractable I 
) const

Returns the Interaction between the BaseInteractable's P and I if it exists, otherwise returns a null pointer.

Parameters
[in]Pthe first BaseInteractable by which the interaction is defined.
[in]Ithe first BaseInteractable by which the interaction is defined.
Returns
the Interaction between the BaseInteractable's P and I, if it exists.
104 {
105  //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
106  for (const auto i : P->getInteractions()) {
107  if (i->getI() == I) {
108  return i;
109  }
110  }
111  return nullptr;
112 }

References constants::i, and Global_Physical_Variables::P.

Referenced by MeshTriangle::checkInteractions(), getInteraction(), and removeObjectKeepingPeriodics().

◆ getInteraction() [1/2]

BaseInteraction * InteractionHandler::getInteraction ( BaseInteractable P,
BaseInteractable I,
unsigned  timeStamp 
)

Returns the Interaction between the BaseInteractable's P and I.

Returns a pointer to the existing Interaction, if the Interaction already exists otherwise creates a new Interaction and returns a pointer to it.

Parameters
[in]Pthe first BaseInteractable by which the interaction is defined.
[in]Ithe first BaseInteractable by which the interaction is defined.
[in]timeStampthe current value of DPMBase::time_.
Returns
the Interaction between the BaseInteractable's P and I
Todo:
TW this can bet set earlier
147 {
148  const BaseSpecies* const species = getDPMBase()->speciesHandler.getMixedObject(P->getIndSpecies(),
149  I->getIndSpecies());
150 
152  if (C == nullptr) {
153  C = species->getNewInteraction(P, I, timeStamp);
154  #ifdef MERCURYDPM_USE_OMP
155  if (omp_get_num_threads()>1) {
156  newObjects_[omp_get_thread_num()].push_back(C);
157  C->setHandler(this);
158  } else {
159  addObject(C);
160  }
161  #else
162  addObject(C);
163  #endif
164  }
165 
166  //set timeStamp
167  C->setTimeStamp(timeStamp);
168 
170  //set species of collision
171  C->setSpecies(species);
172 
173  return C;
174 }
void setTimeStamp(unsigned timeStamp)
Updates the time step of the interacting. Note, time steps used to find completed interactions.
Definition: BaseInteraction.cc:251
void setSpecies(const BaseSpecies *species)
Set the Species of the interaction; note this can either be a Species or MixedSpecies.
Definition: BaseInteraction.cc:390
BaseInteraction * getExistingInteraction(const BaseInteractable *P, const BaseInteractable *I) const
Returns the Interaction between the BaseInteractable's P and I if it exists, otherwise returns a null...
Definition: InteractionHandler.cc:103

References addObject(), BaseHandler< BaseInteraction >::getDPMBase(), getExistingInteraction(), BaseInteractable::getIndSpecies(), SpeciesHandler::getMixedObject(), BaseSpecies::getNewInteraction(), newObjects_, Global_Physical_Variables::P, BaseInteraction::setHandler(), BaseInteraction::setSpecies(), BaseInteraction::setTimeStamp(), and DPMBase::speciesHandler.

Referenced by BaseParticle::getInteractionWith(), ArcWall::getInteractionWith(), BaseWall::getInteractionWith(), Combtooth::getInteractionWith(), MeshTriangle::getInteractionWith(), SineWall::getInteractionWith(), TriangleMeshWall::getInteractionWith(), TriangulatedWall::getInteractionWith(), VChute::getInteractionWith(), SuperQuadricParticle::getInteractionWithSuperQuad(), main(), readAndAddObject(), ChargedBondedInteractionSelfTest::setupInitialConditions(), TwoBondedParticleElasticCollision::setupInitialConditions(), UnionOfWalls::setupInitialConditions(), ChargedBondedParticleUnitTest::setupInitialConditions(), and MultiParticlesInsertion::setupInitialConditions().

◆ getInteraction() [2/2]

BaseInteraction * InteractionHandler::getInteraction ( BaseInteractable P,
BaseInteractable I,
unsigned  timeStamp,
const Vec3D normal 
)

Returns the Interaction between the BaseInteractable's P and I closest to the contact point (should be used when multiple contacts are possible).

Returns a pointer to the existing Interaction, if the Interaction already exists otherwise creates a new Interaction and returns a pointer to it.

Parameters
[in]Pthe first BaseInteractable by which the interaction is defined.
[in]Ithe first BaseInteractable by which the interaction is defined.
[in]timeStampthe current value of DPMBase::time_.
Returns
the Interaction between the BaseInteractable's P and I
265 {
266  BaseInteraction* c = nullptr;
267  Mdouble dNormalMax = 0.9; //minimal agreement required
268  for (const auto& i : P->getInteractions())
269  {
270  if (i->getI() == I && i->getTimeStamp() != timeStamp)
271  {
272  const Mdouble dNormal = Vec3D::dot(normal, i->getNormal());
273  if (dNormal > dNormalMax)
274  {
275  c = i;
276  dNormalMax = dNormal;
277  }
278  }
279  }
280 
281  BaseSpecies* species = getDPMBase()->speciesHandler.getMixedObject(P->getIndSpecies(), I->getIndSpecies());
282 
283  if (c)
284  {
285  c->setTimeStamp(timeStamp);
286  }
287  else
288  {
289  c = species->getNewInteraction(P, I, timeStamp);
290  c->setSpecies(species);
291  addObject(c);
292  //logger(INFO,"new interaction t=%: i=%, n=%",timeStamp,getNumberOfObjects(),normal);
293  }
294 
295  return c;
296 }
double Mdouble
Definition: GeneralDefine.h:34
static Mdouble dot(const Vec3D &a, const Vec3D &b)
Calculates the dot product of two Vec3D: .
Definition: Vector.cc:76

References addObject(), Vec3D::dot(), BaseHandler< BaseInteraction >::getDPMBase(), BaseInteractable::getIndSpecies(), SpeciesHandler::getMixedObject(), BaseSpecies::getNewInteraction(), constants::i, Global_Physical_Variables::P, BaseInteraction::setSpecies(), BaseInteraction::setTimeStamp(), and DPMBase::speciesHandler.

◆ getInteractionDetails()

void InteractionHandler::getInteractionDetails ( void *  interactionData,
unsigned int  index,
unsigned int &  identificationP,
unsigned int &  identificationI,
bool isWallInteraction,
unsigned &  timeStamp 
)

reads the basic interaction details from an MPIInteractionDataArray

because the interactionData array is a void pointer array, it is not possibly to directly read out the interaction data this function reads the basic information such as which objects are interacting and at what time.

Parameters
[in]interactionDatavoid pointer to the mpi interaction data
[in]indexThe index of the interaction in the interaction data
[out]identificationPthe unique id of the P object
[out]idientificationIthe unique id of the I object
[out]isWallInteractiona bool that flags if the interaction is a wall interaction or not
[out]timeStampreads the timestamp of the interaction
248 {
249  BaseInteraction* emptyInteraction = this->createEmptyInteraction();
250  emptyInteraction->getInteractionDetails(interactionData, index, identificationP, identificationI, isWallInteraction,
251  timeStamp);
252  this->deleteEmptyInteraction(emptyInteraction);
253 }
virtual void getInteractionDetails(void *interactionDataArray, unsigned int index, unsigned int &identificationP, unsigned int &identificationI, bool &isWallInteraction, unsigned &timeStamp)
Definition: BaseInteraction.cc:923

References createEmptyInteraction(), deleteEmptyInteraction(), and BaseInteraction::getInteractionDetails().

Referenced by PeriodicBoundaryHandler::processLocalInteractionData(), PeriodicBoundaryHandler::processReceivedInteractionData(), and Domain::processReceivedInteractionData().

◆ getLiquidBridgeVolume()

double InteractionHandler::getLiquidBridgeVolume ( ) const
564  {
565  double liquidVolume = 0;
566  for (auto i : objects_) {
567  auto j = dynamic_cast<LiquidMigrationWilletInteraction*>(i);
568  if (j and !static_cast<BaseParticle*>(j->getP())->isMPIParticle()) liquidVolume += j->getLiquidBridgeVolume();
569  }
570  return getMPISum(liquidVolume);
571 };
Vec3D getMPISum(Vec3D &val)
Definition: MpiDataClass.cc:199
std::vector< BaseInteraction * > objects_
The actual list of Object pointers.
Definition: BaseHandler.h:302
Definition: BaseParticle.h:54
bool isMPIParticle() const
Indicates if this particle is a ghost in the MPI domain.
Definition: BaseParticle.cc:181
Defines the liquid bridge willet interaction between two particles or walls.
Definition: LiquidMigrationWilletInteraction.h:45
Mdouble getLiquidBridgeVolume() const
Definition: LiquidMigrationWilletInteraction.cc:462

References getMPISum(), constants::i, BaseParticle::isMPIParticle(), and BaseHandler< BaseInteraction >::objects_.

Referenced by LiquidMigrationMPI2Test::printTime(), and EvaporationAndHeatTest::printTime().

◆ getMeanOverlap()

Mdouble InteractionHandler::getMeanOverlap ( ) const

The mean overlap of all interactions.

Returns
The mean overlap of all interactions
407 {
408  Mdouble sum = 0;
409  Mdouble n = 0;
410  for (BaseInteraction* const p : objects_)
411  {
412  if (p->getOverlap() > 0)
413  {
414  sum += p->getOverlap();
415  n++;
416  }
417  }
418  return sum / n;
419 }
const unsigned n
Definition: CG3DPackingUnitTest.cpp:32

References n, and BaseHandler< BaseInteraction >::objects_.

Referenced by InitialConditions< SpeciesType >::getMeanRelativeContactRadius(), Sintering::getMeanRelativeContactRadius(), regimeForceUnitTest::getMeanRelativeContactRadius(), main(), GranuDrum::printTime(), Drum::printTime(), and RotatingDrumWet::printTime().

◆ getName()

std::string InteractionHandler::getName ( ) const
overridevirtual

Returns the name of the object.

Returns
the string InteractionHandler

Implements BaseHandler< BaseInteraction >.

425 {
426  return "InteractionHandler";
427 }

Referenced by read().

◆ getNumberOfLiquidBridges()

unsigned InteractionHandler::getNumberOfLiquidBridges ( ) const
573  {
574  int liquidBridges = 0;
575  for (auto i : objects_) {
576  auto j = dynamic_cast<LiquidMigrationWilletInteraction*>(i);
577  if (j and !static_cast<BaseParticle*>(j->getP())->isMPIParticle() && j->getLiquidBridgeVolume()>0) liquidBridges++;
578  }
579  return getMPISum(liquidBridges);
580 };

References getMPISum(), constants::i, BaseParticle::isMPIParticle(), and BaseHandler< BaseInteraction >::objects_.

Referenced by RotatingDrumWet::printTime().

◆ getWriteVTK()

FileType InteractionHandler::getWriteVTK ( ) const

◆ operator=()

InteractionHandler & InteractionHandler::operator= ( const InteractionHandler rhs)

Assignment operator.

Parameters
[in]rhsThe BoundaryHandler on the right hand side of the assignment.
69 {
70  if (this != &rhs)
71  {
72  clear();
73  }
74  writeVTK_ = rhs.writeVTK_;
75  logger(DEBUG, "InteractionHandler::operator =(const InteractionHandler& rhs) finished.");
76  return *this;
77 }
virtual void clear()
Empties the whole BaseHandler by removing all Objects and setting all other variables to 0.
Definition: BaseHandler.h:528

References BaseHandler< BaseInteraction >::clear(), DEBUG, logger, and writeVTK_.

◆ read()

void InteractionHandler::read ( std::istream &  is)
Parameters
[in]isThe input stream from which the information is read.
455 {
456  clear();
457  unsigned int N;
458  std::string dummy;
459  is >> dummy;
460  std::stringstream line;
462  line >> N;
463  if (N > 1e5)
464  {
465  logger(INFO, "Reading % %", N, dummy);
466  }
467  logger(VERBOSE, "In %::read(is): reading in % objects.", getName(), N);
469  // set map
470  particleById.clear();
471  for (BaseParticle* p: getDPMBase()->particleHandler)
472  {
473  particleById[p->getId()] = p;
474  }
475  wallById.clear();
476  for (BaseWall* w: getDPMBase()->wallHandler)
477  {
478  wallById[w->getId()] = w;
479  }
480  for (unsigned int i = 0; i < N; i++)
481  {
482  readAndAddObject(is);
483  }
484  particleById.clear();
485  wallById.clear();
486 }
@ INFO
@ VERBOSE
void setStorageCapacity(const unsigned int N)
Sets the storage capacity of this BaseHandler.
Definition: BaseHandler.h:669
Basic class for walls.
Definition: BaseWall.h:49
std::string getName() const override
Returns the name of the object.
Definition: InteractionHandler.cc:424
void readAndAddObject(std::istream &is) override
Reads an Interaction into the InteractionHandler from restart data.
Definition: InteractionHandler.cc:492
std::map< unsigned, BaseWall * > wallById
Definition: InteractionHandler.h:214
std::map< unsigned, BaseParticle * > particleById
Definition: InteractionHandler.h:213
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:62

References BaseHandler< BaseInteraction >::clear(), BaseHandler< BaseInteraction >::getDPMBase(), helpers::getLineFromStringStream(), getName(), constants::i, INFO, logger, particleById, readAndAddObject(), BaseHandler< BaseInteraction >::setStorageCapacity(), VERBOSE, and wallById.

Referenced by DPMBase::read().

◆ readAndAddObject()

void InteractionHandler::readAndAddObject ( std::istream &  is)
overridevirtual

Reads an Interaction into the InteractionHandler from restart data.

Parameters
[in]isThe input stream from which the information is read.
Todo:
Ant This is a tmp fix as in some cases the line before has not be finished reading. This should be looked at again at a later date.
Todo:
TW: Change identifier in restart file from id to index; is there any reason the id should be kept after restarting, once this is done? (Note, the id is set to the old one in the particle handler because interactions store id, not indices; also note id's are slow

Implements BaseHandler< BaseInteraction >.

493 {
494  std::string type, dummy, idType;
495  unsigned int id0, id1;
496  unsigned timeStamp;
497 
499  is >> type;
500  logger(DEBUG, "InteractionHandler::readAndAddObject(is): reading type %.", type);
501  Mdouble timeStampDouble;
502  is >> idType >> id0 >> id1 >> dummy >> timeStampDouble;
503  timeStamp = timeStampDouble; //in order to read old restart files
504 
506  BaseInteraction* C;
507 
508 #ifdef MERCURYDPM_USE_MPI
509  if (idType.compare("particleIds") == 0)
510  {
511  std::vector<BaseParticle*> list0 = getDPMBase()->particleHandler.getObjectsById(id0);
512  std::vector<BaseParticle*> list1 = getDPMBase()->particleHandler.getObjectsById(id1);
513  for (int p0 = 0; p0 < list0.size(); p0++)
514  {
515  for (int p1 = 0; p1 < list1.size(); p1++)
516  {
517  C = getInteraction(list0[p0],list1[p1], timeStamp);
518  if (C != nullptr)
519  {
520  is >> *C;
521  }
522  }
523  }
524 
525  }
526  else
527  {
528  std::vector<BaseParticle*> list0 = getDPMBase()->particleHandler.getObjectsById(id0);
529  for (int p0 = 0; p0 < list0.size(); p0++)
530  {
531  C = getInteraction(list0[p0],getDPMBase()->wallHandler.getObjectById(id1), timeStamp);
532  if (C != nullptr)
533  {
534  is >> *C;
535  }
536  }
537  }
538 #else
539  //this requires particleById/wallById to be set, which is done in the read() function
540  if (idType == "particleIds")
541  C = getInteraction(particleById[id0],particleById[id1],timeStamp);
542  else
543  C = getInteraction(particleById[id0],wallById[id1], timeStamp);
544  is >> (*C);
545 #endif
546  is.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
547 }
std::vector< T * > getObjectsById(const unsigned int id)
Gets a vector of pointers to the objects with the specific id.
Definition: BaseHandler.h:593
ParticleHandler particleHandler
An object of the class ParticleHandler, contains the pointers to all the particles created.
Definition: DPMBase.h:1437
BaseInteraction * getInteraction(BaseInteractable *P, BaseInteractable *I, unsigned timeStamp)
Returns the Interaction between the BaseInteractable's P and I.
Definition: InteractionHandler.cc:146

References DEBUG, BaseHandler< BaseInteraction >::getDPMBase(), getInteraction(), BaseHandler< T >::getObjectsById(), logger, particleById, DPMBase::particleHandler, and wallById.

Referenced by read().

◆ removeObjectKeepingPeriodics()

void InteractionHandler::removeObjectKeepingPeriodics ( unsigned int  id)

Removes interactions of periodic particles when the periodic particles get deleted (see DPMBase::removeDuplicatePeriodicParticles)

Deleting the three periodic interactions between two real particles is difficult, because its interaction information has to be saved. If the two real particles interacted (which can be checked by looking at the time stamp), the interaction between the real particles is kept, and all interactions that involve ghost particles gets removed; otherwise, the interaction between the lower-indexed real particle with the ghost particle of the higher indexed particles is saved (with the ghost particle replaced by the real particle), and all other interactions removed.

This is what this function is intended for, and it does it in the following way: When an interaction is removed the periodic particle has to be stored in the I pointer So when an interaction is removed where P is normal and I is periodic, and the information is new it will be transfered when the index of P is lower than the index of the real particle of I.

Parameters
[in]theid of the Interaction that needs to be deleted.
Todo:
TW The code assumes in a few places that P->getIndex()<I->getIndex(), but the copySwitchPointer function does not obey that rule; we have to check if this is valid behaviour.
Todo:
this function will create an error if the timeStamp is in the future! This should not happen (ever), but who knows.
317 {
318  BaseInteraction* iMain = getObject(id);
319 
320  BaseParticle* P = dynamic_cast<BaseParticle*>(iMain->getP());
321  BaseParticle* I = dynamic_cast<BaseParticle*>(iMain->getI());
322  if (P != nullptr && I != nullptr) //check that both P and I are particles (not walls)
323  {
325  if (realI != nullptr && !P->getPeriodicFromParticle()) //check that P is a real and I is a ghost particle
326  {
327  if (P->getIndex() < realI->getIndex())
328  {
329  BaseInteraction* iOther = getExistingInteraction(P, realI);
330  //You have to also check for existing interactions of the particles in reverse order since the copySwitchPointer function can revert the order of the particles
332  if (iOther == nullptr)
333  {
334  iOther = getExistingInteraction(realI, P);
335  }
336  if (iOther != nullptr) //if the interaction existed before the ghost particles were created
337  {
338  //Here we decide which of the two interactions should be kept:
339  //the interaction between the two real particles (iMain), or
340  //the interaction between the real and a ghost particle (iOther).
341  //It picks the one for which a collision has happened,
342  //i.e. the one with the newer timeStamp.
344  if (iOther->getTimeStamp() <
345  iMain->getTimeStamp()) //if the interaction has been active during the last computeForce routine, make this the new (real) interaction.
346 
347  {
348  iMain->setI(realI);
349  removeObject(iOther->getIndex());
350  return;
351  }
352  else //if the interaction has not been active during the last computeForce routine
353  {
355  return;
356  }
357  }
358  else //if the interaction has been created during the last computeForce routine, make this a new (real) interaction.
359  {
360  iMain->setI(realI);
361  return;
362  }
363  }
364  }
365  }
366  //this point is reached if either P or I are walls, or P and I are both ghost particles; in these cases, the interaction gets deleted
368 }
Defines the basic properties that a interactable object can have.
Definition: BaseInteractable.h:55
void setI(BaseInteractable *I)
Sets the second object involved in the interaction (often particle or wall).
Definition: BaseInteraction.cc:435
unsigned int getIndex() const
Returns the index of the object in the handler.
Definition: BaseObject.h:118
BaseParticle * getPeriodicFromParticle() const
Returns the 'original' particle this one's a periodic copy of.
Definition: BaseParticle.h:341

References getExistingInteraction(), BaseInteraction::getI(), BaseObject::getIndex(), BaseHandler< BaseInteraction >::getObject(), BaseInteraction::getP(), BaseParticle::getPeriodicFromParticle(), BaseInteraction::getTimeStamp(), Global_Physical_Variables::P, BaseHandler< T >::removeObject(), BaseHandler< BaseInteraction >::removeObject(), and BaseInteraction::setI().

Referenced by SilbertPeriodic::add_flow_particles(), and DPMBase::removeDuplicatePeriodicParticles().

◆ resetNewObjectsOMP()

void InteractionHandler::resetNewObjectsOMP ( )
122  {
123  #ifdef MERCURYDPM_USE_OMP
124  newObjects_.clear();
125  newObjects_.resize(getDPMBase()->getNumberOfOMPThreads());
126  #endif
127 }

References BaseHandler< BaseInteraction >::getDPMBase(), and newObjects_.

Referenced by DPMBase::computeAllForces().

◆ setWriteVTK() [1/2]

void InteractionHandler::setWriteVTK ( bool  writeVTK)
555 {
557 }
@ MULTIPLE_FILES
each time-step will be written into/read from separate files numbered consecutively: name_....
virtual void writeVTK() const
now empty function for writing VTK files.
Definition: BaseHandler.h:286

References MULTIPLE_FILES, NO_FILE, BaseHandler< BaseInteraction >::writeVTK(), and writeVTK_.

◆ setWriteVTK() [2/2]

void InteractionHandler::setWriteVTK ( FileType  f)

◆ write()

void InteractionHandler::write ( std::ostream &  os) const

Writes the InteractionHandler to an output stream, for example a restart file.

Parameters
[in]osThe output stream where the InteractionHandler must be written to, usually a restart file.
434 {
435 #ifdef MERCURYDPM_USE_MPI
436  //note: this function only prints the particles on processor 0
437  //The rest of the particles are processed in the restart file write function
438  MPIContainer& communicator = MPIContainer::Instance();
439  unsigned int totalNumberOfInteractions = getNumberOfObjects();
440  os << "Interactions " << totalNumberOfInteractions << '\n';
441  //logger(INFO,"% interactions",getNumberOfObjects());
442  for (BaseInteraction* it : *this)
443  {
444  os << (*it) << '\n';
445  }
446 #else
447  os << "Interactions " << getNumberOfObjects() << '\n';
448  for (BaseInteraction* i : objects_)
449  os << (*i) << '\n';
450 #endif
451 }
This class contains all information and functions required for communication between processors.
Definition: MpiContainer.h:130
static MPIContainer & Instance()
fetch the instance to be used for communication
Definition: MpiContainer.h:134

References BaseHandler< BaseInteraction >::getNumberOfObjects(), constants::i, MPIContainer::Instance(), and BaseHandler< BaseInteraction >::objects_.

Referenced by DPMBase::write().

Member Data Documentation

◆ newObjects_

std::vector<std::vector<BaseInteraction*> > InteractionHandler::newObjects_

◆ particleById

std::map<unsigned,BaseParticle*> InteractionHandler::particleById
private

Referenced by read(), and readAndAddObject().

◆ wallById

std::map<unsigned,BaseWall*> InteractionHandler::wallById
private

Referenced by read(), and readAndAddObject().

◆ writeVTK_

FileType InteractionHandler::writeVTK_
private

The documentation for this class was generated from the following files: