Advertisement
lingran

cpp_add bending_to_cohesiveLaw

Aug 27th, 2013
85
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 9.85 KB | None | 0 0
  1. /*************************************************************************
  2. *  Copyright (C) 2007 by Bruno Chareyre <bruno.chareyre@imag.fr>         *
  3. *  Copyright (C) 2008 by Janek Kozicki <cosurgi@berlios.de>              *
  4. *                                                                        *
  5. *  This program is free software; it is licensed under the terms of the  *
  6. *  GNU General Public License v2 or later. See file LICENSE for details. *
  7. *************************************************************************/
  8.  
  9. #include "CohesiveFrictionalContactLaw.hpp"
  10. #include<yade/pkg/dem/CohFrictMat.hpp>
  11. #include<yade/pkg/dem/ScGeom.hpp>
  12. #include<yade/pkg/dem/CohFrictPhys.hpp>
  13. #include<yade/core/Omega.hpp>
  14. #include<yade/core/Scene.hpp>
  15.  
  16. YADE_PLUGIN((CohesiveFrictionalContactLaw)(Law2_ScGeom6D_CohFrictPhys_CohesionMoment));
  17. CREATE_LOGGER(Law2_ScGeom6D_CohFrictPhys_CohesionMoment);
  18.  
  19. Real Law2_ScGeom6D_CohFrictPhys_CohesionMoment::normElastEnergy()
  20. {
  21.     Real normEnergy=0;
  22.     FOREACH(const shared_ptr<Interaction>& I, *scene->interactions){
  23.         if(!I->isReal()) continue;
  24.         CohFrictPhys* phys = YADE_CAST<CohFrictPhys*>(I->phys.get());
  25.         if (phys) {
  26.             normEnergy += 0.5*(phys->normalForce.squaredNorm()/phys->kn);
  27.         }
  28.     }
  29.     return normEnergy;
  30. }
  31. Real Law2_ScGeom6D_CohFrictPhys_CohesionMoment::shearElastEnergy()
  32. {
  33.     Real shearEnergy=0;
  34.     FOREACH(const shared_ptr<Interaction>& I, *scene->interactions){
  35.         if(!I->isReal()) continue;
  36.         CohFrictPhys* phys = YADE_CAST<CohFrictPhys*>(I->phys.get());
  37.         if (phys) {
  38.             shearEnergy += 0.5*(phys->shearForce.squaredNorm()/phys->ks);
  39.         }
  40.     }
  41.     return shearEnergy;
  42. }
  43.  
  44. Real Law2_ScGeom6D_CohFrictPhys_CohesionMoment::bendingElastEnergy()
  45. {
  46.     Real bendingEnergy=0;
  47.     FOREACH(const shared_ptr<Interaction>& I, *scene->interactions){
  48.         if(!I->isReal()) continue;
  49.         CohFrictPhys* phys = YADE_CAST<CohFrictPhys*>(I->phys.get());
  50.         if (phys) {
  51.             bendingEnergy += 0.5*(phys->moment_bending.squaredNorm()/phys->kr);
  52.         }
  53.     }
  54.     return bendingEnergy;
  55. }
  56.  
  57. Real Law2_ScGeom6D_CohFrictPhys_CohesionMoment::twistElastEnergy()
  58. {
  59.     Real twistEnergy=0;
  60.     FOREACH(const shared_ptr<Interaction>& I, *scene->interactions){
  61.         if(!I->isReal()) continue;
  62.         CohFrictPhys* phys = YADE_CAST<CohFrictPhys*>(I->phys.get());
  63.         if (phys) {
  64.             twistEnergy += 0.5*(phys->moment_twist.squaredNorm()/phys->ktw);
  65.         }
  66.     }
  67.     return twistEnergy;
  68. }
  69.  
  70. void CohesiveFrictionalContactLaw::action()
  71. {
  72.     if(!functor) functor=shared_ptr<Law2_ScGeom6D_CohFrictPhys_CohesionMoment>(new Law2_ScGeom6D_CohFrictPhys_CohesionMoment);
  73.     functor->always_use_moment_law = always_use_moment_law;
  74.     functor->shear_creep=shear_creep;
  75.     functor->twist_creep=twist_creep;
  76.     functor->creep_viscosity=creep_viscosity;
  77.     functor->scene=scene;
  78.     FOREACH(const shared_ptr<Interaction>& I, *scene->interactions){
  79.         if(!I->isReal()) continue;
  80.         functor->go(I->geom, I->phys, I.get());}
  81. }
  82.  
  83. void Law2_ScGeom6D_CohFrictPhys_CohesionMoment::go(shared_ptr<IGeom>& ig, shared_ptr<IPhys>& ip, Interaction* contact)
  84. {
  85.     const Real& dt = scene->dt;
  86.     const int &id1 = contact->getId1();
  87.     const int &id2 = contact->getId2();
  88.     ScGeom6D* currentContactGeometry  = YADE_CAST<ScGeom6D*> (ig.get());
  89.     CohFrictPhys* currentContactPhysics = YADE_CAST<CohFrictPhys*> (ip.get());
  90.     Vector3r& shearForce    = currentContactPhysics->shearForce;
  91.  
  92.     if (contact->isFresh(scene)) shearForce   = Vector3r::Zero();
  93.     Real un     = currentContactGeometry->penetrationDepth;
  94.     Real Fn    = currentContactPhysics->kn*(un-currentContactPhysics->unp);
  95.  
  96.     if (currentContactPhysics->fragile && (-Fn)> currentContactPhysics->normalAdhesion) {
  97.         // BREAK due to tension
  98.         scene->interactions->requestErase(contact); return;
  99.     } else {
  100.         if ((-Fn)> currentContactPhysics->normalAdhesion) {//normal plasticity
  101.             Fn=-currentContactPhysics->normalAdhesion;
  102.             currentContactPhysics->unp = un+currentContactPhysics->normalAdhesion/currentContactPhysics->kn;
  103.             if (currentContactPhysics->unpMax && currentContactPhysics->unp<currentContactPhysics->unpMax)
  104.                 scene->interactions->requestErase(contact); return;
  105.         }
  106.         currentContactPhysics->normalForce = Fn*currentContactGeometry->normal;
  107.         State* de1 = Body::byId(id1,scene)->state.get();
  108.         State* de2 = Body::byId(id2,scene)->state.get();
  109.         ///////////////////////// CREEP START ///////////
  110.         if (shear_creep) shearForce -= currentContactPhysics->ks*(shearForce*dt/creep_viscosity);
  111.         ///////////////////////// CREEP END ////////////
  112.  
  113.         Vector3r& shearForce = currentContactGeometry->rotate(currentContactPhysics->shearForce);
  114.         const Vector3r& dus = currentContactGeometry->shearIncrement();
  115.  
  116.         //Linear elasticity giving "trial" shear force
  117.         shearForce -= currentContactPhysics->ks*dus;
  118.  
  119.         Real Fs = currentContactPhysics->shearForce.norm();
  120.         Real maxFs = currentContactPhysics->shearAdhesion;
  121.         if (!currentContactPhysics->cohesionDisablesFriction || maxFs==0)
  122.             maxFs += Fn*currentContactPhysics->tangensOfFrictionAngle;
  123.         maxFs = std::max((Real) 0, maxFs);
  124.         if (Fs  > maxFs) {//Plasticity condition on shear force
  125.             if (currentContactPhysics->fragile && !currentContactPhysics->cohesionBroken) {
  126.                 currentContactPhysics->SetBreakingState();
  127.                 maxFs = max((Real) 0, Fn*currentContactPhysics->tangensOfFrictionAngle);
  128.             }
  129.             maxFs = maxFs / Fs;
  130.             Vector3r trialForce=shearForce;
  131.             shearForce *= maxFs;"e
  132.             Real dissip=((1/currentContactPhysics->ks)*(trialForce-shearForce))/*plastic disp*/ .dot(shearForce)/*active force*/;
  133.             if(dissip>0) scene->energy->add(dissip,"plastDissip",plastDissipIx,/*reset*/false);
  134.             if (Fn<0)  currentContactPhysics->normalForce = Vector3r::Zero();//Vector3r::Zero()
  135.         }
  136.         applyForceAtContactPoint(-currentContactPhysics->normalForce-shearForce, currentContactGeometry->contactPoint, id1, de1->se3.position, id2, de2->se3.position);
  137.  
  138.         /// Moment law  ///
  139.         if (currentContactPhysics->momentRotationLaw && (!currentContactPhysics->cohesionBroken || always_use_moment_law)) {
  140.             if (!useIncrementalForm){
  141.                 if (twist_creep) {
  142.                     Real viscosity_twist = creep_viscosity * std::pow((2 * std::min(currentContactGeometry->radius1,currentContactGeometry->radius2)),2) / 16.0;
  143.                     Real angle_twist_creeped = currentContactGeometry->getTwist() * (1 - dt/viscosity_twist);
  144.                     Quaternionr q_twist(AngleAxisr(currentContactGeometry->getTwist(),currentContactGeometry->normal));
  145.                     Quaternionr q_twist_creeped(AngleAxisr(angle_twist_creeped,currentContactGeometry->normal));
  146.                     Quaternionr q_twist_delta(q_twist_creeped * q_twist.conjugate());
  147.                     currentContactGeometry->twistCreep = currentContactGeometry->twistCreep * q_twist_delta;
  148.                 }
  149.                 currentContactPhysics->moment_twist = (currentContactGeometry->getTwist()*currentContactPhysics->ktw)*currentContactGeometry->normal;
  150.                 currentContactPhysics->moment_bending = currentContactGeometry->getBending() * currentContactPhysics->kr;
  151.             }  
  152.             else{ // Use incremental formulation to compute moment_twis and moment_bending (no twist_creep is applied)
  153.                 if (twist_creep) throw std::invalid_argument("Law2_ScGeom6D_CohFrictPhys_CohesionMoment: no twis creep is included if the incremental form for the rotations is used.");
  154.                 Vector3r relAngVel = currentContactGeometry->getRelAngVel(de1,de2,dt);
  155.                 // *** Bending ***//
  156.                 Vector3r relAngVelBend = relAngVel - currentContactGeometry->normal.dot(relAngVel)*currentContactGeometry->normal; // keep only the bending part
  157.                 Vector3r relRotBend = relAngVelBend*dt; // relative rotation due to rolling behaviour  
  158.                 // incremental formulation for the bending moment (as for the shear part)
  159.                 Vector3r& momentBend = currentContactPhysics->moment_bending;
  160.                 momentBend = currentContactGeometry->rotate(momentBend); // rotate moment vector (updated)
  161.                 momentBend = momentBend-currentContactPhysics->kr*relRotBend;
  162.                 // ----------------------------------------------------------------------------------------
  163.                 // *** Torsion ***//
  164.                 Vector3r relAngVelTwist = currentContactGeometry->normal.dot(relAngVel)*currentContactGeometry->normal;
  165.                 Vector3r relRotTwist = relAngVelTwist*dt; // component of relative rotation along n  FIXME: sign?
  166.                 // incremental formulation for the torsional moment
  167.                 Vector3r& momentTwist = currentContactPhysics->moment_twist;
  168.                 momentTwist = currentContactGeometry->rotate(momentTwist); // rotate moment vector (updated)
  169.                 momentTwist = momentTwist-currentContactPhysics->ktw*relRotTwist; // FIXME: sign?
  170.             }
  171.             /// Plasticity ///
  172.             // limit rolling moment to the plastic value, if required
  173.             Real RollMax = currentContactPhysics->maxRollPl*currentContactPhysics->normalForce.norm();
  174.             if (RollMax>0.){ // do we want to apply plasticity?
  175.                 LOG_WARN("If :yref:`CohesiveFrictionalContactLaw::useIncrementalForm` is false, then plasticity would not be applied correctly (the total formulation would not reproduce irreversibility).");
  176.                 Real scalarRoll = currentContactPhysics->moment_bending.norm();    
  177.                 if (scalarRoll>RollMax){ // fix maximum rolling moment
  178.                     Real ratio = RollMax/scalarRoll;
  179.                     currentContactPhysics->moment_bending *= ratio;
  180.                 }  
  181.             }
  182.             // limit twisting moment to the plastic value, if required
  183.             Real TwistMax = currentContactPhysics->maxTwistMoment.norm();
  184.             if (TwistMax>0.){ // do we want to apply plasticity?
  185.                 LOG_WARN("If :yref:`CohesiveFrictionalContactLaw::useIncrementalForm` is false, then plasticity would not be applied correctly (the total formulation would not reproduce irreversibility).");
  186.                 Real scalarTwist= currentContactPhysics->moment_twist.norm();      
  187.                 if (scalarTwist>TwistMax){ // fix maximum rolling moment
  188.                     Real ratio = TwistMax/scalarTwist;
  189.                     currentContactPhysics->moment_twist *= ratio;  
  190.                 }  
  191.             }
  192.             // Apply moments now
  193.             Vector3r moment = currentContactPhysics->moment_twist + currentContactPhysics->moment_bending;
  194.             scene->forces.addTorque(id1,-moment);
  195.             scene->forces.addTorque(id2, moment);          
  196.         }
  197.         /// Moment law END       ///
  198.     }
  199. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement