Cohesion creation- a new constitutive law

Asked by behzad

Hey guys,

I'm writing a new constitutive contact law. It has been derived from CohesiveFrictionalContactLaw.
I derived the material from CohFrictMat and the contact physiscs from CohFrictPhys.

Although the contact forces are as expected from the analytical equations the model fails to make a cohesive interaction. Where do we assign the cohesion strengths? In Ip2 or the Law?

As I see in constitutive contact law, it's assigned in Ip2 by:

contactPhysics->normalAdhesion = std::min(sdec1->normalCohesion,sdec2->normalCohesion)*pow(std::min(Db, Da),2);

So, let's simplify it by ignoring the plasticity and bond breakage. So, why simply saying :

phys->normalAdhesion = (mat1->normalCohesion);

in Ip2, does not make the interaction cohesive?

thanks for any helps.

cheers,
Behzad

Question information

Language:
English Edit question
Status:
Solved
For:
Yade Edit question
Assignee:
No assignee Edit question
Solved by:
behzad
Solved:
Last query:
Last reply:
Revision history for this message
Jérôme Duriez (jduriez) said :
#1

Hi,

Cohesion strengths are material parameters, and are, as usual in Yade, to be defined in the "Material" of bodies. But you have to set consistently some Ip2 attributes to in the end obtain cohesive interactions : setCohesionNow and or setCohesionOnNewContacts (see the doc)

Revision history for this message
behzad (behzad-majidi) said :
#2

Hi,

Yes and I'm using the same method of CohesiveFrictionalContactLaw.
for example I've got:

class Ip2_CohBurgersMat_CohBurgersMat_CohBurgersPhys: public IPhysFunctor {
 public :
  virtual void go(const shared_ptr<Material>& b1,
    const shared_ptr<Material>& b2,
    const shared_ptr<Interaction>& interaction);
    void Calculate_CohBurgersMat_CohBurgersMat_CohBurgersPhys(const shared_ptr<Material>& b1, const shared_ptr<Material>& b2, const shared_ptr<Interaction>& interaction, shared_ptr<CohBurgersPhys> phys);
    int cohesionDefinitionIteration;

 YADE_CLASS_BASE_DOC_ATTRS_CTOR(Ip2_CohBurgersMat_CohBurgersMat_CohBurgersPhys,IPhysFunctor,"Convert 2 instances of :yref:`CohBurgersMat` to :yref:`CohBurgersPhys` using the rule of consecutive connection.",

 ((bool,setCohesionNow,true,,"If true, assign cohesion to all existing contacts in current time-step."))
 ((bool,setCohesionOnNewContacts,true,,"If true, assign cohesion at all new contacts. If false, only existing contacts can be cohesive"))
 ,cohesionDefinitionIteration = -1;
 );
 FUNCTOR2D(CohBurgersMat,CohBurgersMat);
};
REGISTER_SERIALIZABLE(Ip2_CohBurgersMat_CohBurgersMat_CohBurgersPhys);

But, still saying;

InteractionLoop(
[Ig2_Sphere_Sphere_ScGeom(),Ig2_Box_Sphere_ScGeom()],
[Ip2_CohBurgersMat_CohBurgersMat_CohBurgersPhys(setCohesionNow=True, setCohesionOnNewContacts=True)],...)

doesn't make any cohesive interactions.

Revision history for this message
Jan Stránský (honzik) said :
#3

Hi Behzad,
if I understand correctly the problem, you should also use those values
(setCohesionNow,setCohesionOnNewContacts) proprly in Ip2:go function, like
in Ip2_CohFrictMat_CohFrictMat_CohFrictPhys [1]
cheers
Jan

[1]
http://bazaar.launchpad.net/~yade-pkg/yade/git-trunk/view/head:/pkg/dem/CohesiveFrictionalContactLaw.cpp#L274

2014-11-26 19:56 GMT+01:00 behzad <email address hidden>:

> Question #258258 on Yade changed:
> https://answers.launchpad.net/yade/+question/258258
>
> Status: Answered => Open
>
> behzad is still having a problem:
> Hi,
>
> Yes and I'm using the same method of CohesiveFrictionalContactLaw.
> for example I've got:
>
> class Ip2_CohBurgersMat_CohBurgersMat_CohBurgersPhys: public IPhysFunctor {
> public :
> virtual void go(const shared_ptr<Material>& b1,
> const shared_ptr<Material>& b2,
> const shared_ptr<Interaction>&
> interaction);
> void
> Calculate_CohBurgersMat_CohBurgersMat_CohBurgersPhys(const
> shared_ptr<Material>& b1, const shared_ptr<Material>& b2, const
> shared_ptr<Interaction>& interaction, shared_ptr<CohBurgersPhys> phys);
> int cohesionDefinitionIteration;
>
>
> YADE_CLASS_BASE_DOC_ATTRS_CTOR(Ip2_CohBurgersMat_CohBurgersMat_CohBurgersPhys,IPhysFunctor,"Convert
> 2 instances of :yref:`CohBurgersMat` to :yref:`CohBurgersPhys` using the
> rule of consecutive connection.",
>
> ((bool,setCohesionNow,true,,"If true, assign cohesion to all
> existing contacts in current time-step."))
> ((bool,setCohesionOnNewContacts,true,,"If true, assign cohesion at
> all new contacts. If false, only existing contacts can be cohesive"))
> ,cohesionDefinitionIteration = -1;
> );
> FUNCTOR2D(CohBurgersMat,CohBurgersMat);
> };
> REGISTER_SERIALIZABLE(Ip2_CohBurgersMat_CohBurgersMat_CohBurgersPhys);
>
> But, still saying;
>
> InteractionLoop(
> [Ig2_Sphere_Sphere_ScGeom(),Ig2_Box_Sphere_ScGeom()],
> [Ip2_CohBurgersMat_CohBurgersMat_CohBurgersPhys(setCohesionNow=True,
> setCohesionOnNewContacts=True)],...)
>
> doesn't make any cohesive interactions.
>
> --
> You received this question notification because you are a member of
> yade-users, which is an answer contact for Yade.
>
> _______________________________________________
> Mailing list: https://launchpad.net/~yade-users
> Post to : <email address hidden>
> Unsubscribe : https://launchpad.net/~yade-users
> More help : https://help.launchpad.net/ListHelp
>

Revision history for this message
behzad (behzad-majidi) said :
#4

Hi,

I've already done this. And it's actually why I ask to know how an interaction becomes cohesive?

For the moment, I'm ignoring the conditions such as if (I->isActive) or etc. We want to create a cohesive interaction of two cohesive balls which have already define as isCohesive=true with corresponding strengths.

in cpp file, I've got:

void Ip2_CohBurgersMat_CohBurgersMat_CohBurgersPhys::go(const shared_ptr<Material>& b1, const shared_ptr<Material>& b2, const shared_ptr<Interaction>& interaction) {
  if(interaction->phys) return;
  shared_ptr<CohBurgersPhys> phys (new CohBurgersPhys());
  Calculate_CohBurgersMat_CohBurgersMat_CohBurgersPhys(b1, b2, interaction, phys);
  interaction->phys = phys;

  CohBurgersPhys* contactPhys = YADE_CAST<CohBurgersPhys*>(interaction->phys.get());
  phys->cohesionBroken = false;
  phys->initCohesion = true;
  cohesionDefinitionIteration = -1;
  setCohesionNow = true;
}

Revision history for this message
Jan Stránský (honzik) said :
#5

Than the problem might be in Law2::go implementation. It should return true
for existing interactions and false for interactions to be deleted. Could
you check your implementation if takes cohesion into account?
cheers
Jan

2014-11-30 21:36 GMT+01:00 behzad <email address hidden>:

> Question #258258 on Yade changed:
> https://answers.launchpad.net/yade/+question/258258
>
> Status: Answered => Open
>
> behzad is still having a problem:
> Hi,
>
> I've already done this. And it's actually why I ask to know how an
> interaction becomes cohesive?
>
> For the moment, I'm ignoring the conditions such as if (I->isActive) or
> etc. We want to create a cohesive interaction of two cohesive balls
> which have already define as isCohesive=true with corresponding
> strengths.
>
> in cpp file, I've got:
>
> void Ip2_CohBurgersMat_CohBurgersMat_CohBurgersPhys::go(const
> shared_ptr<Material>& b1, const shared_ptr<Material>& b2, const
> shared_ptr<Interaction>& interaction) {
> if(interaction->phys) return;
> shared_ptr<CohBurgersPhys> phys (new CohBurgersPhys());
> Calculate_CohBurgersMat_CohBurgersMat_CohBurgersPhys(b1, b2,
> interaction, phys);
> interaction->phys = phys;
>
> CohBurgersPhys* contactPhys =
> YADE_CAST<CohBurgersPhys*>(interaction->phys.get());
> phys->cohesionBroken = false;
> phys->initCohesion = true;
> cohesionDefinitionIteration = -1;
> setCohesionNow = true;
> }
>
> --
> You received this question notification because you are a member of
> yade-users, which is an answer contact for Yade.
>
> _______________________________________________
> Mailing list: https://launchpad.net/~yade-users
> Post to : <email address hidden>
> Unsubscribe : https://launchpad.net/~yade-users
> More help : https://help.launchpad.net/ListHelp
>

Revision history for this message
behzad (behzad-majidi) said :
#6

The following is what I have in bool Law2:go function.

bool Law2_ScGeom_CohBurgersPhys_CohesiveBurgers::go(shared_ptr<IGeom>& _geom, shared_ptr<IPhys>& _phys, Interaction* I)
{
  Vector3r force = Vector3r::Zero();
  Vector3r torque1 = Vector3r::Zero();
  Vector3r torque2 = Vector3r::Zero();
  if (computeForceTorqueCohBurgers(_geom, _phys, I, force, torque1, torque2) and (I->isActive)) {
    const int id1 = I->getId1();
    const int id2 = I->getId2();

    addForce (id1,-force,scene);
    addForce (id2, force,scene);
    addTorque(id1, torque1,scene);
    addTorque(id2, torque2,scene);
    return true;
  } else return false;

}

Revision history for this message
Jan Stránský (honzik) said :
#7

Hi Behzad,
what does computeForceTorqueCohBurgers do?
Jan

2014-12-01 22:51 GMT+01:00 behzad <email address hidden>:

> Question #258258 on Yade changed:
> https://answers.launchpad.net/yade/+question/258258
>
> Status: Answered => Open
>
> behzad is still having a problem:
> The following is what I have in bool Law2:go function.
>
>
> bool Law2_ScGeom_CohBurgersPhys_CohesiveBurgers::go(shared_ptr<IGeom>&
> _geom, shared_ptr<IPhys>& _phys, Interaction* I)
> {
> Vector3r force = Vector3r::Zero();
> Vector3r torque1 = Vector3r::Zero();
> Vector3r torque2 = Vector3r::Zero();
> if (computeForceTorqueCohBurgers(_geom, _phys, I, force, torque1,
> torque2) and (I->isActive)) {
> const int id1 = I->getId1();
> const int id2 = I->getId2();
>
> addForce (id1,-force,scene);
> addForce (id2, force,scene);
> addTorque(id1, torque1,scene);
> addTorque(id2, torque2,scene);
> return true;
> } else return false;
>
> }
>
> --
> You received this question notification because you are a member of
> yade-users, which is an answer contact for Yade.
>
> _______________________________________________
> Mailing list: https://launchpad.net/~yade-users
> Post to : <email address hidden>
> Unsubscribe : https://launchpad.net/~yade-users
> More help : https://help.launchpad.net/ListHelp
>

Revision history for this message
behzad (behzad-majidi) said :
#8

It calculates the contact forces:

bool computeForceTorqueCohBurgers(shared_ptr<IGeom>& _geom, shared_ptr<IPhys>& _phys, Interaction* I, Vector3r & force, Vector3r & torque1, Vector3r & torque2) {

  const ScGeom& geom=*static_cast<ScGeom*>(_geom.get());
  CohBurgersPhys& phys=*static_cast<CohBurgersPhys*>(_phys.get());
  Scene* scene=Omega::instance().getScene().get();

  const int id1 = I->getId1();
  const int id2 = I->getId2();

  if (geom.penetrationDepth<0) {
    return false;
  } else {
    const BodyContainer& bodies = *scene->bodies;

    const State& de1 = *static_cast<State*>(bodies[id1]->state.get());
    const State& de2 = *static_cast<State*>(bodies[id2]->state.get());

    const Real& dt = scene->dt;

    if (I->isFresh(scene)) {
      phys.ukn = Vector3r(0,0,0);
      phys.uks = Vector3r(0,0,0);
      phys.shearForce = Vector3r(0,0,0);
      phys.normalForce = phys.kmn * geom.penetrationDepth * geom.normal;
    } else {
      Real An = 1.0 + phys.kkn * dt / (2.0 * phys.ckn);
      Real Bn = 1.0 - phys.kkn * dt / (2.0 * phys.ckn);
      Real Cn = dt / (2.0 * phys.ckn * An) + 1.0 / phys.kmn + dt / (2.0 * phys.cmn);
      Real Dn = dt / (2.0 * phys.ckn * An) - 1.0 / phys.kmn + dt / (2.0 * phys.cmn);

      Real As = 1.0 + phys.kks * dt / (2.0 * phys.cks);
      Real Bs = 1.0 - phys.kks * dt / (2.0 * phys.cks);
      Real Cs = dt / (2.0 * phys.cks * As) + 1.0 / phys.kms + dt / (2.0 * phys.cms);
      Real Ds = dt / (2.0 * phys.cks * As) - 1.0 / phys.kms + dt / (2.0 * phys.cms);

      const Vector3r shift2 = scene->isPeriodic ? scene->cell->intrShiftPos(I->cellDist): Vector3r::Zero();
      const Vector3r shiftVel = scene->isPeriodic ? scene->cell->intrShiftVel(I->cellDist): Vector3r::Zero();

      const Vector3r c1x = (geom.contactPoint - de1.pos);
      const Vector3r c2x = (geom.contactPoint - de2.pos - shift2);

      const Vector3r relativeVelocity = (de1.vel+de1.angVel.cross(c1x)) - (de2.vel+de2.angVel.cross(c2x)) + shiftVel;
      const Vector3r normalVelocity = geom.normal.dot(relativeVelocity) * geom.normal;
      const Vector3r shearVelocity = relativeVelocity-normalVelocity;

      const Vector3r normalForceT = (normalVelocity * dt + phys.ukn * (1.0 - Bn / An) - phys.normalForce * Dn) / Cn;
      phys.ukn = (phys.ukn * Bn + (normalForceT + phys.normalForce) * dt / (2.0 * phys.ckn)) / An;
      phys.normalForce = normalForceT;

      const Vector3r shearForceT = -1 * (shearVelocity * dt + phys.uks * (1.0 - Bs / As) - phys.shearForce * Ds) / Cs;
      phys.uks = (phys.uks * Bs + (shearForceT + phys.shearForce) * dt / (2.0 * phys.cks)) / As;
      phys.shearForce = shearForceT;

      const Real maxFs = phys.normalForce.squaredNorm() * std::pow(phys.tangensOfFrictionAngle,2);
      if( phys.shearForce.squaredNorm() > maxFs ) {

        const Real ratio = sqrt(maxFs) / phys.shearForce.norm();
        phys.shearForce *= ratio;
      }

      force = phys.normalForce + phys.shearForce;
      torque1 = -c1x.cross(force);
      torque2 = c2x.cross(force);
      return true;
    }
  }
}

Revision history for this message
Jan Stránský (honzik) said :
#9

Hi Behzad,

>
> if (geom.penetrationDepth<0) {
> return false;
> }
>

If I got it correctly, this condition does not take into account any
cohesion. Then it returns false to Law2::go, therefore Law2::go also
returns false and the interaction is deleted..

Jan

Revision history for this message
behzad (behzad-majidi) said :
#10

Yes, I removed it for testing and it worked.
But what else can I put as a condition here?
Yes, the balls which are touching also must have cohesion installed. But not two balls far away.

I need to have like

if (mat1->isCohevive) and (a touching condition)

What do you think?

Revision history for this message
Jan Stránský (honzik) said :
#11

>
>
>
> I need to have like
>
> if (mat1->isCohevive) and (a touching condition)
>
> What do you think?
>
>
yes, see e.g. [1] how Law2_ScGeom6D_CohFrictPhys_CohesionMoment::go does
this
Jan

[1]
http://bazaar.launchpad.net/~yade-pkg/yade/git-trunk/view/head:/pkg/dem/CohesiveFrictionalContactLaw.cpp#L115

Revision history for this message
behzad (behzad-majidi) said :
#12

Good, got it!

It sounds funny but the problem is that the contact doesn't break now!
I added the breaking condition to the Law2:go function as;

  if ((phys.normalForce.norm()) > phys.normalAdhesion) {
     return false;
  } else
 return true;

but it still doesn't break

Revision history for this message
Jérôme Duriez (jduriez) said :
#13

Hi,

You test here the norm of the normal force, without considering its sign. You have to do another test if you want to check a tensile rupture (we check generally the value of distance between spheres.)

Revision history for this message
behzad (behzad-majidi) said :
#14

Alright. Thanks!