How to export and import a irregular shape particles model.

Asked by Kun Zeng

Hi all,

I am a new user of yade. I tried polyhedra particles falling down into a box. I am wondering how can I export this model after it finishes this falling process and how to import it and down the next simulation? For example, generate a beam on this aggregates.

I used this code and yade.export.textPolyhedra. I don't know whether it is right or not.

######################################################################
# INPUTS
######################################################################
gravity = 100

# box dimensions
widthl = .3
widthr = .3
widthc = .3
height = .3
thick = .5
deep = -.2

# size of grains
sizeMin = 40e-3
sizeMax = 60e-3

frictionAngle = .5
young = 1e8 # stiffness

dt = 1e-3 # time step

nGravityDeposition = 250 # how long to run initial gravity deposition
nCycles = 3 # how many jumps to run afterwards
nStepsBetweenCycles = 200 # number of time steps between jumps
dspl = 20e-3

# how much larger the initial make box should be
fillBoxHFactor = 3
######################################################################
from yade import polyhedra_utils, export

width = widthl+widthc+widthr

# mat, engines, ...
mat = PolyhedraMat(young=young,poisson=10,frictionAngle=frictionAngle)
O.materials.append(mat)
O.engines=[
   ForceResetter(),
   InsertionSortCollider([Bo1_Polyhedra_Aabb(),Bo1_Facet_Aabb()]),
   InteractionLoop(
      [Ig2_Polyhedra_Polyhedra_PolyhedraGeom(), Ig2_Facet_Polyhedra_PolyhedraGeom()],
      [Ip2_PolyhedraMat_PolyhedraMat_PolyhedraPhys()],
      [Law2_PolyhedraGeom_PolyhedraPhys_Volumetric()],
   ),
   NewtonIntegrator(damping=0.4,gravity=(0,0,-gravity)),
 PyRunner(iterPeriod=1,command='checker()'),
]
O.dt = dt
def checker():
 for i in range(nCycles):
  ii = nGravityDeposition+i*nStepsBetweenCycles
  if O.iter == ii:
   moveBottom()
  if O.iter == ii+1:
   stopBottom()
 if O.iter == nGravityDeposition+nCycles*nStepsBetweenCycles:
  O.pause()
def moveBottom():
 v = dspl / O.dt
 for b in movables:
  b.state.vel = (0,0,-v)
def stopBottom():
 for b in movables:
  b.state.vel = (0,0,0)

# box
p000 = Vector3(0,0,0)
p100 = Vector3(widthl,0,0)
p200 = Vector3(widthl+widthc,0,0)
p300 = Vector3(widthl+widthc+widthr,0,0)
pxs = (p000,p100,p200,p300)
p001,p101,p201,p301 = [p+Vector3(0,0,height) for p in pxs]
p010,p110,p210,p310 = [p+Vector3(0,thick,0) for p in pxs]
p011,p111,p211,p311 = [p+Vector3(0,thick,height) for p in pxs]
p00b,p10b,p20b,p30b = [p+Vector3(0,0,deep) for p in pxs]
p01b,p11b,p21b,p31b = [p+Vector3(0,thick,deep) for p in pxs]
def rect(vs,**kw):
 v1,v2,v3,v4 = vs
 return [
  facet((v1,v2,v3),**kw),
  facet((v1,v3,v4),**kw),
 ]
movables = rect((p100,p200,p210,p110)) # bottom center
rects = (
 (p000,p100,p110,p010), # bottom left
 (p200,p300,p310,p210), # bottom left
 (p000,p010,p011,p001), # left
 (p300,p310,p311,p301), # right
 (p000,p100,p101,p001), # front left
 (p100,p200,p201,p101), # front center
 (p200,p300,p301,p201), # front right
 (p010,p110,p111,p011), # back left
 (p110,p210,p211,p111), # back center
 (p210,p310,p311,p211), # back right
 (p100,p200,p20b,p10b), # front center below
 (p110,p210,p21b,p11b), # back center below
 (p100,p110,p11b,p10b), # left below
 (p200,p210,p21b,p20b), # right below
)
rects = movables + sum((rect(r) for r in rects),[])
O.bodies.append(rects)

# gravel
polyhedra_utils.fillBox((0,0,0),(width,thick,fillBoxHFactor*height),mat,sizemin=3*[sizeMin],sizemax=3*[sizeMax],seed=1)

yade.export.textPolyhedra('try2.txt', comment='try2', mask=-1, explanationComment=True, attrs=[])

####################
Thanks.

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

Hello,

this is correct approach. Before export.textPolyhedra, there should probably be some running, in the script e.g.
O.run(N,True)

export.textPolyhedra [1] and ymport.textPolyhedra [2] should fit together.

cheers
Jan

[1] https://yade-dem.org/doc/yade.export.html#yade.export.textPolyhedra
[2] https://yade-dem.org/doc/yade.ymport.html#yade.ymport.textPolyhedra

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

Hi,
Exporting/importing is the source of much troubles.
I would suggest to NOT split the problem in two different scripts for a start. A single script can do this:
Part A: let them fall
Part B: turn them into beam and set relevant boundary conditions (possibly remove the boundaries as well)

Later on, if you want to avoid spending time for part A again and again you can change the script slightly along this line:

if not os.path.isfile("fallen.yade"): #check if part A has be done previously
    Part A
    O.save("fallen.yade")
else:
    O.load("fallen.yade")
Part B

Cheers
Bruno

Revision history for this message
Kun Zeng (zkbread) said :
#3

Hi Jan,

Thanks for your suggestion. However, when I add a code like this:

# gravel
polyhedra_utils.fillBox((0,0,0),(width,thick,fillBoxHFactor*height),mat,sizemin=3*[sizeMin],sizemax=3*[sizeMax],seed=1)

O.run(10000,True)

yade.export.textPolyhedra('try2.txt', comment='try2', mask=-1, explanationComment=True, attrs=[])

after I run this code, there only seems in a loading situation just as everytime I run a model which need take sometime to show the yade interface. And continue in that situatio. Then terminal shows :

ERROR /home/kun/femdem/yade/source/pkg/common/InsertionSortCollider.cpp:240 action: verletDist is set to 0 because no spheres were found. It will result in suboptimal performances, consider setting a positive verletDist in your script.

What's wrong with my code here? Thanks

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

Hi,
Comment #3 is not very clear to me, but the error message is rather clear about how to fix the issue: "consider setting a positive verletDist in your script".

Further, Yade's documentation has a search box which can help. If you search verletDist you find [1]:
 verletDist(=-.5, Automatically initialized)
    Length by which to enlarge particle bounds, to avoid running collider at every step. Stride disabled if zero. Negative value will trigger automatic computation, so that the real value will be verletDist × minimum spherical particle radius; if there are no spherical particles, it will be disabled.

You have no spherical particles, hence the problem when auto-configuring the collider. Set collider's verletDist to a fraction of the polyhedra minimum size and it should be fine.
This is absolutely not related to import/export. Yet if you choose to import/export this verletDist setting will have to be repeated when reloading, which you can easily avoid by not splitting the task in two different scripts (as suggested in #2).
I hope it helps.
Bruno

p.s. This being said, not setting verletDist should raise a warning (sub-optimality), not an error. I just changed that in the sources (commit 949a2d9bd62).

[1] https://yade-dem.org/doc/yade.wrapper.html?highlight=verletdist#yade.wrapper.InsertionSortCollider.verletDist

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

Hello,

concerning the error, you can either follow Bruno's suggestion, or just leave it as it is (with the risk of "suboptimal performance", which should be negligible in the context of using polyhedral elements)

> after I run this code, there only seems in a loading situation just as everytime I run a model which need take sometime to show the yade interface. And continue in that situatio.

O.run(N,True) means it waits until N iterations are computed, not doing anything (including showing yade interface) before N iterations are finished. Apart from that, export.textPolyhedra just saves the file, nothing else, so what you see (if the file is saved correctly) is the expected behavior..

cheers
Jan

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

@Jan,
I think the LOG_ERROR was blocking (isn't it, in general?)

@Kun Zeng
Set verletDist=0 if you don't want to think about the appropriate value.
Else update yade version to get my last change, the error will become a warning then you can continue (and verletDist will be automatically set to zero)

Revision history for this message
Kun Zeng (zkbread) said :
#7

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

Revision history for this message
Kun Zeng (zkbread) said :
#8

@Bruno Thanks for your reply. Your information is very helpful