Problem creating clumps with existing spheres

Asked by Meng Qing Xiang

Hi everyone!

I'm trying to model concrete with clumps . I make a very simple test for creating clumps with existing spheres but it does not work. I get the error "IndexError: Body already has id 0 set; appending such body (for the second time) is not allowed.". The script is as follows:

from yade import pack,export,qt,ymport
#define material for all bodies:
id_Mat=O.materials.append(FrictMat(young=1e6,poisson=0.3,density=1000,frictionAngle=1))
Mat=O.materials[id_Mat]
O.bodies.append(sphere([0,0,0], material=Mat, radius=0.5))
O.bodies.append(sphere([1,0,0], material=Mat, radius=0.5))
O.bodies.append(sphere([0,1,0], material=Mat, radius=0.5))
O.bodies.append(sphere([1,1,0], material=Mat, radius=0.5))
listOfClumpMembers = []
for b in O.bodies:
  tpos=b.state.pos
  if tpos[0]<0.1:
    listOfClumpMembers.append(b)

O.bodies.appendClumped(listOfClumpMembers)

I have checked the related answers but I still cannot solve this problem.
Thanks in advance!!

Question information

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

Hi,

The appendClumped() function does two things from a list of bodies:

- it inserts in the simulation (O.bodies.append() ) the bodies you gave in the list
- it clumps these bodies

As such, it is not intended to be used with existing instances of bodies, such as you're doing here.
See the two following even more minimal examples (thank you very much for your short example though !)

***** DOES NOT WORK : similar to your script, and returning the same error*********
O.bodies.append(sphere([0,0,0], radius=0.5))
O.bodies.append(sphere([1,0,0], radius=0.5))
O.bodies.append(sphere([0,1,0], radius=0.5))

O.bodies.appendClumped([O.bodies[0],O.bodies[2]])
*********************************************************************

*********** WORKS !!! ***************
b0 = sphere([0,0,0], radius=0.5)
b1 = sphere([1,0,0], radius=0.5)
b2 = sphere([0,1,0], radius=0.5)

O.bodies.appendClumped([b0,b2])
*************************************

However, it is true these two examples are not equivalent since you end up with three bodies in the 1st case, and only two in the second (you may just add O.bodies.append(b1) to the second example, though)

The best for you is probably to use the O.bodies.clump() function

********* SOLUTION TO YOUR QUESTION ? ******
O.bodies.append(sphere([0,0,0], radius=0.5))
O.bodies.append(sphere([1,0,0], radius=0.5))
O.bodies.append(sphere([0,1,0], radius=0.5))

listOfFutureClumpMembersIds = []
for b in O.bodies:
  if b.state.pos[0]<0.1:
    listOfFutureClumpMembersIds.append(b.id)

O.bodies.clump(listOfFutureClumpMembersIds)
**************************************

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

With "existing instances of bodies" above, I meant "bodies instances already in your simulation, ie in O.bodies".

In the "WORKS !!!" example, b0, b1, b2 are obviously existing instances of bodies (but they do not immediately belong to your simulation).

Revision history for this message
Meng Qing Xiang (642229461-k) said :
#3

Thanks very much for your help. That really solve my problem.