Generate a specific number of spheres in the empty spaces of a created loose pack

Asked by Pouyan

Hello,

I need to generate a specific number of small particles inside the empty spaces of a created loose pack with bigger spheres. The geometry of the loose pack was created in a separated file and it is loaded at the begging.

O.load('pip0.yade')

sp = pack.SpherePack()
sp.makeCloud((0,0,0),(0.01,0.01,0.01),rMean=.0001,num=100)
sp.toSimulation()

The problem is that small spheres are generated over existing particles and it results in a kinda explosion while there is enough empty space to embed new particles. I was wondering if you could help me to solve this problem.

Regards,
Amir

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

Hi Amir,
you have to add existing particles to SpherePack, otherwise it does not
know about other particles:

######################## script 1 - save simulation
from yade import pack
sp = pack.SpherePack()
sp.makeCloud((0,0,0),(10,10,10),1)
sp.toSimulation()
O.save('pip0.yade')
########################

######################## script 2 - loads simulation and correclty use
SperePack
from yade import pack
O.load('pip0.yade')
# adds all existing particles
sp = pack.SpherePack([(b.state.pos,b.shape.radius) for b in O.bodies])
print len(O.bodies)
sp.makeCloud((0,0,0),(10,10,10),0.1,num=100)
O.bodies.clear() # important !!, otherwise there will be existing particles
twice
sp.toSimulation()
print len(O.bodies)
########################

cheers
Jan

2016-11-27 1:23 GMT+01:00 amir <email address hidden>:

> New question #404417 on Yade:
> https://answers.launchpad.net/yade/+question/404417
>
> Hello,
>
> I need to generate a specific number of small particles inside the empty
> spaces of a created loose pack with bigger spheres. The geometry of the
> loose pack was created in a separated file and it is loaded at the begging.
>
> O.load('pip0.yade')
>
> sp = pack.SpherePack()
> sp.makeCloud((0,0,0),(0.01,0.01,0.01),rMean=.0001,num=100)
> sp.toSimulation()
>
> The problem is that small spheres are generated over existing particles
> and it results in a kinda explosion while there is enough empty space to
> embed new particles. I was wondering if you could help me to solve this
> problem.
>
> Regards,
> Amir
>
>
>
>
>
> --
> You received this question notification because your team yade-users is
> an answer contact for Yade.
>
> _______________________________________________
> Mailing list: https://launchpad.net/~yade-users
> Post to : <email address hidden>
> Unsubscribe : https://launchpad.net/~yade-users
> More help : https://help.launchpad.net/ListHelp
>

Revision history for this message
Pouyan (ppouyan) said :
#2

Thanks a lot Jan Stránský. I followed your guidance, except O.bodies.clear() because I need the existing particles. Unfortunately, part of the new particles are generated over the existing ones; so, explosion happens again. For more details, more than 10 000 particles can be generated just in empty spaces.

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

Hi Amir,
why exactly do you need existing particles? Particles form SpherePack are
created at exactly the same positions and with same radius..

A solution would be not to use sp.toSimulation, but something like
for c,r in sp:
   if cInOBodies(): # some function to determine if the position "c" is new
or is already in existing particles
      continue
   O.bodies.append(sphere(c,r))

​cheers
Jan

Revision history for this message
Pouyan (ppouyan) said :
#4

The SpherePack included bigger particles (2 mm) plays the role of filter in my simulation. Then, a layer of small particles (.2 mm) are created at the top of the filter layer and some downward forces, such as gravity and drag force, are applied on particles to induce them pass through the filter particles. In fact, it simulates an internal erosion. Having completed each time-step , the sample involves a new set of filter and small particles.
Now, I am developing a new algorithm. In this algorithm, porosity of the sample controlled by smaller particles need to be edited. Hence, exact number of small particles should be added randomly into the filter layer when less porosity in layer is required. So, I need to find a way to generate desired number of small particles in empty spaces of sample loaded from previous time-step.

for c,r in sp:
   if cInOBodies():

Could you explain more these two command lines because I could not find it in Yade document.

Thanks for your continued support,
Amir

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

Hi Amir,

Thanks for explanation, but I still don't understand why you need the
existing instances of particles, if particles with same radii and at same
positions are created right after the deletion.. therefore the situation is
exactly the same as before + some new smaller particles are added. Could
you please try to explain the reason (you need some history or state
variables to be preserved)?

the cInBodies function should be written by you :-) a veeeery inefficient
way could be:

def cInBodies(c):
   for b in O.bodies:
      if b.state.pos == c:
         return True
   return False

cheers
Jan

Revision history for this message
Pouyan (ppouyan) said :
#6

I don' t need the history. As you said, I just need old particles at the same position + some new smaller particles. But, when I use the following command lines, I see only new smaller particles and it removes all particles and facets loaded at the beginning.

from yade import pack, plot,ymport,export,geom,bodiesHandling
O.load('pip0.yade')

sp = pack.SpherePack([(b.state.pos,b.shape.radius) for b in O.bodies if b.id<40]) #'Facet' object has no attribute 'radius'
print len(O.bodies)

sp = pack.SpherePack()
sp.makeCloud((0,0,0),(0.01,0.01,0.01),rMean=r2,num=100)

O.bodies.clear()

sp.toSimulation()
print len(O.bodies)

Revision history for this message
Pouyan (ppouyan) said :
#7

MY problem is that the loaded particles are not created right after the deletion. I have prepared two simple scripts. If you run the second script, you will see that new particles fall down freely without effect of filter particles(seems there is no filter particles). I appreciate if you could take a look at the scripts.

######################## script 1 - save simulation
from yade import pack, plot,ymport,export,geom,bodiesHandling
r1 = .003/2.0
nf=40
sp = pack.SpherePack()
sp.makeCloud((0,0,0),(0.01,0.01,0.1),rMean=r1,num=nf)
sp.toSimulation()

O.bodies.append(utils.geom.facetBox((0.005,0.005,0.05),(0.005,0.005,0.05),wallMask=31))

O.engines=[
    ForceResetter(),
    InsertionSortCollider([Bo1_Sphere_Aabb(),Bo1_Facet_Aabb(),Bo1_Wall_Aabb()]),
    InteractionLoop(
 [Ig2_Sphere_Sphere_L3Geom(),Ig2_Facet_Sphere_L3Geom(),Ig2_Wall_Sphere_L3Geom()],
 [Ip2_FrictMat_FrictMat_FrictPhys()],
 [Law2_L3Geom_FrictPhys_ElPerfPl()]
    ),
    GravityEngine(gravity=(0,0,-9.81)),
    NewtonIntegrator(damping=.3),
    PyRunner(command='func()',iterPeriod=100,label='checker'),
    PyRunner(command='addPlotData()',iterPeriod=100)
]
O.dt=1*utils.PWaveTimeStep()

def func():
    if O.iter>20000:
        O.pause()
    O.save("pip0.yade")

def addPlotData():
    if O.iter<20000: return
    plot.addData(i=O.iter,unbalanced=utils.unbalancedForce(),**O.energy)
########################

######################## script 2 - loads simulation
from yade import pack, plot,ymport,export,geom,bodiesHandling
O.load('pip0.yade')
r2 = .001/2.0

sp = pack.SpherePack([(b.state.pos,b.shape.radius) for b in O.bodies if isinstance (b.shape,Sphere)])
print len(O.bodies)

sp = pack.SpherePack()
sp.makeCloud((0,0,0.0),(0.01,0.01,0.01),rMean=r2,num=10)

for b in O.bodies:
    if isinstance (b.shape,Sphere): O.bodies.erase(b.id)
#O.bodies.clear()

sp.toSimulation()
print len(O.bodies)

O.engines=[
    ForceResetter(),
    InsertionSortCollider([Bo1_Sphere_Aabb(),Bo1_Facet_Aabb(),Bo1_Wall_Aabb()]),
    InteractionLoop(
 [Ig2_Sphere_Sphere_L3Geom(),Ig2_Facet_Sphere_L3Geom(),Ig2_Wall_Sphere_L3Geom()],
 [Ip2_FrictMat_FrictMat_FrictPhys()],
 [Law2_L3Geom_FrictPhys_ElPerfPl()]
    ),
    GravityEngine(gravity=(0,0,-9.81)),
    NewtonIntegrator(damping=.3),
    PyRunner(command='func()',iterPeriod=100,label='checker'),
    PyRunner(command='addPlotData()',iterPeriod=100)
]

def func():
    if O.iter>200000:
        O.pause()

def addPlotData():
    plot.addData(i=O.iter,unbalanced=utils.unbalancedForce(),**O.energy)

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

Hi Amir,
thanks for the script, revealing the problem (which would be very difficult
without the scripts). The problem is in your 2nd script:

sp = pack.SpherePack([(b.state.pos,b.shape.radius) for b in O.bodies if
> isinstance (b.shape,Sphere)])
> print len(O.bodies)
> sp = pack.SpherePack() # TO BE DELETED, DO NOT CREATE NEW SpherePack !
> sp.makeCloud((0,0,0.0),(0.01,0.01,0.01),rMean=r2,num=10)

once you create sphere pack from existing particles (first "sp = ..."), do
not create another spherePack, since then sp variable is somathing
completely different and you would lose your particles (as you experience
now).

sp = SpherePack()
sp.fromSimulation() # a more elegant way instead
of pack.SpherePack([(b.state.pos,b.shape.radius) ...)
sp.makeCloud((0,0,0.0),(0.01,0.01,0.01),rMean=r2,num=10)
# ... delete existing spheres OR O.clear(); O.bodies.append(facetBox(...))
sp.toSimulation()

cheers
Jan

Revision history for this message
Pouyan (ppouyan) said :
#9

Thank you for all the support and concern.

Revision history for this message
Pouyan (ppouyan) said :
#10

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