Material of particle changed in the repeated cell

Asked by Leonard

Hi,

I'd like to ask that why the material of particle changed in the repeated cell. I have two types of particles (material 1 and 2, respectively) in a cell, and after I repeated the cell by using cellRepeat function, all the particles in the repeated cells are changed into material 2.

The MWE below may show my question. If you run the MWE, you will see that all the material Ids are 1, but I expect to have two types of materials.
##################
from yade import pack
O.periodic=True
#### define material, two materials are used for 2 type of particles
Mat1 = O.materials.append(FrictMat(young=2e6,poisson=0.3,frictionAngle=radians(30),label='mat1'))
Mat2 = O.materials.append(FrictMat(young=2e6,poisson=0.3,frictionAngle=radians(30),label='mat2'))
######## particles with Mat1
sp1=pack.SpherePack()
sp1.makeCloud((0,0,0),(5,5,5),rMean=.5,rRelFuzz=.5,periodic=True,num=5)
sp1.toSimulation(color=(0,0,1),material='mat1')
######## particles with Mat2
sp2=pack.SpherePack()
sp2.makeCloud((0,0,0),(5,5,5),rMean=.05,rRelFuzz=.0,periodic=True,num=5)
sp2.toSimulation(color=[1,0,0],material='mat2')
#### store all the ids of particles from sp1 and sp2, they will be deleted after repeat cell.
idIn1stCell=[]
for i in O.bodies:
 idIn1stCell.append(i.id)
## repeat cell
sp=pack.SpherePack()
sp.fromSimulation()
sp.cellRepeat((1, 3, 1))
sp.toSimulation(color=[1,1,1])
## remove the original particles in the 1st cell
for i in idIn1stCell:
 O.bodies.erase(i)
## print the material ids, I found that all the material ids are 1, but I expect to have two types of materials.
for i in O.bodies:
 print (i.material.id)
#######################

Thanks!
Leonard

Question information

Language:
English Edit question
Status:
Solved
For:
Yade Edit question
Assignee:
No assignee Edit question
Solved by:
Leonard
Solved:
Last query:
Last reply:
Revision history for this message
Karol Brzezinski (kbrzezinski) said :
#1

Hi Leonard,

sphere pack only stores information about sphere positions and radii (try to read sp1[0]). So, in my opinion, you can skip the part where you append sphere pecks to simulation and then you read this information back from simulation. I guess that you wanted* to achieve something like this:

######### SCRIPT 1
from yade import pack
O.periodic=True
#### define material, two materials are used for 2 type of particles
Mat1 = O.materials.append(FrictMat(young=2e6,poisson=0.3,frictionAngle=radians(30),label='mat1'))
Mat2 = O.materials.append(FrictMat(young=2e6,poisson=0.3,frictionAngle=radians(30),label='mat2'))
######## particles with Mat1
sp1=pack.SpherePack()
sp1.makeCloud((0,0,0),(5,5,5),rMean=.5,rRelFuzz=.5,periodic=True,num=5)
######## particles with Mat2
sp2=pack.SpherePack()
sp2.makeCloud((0,0,0),(5,5,5),rMean=.05,rRelFuzz=.0,periodic=True,num=5)
######## this is a good moment to add sphere packs to simulation
sp1.cellRepeat((1, 3, 1))
sp2.cellRepeat((1, 3, 1))
sp1.toSimulation(color=(0,0,1),material='mat1')
sp2.toSimulation(color=[1,0,0],material='mat2')

## print the material ids, I found that all the material ids are 1, but I expect to have two types of materials.
for i in O.bodies:
 print (i.material.id)
######## END OF SCRIPT 1

*I don't really think you wanted the above script. If you generate spheres in separate sphere packs, they do not see each other and may overlap. I think that better approach is to run makeCloud twice on one sphere pack, and then split to the separate sphere packs based on some condition (most likely radius size in your example). This approach do not work with cellRepeat command. But I think that you may just want to create longer cell at the beginning of the simulation.

######### SCRIPT 2
from yade import pack
O.periodic=True
#### define material, two materials are used for 2 type of particles
Mat1 = O.materials.append(FrictMat(young=2e6,poisson=0.3,frictionAngle=radians(30),label='mat1'))
Mat2 = O.materials.append(FrictMat(young=2e6,poisson=0.3,frictionAngle=radians(30),label='mat2'))
### prepare sphere pack
sp=pack.SpherePack()
sp.makeCloud((0,0,0),(5,15,5),rMean=.5,rRelFuzz=.5,periodic=True,num=15)# I changed dimensions of the cell. I increased number of spheres for better visualization.
sp.makeCloud((0,0,0),(5,15,5),rMean=.05,rRelFuzz=.0,periodic=True,num=500)# Now, spheres shouldn't overlap since they can see each other.
#### now split into two packs, eg. based on the radius
sp1=pack.SpherePack()
sp2=pack.SpherePack()
sp1.isPeriodic = True
sp2.isPeriodic = True
sp1.cellSize = (5,15,5)
sp1.cellSize = (5,15,5)
for s in sp:
 pos = s[0]
 r = s[1]
 if r>0.05:
  sp1.add(pos,r)
 else:
  sp2.add(pos,r)
######## this is a good moment to add sphere packs to simulation

sp1.toSimulation(color=(0,0,1),material='mat1')
sp2.toSimulation(color=[1,0,0],material='mat2')

## print the material ids, I found that all the material ids are 1, but I expect to have two types of materials.
for i in O.bodies:
 print (i.material.id)
######### END OF SCRIPT 2

Last, but not leas solution. Still, makeCloud twice on one spherePack. Add it to simulation, and just change properties of selected spheres.

######### SCRIPT 3
from yade import pack
O.periodic=True
#### define material, two materials are used for 2 type of particles
Mat1 = O.materials.append(FrictMat(young=2e6,poisson=0.3,frictionAngle=radians(30),label='mat1'))
Mat2 = O.materials.append(FrictMat(young=2e6,poisson=0.3,frictionAngle=radians(30),label='mat2'))
### prepare sphere pack
sp=pack.SpherePack()
sp.makeCloud((0,0,0),(5,5,5),rMean=.5,rRelFuzz=.5,periodic=True,num=15)# @Karol: I increased number of spheres for better visualization.
sp.makeCloud((0,0,0),(5,5,5),rMean=.05,rRelFuzz=.0,periodic=True,num=500)# Now, spheres shouldn't overlap since they can see each other.
######## this is a good moment to add sphere packs to simulation
sp.cellRepeat((1, 3, 1))
sp.toSimulation(color=[1,0,0],material='mat1')

# now change the material of spheres based of the shere size
for b in O.bodies:
 if isinstance(b.shape, Sphere):#just making sure I am dealing with spheres before asking for radius
  if b.shape.radius <= 0.05:
   b.material = O.materials[Mat2]
   b.shape.color=[0,0,1] # change color for better visualization.

## print the material ids, I found that all the material ids are 1, but I expect to have two types of materials.
for i in O.bodies:
 print (i.material.id)
######### END OF SCRIPT 3

Cheers,
Karol

Revision history for this message
Leonard (z2521899293) said :
#2

Hi karol,

Thanks for your reply and the very clear example codes. My question has been solved.

Cheers
Leonard