← Back to team overview

yade-users team mailing list archive

Re: [Question #694017]: Extract normal force

 

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

    Status: Open => Answered

Jan Stránský proposed the following answer:
code 1:
> def exportForces():
> totalNormalForce = i.phys.normalForce

code 2:
> def saveForces():
> MagnitudeNormalForce = sum((i.phys.normalForce.norm()))

code 3:
> def addPlotData():
> Force = sum((O.forces.f(i).norm()))

Every update, you completely changed the namings. Yes, it is just naming and here it is clear, but next time please try to stay consistent.
There is no reason for such renaming and then I would prefer not to rename the stuff to prevent confusion.

Every update, you changed the force computation method, without any comment. Next time please consider giving some comment about the reasons.
Ok, from the discussion it came out that the magnitude should be force.norm() instead of force vector itself, so i.phys.normalForce -> i.phys.normalForce.norm() is reasonable.
But why the sum (inside for loop)?
And why i.phys.normalForce -> O.forces.f ?(!?!?)


> This is my updated MWE
> rom yade import pack,utils, plot,ymport,qt

W=working, starting a script with "rom yade..." surely is not :-)

> for i in O.interactions:
>   ... O.forces.f(i)

O.forces.f needs body ID, see documentation [1]. In your code you pass
"i", which is Interaction... (this is what the error says)

O.forces.f returns resulting force on the body. It has no relation to individual interaction forces.
(O.forces.f is sum of all interaction forces on the body, but with no backwards influence)

> sum((O.forces.f(i).norm()))

force.norm() is one number.
What you expect from sum(number)?
try it in python. e.g. sum(2)

>   for i in O.interactions:
>     if ...:
>       Force = sum((O.forces.f(i).norm()))
>     else :
>       Force = 0

this way, you loop over all interactions just to assign Force to be the
force from the very last interaction or 0...

A possible solution:
###
def addPlotData():
    Force = 0.0 # initial zero value
    for i in O.interactions:
        if isinstance(O.bodies[i.id1].shape,Facet) or isinstance(O.bodies[i.id2].shape,Facet):
            Force += i.phys.normalForce.norm() # increment the Force
    # or even a one liner
    # Force = sum(i.phys.normalForce.norm() for i in O.interactions if isinstance(O.bodies[i.id1].shape,Facet) or isinstance(O.bodies[i.id2].shape,Facet))
    plot.addData(i=O.iter,Force=Force)
###

You can save the data with plot.saveDataTxt [2], either inside
addPlotData, or in some other PyRunner with lower frequency, or after
the simulation is finished, or ... whenever you need.

cheers
Jan

[1] https://yade-dem.org/doc/yade.wrapper.html#yade.wrapper.ForceContainer.f
[2] https://yade-dem.org/doc/yade.plot.html#yade.plot.saveDataTxt

-- 
You received this question notification because your team yade-users is
an answer contact for Yade.