dynamic change of gravity vector

Asked by JOHN

Good evening,
I wish to simulate a rotation and the easiest way though was to redefine the gravity vector.
However, i tried my hand by defining
a=(0,0,0)

O.engines=[

   ForceResetter(),
   InsertionSortCollider([Bo1_Sphere_Aabb(),Bo1_Facet_Aabb()]),
   InteractionLoop(
# handle sphere+sphere and facet+sphere collisions
      [Ig2_Sphere_Sphere_ScGeom(),Ig2_Facet_Sphere_ScGeom()],
      [Ip2_FrictMat_FrictMat_FrictPhys()],
      [Law2_ScGeom_FrictPhys_CundallStrack()]
   ),
   NewtonIntegrator(gravity=a,damping=0.4),
   PyRunner(command='gravity()',iterPeriod=1)

]

def graviy():
 a=(0,0,1)
 return a

which doesnt really do anything, (and i think i have misunderstood the nature of the pyrunner functions alltogether)

Thanks for any help!
Cheers

Question information

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

Hello,

If you want to redefine gravity, you need to use the gravity member of the newtonintegrator object:

a=(0,0,0)

O.engines=[

   ForceResetter(),
   InsertionSortCollider([Bo1_Sphere_Aabb(),Bo1_Facet_Aabb()]),
   InteractionLoop(
# handle sphere+sphere and facet+sphere collisions
      [Ig2_Sphere_Sphere_ScGeom(),Ig2_Facet_Sphere_ScGeom()],
      [Ip2_FrictMat_FrictMat_FrictPhys()],
      [Law2_ScGeom_FrictPhys_CundallStrack()]
   ),
   NewtonIntegrator(gravity=a,damping=0.4, label='newtonInt'),
   PyRunner(command='gravity()',iterPeriod=1)

]

def graviy():
  newtonInt.gravity = (0,0,1)

-Robert

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

I guess I should also tell you how a PyRunner works [1]. It serves the purpose of executing some function according to some iteration period. So in your case, each iteration of your simulation will execute "gravity()". So I hope it is obvious that the PyRunner in this example will simply keep redefining gravity to the same value (0,0,1).

If you want to change gravity according to time, your gravity() function simply needs to reflect that. It needs to incorporate O.time:

maxTime = some time when you want gravity to be -9.8

def gravity():
    correction = O.time/maxTime
    newtonInt.gravity = (0,0,-9.8*correction)

so in this case, PyRunner will execute gravity() every iteration, and the gravity will change according to how far along you are in your simulation.

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

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

Hello,

For sake of educational purposes, it's maybe worth to emphasize there was plenty of reasons for your initial script to "do nothing"

- your PyRunner was supposed to execute some "gravity()" Python function, however none was defined. You just defined a "graviy()" function (without "t"). Actually I'm expecting this code to throw an error instead of doing nothing...

- what you wanted is to modify the gravity attribute of the NewtonIntegrator engine instance which was in your O.engines. This was not possible with your commands (see below)

- with gravity=a in the NewtonIntegrator() line of your O.engines definition, you affect the current value of "a" to the gravity attribute, through a "passing by value", not a "passing by reference".
Subsequent changes to a's value will not be reflected in O.engines[3].gravity...

- you're mixing Python tuples (the type of "a") and Vector3r (i.e. 3 real vectors, the type of NewtonIntegrator.gravity). You can thank YADE developers for this to be gracefully handled here (things here work as intended by the user), but I doubt you will always be that lucky in your future YADE-ing ;-)

Jerome

Revision history for this message
JOHN (washingmachine) said :
#4

Thanks Robert Caulk, that solved my question.

Revision history for this message
JOHN (washingmachine) said :
#5

Thank you for your comprehensive answer, it helped more than you know
:-)