can walls be excluded from particles cloud creation?

Asked by JOHN

Good evening,

Is there a way to create particles that cover as much of the free space as possible, but not have particles appear inside the walls?
I currently have this code

from yade.pack import *
from yade import ymport

rod1 = O.bodies.append(ymport.stl('file.stl'))

sp=pack.SpherePack()

sp.makeCloud((0,0,3),(20,20,15),rMean=0.5)
sp.toSimulation()

O.engines=[
   ForceResetter(),
   InsertionSortCollider([Bo1_Sphere_Aabb(),Bo1_Facet_Aabb()]),
   InteractionLoop(
      # handle sphere+sphere and facet+sphere collisions
      [Ig2_Sphere_Sphere_ScGeom(),Ig2_Facet_Sphere_ScGeom()],
      [Ip2_FrictMat_FrictMat_FrictPhys()],
      [Law2_ScGeom_FrictPhys_CundallStrack()]
   ),
   NewtonIntegrator(gravity=(0,-9.81,0),damping=0.4),
   # call the checkUnbalanced function (defined below) every 2 seconds

]
O.dt=.5*PWaveTimeStep()

but whenever i start the simulation a lot of particles end up inside the walls which both slows down the simulation and makes the visualization confusing

Thank you very much for your time,
Any help is appreciated as i am new in yade andprogramming in general
John

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 John,

> i am new in yade and programming in general

welcome :-)

According to your description, what you want should be easy to do. To give you the correct answer, please provide the file "file.stl" such that we can try it ourselves (launchpad questions does not allow attachments, so please place the file somewhere to the internet, e.g. dropbox, and send here the link).

cheers
Jan

Revision history for this message
Bruno Chareyre (bruno-chareyre) said :
#2

Hi John,
A question here is what is 'file.stl'.
If it comes from an analytical description of the shape, then this description could be used to filter some particles out.
If your question is "how to do that for a general stl" it is more involved, it will need to define what is inside and what is outside for an arbitrary collection of facets. I'm not even sure there is a general answer.

If you know how to define "inside" and "outside", then you can simply write
sp.makeCloud((0,0,3),(20,20,15),rMean=0.5)
for x,r in sp:
     if (is inside) sp.toSimulation()

Cheers
Bruno

Revision history for this message
JOHN (washingmachine) said :
#3

Hey, thanks for the quick response,

http://dropmefiles.com/EWLR0

this is the file i am interested in.
There is a reaaaaaaly roundabout way to define in and out and it takes a lot of time to compute. I was hoping for something clever and inbuilt :-) life is not always that easy though

Thanks for the swift answers. They are much appreciated

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

Hello,
thanks for the file. I have tried it, but did not met your description.. All particles are outside and after starting the simulation, the particles just fly parallel to the walls..
Could you please update the code to reproduce the problem with given stl file?
thanks
Jan

Revision history for this message
JOHN (washingmachine) said :
#5

Oops, i seem to have uploaded the wrong file,
http://dropmefiles.com/mR2NW

sorry about that,
If you use this you will see some particles outside and some inside

I didnt realise it until i saw them gathering in the very outer wall

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

Hi John,
try the following code. Also have a look at [1]. In case of any question or problem, let us know.
cheers
Jan

[1] https://answers.launchpad.net/yade/+question/406791

####
import gts
from yade.pack import *
from yade import ymport

facets = ymport.stl('maze.stl')
rod1 = O.bodies.append(facets)

# converts facets to gts (see the other question)
s = gts.Surface()
for facet in facets:
   vs = [facet.state.pos + facet.state.ori*v for v in facet.shape.vertices]
   vs = [gts.Vertex(v[0],v[1],v[2]) for v in vs]
   es = [gts.Edge(vs[i],vs[j]) for i,j in ((0,1),(1,2),(2,0))]
   f = gts.Face(es[0],es[1],es[2])
   s.add(f)
print s.is_closed()
threshold = 1e-3
s.cleanup(threshold)
print s.is_closed()
assert s.is_closed()

# use gts to filter spheres
pred = inGtsSurface(s)

O.engines=[
   ForceResetter(),
   InsertionSortCollider([Bo1_Sphere_Aabb(),Bo1_Facet_Aabb()]),
   InteractionLoop(
# handle sphere+sphere and facet+sphere collisions
      [Ig2_Sphere_Sphere_ScGeom(),Ig2_Facet_Sphere_ScGeom()],
      [Ip2_FrictMat_FrictMat_FrictPhys()],
      [Law2_ScGeom_FrictPhys_CundallStrack()]
   ),
   NewtonIntegrator(gravity=(0,-9.81,0),damping=0.4),
# call the checkUnbalanced function (defined below) every 2 seconds
]

sp=pack.SpherePack()
sp.makeCloud((0,0,3),(20,20,15),rMean=0.5)

# remove spheres completely inside walls
for c,r in sp:
   if pred(c,0):
      continue
   O.bodies.append(sphere(c,r))

# remove spheres partially inside walls
O.dt = 0
O.step() # interactions are created afterwards
toErase = set()
for i in O.interactions:
   b1,b2 = [O.bodies[i] for i in (i.id1,i.id2)]
   if any(isinstance(b.shape,Facet) for b in (b1,b2)): # if facet is involved, delete
      toErase.add(b1)
      toErase.add(b2)
toErase = [b for b in toErase if isinstance(b.shape,Sphere)] # delete just spheres
for b in toErase: # delete the spheres
   O.bodies.erase(b.id)

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

Revision history for this message
JOHN (washingmachine) said :
#7

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

Revision history for this message
JOHN (washingmachine) said :
#8

Thank you!!!!
Amazing responses

Revision history for this message
Bruno Chareyre (bruno-chareyre) said :
#9

For future reference, the correct code in #2 should read:
sp.makeCloud((0,0,3),(20,20,15),rMean=0.5)
for x,r in sp:
     if (is inside): O.bodies.append(sphere(x,r)) #<---- this one was wrong

@Jan, I was not expecting something like "inGtsSurface", very interesting.

B