error in applying constant displacement using state.vel.

Asked by Othman Sh

Hi all,

I'm trying to compress a cloud of spheres in a cylinder to a specific porosity. First I create the cloud in a cylinder shape, then I create a cylinder facet around the spheres. Then I create top and bottom disks to compress the spheres. The problem is that when I try to move the disks with constant velocity using state.vel = (x,y,z), I get this error: AttributeError: 'list' object has no attribute 'state'. My code is copied below. Please let me know if anyone can solve this issue.

Thanks
Othman

----------------------------------------------------------------
from yade import pack

# material parameters

O.materials.append(FrictMat(young = 5e10, poisson = 0.15,frictionAngle = atan(.2), density=1920))

# Spheres

sp=pack.SpherePack()
sp.makeCloud((0,0,0),(.6,.6,.7),rMean=.009,rRelFuzz=.2,periodic=True)
##### cylinder extraction #####
pred=pack.inCylinder((.2,.2,0),(.2,.2,.6),.15)
spheres=filterSpherePack(pred,sp,Material=Material, returnSpherePack=True)
spheres.toSimulation()
yade.qt.View()

# facets to apply confinement

facets=geom.facetCylinder((.2,.2,.3),.15,.6,segmentsNumber=50,wallMask=4)
O.bodies.append(facets)

#creating disks to apply compression

d1=geom.facetCylinder((.2,.2,.6),.145,0,segmentsNumber=50,wallMask=1)
d2=geom.facetCylinder((.2,.2,0),.145,0,segmentsNumber=50,wallMask=1)
disk1= O.bodies.append(d1)
disk2= O.bodies.append(d2)

disk1.state.vel=(0,0,10)
disk2.state.vel=(0,0,-10)

############################ Engine #############################
O.dt=.5*utils.PWaveTimeStep()

O.engines=[
 ForceResetter(),
 InsertionSortCollider([
  Bo1_Sphere_Aabb(aabbEnlargeFactor=enlargeFactor,label='bo1s'),
  Bo1_Facet_Aabb()
 ]),
 InteractionLoop(
  [
   Ig2_Sphere_Sphere_ScGeom(interactionDetectionFactor=enlargeFactor,label='ss2d3dg'),
   Ig2_Facet_Sphere_ScGeom(),
  ],
  [

   Ip2_FrictMat_FrictMat_FrictPhys(),
   Ip2_FrictMat_FrictMat_FrictPhys(),
  ],
  [

   Law2_ScGeom_FrictPhys_CundallStrack(),
  ],
 ),

 NewtonIntegrator(damping=.3),

 PyRunner(command='P()',iterPeriod=500)
]

def P():
   print ('porosity = ', utils.porosity())

Question information

Language:
English Edit question
Status:
Solved
For:
Yade Edit question
Assignee:
No assignee Edit question
Solved by:
Othman Sh
Solved:
Last query:
Last reply:
Revision history for this message
Jérôme Duriez (jduriez) said :
#1

Hi,

The error says it all: the you're asking in "disk*.state.vel=something" to access (and modify) the state.vel of list objects, and not Body objects. Yade Body objects do have a state.vel, (Python) lists do not.

Your disk1, disk2 indeed are lists of bodies ids, because your top and bottom disks are composed of many facet bodies.

You need to touch (for state.vel modifications) the bodies themselves, not their (list of) ids.
General method is:

body = O.bodies[id] # this is a body when id is an integer
body.state.vel = (0,0,1) # this will then be possible

Not that I do not think you really need top and bottom *disks*. You could use as well a single Box/Wall/... body, even though it will match less nicely the cylinder shape of your sample.

Jérôme

Revision history for this message
Othman Sh (othman-sh) said :
#2

Thank you Jérôme,

I made the code as below and that solved my problem.

#creating disks

d1=geom.facetCylinder((.2,.2,.6),.145,0,segmentsNumber=50,wallMask=1)
d2=geom.facetCylinder((.2,.2,0),.145,0,segmentsNumber=50,wallMask=1)

disk1IDs= O.bodies.append(d1)
disk2IDs= O.bodies.append(d2)

for i in disk1IDs:
 body= O.bodies[i]
 body.state.vel = (0,0,-10)

for n in disk2IDs:
 body= O.bodies[n]
 body.state.vel = (0,0,10)