MercuryDPM  Alpha
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
BaseInteraction.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 
26 
27 #include "BaseInteraction.h"
28 #include "InteractionHandler.h"
29 #include "Particles/BaseParticle.h"
30 #include "Species/BaseSpecies.h"
31 #include "DPMBase.h"
32 #include<iomanip>
33 #include<fstream>
34 
45  : BaseObject()
46 {
47  P_ = P;
48  P->addInteraction(this);
49  I_ = I;
50  I->addInteraction(this);
51  normal_.setZero();
52  overlap_ = 0;
53  timeStamp_ = timeStamp;
54  species_ = 0;
55  force_.setZero();
56  torque_.setZero();
57 #ifdef DEBUG_CONSTRUCTOR
58  std::cout<<"BaseInteraction::BaseInteraction() finished"<<std::endl;
59 #endif
60 }
61 
67  : BaseObject(p)
68 {
69  P_ = p.P_;
70  I_ = p.I_;
71  normal_ = p.normal_;
72  overlap_ = p.overlap_;
73  force_ = p.force_;
74  torque_ = p.torque_;
75  species_ = p.species_;
77 }
78 
83  : BaseObject()
84 {
85  P_ = nullptr;
86  I_ = nullptr;
87  normal_.setZero();
88  overlap_ = 0;
89  timeStamp_ = 0;
90  species_ = 0;
91  force_.setZero();
92  torque_.setZero();
93 }
94 
100 {
101  P_->removeInteraction(this);
102  I_->removeInteraction(this);
103 }
104 
113 void BaseInteraction::write(std::ostream& os) const
114 {
115  os << getName();
116  if (dynamic_cast<BaseParticle*>(I_) != nullptr)
117  os << " particleIds " << P_->getId() << " " << I_->getId();
119  else
120  os << " particleWallIds " << P_->getId() << " " << I_->getId();
121  os <<" timeStamp "<<timeStamp_<< " force " << force_ << " torque " << torque_;
122 }
123 
131 void BaseInteraction::read(std::istream& is)
132 {
133  //the rest gets read by the interaction handler
134  std::string dummy;
135  is >> dummy >> force_ >> dummy >> torque_;
136 }
137 
143 std::string BaseInteraction::getName() const
144 {
145  return "BaseInteraction";
146 }
147 
154 {
155  normal_ = normal;
156 }
157 
163 {
164  distance_ = distance;
165 }
166 
173 {
174  overlap_ = overlap;
175 }
176 
177 /*
178  * \details set the contact point between the two interactable objects involved
179  * \param[in] contactPoint Vec3D vector which will become the new contact point.
180  */
182 {
183  contactPoint_ = contactPoint;
184 }
185 
193 {
194  timeStamp_ = timeStamp;
195 }
196 
203 {
204  handler_ = handler;
205 }
206 
213 {
214  return handler_;
215 }
216 
222 {
224 }
225 
241 {
242  //Copy the interaction of ghost
243  BaseInteraction* C = copy();
244  //Finds out which of P and I is that the particle from whom the ghost is begin created.
245  //The object being interacted with is set to P
246  if (C->getP() == original)
247  {
248  //Reverse some force history
249  C->reverseHistory();
250  //Set the P to the original particle
251  C->P_ =C->getI();
252  }
253  //The new ghost particle is set to I in the interaction.
254  C->I_ = ghost;
255 
256  //Add the the interaction to both original and the ghost
257  C->getP()->addInteraction(C);
258  C->getI()->addInteraction(C);
259  handler_->addObject(C);
260 }
261 
268 {
269  return force_;
270 }
271 
278 {
279  return torque_;
280 }
281 
288 {
289  return normal_;
290 }
291 
299 {
300  return contactPoint_;
301 }
302 
309 {
310  return overlap_;
311 }
312 
319 {
320  return sqrt(2.0*getEffectiveRadius()*getOverlap());
321 }
322 
329 {
330  return P_;
331 }
332 
339 {
340  return I_;
341 }
342 
349 {
350  return P_;
351 }
352 
359 {
360  return I_;
361 }
362 
370 {
371  return timeStamp_;
372 }
373 
386 {
387 
388 }
389 
398 {
399  species_ = species;
400 }
401 
411 {
412  P_->removeInteraction(this);
413  P_=P;
414  P_->addInteraction(this);
415 }
416 
426 {
427  I_->removeInteraction(this);
428  I_=I;
429  I_->addInteraction(this);
430 }
431 
441 void BaseInteraction::writeToFStat(std::ostream& os) const
442 {
443  BaseParticle* IParticle = dynamic_cast<BaseParticle*>(I_);
444  BaseParticle* PParticle = dynamic_cast<BaseParticle*>(P_);
445 
446  Vec3D tangentialForce = getTangentialForce();
447  Mdouble tangentialOverlap = getTangentialOverlap();
448 
449  Mdouble scalarNormalForce = Vec3D::dot(force_, getNormal());
450  Mdouble scalarTangentialForce = tangentialForce.getLength();
451  Vec3D tangential;
452  if (scalarTangentialForce!=0.0)
453  tangential = tangentialForce/scalarTangentialForce;
454  else
455  tangential = Vec3D(0.0,0.0,0.0);
456 
460  Vec3D centre;
461  if (IParticle!=0)
462  centre = getP()->getPosition() - normal_ * (PParticle->getRadius() + IParticle->getRadius() - overlap_)/2.0;
463  //centre = 0.5 * (getP()->getPosition() + getI()->getPosition());
464  else
465  centre = getP()->getPosition() - normal_ * (PParticle->getRadius() - overlap_);
466 
467  if (PParticle!=0 && !PParticle->isFixed())
468  {
469  os << timeStamp_
470  << " " << P_->getIndex()
471  << " " << static_cast<int>((IParticle==0?(-I_->getIndex()-1):I_->getIndex()))
472  << " " << centre
473  << " " << getOverlap()
474  << " " << tangentialOverlap
475  << " " << scalarNormalForce
476  << " " << scalarTangentialForce
477  << " " << (IParticle==0?-normal_:normal_)
478  << " " << (IParticle==0?-tangential:tangential) << std::endl;
480  }
481  if (IParticle!=0 && !IParticle->isFixed() && IParticle->getPeriodicFromParticle()==0)
482  {
483  os << timeStamp_
484  << " " << I_->getIndex()
485  << " " << P_->getIndex()
486  << " " << centre
487  << " " << getOverlap()
488  << " " << tangentialOverlap
489  << " " << scalarNormalForce
490  << " " << scalarTangentialForce
491  << " " << -normal_
492  << " " << -tangential << std::endl;
493  }
494 
495 }
496 
497 /*
498  * \details Returns the distance between the two interactable objects involved
499  * in the interaction.
500  * \return Mdouble which is the distance between the two interacting objects.
501  */
503 {
504  return distance_;
505 }
506 
515 {
516  return 0;
517 }
518 
527 {
528  return Vec3D(0.0,0.0,0.0);
529 }
530 
537 {
538  return relativeVelocity_;
539 }
540 
548 {
550 }
551 
560 {
561  return absoluteNormalForce_;
562 }
563 
570 {
571  force_+=force;
572 }
573 
580 {
581  torque_+=torque;
582 }
583 
591 {
592  force_=force;
593 }
594 
602 {
603  torque_=torque;
604 }
605 
613 {
614  relativeVelocity_=relativeVelocity;
615 }
616 
624 {
625  normalRelativeVelocity_=normalRelativeVelocity;
626 }
627 
634 {
635  absoluteNormalForce_ = absoluteNormalForce;
636 }
637 
646 {
647  return species_;
648 }
649 
658 {}
659 
667 {
668  return 0.0;
669 }
670 
682 {
683 }
684 
686 {
688 }
689 
690 void BaseInteraction::setMultiContactIdentifier(unsigned int multiContactIdentifier)
691 {
692  multiContactIdentifier_ = multiContactIdentifier;
693 }
694 
695 
697 {
698  contactPoint_=rotationMatrix*contactPoint_;
699  relativeVelocity_=rotationMatrix*relativeVelocity_;
700  force_=rotationMatrix*force_;
701  torque_=rotationMatrix*torque_;
702  normal_=rotationMatrix*normal_;
704 }
705 
716 {
717  const BaseParticle* PParticle = dynamic_cast<const BaseParticle*>(getP());
718  const BaseParticle* IParticle = dynamic_cast<const BaseParticle*>(getI());
719  if (PParticle==nullptr)
720  {
721  std::cerr << "BaseInteraction::getEffectiveCorrectedRadius(): first interactable P is not a particle" << std::endl;
722  exit(-1);
723  }
724  //Compute the reduced diameter
725  if (IParticle==nullptr) //if particle-wall
726  {
727  return PParticle->getRadius();
728  }
729  else
730  {
731  Mdouble radiusP = PParticle->getRadius();
732  Mdouble radiusI = IParticle->getRadius();
733  return radiusP * radiusI / (radiusP + radiusI);
734  }
735 }
736 
747 {
748  const BaseParticle* PParticle = dynamic_cast<const BaseParticle*>(getP());
749  const BaseParticle* IParticle = dynamic_cast<const BaseParticle*>(getI());
750  if (PParticle==nullptr)
751  {
752  std::cerr << "BaseInteraction::getEffectiveCorrectedRadius(): first interactable P is not a particle" << std::endl;
753  exit(-1);
754  }
755  //Compute the reduced diameter
756  if (IParticle==nullptr) //if particle-wall
757  {
758  return PParticle->getMass();
759  }
760  else
761  {
762  Mdouble massP = PParticle->getMass();
763  Mdouble massI = IParticle->getMass();
764  return massP * massI / (massP + massI);
765  }
766 }
767 
778 {
779  BaseParticle* PParticle = dynamic_cast<BaseParticle*>(getP());
780  BaseParticle* IParticle = dynamic_cast<BaseParticle*>(getI());
781  if (PParticle==nullptr)
782  {
783  std::cerr << "BaseInteraction::getEffectiveCorrectedRadius(): first interactable P is not a particle" << std::endl;
784  exit(-1);
785  }
786  //Compute the reduced diameter
787  if (IParticle==nullptr) //if particle-wall
788  {
789  return PParticle->getRadius() - 0.5*getOverlap();
790  }
791  else
792  {
793  Mdouble radiusP = PParticle->getRadius() - 0.5*getOverlap();
794  Mdouble radiusI = IParticle->getRadius() - 0.5*getOverlap();
795  return radiusP * radiusI / (radiusP + radiusI);
796  }
797 }
798 
800 {
801 }
802 
807 {
808  BaseParticle* IParticle = dynamic_cast<BaseParticle*>(I_);
809  BaseParticle* PParticle = dynamic_cast<BaseParticle*>(P_);
810 
811  Vec3D tangentialForce = getTangentialForce();
812  Mdouble tangentialOverlap = getTangentialOverlap();
813 
814  Mdouble scalarNormalForce = Vec3D::dot(force_, getNormal());
815  Mdouble scalarTangentialForce = tangentialForce.getLength();
816  Vec3D tangential;
817  if (scalarTangentialForce!=0.0)
818  tangential = tangentialForce/scalarTangentialForce;
819  else
820  tangential = Vec3D(0.0,0.0,0.0);
821 
824  Vec3D centre;
825  if (IParticle!=nullptr)
826  centre = getP()->getPosition() - normal_ * (PParticle->getRadius() + IParticle->getRadius() - overlap_)/2.0;
827  else
828  centre = getP()->getPosition() - normal_ * (PParticle->getRadius() - overlap_);
829 
830  if (PParticle!=nullptr && !PParticle->isFixed())
831  {
833  P_->getIndex(),
834  static_cast<int>((IParticle==0?(-I_->getIndex()-1):I_->getIndex())),
835  centre,
836  getOverlap(),
837  tangentialOverlap,
838  scalarNormalForce,
839  scalarTangentialForce,
840  (IParticle==0?-normal_:normal_),
841  (IParticle==0?-tangential:tangential));
842  }
843  if (IParticle!= nullptr && !IParticle->isFixed() && IParticle->getPeriodicFromParticle()==0)
844  {
846  I_->getIndex(),
847  static_cast<int>(P_->getIndex()),
848  centre,
849  getOverlap(),
850  tangentialOverlap,
851  scalarNormalForce,
852  scalarTangentialForce,
853  -normal_,
854  -tangential);
855 
856  }
857 }
858 
860  return 0;
861 }
862 
863 std::string BaseInteraction::getTypeVTK(unsigned i) const {
864  return "";
865 }
866 
867 std::string BaseInteraction::getNameVTK(unsigned i) const {
868  return "";
869 }
870 
871 std::vector<Mdouble> BaseInteraction::getFieldVTK(unsigned i) const {
872  return std::vector<Mdouble>();
873 }
const Vec3D & getForce() const
Gets the current force (vector) between the two interacting objects.
BaseInteractable * I_
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
Mdouble getEffectiveRadius() const
Returns a Mdouble to the effective radius of the interaction. (Not corrected for the overlap) ...
void setNormal(Vec3D normal)
Sets the normal vector between the two interacting objects.
void copySwitchPointer(const BaseInteractable *original, BaseInteractable *ghost) const
This copies the interactions of the original particle and replaces the original with the ghost copy...
virtual void gatherContactStatistics(unsigned int index1 UNUSED, int index2 UNUSED, Vec3D Contact UNUSED, Mdouble delta UNUSED, Mdouble ctheta UNUSED, Mdouble fdotn UNUSED, Mdouble fdott UNUSED, Vec3D P1_P2_normal_ UNUSED, Vec3D P1_P2_tangential UNUSED)
//Not unsigned index because of possible wall collisions.
Definition: DPMBase.cc:822
BaseSpecies is the class from which all other species are derived.
Definition: BaseSpecies.h:44
InteractionHandler * getHandler() const
Gets a point to the interaction handlers to which this interaction belongs.
void setOverlap(Mdouble overlap)
Set the overlap between the two interacting object.
virtual BaseInteraction * copy() const =0
Makes a copy of the interaction and returns a pointer to the copy.
bool removeInteraction(BaseInteraction *I)
Removes an interaction from this BaseInteractable.
virtual void actionsAfterTimeStep()
void addInteraction(BaseInteraction *I)
Adds an interaction to this BaseInteractable.
BaseSpecies * species_
void setI(BaseInteractable *I)
Sets the second object involved in the interaction (often particle or wall).
It is an abstract base class due to the purely virtual functions declared below. Even if the function...
Definition: BaseObject.h:49
const Vec3D & getRelativeVelocity() const
Returns a constant reference to a vector of relative velocity.
double Mdouble
virtual void reverseHistory()
When periodic particles some interaction need certain history properties reversing. This is the function for that.
void setRelativeVelocity(Vec3D relativeVelocity)
set the relative velocity of the current of the interactions.
void setZero()
Sets all elements to zero.
Definition: Vector.cc:52
void setContactPoint(Vec3D contactPoint)
Set the location of the contact point between the two interacting objects.
void addTorque(Vec3D torque)
void removeFromHandler()
Removes this interaction from its interaction hander.
void setForce(Vec3D force)
set total force (this is used by the normal force, tangential forces are added use addForce) ...
virtual std::vector< Mdouble > getFieldVTK(unsigned i) const
static Mdouble dot(const Vec3D &a, const Vec3D &b)
Calculates the dot product of two Vec3D: .
Definition: Vector.cc:167
void setNormalRelativeVelocity(Mdouble normalRelativeVelocit)
set the normal component of the relative velocity.
BaseInteraction()
Empty constructor.
void setDistance(Mdouble distance)
Sets the interaction distance between the two interacting objects.
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.
void gatherContactStatistics()
const Vec3D & getPosition() const
Returns the position of this BaseInteractable.
Stores information about interactions between two interactable objects; often particles but could be ...
static Mdouble getLength(const Vec3D &a)
Calculates the length of a Vec3D: .
Definition: Vector.cc:414
BaseParticle * getPeriodicFromParticle() const
Returns the 'original' particle this one's a periodic copy of.
BaseInteractable * P_
const Vec3D & getContactPoint() const
Gets constant reference to contact point (vector).
Mdouble getNormalRelativeVelocity() const
Returns a double which is the norm (length) of the relative velocity vector.
virtual ~BaseInteraction()
The default destructor.
void setMultiContactIdentifier(unsigned int multiContactIdentifier_)
void setTimeStamp(Mdouble timeStamp)
Updates the time step of the interacting. Note, timesteps used to find completed interactions.
virtual void rotateHistory(Matrix3D &rotationMatrix)
When periodic particles are used, some interactions need certain history properties rotated (e...
const BaseSpecies * getBaseSpecies() const
Return a constant point to BaseSpecies of the interaction.
Mdouble getMass() const
Returns the particle's mass_.
virtual void removeObject(unsigned const int id)
Removes an Object from the BaseHandler.
Definition: BaseHandler.h:333
Container to store Interaction objects.
const Vec3D & getNormal() const
Gets the normal vector between the two interacting objects.
void setHandler(InteractionHandler *handler)
Sets the pointer to the interaction hander which is storing this interaction.
virtual std::string getTypeVTK(unsigned i) const
void setP(BaseInteractable *P)
Sets the first object involved in the interaction (normally a particle).
#define UNUSED
Definition: GeneralDefine.h:39
void setTorque(Vec3D torque)
set the total force (this is used by the normal force, tangential torques are added use addTorque) ...
virtual const Vec3D getTangentialForce() const
Mdouble getRadius() const
Returns the particle's radius_.
Mdouble getOverlap() const
Returns a Mdouble with the current overlap between the two interacting objects.
virtual std::string getNameVTK(unsigned i) const
void addForce(Vec3D force)
add an force increment to the total force.
void setAbsoluteNormalForce(Mdouble absoluteNormalForce)
the absolute values of the norm (length) of the normal force
Mdouble normalRelativeVelocity_
unsigned multiContactIdentifier_
BaseInteractable * getI()
Mdouble getDistance() const
Returns an Mdouble which is the norm (length) of distance vector.
virtual void integrate(Mdouble timeStep)
integrates variables of the interaction which need to be integrate e.g. the tangential overlap...
Mdouble getContactRadius() const
Returns a Mdouble with the current contact between the two interacting objects.
virtual std::string getName() const
Virtual function which allows interactions to be named.
const Vec3D & getTorque() const
Gets the current torque (vector) between the two interacting objects.
virtual void read(std::istream &is)
Interaction read function, which accepts an std::istream as input.
Defines the basic properties that a interactable object can have.
virtual Mdouble getElasticEnergy() const
Returns a Mdouble which is the current about of Elastic energy in the interaction.
Mdouble absoluteNormalForce_
virtual void computeForce()
Virtual function that contains the force law between the two objects interacting. ...
BaseInteractable * getP()
Returns a pointer to first object involved in the interaction (normally a particle).
Implementation of a 3D matrix.
Definition: Matrix.h:36
Implementation of a 3D vector (by Vitaliy).
Definition: Vector.h:45
DPMBase * getDPMBase()
Gets the problem that is solved using this handler.
Definition: BaseHandler.h:543
void addObject(BaseInteraction *I)
Adds an Interaction to the InteractionHandler.
virtual Mdouble getTangentialOverlap() const
get the length of the current tangential overlap
virtual void write(std::ostream &os) const
Interaction print function, which accepts an std::ostream as input.
bool isFixed() const
Is fixed Particle function. It returns whether a Particle is fixed or not, by checking its inverse Ma...
Mdouble getEffectiveCorrectedRadius()
Returns a Mdouble to the effective radius corrected for the overlaps of the particles.
void writeToFStat(std::ostream &os) const
Writes forces data to the FStat file.
unsigned int getMultiContactIdentifier() const
Mdouble getEffectiveMass() const
Returns a Mdouble to the effective radius of the interaction. (Not corrected for the overlap) ...
InteractionHandler * handler_
virtual unsigned getNumberOfFieldsVTK() const
Mdouble getAbsoluteNormalForce() const
Returns the absolute value of the norm (length) of the Normal force vector.