How to clump spheres and facet

Asked by Wenbin Fei

I'd like to
Step1. import a CT scanned surface to Yade as a facet
Step2. create spheres inside this surface.
Step3. clump this surface (facet) and interior spheres together to imitate the real CT scanned particle.

The outer surface (facet) is important to me because I need an accurate geometry and transfer it to finite element software.
this idea is from the PFC documents, the outer surface in PFC does not involve in the collision.
I set the argument "noBound=True" when generateing the facet. However, the facet still collides with interior spheres.

The evidence of collision between outersurface and interior spheres are:
1. the wires on the outer surface are shining.
2. if the outersurface is igorned in the clump by modifing scripts as below, the clump of shperes drop quite faster.

 #O1=O.bodies.append(pack.gtsSurface2Facets(surf,fixed=False,noBound=True,material=m))
 sp=pack.randomDensePack(pack.inGtsSurface(surf),radius=0.1,memoizeDb=memoizeDb,returnSpherePack=True)
 Otemp=sp.toSimulation()
 #O3=O1+Otemp
 O3=Otemp

BTW, create a template and use replaceByClumps() is also my expectation.

Looking forward to any suggestion.
Wenbin
#############Script##################
# modified script yade/examples/gts-horse/horse.py
from yade import pack,ymport
#import gts
m = PolyhedraMat()
m.density = 2600 #kg/m^3
m.young = 1E6 #Pa
m.poisson = 20000/1E6
m.frictionAngle = 0.6 #rad

# create rectangular box from facets
O.bodies.append(geom.facetBox((-77.,-75.,-62.),(1.0,1.,1.),wallMask=31))

# parameters for radom packing in imported surface
memoizeDb='/tmp/gts-triax-packings.sqlite'
sp=SpherePack()
# import surface
surf=gts.read(open('OS-single.gts'))

# generate lists of spheres and outer surface
if surf.is_closed():
 O1=O.bodies.append(pack.gtsSurface2Facets(surf,fixed=False,noBound=True,material=m))
 sp=pack.randomDensePack(pack.inGtsSurface(surf),radius=0.1,memoizeDb=memoizeDb,returnSpherePack=True)
 Otemp=sp.toSimulation()
 O3=O1+Otemp
 #O3=Otemp

#clump spheres and surface together
idClump=O.bodies.clump(O3)

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,0,-9.81),damping=0.4),
    ## save data for Paraview
   #VTKRecorder(fileName='3d-vtk-',recorders=['all'],iterPeriod=5),

    # call the checkUnbalanced function (defined below) every 2 seconds
   PyRunner(command='checkUnbalanced()',realPeriod=2),
 #PyRunner(iterPeriod=10,command='addPlotData()')
 #PyRunner(realPeriod=100,command='finish()')
]

O.dt=.4*PWaveTimeStep()

# enable energy tracking; any simulation parts supporting it
# can create and update arbitrary energy types, which can be
# accessed as O.energy['energyName'] subsequently
O.trackEnergy=True

# if the unbalanced forces goes below .05, the packing
# is considered stabilized, therefore we stop collected
# data history and stop
def checkUnbalanced():
   if unbalancedForce()<.05:
      O.pause()
      plot.saveDataTxt('bbb.txt.bz2')
      # plot.saveGnuplot('bbb') is also possible

O.saveTmp()
O.timingEnabled=True
O.trackEnergy=True
from yade import plot
plot.plots={'i':('total',O.energy.keys,)}
# def addPlotData(): plot.addData(i=O.iter,total=O.energy.total(),**O.energy)
# plot.plot(subPlots=False)

# this function is called when the simulation is finished
def finish():
   # snapshot is label of qt.SnapshotEngine
   # the 'snapshots' attribute contains list of all saved files
   makeVideo(snapshot.snapshots,'3d.mpeg',fps=1,bps=100)
   O.pause()

from yade import qt
qt.View()

Question information

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

Hello Wenbin,

> However, the facet still collides with interior spheres.

How do you know this? I have tried your script but could not find evidence, visually or computationally..

cheers
Jan

Revision history for this message
Wenbin Fei (brian-fei) said :
#2

Hi Jan,

Thanks for your prompt reply.

I think the evidence of collision between outer surface and interior spheres are:
1. the wires on the outer surface are shining.
2. if the outer surface is ignored in the clump by modifying scripts as below, the clump of spheres drop quite faster.

 #O1=O.bodies.append(pack.gtsSurface2Facets(surf,fixed=False,noBound=True,material=m))
 sp=pack.randomDensePack(pack.inGtsSurface(surf),radius=0.1,memoizeDb=memoizeDb,returnSpherePack=True)
 Otemp=sp.toSimulation()
 #O3=O1+Otemp
 O3=Otemp

Regards

Wenbin

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

Hi Wenbin,

> 1. the wires on the outer surface are shining.

please be more specific how you get this visualization..

> 2. if the outer surface is ignored in the clump by modifying scripts as below, the clump of spheres drop quite faster.

sorry, I cannot reproduce this.. in both cases it takes roughly 1500 iterations to fall to the bottom..

cheers
Jan

Revision history for this message
Wenbin Fei (brian-fei) said :
#4

HI Jan

I upload the scripts and a word file of explanation in google drive. the link is

https://drive.google.com/open?id=165UJERs6-h3uCxBNV8hYDmBIEVkCcckc

> 1. the wires on the outer surface are shining (clump-with-surface).
In the case of clump with surface, you can see the colours of the wires are changing when the clump drop.

> 2. In the folder of "clump-without-sruface", I just changed the scripts as below:

 #O1=O.bodies.append(pack.gtsSurface2Facets(surf,fixed=False,noBound=True,material=m))
 sp=pack.randomDensePack(pack.inGtsSurface(surf),radius=0.1,memoizeDb=memoizeDb,returnSpherePack=True)
 Otemp=sp.toSimulation()
 #O3=O1+Otemp
 O3=Otemp

The computational time is quite shorter (drop faster) than the previous one. I think the reason why the clump with surface drops slower in the previous case because collision between the outer surface and spheres exists even though I assign “noBound=True” when generate the facet.

Many thanks
Wenbin

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

> 1. the wires on the outer surface are shining (clump-with-surface).
> In the case of clump with surface, you can see the colours of the wires are changing when the clump drop.

the wires are just triangles forming the facets, no interactions. They are changing colors because the wires with different colors occupy same edges and randomly is visible one or the other

> The computational time is quite shorter

yes, but the reason is that the facets are not clumped and they are not manipulated (like their pos and ori updated) during the clump motion

you can try to loop over interactions and test whether there are some interactions between spheres and the facets of the clump, something like (not tested):
###
def intCheck(): # to be e.g. with PyRunner
   n = 0
   for i in O.interactions:
      b1,b2 = [O.bodies[id] for id in (i.id1,i.id2)]
      if ( isinstance(b1.shape,Sphere) and isinstance(b2.shape,Facet) ) or ( isinstance(b1.shape,Facet) and isinstance(b2.shape,Sphere) ):
         if b1.id in O3 and b2.id in O3:
            n += 1
   print n
###

cheers
Jan

Revision history for this message
Wenbin Fei (brian-fei) said :
#6

Hi Jan,

I tested the interaction, the number n is always 0. Does that mean I clumped the facet with spheres together successfully?

My aim is to fill this kind of irregular particle (clump of facet and spheres) in a box following a certain grain size distribution.

I read the clumpTemplate but its structure can not allow me to adapt it to make the template of this irregular particle because I can not determine the relRadii.

Alternatively, makeClumpCloud is potentially feasible, but I have not found a way to include the facet.

Do you have any suggestion?

Best regards

Wenbin

Revision history for this message
Wenbin Fei (brian-fei) said :
#7

Hi Jan,

My script is as below when just considering the spheres.

#################
if surf.is_closed():
 #O1=O.bodies.append(pack.gtsSurface2Facets(surf,fixed=False,noBound=True,material=m))
 sp1=pack.randomDensePack(pack.inGtsSurface(surf),radius=0.1,memoizeDb=memoizeDb,returnSpherePack=True)

sp.makeClumpCloud((0,0,0),(20,20,20),[sp1],periodic=True,num=3)

sp.toSimulation()
###################

Thanks

Wenbin

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

> I tested the interaction, the number n is always 0. Does that mean I clumped the facet with spheres together successfully?

yes :-)

if the simulation is slowed down significantly using facets that are not actually used for the simulation, you can use current clump pos and ori to get position of facets as a postprocessing

I am not very familiar with makeClumpCloud and clump templates, maybe you can cerate a new question aimed on this..

Jan

Revision history for this message
Wenbin Fei (brian-fei) said :
#9

Hi Jan

Thanks for your time and kind help.

I will create a new question.

Wenbin