How to generate particles in a cylinder given their mass distribution with size?

Asked by Hashir Ahmad

I have the total mass of the body and the particle distribution in the following manner:

Mass of particles(size: 2mm) = 40% of total
Mass of particles(size: 4mm) = rest

Given the specific density of the particle, I can calculate the mass of each particle. Now I have to append these particles to O.bodies using cylinder as a predicate such that they are randomly distributed in space. Please help!

Question information

Language:
English Edit question
Status:
Solved
For:
Yade Edit question
Assignee:
No assignee Edit question
Solved by:
Jan Stránský
Solved:
Last query:
Last reply:
Revision history for this message
Jan Stránský (honzik) said :
#1

Hello,
I see several options, based on your goal (about which I am not sure from your message). It also depends on the meaning of "randomly distributed in space" (especially desired density of resulting packing). To get better advises, please specify more your problem.

options for dense packing:
- create easily cubic packing:
   - either try to define cylinder such that after extracting it has desired mass
   - or extract cylinder with defined dimensions and mass whichever it has
   - or you can play with compression stage to get desired packing fraction such that both cylinder size and mass fits your requirements.

options for loose packing:
- define cylinder, place randomly particles to the cylinder until desired total mass is met

cheers
Jan

Revision history for this message
Hashir Ahmad (hash.ir) said :
#2

Thanks for this info.
I desire a dense packing in a cylinder predicate(whose volume I have) and I have to fill particles in such a way that some particles of size 2mm occupy some percentage of the mass and the rest of size 4mm occupy the remaining mass. How can I achieve this?

Should I use pack.SpherePack() or O.bodies.append(loop for particle generation) ?

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

> Should I use pack.SpherePack() or O.bodies.append(loop for particle generation) ?
Yes, both :-)
You can use the approach with TriaxialTest, but with importFilename argument:

##########
from yade import ymport
from yade import pack
txt = 'packing.txt'

# create initial packing
sp = SpherePack()
dim = 1.5e-1
minc,maxc = Vector3(0,0,0), dim*Vector3(1,1,1)
sp.makeCloud(minc,maxc,rMean=4e-3,num=500)
# change num in both cases to get desired mass ratio
sp.makeCloud(minc,maxc,rMean=2e-3,num=1000)
sp.toSimulation()
with open(txt,'w') as f:
   for b in O.bodies:
      x,y,z = b.state.pos
      r = b.shape.radius
      f.write("{} {} {} {}\n".format(x,y,z,r))

# TriaxialTest
O.reset()
test = TriaxialTest(importFilename=txt)
test.load()
O.run(1000,True)
# extract cylinder
mina,maxa = aabbExtrema()
d0 = max(mina)
d1 = min(maxa)
size = d1-d0
c = d0+.5*size
c0 = Vector3(c,c,d0)
c1 = Vector3(c,c,d1)
pred = pack.inCylinder(c0,c1,.4*size)
cyl = [b.id for b in O.bodies if isinstance(b.shape,Sphere) and pred(b.state.pos,b.shape.radius)]
with open(txt,'w') as f:
   f.write("#format_x_y_z_r\n")
   for i in cyl:
      b = O.bodies[i]
      x,y,z = b.state.pos
      r = b.shape.radius
      f.write("{} {} {} {}\n".format(x,y,z,r))

# load
O.reset()
sphs = ymport.text(txt)
O.bodies.append(sphs)
##########

cheers
Jan

[1] https://yade-dem.org/doc/yade.wrapper.html#yade.wrapper.TriaxialTest.importFilename
[2] https://yade-dem.org/doc/yade.pack.html#yade._packSpheres.SpherePack.makeCloud

Revision history for this message
Hashir Ahmad (hash.ir) said :
#4

Hello Jan

This code does the work for me. I want to ask some questions though.

1. When I change the 'rMean' and 'num' in makeCloud function, I am not able to see the desired output

e.g sp.makeCloud(minc, maxc, rMean=9.5e-3, num=400)
sp.makeCloud(minc, maxc, rMean=24.5e-3, num=600)

The result shows the particles of same size and their count is also very less.

Regards
Hashir

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

Hello,
take care of error and warnings. I got

WARN /build/yade-KKgSmd/yade-1.20.0/pkg/dem/SpherePack.cpp:211 makeCloud: Exceeded 1000 tries to insert non-overlapping sphere to packing. Only 231 spheres were added, although you requested 400.
WARN /build/yade-KKgSmd/yade-1.20.0/pkg/dem/SpherePack.cpp:211 makeCloud: Exceeded 1000 tries to insert non-overlapping sphere to packing. Only 0 spheres were added, although you requested 600.

i.e. if you want to use this number of particles of this size, you need bigger area to cover (defined by minc,maxc a therefore dim value). In your case, all volume is filled by the first makeCloud and there is no space left for the other makeCloud
I used dim=9e-1 with nice results.

cheers
Jan

Revision history for this message
Hashir Ahmad (hash.ir) said :
#6

Hey Jan,

Sorry I was busy last week and couldn't reply. You have provided just what I need. One thing though, the geometry keeps on changing when I run the code multiple times. I thought it has something to do with the Triaxial part, so I commented that portion. But then the code displays nothing on the 3D model. The rest of the code seems fine and is understandable.

Regards
Hashir

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

Hi Hashir,
the geometry is different each time, because makeCloud creates each time different initial positions. Use seed to make it each time the same
sp.makeCloud(..., seed=1) # [3] you can also use any nonzero integer
cheers
Jan

[3] https://yade-dem.org/doc/yade.pack.html#yade._packSpheres.SpherePack.makeCloud

Revision history for this message
Hashir Ahmad (hash.ir) said :
#8

Thanks Jan Stránský, that solved my question.

Revision history for this message
Karol Brzezinski (kbrzezinski) said :
#9