# Generate a random packed bed of spherocylinders in a cylindrical column

167 views
reopened Dec 24, 2017
I want to generate a random packed bed of spherocylinders (capsules) in a cylindrical column.

How could I do this task with WooDEM?

Is it possible to get the particle positions at the end of the simulation in a text file in the form of their A and B coordinates (x,y,z coordinates of the cylinder initial and final points, which completely define the position, instead of using one point and three angles)?

answered Jun 24, 2017 by (45,230 points)

Hi,

you can use a script like this for what you need:

import woo, woo.core, woo.dem, woo.pack
# this returns geometry only via dynamic simulation
packed=woo.pack.randomDensePack2(
# define the geometyr (cylinder)
predicate=woo.pack.inCylinder((0,0,0),(0,0,2),1),
# define what particles go into the cylinder
)
# create new scene
S=woo.master.scene=woo.core.Scene(fields=[woo.dem.DemField()])
packed.toDem(S,S.dem,mat=woo.utils.defaultMaterial())
# print endpoint coordinates for all of them
for p in S.dem.par:
if not isinstance(p.shape,woo.dem.Capsule): continue
print(p.shape.endPt(0),p.shape.endPt(1))

Note however a few caveats:

1. You will need the latest version of woo from git (or wait for the package from woo-daily PPA) since I only wrapped Capsule::endPt in python now (the function existed before, by only in c++)
2. The dynamic simulation in randomDensePack2 is somewhat unreliable depending on what you do, and might involve some hand-tuning. On the top of that, I did some big fixes in the underlying PeriIsoCompressor engine lately... I am not sure what the result will be, as the input variation is too big.
3. The generated packing is not 100% overlap-free, which is in fact impossible (at least with dynamic methods). If you use the packing later, make sure you take the initial position as equilibrium, to avoid initial explosion.

If you only need loose packing, or want to run gravity deposition yourself, that is another topic, and the solution would be simpler (no secondary simulation involved, just generation and deposition):

import woo.core, woo.dem, woo.utils, math
from minieigen import *
woo.master.usesApi=10103
S=woo.master.scene=woo.core.Scene(
fields=[woo.dem.DemField(
gravity=(0,0,-10),
# add bottom and cylinder walls
)],
engines=woo.dem.DemField.minimalEngines()+[woo.dem.CylinderInlet(
stepPeriod=200,
height=2,
node=woo.core.Node((0,0,0),((0,1,0),-math.pi/2)),
massRate=0,
materials=[woo.utils.defaultMaterial()],
)
])
# run and stop manually when happy


The post-processing to save particle endpoints would be the same as in the former case.

HTH, Vaclav

commented Jul 12, 2017 by (140 points)
edited Jul 12, 2017

Thank you very much for your help.
The Python script works fine, but I need to add two features:

• I want monodisperse spherocylinders, not a PSD.
• I want to save particle positions in a simple text file as six Cartesian coordinates (x, y, z) per row (without using orientation angles): the first three are for point A, while the last three are for point B. In this way any spherocylinder is completely defined, once you know its radius in a monodisperse packing.
commented Jul 12, 2017 by (45,230 points)

Monodisperse is only a special type of PSD, so you assign step-wise function to the PSD, like psdPts=[(.2,0),(.2,1)] to have all of them .2, and shaftRadioRatio=(2.,2.) to have the elongation identical everywhere. The PSD diameter is volumetrically equivalent diameter (not diameter of the shaft), watch out for that.

As a code guru, writing the positions into file is surely trivial for you (untested, something like this:

with open('coords.txt','w') as out:
for p in S.dem.par:
if not isinstance(p.shape,woo.dem.Capsule): continue
a,b=p.shape.endPt(0),p.shape.endPt(1)
out.write('%g %g %g %g %g %g\n'%(a[0],a[1],a[2],b[0],b[1],b[2])
# with python3 arguably more elegant
# out.write('%g %g %g %g %g %g\n'%(*a,*b))
# or even save one line with
# out.write(6*'%g '%(*p.shape.endPt(0),*p.shape.endPt(1))+'\n')

commented Jul 22, 2017 by (140 points)

Sorry, but I am not a Python expert.
I am still unable to print the position of particles in a text file with your suggestions, probably because the simulation goes on and I have to wait until it stops.
I am not interested in seeing the simulation in a 3D graphical window, but I am interested in the text file with the position of particles.
Is it possible also to directly export the packed bed in VTK format, suitable to be opened in ParaView?

commented Jul 22, 2017 by (45,230 points)

Alright, guru, here you go. Save this as something, like aa.py. Then run woo aa.py, then wait a bit. It will open Paraview for you, and write coordinates. You can quit by pressing Ctrl-D from woo, or typing exit.

There is no way to export the packed bed in VTK format other than triangulated capsule surfaces; there is not capsule-shaped primitive in VTK.

import woo.core, woo.dem, woo.utils, math, woo.paraviewscript
from minieigen import *
woo.master.usesApi=10103
S=woo.master.scene=woo.core.Scene(
fields=[woo.dem.DemField(
gravity=(0,0,-10),
# add bottom and cylinder walls
)],
engines=woo.dem.DemField.minimalEngines(damping=.4)+[woo.dem.CylinderInlet(
stepPeriod=200,
height=2,
node=woo.core.Node((0,0,0),((0,1,0),-math.pi/2)),
massRate=0,
materials=[woo.utils.defaultMaterial()],
),
woo.core.PyRunner('ubf=woo.utils.unbalancedForce(S)\nprint(ubf)\nif ubf<.05 and S.step>1000: done(S)',400),
])

def done(S):
S.stop()
with open('capsules.txt','w') as out:
for p in S.dem.par:
if not isinstance(p.shape,woo.dem.Capsule): continue
a,b=p.shape.endPt(0),p.shape.endPt(1)
out.write('%g %g %g %g %g %g\n'%(a[0],a[1],a[2],b[0],b[1],b[2]))
vtk=woo.dem.VtkExport(out='capsules-')
vtk(S) # trigger manually writing Paraview data files
# write paraview script and run it
woo.paraviewscript.write('capsules.py',**woo.paraviewscript.kwFromVtkExport(vtk))
woo.paraviewscript.launchPV('capsules.py')

S.run()

commented Jul 27, 2017 by (140 points)
edited Dec 24, 2017

Thanks for your answer, but the generated packing is too loose for my needs. Could you suggest a strategy to obtain a denser packing?