# i.geom.incidentVel is not a vector

Hello,

This is a very basic question
But, unfortunately, when i print it in my script, the output is not a vector but is:
<bound method ScGeom.incidentVel of <ScGeom instance at 0x7ff930003690>>

Can you explain me what's happening ??

My very simple script is below

Best

V.

#*********************************************************************************
# basic simulation showing sphere falling ball gravity,
# bouncing against another sphere

# DATA COMPONENTS

# add 2 particles to the simulation
# they the default material (utils.defaultMat)
O.bodies.append([
sphere((0,0,0.9),.5)
])

# FUNCTIONAL COMPONENTS

# simulation loop -- see presentation for the explanation
O.engines=[
ForceResetter(),
InsertionSortCollider([Bo1_Sphere_Aabb()]),
InteractionLoop(
[Ig2_Sphere_Sphere_ScGeom()], # collision geometry
[Ip2_FrictMat_FrictMat_FrictPhys()], # collision "physics"
[Law2_ScGeom_FrictPhys_CundallStrack()]
), # contact law -- apply forces
PyRunner(iterPeriod=1,command="contactp()"),
# Apply gravity force to particles. damf ing: numerical dissipation of energy.
NewtonIntegrator(gravity=(0,0,-9.81),damping=0.1)
]

# set timestep to a fraction of the critical timestep
O.dt=.5e-4*PWaveTimeStep()

# save the simulation, so that it can be reloaded later, for experimentation
O.saveTmp()

def contactp():

for i in O.interactions:

particle1= O.bodies[i.id1]
particle2= O.bodies[i.id2]

cp = i.geom.contactPoint
R1=i.geom.refR1; R2=i.geom.refR2
pdepth=i.geom.penetrationDepth

v = i.geom.incidentVel

print 'id1=', i.id1,'id2=', i.id2
print 'R1=',R1,'R2=',R2
print 'cp=', i.geom.contactPoint
print 'pdepth=', i.geom.penetrationDepth
print 'incidentVel=', v
#**************************************************************************************

## Question information

Language:
English Edit question
Status:
For:
Assignee:
No assignee Edit question
Last query:
2020-04-24
2020-04-26

## This question was reopened

 Jérôme Duriez (jduriez) said on 2020-04-24: #1

You forgot the parentheses: geom.incidentVel() is the correct syntax since it is a function (see the "error" message)

;-)

 Rioual (francois-rioual-v) said on 2020-04-24: #3

Hi Jerome,

No, this is not an error message I get.
Instead of having a vector (velocity) at output for i.geom.incidentVel , i get =<bound method ScGeom.incidentVel of <ScGeom instance at 0x55e2957905f0>>
???

Thanks

V.

ps: the error message appears when I add ()

 Jan Stránský (honzik) said on 2020-04-26: #4

Hello,

> ps: the error message appears

please always try to be as specific as possible (in this case providing the complete error message)

In these cases, please first consult the documentation [1]. You should pass Interaction instance as an argument:
v = i.geom.incidentVel(i)

cheers
Jan

 Jérôme Duriez (jduriez) said on 2020-04-27: #5

Because I previously overlooked that necessary Interaction attribute (thanks Jan), let me try to add more explanations:

Your initial output message (more than an "error" message, indeed) was some "..method..". In the framework of object-oriented programming (like Python, C++, and YADE, where everything is an instance (= an item, one may say) of some given Class), method means function, and parentheses are then mandatory.
At least, as soon as you're interested more in the return value than in the function itself.. That was your case: you wanted to have the Vector3 returned by that method incidentVel, and not the method itself.

Then the question is, what do you have to put inside those parentheses ?

Most often, nothing. You can call directly eg i.geom.dict() even though the doc would mention one attribute "arg1" [*]. This arg1 attribute actually refers to the object whose method you're calling, so it's not necessary to pass it as an attribute.

On the other hand, incidentVel doc here mentions other attributes than arg1: an Interaction instance in particular => this one is necessary, see Jan's syntax.

There also is a bracket-delimited attribute, here avoidGranularRatcheting, with an equal sign. This one is an optional attribute, it has some default value = the right hand side of the equality. You do not need to pass this attribute as long as you're happy with that default value.

Further reading could be found in Python documentation about Python functions and their docstrings.

 Rioual (francois-rioual-v) said on 2020-04-27: #6

...Thank you very much you all, it works now but I don't really see the logic for precising (i): i.geom already precises that you are referring to interaction "i", no ??
hence, i.geom.penetrationDepth works
i.geom.contactPoint works
!!!

Best

V.

 Jérôme Duriez (jduriez) said on 2020-04-27: #7

penetrationDepth and contactPoint are attributes of the ScGeom class, not methods, so you can anyway not compare with the behavior for a method like incidentVel()

I otherwise agree it's a little deceiving to have to type i.geom.incidentVel(i)..

But I personally understand it thinking to i.geom.incidentVel(i), as (i.geom).incidentVel(i), where (i.geom) is just a ScGeom object, with all its attributes and methods, but with no more connection to the interaction i itself.

So, when calling the incidentVel() method of that ScGeom object, you have to pass again the interaction object that is "behind" (because the computations behind incidentVel() require data that are in i itself, and that are not contained in the ScGeom object i.geom)