MercuryDPM  Alpha
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
BaseInteractable.cc
Go to the documentation of this file.
1 //Copyright (c) 2013-2015, 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 "BaseInteractable.h"
28 #include "Particles/BaseParticle.h"
31 
39 {
44  force_.setZero();
45  torque_.setZero();
46  indSpecies_ = 0;
47  species_ = nullptr;
48  prescribedPosition_ = nullptr;
49  prescribedVelocity_ = nullptr;
50  prescribedOrientation_ = nullptr;
52  logger(DEBUG, "BaseInteractable::BaseInteractable() finished");
53 }
54 
62  : BaseObject(p)
63 {
64  interactions_.clear();
65  position_ = p.position_;
67  velocity_ = p.velocity_;
69  force_ = p.force_;
70  torque_ = p.torque_;
71  species_ = p.species_;
77  logger(DEBUG,"BaseInteractable::BaseInteractable(const BaseInteractable &p finished");
78 }
79 
84 {
85  logger(VERBOSE, "Deleting BaseInteractable with index= % and id = % size = %", getIndex(),getId(),interactions_.size());
86  while (interactions_.size() > 0)
87  {
88  interactions_.front()->removeFromHandler();
89  }
90  logger(DEBUG,"BaseInteractable::~BaseInteractable() finished");
91 }
92 
98 unsigned int BaseInteractable::getIndSpecies() const
99 {
100  return indSpecies_;
101 }
102 
110 {
111  indSpecies_ = indSpecies;
112 }
113 
122 {
123  //logger.assert(species_,"Species of % % has to be defined",getName(),getIndex());
124  return species_;
125 }
126 
136 {
137  if (species->getHandler() == nullptr)
138  {
139  logger(ERROR, "Error: Species is not part of any handler yet");
140  }
141 
142  species_ = species;
143  indSpecies_ = species->getIndex();
144 }
145 
155 {
156  return force_;
157 }
158 
168 {
169  return torque_;
170 }
171 
180 {
181  force_ = force;
182 }
183 
193 {
194  torque_ = torque;
195 }
196 
203 void BaseInteractable::addForce(const Vec3D& addForce)
204 {
205  force_ += addForce;
206 }
207 
214 void BaseInteractable::addTorque(const Vec3D& addTorque)
215 {
216  torque_ += addTorque;
217 }
218 
229 {
230  return position_;
231 }
232 
244 {
245  return orientation_;
246 }
247 
255 {
256  position_ = position;
257 }
258 
259 
267 void BaseInteractable::setOrientation(const Vec3D& orientation)
268 {
269  orientation_ = orientation;
270 }
271 
278 void BaseInteractable::move(const Vec3D& move)
279 {
280  position_ += move;
281 }
282 
289 void BaseInteractable::rotate(const Vec3D& rotate)
290 {
291  orientation_ += rotate;
292 }
293 
301 void BaseInteractable::read(std::istream& is)
302 {
303  BaseObject::read(is);
304  std::string dummy;
305  is >> dummy >> indSpecies_;
306  is >> dummy >> position_;
307  is >> dummy;
308  //this if-statement is added to read Kasper van der Vaart's data files, which contain an additional variable named positionAbsolute
309  if (dummy.compare("positionAbsolute") == 0)
310  {
311  is >> dummy >> dummy >> dummy >> dummy;
312  }
313  is >> orientation_ >> dummy;
314  is >> dummy >> velocity_;
315  is >> dummy >> angularVelocity_ >> dummy;
316  is >> dummy >> force_;
317  is >> dummy >> torque_;
318 }
319 
328 void BaseInteractable::write(std::ostream& os) const
329 {
330  BaseObject::write(os);
331  os << " indSpecies " << indSpecies_
332  << " position " << position_
333  << " orientation " << orientation_ << " " << 0.0
334  << " velocity " << velocity_
335  << " angularVelocity " << angularVelocity_ << " " << 0.0
336  << " force " << force_
337  << " torque " << torque_;
338 }
339 
345 const std::list<BaseInteraction*>& BaseInteractable::getInteractions() const
346 {
347  return interactions_;
348 }
349 
356 {
357  interactions_.push_back(I);
358 }
359 
372 {
373  for (std::list<BaseInteraction*>::iterator it = interactions_.begin(); it != interactions_.end(); ++it)
374  {
375  if (I == (*it))
376  {
377  logger(VERBOSE, "Removing interaction from % between % and %",getId(),I->getI()->getId(),I->getP()->getId());
378  interactions_.erase(it);
379  return true;
380  }
381  }
382  logger(WARN, "Error in BaseInteractable::removeInteraction: Interaction could not be removed");
383  return false;
384 }
385 
394 {
395  return velocity_;
396 }
397 
406 {
407  return angularVelocity_;
408 }
409 
415 {
416  velocity_ = velocity;
417 }
418 
424 void BaseInteractable::setAngularVelocity(const Vec3D& angularVelocity)
425 {
426  angularVelocity_ = angularVelocity;
427 }
428 
435 {
436  velocity_ += velocity;
437 }
438 
444 void BaseInteractable::addAngularVelocity(const Vec3D& angularVelocity)
445 {
446  angularVelocity_ += angularVelocity;
447 }
449 {
450  return getVelocity() - Vec3D::cross(contact - getPosition(), getAngularVelocity());
451 }
452 
460 {
461  for (BaseInteraction* interaction : pOriginal.interactions_)
462  {
463  //So here this is the ghost and it is the interaction of the ghost/
464  interaction->copySwitchPointer(&pOriginal, this);
465  }
466 }
467 
486 void BaseInteractable::setPrescribedPosition(const std::function<Vec3D (double)>& prescribedPosition)
487 {
488  prescribedPosition_ = prescribedPosition;
489 }
490 
497 {
499  {
501  }
502 }
503 
517 void BaseInteractable::setPrescribedVelocity(const std::function<Vec3D (double)>& prescribedVelocity)
518 {
519  prescribedVelocity_ = prescribedVelocity;
520 }
521 
528 {
530  {
532  }
533 }
534 
547 void BaseInteractable::setPrescribedOrientation(const std::function<Vec3D (double)>& prescribedOrientation)
548 {
549  prescribedOrientation_ = prescribedOrientation;
550 }
551 
559 {
561  {
563  }
564 }
565 
566 /*
567  * \details This functions sets a std::function which specifies the
568  * AngularVeclocity of an interactable. This function takes a double
569  * the time and returns a Vec3D which is the new angular velocity.
570  * See also BaseInteractable::setPrescribedOrientation
571  * Note this functions works the same way as
572  * BaseInteractable::setPosition and BaseInteractable::setVeclocity.
573  */
574 void BaseInteractable::setPrescribedAngularVelocity(const std::function<Vec3D (double)>& prescribedAngularVelocity)
575 {
576  prescribedAngularVelocity_ = prescribedAngularVelocity;
577 }
578 
586 {
588  {
590  }
591 }
592 
611 void BaseInteractable::integrateBeforeForceComputation(double time, double timeStep)
612 {
613  if (prescribedPosition_ )
614  {
615  if (prescribedVelocity_ )
616  {
617  //Both the velocity and position are defined; as we are using leap
618  //frog method so the velocity is evaluated half a time later.
619  applyPrescribedPosition(time + timeStep);
620  applyPrescribedVelocity(time + 0.5 * timeStep);
621  }
622  else
623  {
624  //Only the position is defined.
625  //Velocity is evaluated from a finite different of the Position
626  //Note, we use 0.5 +- 0.1 timeStep for the velocity eval.
627  applyPrescribedPosition(time + timeStep);
628  setVelocity((prescribedPosition_(time + 0.6 * timeStep) - prescribedPosition_(time + 0.4 * timeStep)) / (0.2 * timeStep));
629  }
630  }
631  else
632  {
633  if (prescribedVelocity_ )
634  {
635  //Only the velocity is set. The position is calculated from the
636  //the integral of velocity.
637  applyPrescribedVelocity(time + 0.5 * timeStep);
638  move(getVelocity() * timeStep);
639  }
640  else
641  {
642  //Neither is set move based on the computed velocity of the object.
643  move(getVelocity() * timeStep);
644  }
645  }
647  {
649  {
650  applyPrescribedOrientation(time + timeStep);
651  applyPrescribedAngularVelocity(time + 0.5 * timeStep);
652  }
653  else
654  {
655  applyPrescribedOrientation(time + timeStep);
656  setAngularVelocity((prescribedOrientation_(time + 0.6 * timeStep) - prescribedOrientation_(time + 0.4 * timeStep)) / (0.2 * timeStep));
657  }
658  }
659  else
660  {
662  {
663  applyPrescribedAngularVelocity(time + 0.5 * timeStep);
664  rotate(getAngularVelocity() * timeStep);
665  }
666  else
667  {
668  rotate(getAngularVelocity() * timeStep);
669  }
670  }
671 }
672 
680 void BaseInteractable::integrateAfterForceComputation(double time, double timeStep)
681 {
683  {
685  {
686  applyPrescribedVelocity(time + timeStep);
687  }
688  else
689  {
690  setVelocity((prescribedPosition_(time + 1.1 * timeStep) - prescribedPosition_(time + 0.9 * timeStep)) / (0.2 * timeStep));
691  }
692  }
693  else
694  {
696  {
697  applyPrescribedVelocity(time + 0.5 * timeStep);
698  }
699  }
701  {
703  {
704  applyPrescribedAngularVelocity(time + timeStep);
705  }
706  else
707  {
708  setAngularVelocity((prescribedOrientation_(time + 1.1 * timeStep) - prescribedOrientation_(time + 0.9 * timeStep)) / (0.2 * timeStep));
709  }
710  }
711  else
712  {
714  {
715  applyPrescribedAngularVelocity(time + 0.5 * timeStep);
716  }
717  }
718 }
void setPrescribedVelocity(const std::function< Vec3D(double)> &prescribedVelocity)
Allows the velocity of an infinite mass interactable to be prescribed.
unsigned int getId() const
Returns the unique identifier of any particular object.
Definition: BaseObject.cc:116
unsigned int getIndex() const
Returns the index of the object in the handler.
Definition: BaseObject.cc:108
void rotate(const Vec3D &rotate)
Rotates this BaseInteractable.
std::function< Vec3D(double)> prescribedPosition_
void copySwitchPointer(const BaseInteractable *original, BaseInteractable *ghost) const
This copies the interactions of the original particle and replaces the original with the ghost copy...
void addVelocity(const Vec3D &velocity)
adds an increment to the velocity.
void setVelocity(const Vec3D &velocity)
set the velocity of the BaseInteractable.
unsigned int indSpecies_
void applyPrescribedPosition(double time)
Computes the position from the user defined prescribed position function.
const Vec3D & getForce() const
Returns the force on this BaseInteractable.
Logger< MERCURY_LOGLEVEL > logger("MercuryKernel")
void addForce(const Vec3D &addForce)
Adds an amount to the force on this BaseInteractable.
std::function< Vec3D(double)> prescribedVelocity_
void setOrientation(const Vec3D &orientation)
Sets the orientation of this BaseInteractable.
bool removeInteraction(BaseInteraction *I)
Removes an interaction from this BaseInteractable.
void addInteraction(BaseInteraction *I)
Adds an interaction to this BaseInteractable.
const ParticleSpecies * getSpecies() const
Returns a pointer to the species of this BaseInteractable.
void applyPrescribedAngularVelocity(double time)
Computes the angular velocity from the user defined prescribed angular velocity.
It is an abstract base class due to the purely virtual functions declared below. Even if the function...
Definition: BaseObject.h:49
void setPrescribedAngularVelocity(const std::function< Vec3D(double)> &prescribedAngularVelocity)
Allows the angular velocity of the infinite mass interactable to be prescribed.
virtual const Vec3D getVelocityAtContact(const Vec3D &contact) const
Returns the velocity at the contact point, use by many force laws.
void applyPrescribedOrientation(double time)
Computes the orientation from the user defined prescribed orientation function.
void integrateBeforeForceComputation(double time, double timeStep)
This is part of integrate routine for objects with infinite mass.
void setZero()
Sets all elements to zero.
Definition: Vector.cc:52
virtual const Vec3D & getAngularVelocity() const
Returns the angular velocity of this interactable.
virtual ~BaseInteractable()
Destructor, it simply destructs the BaseInteractable and all the objects it contains.
void setPrescribedPosition(const std::function< Vec3D(double)> &prescribedPosition)
Allows the position of an infinite mass interactable to be prescribed.
const Vec3D & getPosition() const
Returns the position of this BaseInteractable.
const Vec3D & getOrientation() const
Returns the orientation of this BaseInteractable.
Stores information about interactions between two interactable objects; often particles but could be ...
#define MERCURY_DEPRECATED
Definition: GeneralDefine.h:37
void addAngularVelocity(const Vec3D &angularVelocity)
add an increment to the angular velocity.
SpeciesHandler * getHandler() const
Returns the pointer to the handler to which this species belongs.
Definition: BaseSpecies.cc:74
void setSpecies(const ParticleSpecies *species)
Sets the species of this BaseInteractable.
virtual void read(std::istream &is)=0
Reads a BaseInteractable from an input stream.
const ParticleSpecies * species_
const Vec3D & getTorque() const
Returns the torque on this BaseInteractable.
std::list< BaseInteraction * > interactions_
std::function< Vec3D(double)> prescribedOrientation_
static Vec3D cross(const Vec3D &a, const Vec3D &b)
Calculates the cross product of two Vec3D: .
Definition: Vector.cc:255
virtual void read(std::istream &is)=0
A purely virtual method with an implementation which reads the index from the stream and assigns it t...
Definition: BaseObject.cc:124
void copyInteractionsForPeriodicParticles(const BaseInteractable &p)
Copies interactions to this BaseInteractable whenever a periodic copy made.
virtual void setIndSpecies(unsigned int indSpecies)
Sets the index of the Species of this BaseInteractable.
BaseInteractable * getI()
void setPosition(const Vec3D &position)
Sets the position of this BaseInteractable.
void applyPrescribedVelocity(double time)
Computes the velocity from the user defined prescribed velocity function.
void setForce(const Vec3D &force)
Sets the force on this BaseInteractable.
void setTorque(const Vec3D &torque)
Sets the torque on this BaseInteractable.
Defines the basic properties that a interactable object can have.
void addTorque(const Vec3D &addTorque)
Adds an amount to the torque on this BaseInteractable.
std::function< Vec3D(double)> prescribedAngularVelocity_
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).
virtual void write(std::ostream &os) const =0
Write a BaseInteractable to an output stream.
virtual const Vec3D & getVelocity() const
Returns the velocity of this interactable.
Implementation of a 3D vector (by Vitaliy).
Definition: Vector.h:45
virtual void move(const Vec3D &move)
Moves this BaseInteractable by adding an amount to the position.
void setPrescribedOrientation(const std::function< Vec3D(double)> &prescribedOrientation)
Allows the orientation of the infinite mass interactbale to be prescribed.
void setAngularVelocity(const Vec3D &angularVelocity)
set the angular velocity of the BaseInteractble.
virtual void write(std::ostream &os) const =0
A purely virtual function which has an implementation which writes the name and the object id_ to the...
Definition: BaseObject.cc:133
BaseInteractable()
Default BaseInteractable constructor, it simply creates an empty BaseInteractable.
void integrateAfterForceComputation(double time, double timeStep)
This is part of the integration routine for objects with infinite mass.