How to check if there is interaction between Id1 and Id2 at current step?

Asked by Leonard on 2019-08-31

Hi,
I'd like to make the simulation pause when O.interactions[id1,id2] lost, so I tried two ways to check if there is interaction between id1 and id2 at current step?
1.def stopIfIntLost():
    if O.interactions[1,2].isReal ==False:
        O.pause()
But I found that this way is wrong according to [1].
2. def stopIfIntLost():
    if O.interactions[1,2].geom.penetrationDepth==0:
        O.pause()
But I think this way is not good (it is wrong), because when O.interactions[1,2] lost, there will post an error.
What I want is something like:
def stopIfIntLost():
    if there is no interaction between id1 and id2:
        O.pause()
Is there any strategy you recommend to achieve it?
Many thanks.

[1]https://yade-dev.gitlab.io/trunk/yade.wrapper.html#yade.wrapper.Interaction.isReal

Question information

Language:
English Edit question
Status:
Solved
For:
Yade Edit question
Assignee:
No assignee Edit question
Solved by:
Jan Stránský
Solved:
2019-09-02
Last query:
2019-09-02
Last reply:
2019-09-02
Jan Stránský (honzik) said : #1

Hello,

###
def stopIfIntLost():
    if O.interactions.has(1,2): # [1]
        O.pause()
###

cheers
Jan

[1] https://yade-dem.org/doc/yade.wrapper.html#yade.wrapper.InteractionContainer.has

Leonard (z2521899293) said : #2

Hi Jan,
Thanks for your answer, I think it should work.
However, when I check "O.interactions.has(1,2)" using this MWE, it seems that when there is no interaction between id1 and id2, O.interactions.has(1,2) can still be True:
#####
from yade import pack, plot

sand = CohFrictMat(isCohesive=True,young=30e9,poisson=0.3,frictionAngle=radians(30),density=2650.0,normalCohesion=10e9, shearCohesion=80e6,label='sand')
O.materials.append(sand)

s1=utils.sphere((0,0,0),radius=1,color=[1,1,1],fixed=True,material='sand')
s2=utils.sphere((0,0,1.8),radius=0.8,color=[1,1,1],material='sand')

O.bodies.append(s1)
O.bodies.append(s2)

s2.state.blockedDOFs='z'
s2.state.vel = Vector3(0,0,1e2)

Gl1_Sphere.quality=3

O.engines=[
    ForceResetter(),
    InsertionSortCollider([Bo1_Sphere_Aabb()]),
    InteractionLoop(
        [Ig2_Sphere_Sphere_ScGeom6D()],
        [Ip2_CohFrictMat_CohFrictMat_CohFrictPhys()],
        [Law2_ScGeom6D_CohFrictPhys_CohesionMoment()]
    ),
    NewtonIntegrator(damping=0.4),
]
# run for one step for generating interaction
O.step()
####
I found that:
At iter 1, I run:
In [1]: for i in O.interactions:
   ...: print i.id1,i.id2
   ...:
0 1

In [2]: O.interactions.has(0,1)
Out[2]: True
It is correct, then I move forward for one step to make the two spheres separate and check again:
In [3]: O.step()

In [4]: for i in O.interactions:
   ...: print i.id1,i.id2
   ...:

In [5]: O.interactions.has(0,1)
Out[5]: True
It means that at iter2, there is no interaction between id1 and id2, but O.interactions.has(0,1) still equals True.
Could you please point out where is the problem?
Thanks!

Best Jan Stránský (honzik) said : #3

"for i in O.interaction:" iterates only real interactions. So in the second step, you can try:

i=O.interactions[0,1]
i.isReal # should be False

Then it depends on your needs which exactly criterion you use.

cheers
Jan

Leonard (z2521899293) said : #4

Thanks Jan Stránský, that solved my question.