Straining rate in PeriTriaxController

Asked by Mehdi Pouragha

Hi all,

I have a question regarding PeriTriaxController. In the following simple simulation, when I assign the same strain rate to exx, eyy, and exy, the increments of strain I measure at end are NOT the same (which I think should be, unless I am not understanding the process clearly).

Now, if I reset the cell transformation by activating the following block in the script ....

#O.cell.trsf=Matrix3.Identity
#O.run(1,True)

... with this modification the increments become almost the same.

My questions are:
1) why the same rates produce different strain increments?
2) why resetting the cell transformation changes the increments of strain afterwards?

I really appreciate if you can help me understand what I am doing wrong. This has been bugging me for more than a week now.

Thanks a lot!

--------------------------------------------------

from yade import pack,qt

O.periodic=True
O.cell.setBox(.1,.1,.1)
sp=pack.SpherePack()
radius=5e-3
num=sp.makeCloud((0,0,0),(.1,.1,.1),radius,.2,500,periodic=True)
O.bodies.append([sphere(s[0],s[1]) for s in sp])

O.engines=[
 ForceResetter(),
 InsertionSortCollider([Bo1_Sphere_Aabb()],verletDist=.05*radius),
 InteractionLoop(
  [Ig2_Sphere_Sphere_ScGeom()],
  [Ip2_FrictMat_FrictMat_FrictPhys()],
  [Law2_ScGeom_FrictPhys_CundallStrack()]
 ),
 PeriTriaxController(dynCell=True,mass=0.2,maxUnbalanced=0.01,relStressTol=0.02,goal=[-1e4,-1e4,0],stressMask=3,globUpdate=5,maxStrainRate=[1.,1.,1.],label='triax'),
 NewtonIntegrator(damping=.2),
]
O.dt=PWaveTimeStep()

while 1:
  O.run(1000, True)

  unb=unbalancedForce()
  print 'unbalanced force:',unb,' xx stress=',triax.stressTensor[0,0], ' yy stress=',triax.stressTensor[1,1]
  if unb<1e-3 and abs((-1e4-triax.stressTensor[0,0])/-1e4)<1e-3 and abs((-1e4-triax.stressTensor[1,1])/-1e4)<1e-3:
    break

rate = 1e-5

triax.stressMask=4
O.cell.velGrad=Matrix3(0,rate,0, 0,0,0, 0,0,0) # (du/dx, du/dy, du/dz, dv/dx, dv/dy, dv/dz, dw/dx, dw/dy, dw/dz)
triax.maxStrainRate = [rate,rate,0.0]
#triax.growDamping = 0.0

######## to be activated for comparison

#O.cell.trsf=Matrix3.Identity
#O.run(1,True)

##############

eps_xx, eps_yy = triax.strain[0], triax.strain[1]
#eps_xx, eps_yy = O.cell.trsf[0,0], O.cell.trsf[1,1]
eps_xy = O.cell.trsf[0,1]

dummy_deps = -1
triax.goal=[-100,-100 ,triax.stressTensor[2,2]] #-100 is meaningless. Just to make sure straining is occurring in the right diretion
nT = 100
O.run(nT,True)

dexx = triax.strain[0] - eps_xx
deyy = triax.strain[1] - eps_yy
dexy = O.cell.trsf[0,1] - eps_xy

print 'dexx=', dexx, ' deyy=',deyy, ' dexy=',dexy

Question information

Language:
English Edit question
Status:
Solved
For:
Yade Edit question
Assignee:
No assignee Edit question
Solved by:
Bruno Chareyre
Solved:
Last query:
Last reply:
Revision history for this message
Robert Caulk (rcaulk) said :
#1

Hello,

>> 1) why the same rates produce different strain increments?

I do not understand your question. I ran your script, which explicitly executes:

triax.maxStrainRate = [rate,rate,0.0]

and finally prints:

"dexx= -3.96592748642e-08 deyy= -3.96592878538e-08 dexy= 2.75274092903e-08"

Appearing to show that equivalent strain rate yields equivalent strain. Or is it that you believe the transformation matrix, O.cell.trsf[0,1], should be equivalent to the strain values, triax.strain[0]=traix.strain[1]?

>> 2) why resetting the cell transformation changes the increments of strain afterwards?

It doesn't:

dexx= -3.96592803723e-08 deyy= -3.96592804735e-08 dexy= 4.00598778322e-08

The strain increments remain the same. O.cell.trsf is simply providing you with the accumulated transformation of the cell. Or more described in more detail by Václav [1]:

"Current transformation matrix of the cell, which defines how far is the current cell geometry (:yref:`hSize<Cell.hSize>`) from the reference configuration. Changing trsf will not change :yref:`hSize<Cell.hSize>`, it serves only as accumulator for transformations applied via :yref:`velGrad<Cell.velGrad>`."

[1]https://github.com/yade/trunk/blob/master/core/Cell.hpp#L153

Revision history for this message
Mehdi Pouragha (mpouragha) said :
#2

Thanks for the explanation Robert!

>> is it that you believe the transformation matrix, O.cell.trsf[0,1], should be equivalent to the strain values, triax.strain[0]=traix.strain[1]?

Yes. My concern was the off-diagonal strain (exy) not being the same as the normal strain despite the rates being equal. Am I wrong in assuming that exy =0.5 (O.cell.trsf[0,1] + O.cell.trsf[1,0])?

(The factor of 0.5 is missing from my script but that is not the main point).

About the 2nd question;

cell.trsf is the time-accumulation of cell.velGrad. So, for a fixed cell.velGrad and fixed number of steps, if I reset the reference trsf point by O.cell.trsf=Matrix3.Identity, it should not affect the resulting change in dexy. Which is not the case if you compare the two results you mentioned.

Thanks again.

Revision history for this message
Robert Caulk (rcaulk) said :
#3

Hello Mehdi,

Ok, thankyou for clearly elaborating. It seems you might be confused about the definition of the transformation matrix in this case. Here, O.cell.trsf, is the deformation gradient which can be used to determine strain, but by itself simply gives you a transformation from one state to another.

If you want to pull the natural strain from the deformation gradient, you would do something like:

strain = .5*(O.cell.trsf+O.cell.trsf.transpose()) - I

which is conveniently provided for you as O.cell.getSmallStrain() [1].

Now, if you want the velGrad to reflect equal rates in dv_x/dy and dv_y/dx, you will need to add that:

O.cell.velGrad=Matrix3(0,rate,0, rate,0,0, 0,0,0)

Please let me know if this answers your question or not :-)

Cheers,

Robert

[1]https://yade-dem.org/doc/yade.wrapper.html#yade.wrapper.Cell.getSmallStrain

Revision history for this message
Best Bruno Chareyre (bruno-chareyre) said :
#4

Hi Mehdi,
If I understand correctly the main problem is that you expect from the transformation tensor properties which only apply in the small strain + small rotation approximation. Typically: exy =0.5 (O.cell.trsf[0,1] + O.cell.trsf[1,0]). The problem is this is not a frame independent quantity in large deformations.
When you don't reset trsf to identity it has components of the order of 0.7, which is far away from a "small" thing. This is reflected by the fact that your definition of shear is not frame independent. It is to be expected.

What needs to be constant is the change of trsf, with or without reseting it to identity. And it is the case, see code below replacing your last section. Note that the composition of transformations implies products, not additions, therefore calculating an "increment" between two transformations needs multiplication by an inverse, while you where doing substractions.

Cheers

Bruno

######## to be activated for comparison
O.cell.trsf=Matrix3.Identity
O.run(1,True)
initTrsf= O.cell.trsf

##############
dummy_deps = -1
triax.goal=[-100,-100 ,triax.stressTensor[2,2]] #-100 is meaningless. Just to make sure straining is occurring in the right diretion
nT = 100
O.run(nT,True)

#print "incremental trsf:",
dF=O.cell.trsf*(initTrsf.inverse())
print 'dFxx=', dF[0,0], ' dFyy=',dF[1,1], ' dFxy=',dF[0,1]

Bruno

Revision history for this message
Mehdi Pouragha (mpouragha) said :
#5

Thanks Bruno and Robert for the clarifications. I really appreciate all the support! I understand it much better now.

It may be a good idea to include this calculation of strain somewhere in the examples, just a suggestion.

Mehdi

Revision history for this message
Mehdi Pouragha (mpouragha) said :
#6

Thanks Bruno Chareyre, that solved my question.

Revision history for this message
Bruno Chareyre (bruno-chareyre) said :
#7

> to include this calculation of strain somewhere in the examples

Which calculation, sorry? I did not define any strain in #4.
Bruno

Revision history for this message
Mehdi Pouragha (mpouragha) said :
#8

As far as I understood, you are saying that the small strain increments should be measured through the dF that you defined in #4, not from the increment in O.cell.trsf alone, right?

[Or are you saying that increment of strain is still the increment of O.cell.trsf, but the O.cell.velGrad produces to different strain rates in the two cases that I mentioned in my original question?]

To clarify again, my original concern was to impose constant normal and shear strain rates. So in my original script, I am either measuring wrong increments of strain, or imposing the wrong strain rates.

Revision history for this message
Bruno Chareyre (bruno-chareyre) said :
#9

I did not say a thing about "strain increments" and I don't dare trying because it leads to rather complex finite strain problems, and in most cases (including yours) it is not necessary.
What can be defined unambiguously is: 1/ strain rate, the symmetric part of velocity gradient, and 2/ the transformation tensor between two states (i.e. the multiplicative accumulation of velocity gradient over time).

> "So in my original script, I am either measuring wrong increments of strain, or imposing the wrong strain rates."

You were measuring wrong increments. Constant strain rate just means constant velGrad, and that was your situation already.

Bruno

Revision history for this message
Mehdi Pouragha (mpouragha) said :
#10

So the right way of measuring small strains is to reset the O.cell.trsf to identity and use O.cell.getSmallStrain() (which is the same as my original measurement of strain), am I right? Without resetting, the change in O.cell.getSmallStrain() does not reflect the small strain increment (?)

Revision history for this message
Chareyre (bruno-chareyre-9) said :
#11

Yes and no... the question is actually confusing me. Resetting trsf is
probably a good idea but I would suggest to step back: there is no need to
consider small strain increments at all, whatever the reference
configuration.
maxStrainRate is not speaking of small strains, nor is triax.strain (it is
natural strain). It seems to me that you created an artificial problem.
What is the objective?
Bruno

Le 24 oct. 2018 18:16, "Mehdi Pouragha" <
<email address hidden>> a écrit :

Question #675377 on Yade changed:
https://answers.launchpad.net/yade/+question/675377

Mehdi Pouragha posted a new comment:
So the right way of measuring small strains is to reset the O.cell.trsf
to identity and use O.cell.getSmallStrain() (which is the same as my
original measurement of strain), am I right? Without resetting, the
change in O.cell.getSmallStrain() does not reflect the small strain
increment (?)

--
You received this question notification because your team yade-users 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
Mehdi Pouragha (mpouragha) said :
#12

The objective was to 1) apply constant normal and shear strain rates, and 2) measure the strains-- both within small strain ranges.

As you mentioned, the first one conveniently is done through maxStrainRate.

The second point, measurement of strain, can be done for normal strains through triax.strain, as you indicated. The difficulty was with shear terms. For the shear strains, my rookie mistake was to think that; regardless of the current value of cell.trsf, if the applied "increment" of the strain is small, we can still measure the shear strain by finding the change in cell.getSmallStrain(). This appears not to be true. But I can imagine it might be a plausible mistake to make.

Yes, we can say there is no need to consider small strain increments at all, and all the ambiguities are resolved if we use finite strain calculation. But still, in many cases, people like me are interested in small strains and may resort to convenient small strain calculations and functions, without noticing the pitfalls. All I was suggesting is that it would be helpful to mention that functions such as cell.getSmallStrain() will contain non-negligible errors, even for small increments of strain, if the cell.trsf is far from identity.

Revision history for this message
Bruno Chareyre (bruno-chareyre) said :
#13

> cell.getSmallStrain() will contain non-negligible errors, even for small increments of strain

Nope, it will not, this is where you loose me. :)
When you don't reset trsf you are calculating small strain for a large transformation. That is all.
In simple shear it is convenient and common to define the accumulated shear as velGrad_xy*time.
That's why you don't need a small strain approximation of any shear component.

Bruno

Revision history for this message
Mehdi Pouragha (mpouragha) said :
#14

I understand what you are saying , and I am not implying that there is anything wrong with the code and functions!

All I am saying, at the risk of repeating myself, is that the mistake I made may be a common one and others may make it too, without realizing it. But you are certainly a better judge of that.

Thanks again Bruno.

Mehdi