woo

Disappearing Spheres, clouds of clumps and compaction?

Asked by Simon Gibbon

I am looking to study the gentle compression by a membrane descending on a particle bed confined within a box – then look at effects of particle shape and particle size distrbution on the structures generated.

So first I am trying to understand how to replicate the gravity example from Yade.

Woo is so comprehensive that I am struggling to know where to start, connecting the tutorials with the full documentation is proving challenging.

I am looking for pointing in the right direction or an example I have missed or some other examples doing something similar.

A few of my current questions:
     Why do spheres disappear when I create a cloud of spheres inside 5 walls and apply gravity?
     How do I create a cloud of clumps?
     I assume then I can just settle a cloud of clumps as I am doing for spheres?

I include my journey so far below, if of interest.

Thanks, Simon

Starting from the Woo facet-facet.py example, I am able to create and settle a bed of spherical partiles under gravity, but particle disappear:
import woo
from woo.dem import *
from woo.fem import *
from woo.core import *
from random import random as rnd
from woo import pack

import woo.log, woo.utils
from minieigen import *
from math import *

mat=woo.utils.defaultMaterial()
S=woo.master.scene=Scene(
#Sphere sphere interactions included already, so add in wall interaction
 engines=DemField.minimalEngines(damping=.4)+[IntraForce([In2_Wall_ElastMat()])],
 fields=[DemField(
  gravity=(0,0,-10),
# loneMask=0, # no loneMask at all
 )],
)

#Create a box to contain the particles with 5 walls
S.dem.par.add([
 Wall.make(0,sense=1,axis=2,mat=mat),
 Wall.make(0,sense=1,axis=1,mat=mat),
 Wall.make(1,sense=1,axis=1,mat=mat),
 Wall.make(0,sense=1,axis=0,mat=mat),
 Wall.make(1,sense=1,axis=0,mat=mat)
])

# sphere packing is not equivalent to particles in simulation, it contains only the pure geometry
sp=pack.SpherePack()
# generate randomly spheres with uniform radius distribution
sp.makeCloud((0,0,0),(1,1,1),rMean=.04,rRelFuzz=.5)
# add the sphere pack to the simulation
sp.toSimulation(S)

S.dt=3e-4
S.saveTmp()
S.one()

This works to an extent, the particles fall under gravity, but particles appear to disappear during the simulation. Why am I loosing spheres?

But I can't work out who to add clumps rather than spheres.

However looking at some of the examples, then this will add clumps via a generator, but I don't get the settling and clumps are added all the time:
import woo
from woo.dem import *
from woo.fem import *
from woo.core import *
from random import random as rnd
from woo import pack

import woo.log, woo.utils
from minieigen import *
from math import *

mat=woo.utils.defaultMaterial()

generators=[
 PsdClumpGenerator(psdPts=[(.15,0),(.25,1.)],discrete=False,mass=True,
  clumps=[
                  SphereClumpGeom(centers=[(0,0,-.1),(0,0,-.05),(0,0,0),(0,0,.05),(0,0,.1)],radii=(.075,.075,.075,.075,.075),scaleProb=[(0,1.)]),
                  SphereClumpGeom(centers=[(.05,0,0) ,(0,.05,0) ,(0,0,.05)],radii=(.05,.05,.05),scaleProb=[(0,.5)]),
  ],
 ),
]

#Set up the scene to include wall interactions and inlet for the clumps
S=woo.master.scene=Scene(
      engines=woo.utils.defaultEngines(damping=.4,dynDtPeriod=10)+[IntraForce([In2_Wall_ElastMat()])]+[BoxInlet(box=((0,0,0),(1,1,1)),stepPeriod=100,maxMass=3e3,maxNum=-1,massRate=0,maxAttempts=100,attemptPar=50,atMaxAttempts=BoxInlet.maxAttWarn,generator=generators[i],materials=[mat]) for i in range(len(generators))],
 fields=[DemField(
  gravity=(0,0,-10),
            loneMask=0,
 )],
)

#Create a box to contain the particles with 5 walls
S.dem.par.add([
 Wall.make(0,sense=1,axis=2,mat=mat),
 Wall.make(0,sense=1,axis=1,mat=mat),
 Wall.make(1,sense=1,axis=1,mat=mat),
 Wall.make(0,sense=1,axis=0,mat=mat),
 Wall.make(1,sense=1,axis=0,mat=mat)
])

S.dt=3e-4
S.saveTmp()
S.one()

This is obviously not the right way to go, as I don't want particles being created during the simulation.

So looking at sphere packing, I have tried a lots of different approaches.
import woo
from woo.dem import *
from woo.fem import *
from woo.core import *
from random import random as rnd
from woo import pack

import woo.log, woo.utils
from minieigen import *
from math import *

mat=woo.utils.defaultMaterial()

S=woo.master.scene=Scene(
 engines=DemField.minimalEngines(damping=.4)+[IntraForce([In2_Wall_ElastMat()])]+[IntraForce([In2_Membrane_ElastMat(applyBary=True)])],
 fields=[DemField(
  gravity=(0,0,-10),
  loneMask=0, # no loneMask at all
 )],
)

S.dem.par.add([
 Wall.make(0,sense=1,axis=2,mat=mat),
 Wall.make(0,sense=1,axis=1,mat=mat),
 Wall.make(1,sense=1,axis=1,mat=mat),
 Wall.make(0,sense=1,axis=0,mat=mat),
 Wall.make(1,sense=1,axis=0,mat=mat)
])

#sp=pack.SpherePack(shapepack=SphereClumpGeom(centers=[(0,0,-.1),(0,0,-.05),(0,0,0),(0,0,.05),(0,0,.1)],radii=(.075,.075,.075,.075,.075),scaleProb=[(0,1.)]))
#sp=pack.ShapePack()
sp=pack.SpherePack()
sp.add(SphereClumpGeom(centers=[(0,0,-.1),(0,0,-.05),(0,0,0),(0,0,.05),(0,0,.1)],radii=(.075,.075,.075,.075,.075)))
#sp.add(SphereClumpGeom(centers=[(0,0,-.1),(0,0,-.05),(0,0,0),(0,0,.05),(0,0,.1)],radii=(.075,.075,.075,.075,.075)))
#clump=SphereClumpGeom(centers=[(0,0,-.1),(0,0,-.05),(0,0,0),(0,0,.05),(0,0,.1)],radii=(.075,.075,.075,.075,.075))
#addClumped(
#clumps=[
# SphereClumpGeom(centers=[(0,0,-.1),(0,0,-.05),(0,0,0),(0,0,.05),(0,0,.1)],radii=(.075,.075,.075,.075,.075),scaleProb=[(0,1.)]),
# SphereClumpGeom(centers=[(.05,0,0) ,(0,.05,0) ,(0,0,.05)],radii=(.05,.05,.05),scaleProb=[(0,.5)]))
 # ]
# generate randomly spheres with uniform radius distribution
#sp.add([clumps])

sp.makeCloud((0,0,0),(1,1,1),rMean=.04,rRelFuzz=.5)
# add the sphere pack to the simulation
sp.toSimulation(S)

S.dt=3e-4
S.saveTmp()
S.one()

Starting from psd-clump.py then:
from woo.core import *
from woo.dem import *
from minieigen import *

import woo.log
S=woo.master.scene=woo.core.Scene(fields=[DemField(gravity=(0,0,-9.81))])

S.engines=[
 InsertionSortCollider([Bo1_Sphere_Aabb()]),
 BoxInlet(
  box=((0,0,0),(1,1,1)),
  maxMass=-1,maxNum=-1,massRate=0,maxAttempts=50,attemptPar=50,atMaxAttempts=BoxInlet.maxAttWarn,
  generator=PsdClumpGenerator(
   psdPts=[(.1,0),(.2,1.)],discrete=False,mass=True,
   clumps=[
    SphereClumpGeom(centers=[(0,0,-.1),(0,0,-.05),(0,0,0),(0,0,.05),(0,0,.1)],radii=(.075,.075,.075,.075,.075),scaleProb=[(0,1.)]),
    SphereClumpGeom(centers=[(.05,0,0) ,(0,.05,0) ,(0,0,.05)],radii=(.05,.05,.05),scaleProb=[(0,.5)]),
   ],
  ),
  materials=[woo.dem.ElastMat(density=1)]
 ),
      Leapfrog(reset=True)
]

S.one()
#S.engines[1]=DemField.minimalEngines(damping=.4)
S.dem.nodes

from woo import pack
sp=pack.SpherePack()
sp.fromSimulation(S)

Once again ok for adding clumps but doesn't stop adding and doesn't settle.

So play with it a bit more, but now crashes Woo entirely:
from woo.core import *
from woo.dem import *
from minieigen import *
from woo import utils,pack
#
import woo.log
mat=utils.defaultMaterial()
S=woo.master.scene=woo.core.Scene(fields=[DemField(gravity=(0,0,-9.81))])
S.dem.par.add([utils.wall(1,axis=2,sense=0,mat=mat,glAB=((-10,-1),(20,11))),])
sp=pack.SpherePack()
# generate randomly spheres with uniform radius distribution
sp.makeCloud((0,0,0),(1,1,1),rMean=.04,rRelFuzz=.5)
# add the sphere pack to the simulation
sp.toSimulation(S)

S.engines=[
# ForceResetter(),
   Leapfrog(reset=True,damping=.1),
   InsertionSortCollider([Bo1_Sphere_Aabb(),Bo1_Facet_Aabb()]),
   ContactLoop([Cg2_Sphere_Sphere_L6Geom(),Cg2_Facet_Sphere_L6Geom()],[Cp2_FrictMat_FrictPhys()],[Law2_L6Geom_FrictPhys_IdealElPl()],applyForces=False), # forces are applied in IntraForce
]

S.engines=[
 InsertionSortCollider([Bo1_Sphere_Aabb()]),
 BoxInlet(
  box=((0,0,0),(1,1,1)),
  maxMass=-1,maxNum=-1,massRate=0,maxAttempts=50,attemptPar=50,atMaxAttempts=BoxInlet.maxAttWarn,
  generator=PsdClumpGenerator(
   psdPts=[(.1,0),(.2,1.)],discrete=False,mass=True,
   clumps=[
    SphereClumpGeom(centers=[(0,0,-.1),(0,0,-.05),(0,0,0),(0,0,.05),(0,0,.1)],radii=(.075,.075,.075,.075,.075),scaleProb=[(0,1.)]),
    SphereClumpGeom(centers=[(.05,0,0) ,(0,.05,0) ,(0,0,.05)],radii=(.05,.05,.05),scaleProb=[(0,.5)]),
   ],
  ),
  materials=[woo.dem.ElastMat(density=1)]
 ),
      Leapfrog(reset=True)
]

S.one()

#S.engines[1]=DemField.minimalEngines(damping=.4)
S.dem.nodes

from woo import pack
sp=pack.SpherePack()
sp.fromSimulation(S)

So as you can see I am not quite sure where to go from here.

Question information

Language:
English Edit question
Status:
Solved
For:
woo Edit question
Assignee:
No assignee Edit question
Solved by:
Václav Šmilauer
Solved:
Last query:
Last reply:
Revision history for this message
Václav Šmilauer (eudoxos) said :
#1

Hi Simon, I will check your problem tonight or over the weekend, stay tuned. If I understand correctly, the first task is to have gravity deposition of particles (generated in some way) which stabilizes, right?

Revision history for this message
Best Václav Šmilauer (eudoxos) said :
#2

Hi, I looked a bit a will comment on issues I find:

1. in all the scripts, you set all walls with sense=1. The doc http://woodem.eu/doc/woo.dem.html#woo.dem.Wall.sense explains (tersely) . Which means that even walls at y=+1 and x=+1 will push any touching particles outside (to the + sense), which makes them effectively disappear (the initial overlap is huge, and they are shot away); so make those sense=-1 and it will work. Or, just leave sense out, the wall will interact both ways. It is useful when the overlaps are big and there is the danger of the particle getting through, and being shot away.

2. In the second script, the same thing with Wall.sense applies. Additionally, the generator will keep making new particles as soon as it manages to place them. The solution is to say nDo=1 (http://woodem.eu/doc/woo.core.html#woo.core.PeriodicEngine.nDo), in that case the inlet will run just once and never more.

Maybe look at the script in http://woodem.eu/doc/tutorial/inlets.html#spatial-bias -- that also explains about clumps.

In general, the woo.pack.SpherePack interface is somewhat obsolete, the inlet & generator approach is much more flexible; plus I'd like to add some convenience function to generate packing at once (a la SpherePack.makeCloud). That leads me to the 3rd script with clumps:

3. ShapePack is only meant to keep fixed arrangement of particles, not to generate them. For that, use again inlet & the appropriate generator, like you did in the 2nd script.

4. the script based on psd-clumps.py cloud be again fixed with nDo=1; don't specify engines one-by-one (collider, integrator etc), use DemField.minimalEngines(...), that way you are less likely to mess things up -- in this script, for instance, there is will be no collision taking place (missing ContactLoop in engines).

 I must have removed psd-clumps.py already, can't find it here.

5. The same as before, use DemField.minimalEngines, it will do the right thing. You probably got the error

  RuntimeError: InsertionSortCollider: No bound was created for #0, provide a Bo1_*_Aabb functor for it.

which can be fixed by adding Bo1_Wall() to InsertionSortCollider args (next to Bo1_Sphere_Aabb()).

As a note, you don't have to set S.dt in woo, just leave the default (NaN) and it shoul dcorrectly set both the initial timestep as well as (if you use DemField.minimalEngines) adjust timestep during the simulation according to what is happening.

Next time, don't hesistate to ask right away instead of frustrating experimentation (like the script with clumps). It is also useful for me, because I know what the docs need.

Cheers!

Václav

Revision history for this message
Simon Gibbon (simon-gibbon) said :
#3

Vaclav,

Thanks very much for your really helpful comments, and encouragement to ask earlier much appreciated, I sort of have been frustrated, but also not as I have been learning on the way and getting a far better idea of the full potential of what Woo can do.

I now need to have a work through with your suggestions and probably read the documentation (RTFM) a bit more thoroughly to get my head around the way the different engines work. I will post my progress.

In the past I have used a program called MacroPac for particle packing which was effectively point and click, however also really frustrating that you couldn't play with the physics inside it, stating the potentially obvious the beauty of Woo is that it opens the whole process up so I should be able to do far more physically realistic things, obviously with great power comes the ability to mess things up.

Best wishes, Simon

Revision history for this message
Simon Gibbon (simon-gibbon) said :
#4

Thanks Václav Šmilauer, that solved my question.