MercuryDPM  Trunk
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
BaseInteractable.h
Go to the documentation of this file.
1 //Copyright (c) 2013-2020, 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 #ifndef BASEINTERACTABLE_H
27 #define BASEINTERACTABLE_H
28 
29 #include <functional>
30 #include <vector>
31 #include "BaseObject.h"
32 #include "Math/Vector.h"
33 #include "Math/Quaternion.h"
34 
35 class BaseParticle;
36 
37 class ParticleSpecies;
38 
39 class BaseInteraction;
40 
41 class InteractionHandler;
42 
55 {
56 public:
61 
66 
71  ~BaseInteractable() override;
72 
76  void read(std::istream& is) override;
77 
82  void write(std::ostream& os) const override;
83 
88  unsigned int getIndSpecies() const
89  { return indSpecies_; }
90 
98  virtual void setIndSpecies(unsigned int indSpecies)
99  { indSpecies_ = indSpecies; }
100 
109  {
110  return species_;
111  }
112 
116  void setSpecies(const ParticleSpecies* species);
117 
126  const Vec3D& getForce() const
127  { return force_; }
128 
138  const Vec3D& getTorque() const
139  { return torque_; }
140 
149  void setForce(const Vec3D& force)
150  { force_ = force; }
151 
161  void setTorque(const Vec3D& torque)
162  { torque_ = torque; }
163 
171  void addForce(const Vec3D& addForce);
172 
180  void addTorque(const Vec3D& addTorque);
181 
182  /*
183  * This function sets the forces and torques acting on an interactable (particle/wall) to zero at teh beginning of computeOneTimeStep.
184  *
185  * For omp simulations, it further sets does the first step of summing up all forces (and torques) acting on an interactable.
186  * It is step 1 of the add-by-reduction approach:
187  * 1. Declare a vector forceOMP_, one element per thread, and set it to zero.
188  * 2. When a new force needs to be added to the interactable, don't add it immediately.
189  * Add it to forceOMP_[threadNum] instead
190  * 3. Add all forces in forceOMP_ together to force_.
191  * This reduction approach allows step 2 to be run in parallel, while step 3 needs to be done in sequence.
192  * It is efficient, since step 3 is much quicker than step 2.
193  */
194  void resetForceTorque(int numberOfOMPthreads);
195 
196  /*
197  * This function does the last step of summing up all forces (and torques) acting on an interactable.
198  * It is step 3 of the add-by-reduction approach:
199  * 1. Declare a vector forceOMP_, one element per thread, and set it to zero.
200  * 2. When a new force needs to be added to the interactable, don't add it immediately.
201  * Add it to forceOMP_[threadNum] instead
202  * 3. Add all forces in forceOMP_ together to force_.
203  * This reduction approach allows step 2 to be run in parallel, while step 3 needs to be done in sequence.
204  * It is efficient, since step 3 is much quicker than step 2.
205  */
206  void sumForceTorqueOMP();
207 
218  const Vec3D& getPosition() const
219  { return position_; }
220 
230  const Quaternion& getOrientation() const
231  { return orientation_; }
232 
239  void setPosition(const Vec3D& position)
240  { position_ = position; }
241 
245  void setOrientationViaNormal(Vec3D normal);
246 
250  void setOrientationViaEuler(Vec3D eulerAngle);
251 
260  void setOrientation(const Quaternion& orientation)
261  { orientation_ = orientation; }
262 
266  virtual void move(const Vec3D& move);
267 
271  virtual void rotate(const Vec3D& angularVelocityDt);
272 
277  const std::vector<BaseInteraction*>& getInteractions() const
278  { return interactions_; }
279 
284 
289 
295 
299  void setVelocity(const Vec3D& velocity);
300 
304  void setAngularVelocity(const Vec3D& angularVelocity);
305 
312  void addVelocity(const Vec3D& velocity)
313  { velocity_ += velocity; }
314 
318  void addAngularVelocity(const Vec3D& angularVelocity);
319 
323  virtual const Vec3D& getVelocity() const;
324 
328  virtual const Vec3D& getAngularVelocity() const;
329 
334  void setPrescribedPosition(const std::function<Vec3D(double)>& prescribedPosition);
335 
340  void applyPrescribedPosition(double time);
341 
346  void setPrescribedVelocity(const std::function<Vec3D(double)>& prescribedVelocity);
347 
352  void applyPrescribedVelocity(double time);
353 
358  void setPrescribedOrientation(const std::function<Quaternion(double)>& prescribedOrientation);
359 
364  void applyPrescribedOrientation(double time);
365 
370  void setPrescribedAngularVelocity(const std::function<Vec3D(double)>& prescribedAngularVelocity);
371 
376  void applyPrescribedAngularVelocity(double time);
377 
384  virtual BaseInteraction* getInteractionWith(BaseParticle* P, unsigned timeStamp, InteractionHandler* interactionHandler)=0;
385 
389  virtual const Vec3D getVelocityAtContact(const Vec3D& contact) const;
390 
394  void integrateBeforeForceComputation(double time, double timeStep);
395 
400  void integrateAfterForceComputation(double time, double timeStep);
401 
405  virtual bool isFixed() const =0;
406 
408  virtual Mdouble getInvMass() const
409  { return 0.0; }
410 
414  virtual Mdouble getCurvature(const Vec3D& labFixedCoordinates) const
415  { return 0.0; }
416 
417 private:
422  std::function<Vec3D(double)> prescribedPosition_;
423 
428  std::function<Vec3D(double)> prescribedVelocity_;
429 
434  std::function<Quaternion(double)> prescribedOrientation_;
435 
440  std::function<Vec3D(double)> prescribedAngularVelocity_;
441 
447 
453 
458 
463 
468 
469  /*
470  * This variable is needed in omp simulations to sum up all forces (and torques) acting on an interactable.
471  * It is used in an add-by-reduction approach:
472  * 1. Declare a vector forceOMP_, one element per thread, and set it to zero.
473  * 2. When a new force needs to be added to the interactable, don't add it immediately.
474  * Add it to forceOMP_[threadNum] instead
475  * 3. Add all forces in forceOMP_ together to force_.
476  * This reduction approach allows step 2 to be run in parallel, while step 3 needs to be done in sequence.
477  * It is efficient, since step 3 is much quicker than step 2.
478  */
479  std::vector<Vec3D> forceOMP_;
480 
484  std::vector<Vec3D> torqueOMP_;
485 
491 
495  unsigned int indSpecies_;
496 
501 
505  std::vector<BaseInteraction*> interactions_;
506 };
507 
508 #endif
509 
void setPrescribedVelocity(const std::function< Vec3D(double)> &prescribedVelocity)
Allows the velocity of an infinite mass interactable to be prescribed.
Implementation of a 3D quaternion (by Vitaliy).
Definition: Quaternion.h:62
const Vec3D & getPosition() const
Returns the position of this BaseInteractable.
void addVelocity(const Vec3D &velocity)
adds an increment to the velocity.
std::function< Vec3D(double)> prescribedAngularVelocity_
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.
double Mdouble
Definition: GeneralDefine.h:34
const ParticleSpecies * getSpecies() const
Returns a pointer to the species of this BaseInteractable.
void addForce(const Vec3D &addForce)
Adds an amount to the force on this BaseInteractable.
void resetForceTorque(int numberOfOMPthreads)
bool removeInteraction(BaseInteraction *I)
Removes an interaction from this BaseInteractable.
void addInteraction(BaseInteraction *I)
Adds an interaction to 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:50
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.
virtual BaseInteraction * getInteractionWith(BaseParticle *P, unsigned timeStamp, InteractionHandler *interactionHandler)=0
Returns the interaction between this object and a given BaseParticle.
virtual bool isFixed() const =0
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.
std::function< Quaternion(double)> prescribedOrientation_
void setOrientationViaEuler(Vec3D eulerAngle)
Sets the orientation of this BaseInteractable by defining the euler angles.
void setPrescribedOrientation(const std::function< Quaternion(double)> &prescribedOrientation)
Allows the orientation of the infinite mass interactbale to be prescribed.
virtual const Vec3D & getAngularVelocity() const
Returns the angular velocity of this interactable.
const Vec3D & getForce() const
Returns the force on this BaseInteractable.
std::function< Vec3D(double)> prescribedPosition_
void setPrescribedPosition(const std::function< Vec3D(double)> &prescribedPosition)
Allows the position of an infinite mass interactable to be prescribed.
Stores information about interactions between two interactable objects; often particles but could be ...
void addAngularVelocity(const Vec3D &angularVelocity)
add an increment to the angular velocity.
void setSpecies(const ParticleSpecies *species)
Sets the species of this BaseInteractable.
void write(std::ostream &os) const override
Write a BaseInteractable to an output stream.
const ParticleSpecies * species_
std::vector< Vec3D > torqueOMP_
std::function< Vec3D(double)> prescribedVelocity_
Quaternion orientation_
std::vector< BaseInteraction * > interactions_
Container to store Interaction objects.
void copyInteractionsForPeriodicParticles(const BaseInteractable &p)
Copies interactions to this BaseInteractable whenever a periodic copy made.
std::vector< Vec3D > forceOMP_
void setPosition(const Vec3D &position)
Sets the position of this BaseInteractable.
const Vec3D & getTorque() const
Returns the torque on this BaseInteractable.
virtual void rotate(const Vec3D &angularVelocityDt)
Rotates 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.
const std::vector< BaseInteraction * > & getInteractions() const
Returns a list of interactions which belong to this interactable.
void setOrientationViaNormal(Vec3D normal)
Sets the orientation of this BaseInteractable by defining the vector that results from the rotation o...
void setTorque(const Vec3D &torque)
Sets the torque on this BaseInteractable.
Defines the basic properties that a interactable object can have.
void setOrientation(const Quaternion &orientation)
Sets the orientation of this BaseInteractable.
void addTorque(const Vec3D &addTorque)
Adds an amount to the torque on this BaseInteractable.
unsigned int getIndSpecies() const
Returns the index of the species associated with the interactable object.
virtual Mdouble getCurvature(const Vec3D &labFixedCoordinates) const
virtual const Vec3D & getVelocity() const
Returns the velocity of this interactable.
Definition: Vector.h:49
virtual void move(const Vec3D &move)
Moves this BaseInteractable by adding an amount to the position.
const Quaternion & getOrientation() const
Returns the orientation of this BaseInteractable.
virtual Mdouble getInvMass() const
void setAngularVelocity(const Vec3D &angularVelocity)
set the angular velocity of the BaseInteractble.
void read(std::istream &is) override
Reads a BaseInteractable from an input stream.
BaseInteractable()
Default BaseInteractable constructor.
void integrateAfterForceComputation(double time, double timeStep)
This is part of the integration routine for objects with infinite mass.
virtual void setIndSpecies(unsigned int indSpecies)
Sets the index of the Species of this BaseInteractable.
~BaseInteractable() override
Destructor, it simply destructs the BaseInteractable and all the objects it contains.