MercuryDPM  Alpha
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
MindlinInteraction.cc
Go to the documentation of this file.
1 //Copyright (c) 2013-2017, 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 "MindlinInteraction.h"
29 #include "Particles/BaseParticle.h"
30 #include "InteractionHandler.h"
31 #include <iomanip>
32 #include <DPMBase.h>
33 
40  : BaseInteraction(P, I, timeStamp)
41 {
43  //k_edit
44  //setting the "previousSlidingSpring_" initially to zero, as before a contact
45  //this parameter should (obviously) not carry a value.
47  //similarly, setting the turning point tangential forces to zero, as a "new"
48  //interaction will clearly have no such history
51  //k_edit
52  //setting the K_t0 parameter by default to zero...
54  //...and its previous value...
56 
58  //k_edit
59  //...and, similarly, the "normal" tangential stiffness, K_t
61  //k_edit
62  //setting the tangential force direction by default to -1 (i.e. acting against the motion!)
64  //k_edit
65  //setting to zero the temporary 'holders' which store intermediate values of tangential force
66  //and displacement during multiple-step force calculations
71  //Similarly for temporary turning point force values...
74  //...and the turning point displacement values
77  //k_edit
78  //setting the variable which stores the minimum displacement for simple loading to zero
80  //k_edit
81  //setting the priorLoadingFlag to zero as, when an interaction is created for the first time,
82  //there will, by definition, have been no prior loading
84  //ensuring that the initial tangential velocity of a new interaction is zero until updated
86 
87 #ifdef DEBUG_CONSTRUCTOR
88  std::cout<<"MindlinInteraction::MindlinInteraction() finished"<<std::endl;
89 #endif
90 }
95  : BaseInteraction(p)
96 {
98  //k_edit
99  //setting the K_t0 parameter to that possessed by the interaction
100  //to be copied....
102  //...and its previous value...
104  //...and the same for the "normal" tangential stiffness parameter
106  //k_edit
107  //allowing turning point forces to be copied when an interaction is copied
110  //k_edit
111  //allowing the direction of the tangential force to be "remembered" also
112  //by the copied interaction
114  //k_edit
115  //copying the temporary 'holders' which store intermediate values of tangential force
116  //and displacement during multiple-step force calculations
121  //and similarly for the temporary turning point variables
124  //...and the displacement equivalents
127  //k_edit
128  //copying the variable which stores the minimum displacement for simple loading
130  //k_edit
132  //copying the initial tangential velocity
134 
136 #ifdef DEBUG_CONSTRUCTOR
137  std::cout<<"MindlinInteraction::MindlinInteraction(const MindlinInteraction& p) finished"<<std::endl;
138 #endif
139 }
144 {
145 #ifdef MERCURY_USE_MPI
146  logger(FATAL,"MindlinInteractions are currently not implemented in parallel MercuryDPM");
147 #endif
148 }
153 {
154 #ifdef DEBUG_DESTRUCTOR
155  std::cout<<"MindlinInteraction::~MindlinInteraction() finished"<<std::endl;
156 #endif
157 }
161 void MindlinInteraction::write(std::ostream& os) const
162 {
163  //BaseInteraction::write(os);
164  os << " slidingSpring " << slidingSpring_;
165 }
169 void MindlinInteraction::read(std::istream& is)
170 {
171  //BaseInteraction::read(is);
172  std::string dummy;
173  is >> dummy >> slidingSpring_;
174 }
175 
176 //k_new
177 
178 
179 //k_edit
180 //Allows the K_t0 parameter (for Mindlin model) to be set
182  tangentialStiffnessZero_ = newKt0;
183 }
184 
185 //k_edit
186 //Allows the K_t0 parameter (for Mindlin model) to be accessed
189 }
190 
191 //k_edit
192 //Allows the "normal" K_t parameter (for Mindlin model) to be accessed
194  return tangentialStiffness_;
195 }
196 
197 //k_edit
198 //A quick way to update the K_t0 parameter when necessary
199 //**************k_TODO at present, only valid for particle-wall interactions and/or interactions*********************
200 //between similar particles; need to include the reduced parameters for dissimilar particles!
201 //takes as arguments the relevant particle radius and the relevant shear modulus
203  //K_t0 = 8G_eq * sqrt(R_eq * delta_n) (Di Renzo and Di Maio)
204  tangentialStiffnessZero_ = 8 * shearMod * sqrt(rad * getOverlap());
205 }
206 
207 //k_new
208 //A general function to update the tangential stiffness corresponding to an interaction for *any* loading path
209 //Takes as arguments:
210 // i) the relevant getSlidingFrictionCoefficientStatic() for the current species,
211 // ii) The vector direction corresponding to the particles current tangential motion relative to its initial loading
212 // iii) A boolean to determine whether the turning point force should be considered (false if a 'virgin loading' OR
213 // if the current tangential force exceeds the magnitude of the relevant turning point force
214 // iv) a boolean to indicate whether loading or unloading
215 void MindlinInteraction::updateK_t(const Mdouble fric, const Vec3D direction,const bool useTurningPoint, const bool isLoading) {
216  //creating a simple positive or negative integer 'multiplier', m, whose values are either +1 or -1
217  //that can be used to alter the relevant equations depending on if we are loading or unloading
218  Mdouble m;
219  //A parameter to temporarily hold the relevant turning point so that this function can work both for
220  //loading and loading.
221  Vec3D turningPoint;
222  //Changing the directions and turning points used in calculation depending on if we are loading or unloading
223  if (isLoading) {
224  m = 1;
225  turningPoint = tangentialForceTurningPointUL_;
226  }
227  else {
228  m = -1;
229  turningPoint = tangentialForceTurningPointLU_;
230  }
231  //if the current part of the interaction can be treated as a virgin loading
232  //(i.e. the turning point can be ignored), we simply update K_t in the 'standard' manner
233  if (!useTurningPoint) {
234  //determining the direction of the current tangential force relative to the
235  //current direction of motion
236  Mdouble forceDirection = Vec3D::dot(Vec3D::getUnitVector(tangentialForceTemp_),direction);
237  //finding the scalar ratio f_t1 / (mu f_n1)
238  //(note for a first loading f_t1 is simply equal to f_t, and similarly f_n1 f_n = const
239  Mdouble forceRatio = tangentialForceTemp_.getLength() / (fric * getAbsoluteNormalForce());
240  //changing the direction of the force ratio, if necessary, based on its relative orientation
241  //with respect to the current tangential motion.
242  if (forceDirection<0)
243  forceRatio = -forceRatio;
244  //using the scalar ratio to update tangential stiffness
245  tangentialStiffness_ = tangentialStiffnessZero_* cbrt(1 - forceRatio);
246  }
247  //alternatively, if we are reloading and within the limits where the turning point force must be considered
248  else {
249  Vec3D resultantForce = m*(tangentialForceTemp_ - turningPoint);
250  //QUESTION: Does it make sense to use the total force here? Or should I just use the tangentialForceTemp?
251  Mdouble forceDirection = Vec3D::dot(Vec3D::getUnitVector(resultantForce),direction);
252  Mdouble forceRatio = resultantForce.getLength() / (2 * fric * getAbsoluteNormalForce());
253  //changing the direction of the force ratio, if necessary, based on its relative orientation
254  //with respect to the current tangential motion.
255  if (forceDirection<0)
256  forceRatio = -forceRatio;
257  //using the scalar ratio to update tangential stiffness
258  tangentialStiffness_ = tangentialStiffnessZero_* cbrt(1 - m*forceRatio);
259  }
260 }
261 
263  //If tangential forces are absent
264  if (getAbsoluteNormalForce() == 0.0) return;
265 
266  const MindlinSpecies *species = getSpecies();//dynamic_cast
267 
268  //Checking if the relevant particle species has a non-zero friction coefficient
269  if (species->getSlidingFrictionCoefficient() != 0.0) {
270  //Compute the tangential component of relativeVelocity_
271  Vec3D tangentialRelativeVelocity = getRelativeVelocity() - getNormal() * getNormalRelativeVelocity();
272  {
273  // *************************************************************************************************************************
274  // **********************************************GENERAL CALCULATIONS*******************************************************
275  // *************************************************************************************************************************
276  //used to Integrate the spring
277  //if particle-wall
278  if (dynamic_cast<BaseParticle *>(getI()) == 0) {
279  slidingSpringVelocity_ = tangentialRelativeVelocity;
280  }
281  //if particle-particle
282  else {
283  slidingSpringVelocity_ = (tangentialRelativeVelocity -
284  Vec3D::dot(slidingSpring_, getP()->getVelocity() - getI()->getVelocity()) *
285  getNormal() / getDistance());
286  }
287  //integrate(getHandler()->timeStep_);
289 
290  //1) Calculating the current value of K_t0
291  //This is identical for both unloading and loading (under constant normal force) and hence can
292  //potentially later be moved for neatness/efficiency
293  Mdouble r1 = 1.0 * getEffectiveRadius();
295 
296  //2) Calculating the relevant tangential dissipation constant based on the current stiffness (and other relevant parameters)
297  Mdouble slidingDissipationCoefficient = species->getSlidingDissipation()*sqrt(8.0*getEffectiveMass()*tangentialStiffnessZero_);
298 
299  //3) Using the parameters determined above, calculating the tangential force as per Di Maio and Di Renzo eqn. (37)
300  tangentialForce_ = - tangentialStiffnessZero_ * slidingSpring_ - slidingDissipationCoefficient * tangentialRelativeVelocity;
301 
302  //applying the Coulomb criterion (Di Maio and Di Renzo eqn. (36)) to ensure falsely large tangential forces are avoided
303  //if all is OK, i.e. if tangential force is smaller than mu*f_n, we simply add the tangential force calculated.
306  }
307  //otherwise, we take the force as mu*f_n and recalculate the spring length accordingly
308  else {
309 
311  //adding the force as mu*f_n
313  //updating the spring length accordingly
314  slidingSpring_ = -(tangentialForce_ + slidingDissipationCoefficient * tangentialRelativeVelocity) / tangentialStiffnessZero_;
315  }
316  }
317  }
319 }
320 
325 {
327 }
332 {
333 
334  //new_edit replacing outdated 'getSlidingStiffness()'
335  //return 0.5 * getSpecies()->getSlidingStiffness() * slidingSpring_.getLengthSquared();
337 }
342 {
344  //k_edit Indeed it should - todo done :)
345  //k_edit
346  //Updating sliding spring to give positive / negative values dependent on the direction of the extension
348 }
349 
354 {
355  return tangentialForce_;
356 }
357 
358 //k_edit
359 //Overwrites the function of the same name in the BaseInteraction class
360 //so that the tangential force direction can be known in the base interaction
361 //class and hence used to correctly output a **signed** tangential force value.
362 //(the value was previously always positive!)
364 {
366 }
371 {
372  return dynamic_cast<const MindlinSpecies*>(getBaseSpecies());
373 }
378 {
379  return "Mindlin";
380 }
385 {
389 }
390 
392 {
393  slidingSpring_=rotationMatrix*slidingSpring_;
395  tangentialForce_=rotationMatrix*tangentialForce_;
396 }
397 
398 //k_edit
407 {
409 }
410 
411 //k_edit
418 {
419  absoluteNormalForcePrevious_ = absoluteNormalForcePrevious;
420 }
static Mdouble getLengthSquared(const Vec3D &a)
Calculates the squared length of a Vec3D: .
Definition: Vector.cc:291
Mdouble getSlidingDissipation() const
Allows the tangential viscosity to be accessed.
Mdouble getEffectiveRadius() const
Returns a Mdouble to the effective radius of the interaction. (Not corrected for the overlap) ...
void updateTangentialStiffnessZero(Mdouble rad, double shearMod)
Mdouble getSlidingFrictionCoefficient() const
Allows the (dynamic) Coulomb friction coefficient to be accessed.
std::string getBaseName() const
Returns the type/name of interaction (sliding friction interaction)
static Vec3D getUnitVector(const Vec3D &a)
Returns a unit Vec3D based on a.
Definition: Vector.cc:428
Logger< MERCURY_LOGLEVEL > logger("MercuryKernel")
InteractionHandler * getHandler() const
Gets a point to the interaction handlers to which this interaction belongs.
Mdouble getTangentialOverlap() const override
Returns the amount of tangential overlap which is needed by BaseInteraction::writeToFstat().
Vec3D slidingSpringVelocity_
Stores the rate at which the sliding spring compressed or relaxed. Set in the member function compute...
void updateK_t(const Mdouble fric, const Vec3D direction, const bool useTurningPoint, const bool isLoading)
Vec3D tangentialForceTurningPointULTemp_
Vec3D tangentialDisplacementTurningPointLU_
Mdouble absoluteNormalForcePrevious_
const Vec3D & getRelativeVelocity() const
Returns a constant reference to a vector of relative velocity.
double Mdouble
Computes the forces corresponding to sliding friction.
void setZero()
Sets all elements to zero.
Definition: Vector.cc:52
static Mdouble dot(const Vec3D &a, const Vec3D &b)
Calculates the dot product of two Vec3D: .
Definition: Vector.cc:167
Vec3D slidingSpring_
Stores the amount of sliding spring ( ) compression from the expression . Set in the member function ...
MindlinSpecies contains the parameters used to describe sliding friction.
void integrate(Mdouble timeStep) override
Increments the amount of compression in sliding spring.
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
const Mdouble getTangentialForceDirection() const
void reverseHistory() override
A useful feature if one wants to return to the initial state of the spring. However, reverse history decrements the current state to the state corresponding to previous time step. Decrements the value of slidingSpring_.
Mdouble getNormalRelativeVelocity() const
Returns a double which is the norm (length) of the relative velocity vector.
const BaseSpecies * getBaseSpecies() const
Return a constant point to BaseSpecies of the interaction.
void rotateHistory(Matrix3D &rotationMatrix) override
When periodic particles are used, some interactions need certain history properties rotated (e...
void computeFrictionForce()
Computes the tangential force generated due to compression in the sliding spring. Does take into acco...
const Vec3D & getNormal() const
Gets the normal vector between the two interacting objects.
Mdouble getElasticEnergy() const override
Returns the amount of elastic energy stored in sliding spring.
Mdouble getShearModulus() const
const Vec3D getTangentialForce() const override
Returns the sliding friction force vector.
Mdouble getOverlap() const
Returns a Mdouble with the current overlap between the two interacting objects.
void addForce(Vec3D force)
add an force increment to the total force.
Vec3D tangentialForce_
Computes the tangential force such that . Set and computed in computeFrictionForce().
void setTangentialStiffnessZero(Mdouble newKt0)
BaseInteractable * getI()
Mdouble getAbsoluteNormalForcePrevious() const
Returns the absolute value of the norm (length) of the previous Normal force vector.
Mdouble getDistance() const
Returns an Mdouble which is the norm (length) of distance vector.
const MindlinSpecies * getSpecies() const
Returns a const pointer of type MindlinSpecies*.
Defines the basic properties that a interactable object can have.
Mdouble getTangentialStiffnessZero()
Mdouble tangentialStiffnessZeroPrevious_
virtual ~MindlinInteraction()
Destructor.
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
Vec3D tangentialDisplacementTurningPointUL_
MindlinInteraction()
Empty constructor.
DPMBase * getDPMBase()
Gets the problem that is solved using this handler.
Definition: BaseHandler.h:543
Mdouble getTimeStep() const
Allows the time step dt to be accessed.
Definition: DPMBase.cc:465
Vec3D tangentialForceTurningPointLUTemp_
void setAbsoluteNormalForcePrevious(Mdouble absoluteNormalForcePrevious)
allows the previous normal force to be (re)set from external classes
void write(std::ostream &os) const override
Interaction write function, which accepts an std::ostream as input.
void read(std::istream &is) override
Interaction read function, which accepts an std::istream as input.
Mdouble getEffectiveMass() const
Returns a Mdouble to the effective radius of the interaction. (Not corrected for the overlap) ...
Mdouble getAbsoluteNormalForce() const
Returns the absolute value of the norm (length) of the Normal force vector.