save spheres coordinates to a file

Asked by hafsa

hi every one ,
i am trying to save properties of spheres (id,x,y,z,r,force) in file during simulation each second (period=1 s) and add iteration number to base name each 1s.
the simulation is about filling a cylinder by pouring spheres under vertical vibration .
and this is what i obtain :
ArgumentError Traceback (most recent call last)
/usr/bin/yade in <module>()

/usr/bin/yade in myaddData()
     43 def myaddData():
     44 for b in bodies2:
---> 45 idt,rad=O.bodies[b].id,O.bodies[b].radius
     46 x,y,z=O.bodies[b].state.pos[0],O.bodies[b].state.pos[1],O.bodies[b].state.pos[2]
     47 veloc,force=O.bodies[b].vel[2],O.forces.f(O.bodies[b].id)

and i have error in :
  File "save.py", line 51, in <module>
    yade.wrapper.Recorder(addIternNum=True,file=fil)
AttributeError: No such attribute: addIternNum.

my script is :
#!/usr/bin/python
# coding: utf-8

from yade import pack,plot,export

#material of cylinder
Mat1 = O.materials.append(ViscElMat(kn=10.0e4,ks=10.0e4,frictionAngle=0.455,density=2650.0))

# create Cylinder
Cylinder=O.bodies.append(geom.facetCylinder((0,0,1.5),2.0,height=3.0,wallMask=6,segmentsNumber=64,material=Mat1))

# create sphere packing
sp=pack.SpherePack()
sp.makeCloud((-1.2,-1.2,1.5),(1.2,1.2,8.0),rMean=.2,rRelFuzz=.1,num=128)
sp.toSimulation(color=(0,1,0))

O.engines=[
    ForceResetter(),
    InsertionSortCollider([Bo1_Sphere_Aabb(),Bo1_Facet_Aabb()]),
    InteractionLoop(

        [Ig2_Sphere_Sphere_ScGeom(),Ig2_Facet_Sphere_ScGeom()],
        [Ip2_FrictMat_FrictMat_FrictPhys()],
        [Law2_ScGeom_FrictPhys_CundallStrack()]
    ),
    NewtonIntegrator(gravity=(0,0,-9.81),damping=0.3),
    HarmonicMotionEngine(A=[0,0,0.5], f=[0,0,1.0], fi = [0.0,0.0,pi],ids =Cylinder),# vertical vibration
    # HarmonicMotionEngine(A = (0,0.002,0),f = (0,50,0),fi = (0,-0.5*math.pi,0),ids =Cylinder), horizontal vibration
    PyRunner(command='myaddData()',realPeriod=1,initRun=True), #call def fonction every second
 ]

O.dt=utils.PWaveTimeStep() #to slow down the motion O.dt=.9*PWaveTimeStep()
O.resetTime()

# open file
fil=open("vibrations.txt","a+")
fil.write ('id \t x \t y \t z \t velocity \t radius \t force \n')

bodies2 = [b for b in O.bodies if isinstance(b.shape,Sphere)]
print 'number of particles2 :', len(bodies2)

#saving parameters of spheres in file
def myaddData():
   for b in bodies2:
      idt,rad=O.bodies[b].id,O.bodies[b].radius
      x,y,z=O.bodies[b].state.pos[0],O.bodies[b].state.pos[1],O.bodies[b].state.pos[2]
      veloc,force=O.bodies[b].vel[2],O.forces.f(O.bodies[b].id)
   fil.write("{:e} {:e} {:e} {:e} {:e} {:e} {:e}\n".format(idt,x,y,z,veloc,rad,force)) # ( .format = % )

# add iteration number to basename
yade.wrapper.Recorder(addIternNum=True,file=fil)
O.saveTmp()
fil.close()

Any ideas ?

Thanks in advance.

Question information

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

Hi,

O.bodies[b].radius does not exist. It should be O.bodies[b].shape.radius (if O.bodies[b] is a sphere).
Regards
Bruno

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

Ah... and in O.bodies[b] 'b' should be an integer, not a body.

Else it is a bit like O.bodies[O.bodies[O.bodies[O.bodies[....]]]]]]]]]]]]

Bb]

Revision history for this message
hafsa (sebbah.hafsa) said :
#3

hi Bruno ,
thank you for answer me , i changed the script like you advise me to :

#saving parameters of spheres in file
def myaddData():
   for b in O.bodies:
      idt,rad=b.id,b.shape.radius
      x,y,z=b.state.pos[0],b.state.pos[1],b.state.pos[2]
      veloc,force=b.vel[2],O.forces.f(b.id)
   fil.write("{:e} {:e} {:e} {:e} {:e} {:e} {:e}\n".format(idt,x,y,z,veloc,rad,force)) # ( .format = % )

but still have problem on radius :

AttributeError Traceback (most recent call last)
/usr/bin/yade in <module>()

/usr/bin/yade in myaddData()
     43 def myaddData():
     44 for b in O.bodies:
---> 45 idt,rad=b.id,b.shape.radius
     46 x,y,z=b.state.pos[0],b.state.pos[1],b.state.pos[2]
     47 veloc,force=b.vel[2],O.forces.f(b.id)

AttributeError: 'Facet' object has no attribute 'radius'

and in wpapper.Record () :

  File "save.py", line 51, in <module>
    yade.wrapper.Recorder(addIternNum=True,file=fil)
AttributeError: No such attribute: addIternNum.
[[ ^L clears screen, ^U kills line. F12 controller, F11 3d view (use h-key for showing help), F10 both, F9 generator, F8 plot. ]]

Thanks in advance.

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

O.bodies contains all bodies, including any walls (Facet) you might have appended. I guess walls don't have radii :-)

You can use a check like this:

def myaddData():
   for b in O.bodies:
      if not isinstance(b.shape,sphere): continue
      idt,rad=b.id,b.shape.radius
      x,y,z=b.state.pos[0],b.state.pos[1],b.state.pos[2]
      veloc,force=b.vel[2],O.forces.f(b.id)
      fil.write("{:e} {:e} {:e} {:e} {:e} {:e} {:e}\n".format(idt,x,y,z,veloc,rad,force)) # ( .format = % )

>> yade.wrapper.Recorder(addIternNum=True,file=fil)

Recorder is a separate engine in Yade [1], one that appears to have very little documentation associated with it. I've never used it, I use VTKRecorder for this type of data collection [2].

[1]https://yade-dev.gitlab.io/trunk/yade.wrapper.html#yade.wrapper.Recorder
[2]https://yade-dev.gitlab.io/trunk/user.html#saving-data-during-the-simulation

Revision history for this message
hafsa (sebbah.hafsa) said :
#5

hi Robert ,
thank you for answer me , i changed O.bodies like you said and it's work so thank you a obtain file (vibration.txt) contains properties
but the problem that ( id ) start with 192 not by zero . and i used VTKRecorder but i don't know how to add this properties .
Any idea ?

Thanks in advance.

there's my code :
from yade import pack,plot,export,wrapper

#material of cylinder
Mat1 = O.materials.append(ViscElMat(kn=10.0e4,ks=10.0e4,frictionAngle=0.455,density=2650.0))

# create Cylinder
Cylinder=O.bodies.append(geom.facetCylinder((0,0,1.5),2.0,height=3.0,wallMask=6,segmentsNumber=64,material=Mat1))

# create sphere packing
sp=pack.SpherePack()
sp.makeCloud((-1.2,-1.2,1.5),(1.2,1.2,8.0),rMean=.2,rRelFuzz=.1,num=128)
sp.toSimulation(color=(0,1,0))

O.engines=[
    ForceResetter(),
    InsertionSortCollider([Bo1_Sphere_Aabb(),Bo1_Facet_Aabb()]),
    InteractionLoop(

        [Ig2_Sphere_Sphere_ScGeom(),Ig2_Facet_Sphere_ScGeom()],
        [Ip2_FrictMat_FrictMat_FrictPhys()],
        [Law2_ScGeom_FrictPhys_CundallStrack()]
    ),
    NewtonIntegrator(gravity=(0,0,-9.81),damping=0.3),
    HarmonicMotionEngine(A=[0,0,0.5], f=[0,0,1.0], fi = [0.0,0.0,pi],ids =Cylinder),# vertical vibration
    # HarmonicMotionEngine(A = (0,0.002,0),f = (0,50,0),fi = (0,-0.5*math.pi,0),ids =Cylinder), horizontal vibration
    PyRunner(command='myaddData()',realPeriod=1,initRun=True), #call def fonction every second
    VTKRecorder(iterPeriod=100,recorders=['myaddData()'],fileName='vibrations.txt-') # add iteration number to basename
 ]

O.dt=utils.PWaveTimeStep() #to slow down the motion O.dt=.9*PWaveTimeStep()
O.resetTime()

# open file
fil=open("vibrations.txt.bz","a+")
fil.write ('id \t x \t y \t z \t velocity \t radius \t force \n')

#saving parameters of spheres in file
def myaddData():
   for b in O.bodies:
      if isinstance(b.shape,Sphere):
         number,rad=b.id,b.shape.radius
         x,y,z=b.state.pos[0],b.state.pos[1],b.state.pos[2]
         veloc,force=b.state.vel[2],O.forces.f(b.id)
         fil.write("{:d}\t{:.3g}\t{:.3g}\t{:.3g}\t{:.3g}\t{:.3g}\t{}\n".format(number,x,y,z,veloc,rad,force)) # ( .format = % )

O.saveTmp()
.

Revision history for this message
Jan Stránský (honzik) said :
#6

> ( id ) start with 192 not by zero
> Cylinder=O.bodies.append(geom.facetCylinder(...

because the first 192 bodies are facets created by the facetCylinder command.
cheers
Jan

Revision history for this message
hafsa (sebbah.hafsa) said :
#7

thank Jan my problem is solved
for the person who wont saved properties of spheres in cylinder there's my code :

from yade import pack,plot,export,wrapper

#material of cylinder
Mat1 = O.materials.append(ViscElMat(kn=10.0e4,ks=10.0e4,frictionAngle=0.455,density=2650.0))

# create sphere packing
sp=pack.SpherePack()
sp.makeCloud((-1.2,-1.2,1.5),(1.2,1.2,8.0),rMean=.2,rRelFuzz=.1,num=128)
sp.toSimulation(color=(0,1,0))

# create Cylinder
Cylinder=O.bodies.append(geom.facetCylinder((0,0,1.5),2.0,height=3.0,wallMask=6,segmentsNumber=64,material=Mat1))

#time of simulation
O.stopAtIter=5000

# interactions
O.engines=[
    ForceResetter(),
    InsertionSortCollider([Bo1_Sphere_Aabb(),Bo1_Facet_Aabb()]),
    InteractionLoop(

        [Ig2_Sphere_Sphere_ScGeom(),Ig2_Facet_Sphere_ScGeom()],
        [Ip2_FrictMat_FrictMat_FrictPhys()],
        [Law2_ScGeom_FrictPhys_CundallStrack()]
    ),
    NewtonIntegrator(gravity=(0,0,-9.81),damping=0.3),
    HarmonicMotionEngine(A=[0,0,0.5], f=[0,0,1.0], fi = [0.0,0.0,0.0],ids =Cylinder),# vertical vibration
    # HarmonicMotionEngine(A = (0,0.002,0),f = (0,50,0),fi = (0,-0.5*math.pi,0),ids =Cylinder), horizontal vibration
    PyRunner(command='myaddData()',iterPeriod=100,initRun=True), #call def fonction
 ]

O.dt=utils.PWaveTimeStep() #to slow down the motion O.dt=.9*PWaveTimeStep()
O.resetTime()

#saving parameters of spheres in file
def myaddData():
   if (O.iter%8==0):
      # open file
      fil=open("vibs_."+str(O.iter),"a+")
      fil.write ('id \t x \t y \t z \t vz \t radius \t force \n')
      for b in O.bodies:
         if (type(b.shape)==Sphere):
            number,rad=b.id,b.shape.radius
            x,y,z=b.state.pos[0],b.state.pos[1],b.state.pos[2]
            veloc,force=b.state.vel[2],O.forces.f(b.id)
            fil.write("{:d}\t{:.3g}\t{:.3g}\t{:.3g}\t{:.3g}\t{:.3g}\t{}\n".format(number,x,y,z,veloc,rad,force)) # ( .format = % )

O.saveTmp()

Revision history for this message
hafsa (sebbah.hafsa) said :
#8

thank you Jan