# do nothing if we have the coarsened horse already if not os.path.exists('horse.coarse.gts'): if os.path.exists('horse.gts'): surf=gts.read(open('horse.gts')); surf.coarsen(1000); surf.write(open('horse.coarse.gts','w')) else: print """horse.gts not found, you need to download input data: wget http://gts.sourceforge.net/samples/horse.gts.gz gunzip horse.gts.gz """ quit() surf=gts.read(open('horse.coarse.gts')) if surf.is_closed(): pred=pack.inGtsSurface(surf) aabb=pred.aabb() dim0=aabb[1][0]-aabb[0][0]; radius=dim0/40. # get some characteristic dimension, use it for radius O.bodies.append(pack.regularHexa(pred,radius=radius,gap=radius/4.)) surf.translate(0,0,-(aabb[1][2]-aabb[0][2])) # move surface down so that facets are underneath the falling spheres O.bodies.append(pack.gtsSurface2Facets(surf,wire=True)) O.engines=[ ForceResetter(), InsertionSortCollider([Bo1_Sphere_Aabb(),Bo1_Facet_Aabb()],label='collider'), InteractionLoop( [Ig2_Sphere_Sphere_ScGeom(),Ig2_Facet_Sphere_ScGeom()], [Ip2_FrictMat_FrictMat_FrictPhys()], [Law2_ScGeom_FrictPhys_CundallStrack()], ), NewtonIntegrator(damping=.1,gravity=[0,0,-5000]),
#### controling parameters mesh = 'parallellepiped' #name of gts mesh sizeRatio = 10. # defines discretisation (sizeRatio=meshLength/particleDiameter) #### import mesh locale.setlocale( locale.LC_ALL, 'en_US.UTF-8' ) #gts is locale-dependend. If, for example, german locale is used, gts.read()-function does not import floats normally surface = gts.read(open(mesh + '.gts')) print 'closed? ', surface.is_closed() #### generate packing if surface.is_closed(): pred = pack.inGtsSurface(surface) # get characteristic dimensions aabb = pred.aabb() dim = pred.dim() center = pred.center() minDim = min(dim[0], dim[1], dim[2]) # define discretisation radius = minDim / (2 * sizeRatio) print center, dim, ' | minDim=', minDim, ' | diameter=', 2 * radius ### regular packing #O.bodies.append(pack.regularHexa(pred,radius=radius,gap=0.,color=(0.9,0.8,0.6))) #O.bodies.append(pack.regularOrtho(pred,radius=radius,gap=0.,color=(0.9,0.8,0.6))) sp = SpherePack() # random packing sp = pack.randomDensePack( pred,
""" from yade import pack,qt import gts, locale locale.setlocale(locale.LC_ALL, 'en_US.UTF-8') #gts is locale-dependend. If, for example, german locale is used, gts.read()-function does not import floats normally ''' if you get "Error: unsupported locale setting" -> type as root: "dpkg-reconfigure locales" -> choose "en_US.UTF-8" (press space to choose) ''' s1=gts.read(open('horse.coarse.gts')) s2=gts.Surface(); s2.copy(s1); s2.translate(0.04,0,0) O.bodies.append(pack.gtsSurface2Facets(s1,color=(0,1,0))+pack.gtsSurface2Facets(s2,color=(1,0,0))) s12=gts.Surface(); s12.copy(s1.union(s2)); s12.translate(0,0,.1) radius=0.002 O.bodies.append(pack.gtsSurface2Facets(s12,color=(0,0,1))) qt.View() from time import time t0=time() O.bodies.append(pack.regularHexa(pack.inGtsSurface(s1) | pack.inGtsSurface(s2),radius,gap=0,color=(0,1,0))) t1=time() print 'Using predicate union: %gs'%(t1-t0) O.bodies.append(pack.regularHexa(pack.inGtsSurface(s12),radius,gap=0.,color=(1,0,0))) t2=time() print 'Using surface union: %gs'%(t2-t1)
#pylab.plot(*zip(*poly)); pylab.xlim(xmin=0); pylab.grid(); pylab.title('Meridian of the revolution surface\n(close to continue)'); pylab.gca().set_aspect(aspect='equal',adjustable='box'); pylab.show() thetas = arange(0, pi / 8, pi / 24) pts = pack.revolutionSurfaceMeridians([poly for theta in thetas], thetas, origin=Vector3(-4, 0, -1), orientation=Quaternion.Identity) surf = pack.sweptPolylines2gtsSurface(pts, capStart=True, capEnd=True, threshold=1e-4) O.bodies.append(pack.gtsSurface2Facets(surf, color=(1, 0, 1))) # fill this solid with triaxial packing; it will compute minimum-volume oriented bounding box # to minimize the number of throw-away spheres. # It does away with about 3k spheres for radius 3e-2 sp1 = SpherePack() sp1 = pack.randomDensePack(pack.inGtsSurface(surf), radius=3e-2, rRelFuzz=1e-1, memoizeDb='/tmp/gts-triax.sqlite', returnSpherePack=True) sp1.toSimulation() # translate the surface away and pack it again with sphere, but without the oriented bounding box (useOBB=False) # Here, we need 20k spheres (with more or less the same result) surf.translate(0, 0, 1) O.bodies.append(pack.gtsSurface2Facets(surf, color=(1, 0, 0))) sp2 = SpherePack() sp2 = pack.randomDensePack(pack.inGtsSurface(surf), radius=3e-2, rRelFuzz=1e-1, memoizeDb='/tmp/gts-triax-packings.sqlite', useOBB=False,
''' s1 = gts.read(open('horse.coarse.gts')) s2 = gts.Surface() s2.copy(s1) s2.translate(0.04, 0, 0) O.bodies.append( pack.gtsSurface2Facets(s1, color=(0, 1, 0)) + pack.gtsSurface2Facets(s2, color=(1, 0, 0))) s12 = gts.Surface() s12.copy(s1.union(s2)) s12.translate(0, 0, .1) radius = 0.002 O.bodies.append(pack.gtsSurface2Facets(s12, color=(0, 0, 1))) qt.View() from time import time t0 = time() O.bodies.append( pack.regularHexa(pack.inGtsSurface(s1) | pack.inGtsSurface(s2), radius, gap=0, color=(0, 1, 0))) t1 = time() print 'Using predicate union: %gs' % (t1 - t0) O.bodies.append( pack.regularHexa(pack.inGtsSurface(s12), radius, gap=0., color=(1, 0, 0))) t2 = time() print 'Using surface union: %gs' % (t2 - t1)
# define the section shape as polygon in 2d; repeat first point at the end to close the polygon sq2 = sqrt(2) poly = ((3 + 0.1, 0), (3 + 0, 0.1), (3 + sq2, 0.1 + sq2), (3 + 0.1 + sq2, sq2), (3 + 0.1, 0)) # pylab.plot(*zip(*poly)); pylab.xlim(xmin=0); pylab.grid(); pylab.title('Meridian of the revolution surface\n(close to continue)'); pylab.gca().set_aspect(aspect='equal',adjustable='box'); pylab.show() thetas = arange(0, pi / 8, pi / 24) pts = pack.revolutionSurfaceMeridians( [poly for theta in thetas], thetas, origin=Vector3(-4, 0, -1), orientation=Quaternion.Identity ) surf = pack.sweptPolylines2gtsSurface(pts, capStart=True, capEnd=True, threshold=1e-4) O.bodies.append(pack.gtsSurface2Facets(surf, color=(1, 0, 1))) # fill this solid with triaxial packing; it will compute minimum-volume oriented bounding box # to minimize the number of throw-away spheres. # It does away with about 3k spheres for radius 3e-2 O.bodies.append( pack.randomDensePack(pack.inGtsSurface(surf), radius=3e-2, rRelFuzz=1e-1, memoizeDb="/tmp/gts-triax.sqlite") ) # translate the surface away and pack it again with sphere, but without the oriented bounding box (useOBB=False) # Here, we need 20k spheres (with more or less the same result) surf.translate(0, 0, 1) O.bodies.append(pack.gtsSurface2Facets(surf, color=(1, 0, 0))) O.bodies.append( pack.randomDensePack( pack.inGtsSurface(surf), radius=3e-2, rRelFuzz=1e-1, memoizeDb="/tmp/gts-triax-packings.sqlite", useOBB=False ) ) from yade import qt qt.View()
surf = pack.sweptPolylines2gtsSurface(pts, capStart=True, capEnd=True, threshold=1e-4) # add the surface as facets to the simulation, to make it visible O.bodies.append(pack.gtsSurface2Facets(surf, color=(1, 0, 1))) # now fill the inGtsSurface predicate constructed form the same surface with sphere packing generated by TriaxialTest # with given radius and standard deviation (see documentation of pack.randomDensePack) # # The memoizeDb will save resulting packing into given file and next time, if you run with the same # parameters (or parameters that can be scaled to the same one), # it will load the packing instead of running the triaxial compaction again. # Try running for the second time to see the speed difference! memoizeDb = '/tmp/gts-triax-packings.sqlite' O.bodies.append( pack.randomDensePack(pack.inGtsSurface(surf), radius=5e-3, rRelFuzz=1e-4, memoizeDb=memoizeDb)) # We could also fill the horse with triaxial packing, but have nice approximation, the triaxial would run terribly long, # since horse discard most volume of its bounding box # Here, we would use a very crude one, however if 1: import gts horse = gts.read(open('horse.coarse.gts')) #; horse.scale(.25,.25,.25) O.bodies.append(pack.gtsSurface2Facets(horse)) O.bodies.append( pack.randomDensePack(pack.inGtsSurface(horse), radius=5e-3, memoizeDb=memoizeDb)) horse.translate(.07, 0, 0)
# -*- coding: utf-8 -*- """ CAUTION: Running this script can take very long! """ from numpy import arange from yade import pack import pylab # define the section shape as polygon in 2d; repeat first point at the end to close the polygon sq2=sqrt(2) poly=((3+.1,0),(3+0,.1),(3+sq2,.1+sq2),(3+.1+sq2,sq2),(3+.1,0)) #pylab.plot(*zip(*poly)); pylab.xlim(xmin=0); pylab.grid(); pylab.title('Meridian of the revolution surface\n(close to continue)'); pylab.gca().set_aspect(aspect='equal',adjustable='box'); pylab.show() thetas=arange(0,pi/8,pi/24) pts=pack.revolutionSurfaceMeridians([poly for theta in thetas],thetas,origin=Vector3(-4,0,-1),orientation=Quaternion.Identity) surf=pack.sweptPolylines2gtsSurface(pts,capStart=True,capEnd=True,threshold=1e-4) O.bodies.append(pack.gtsSurface2Facets(surf,color=(1,0,1))) # fill this solid with triaxial packing; it will compute minimum-volume oriented bounding box # to minimize the number of throw-away spheres. # It does away with about 3k spheres for radius 3e-2 O.bodies.append(pack.randomDensePack(pack.inGtsSurface(surf),radius=3e-2,rRelFuzz=1e-1,memoizeDb='/tmp/gts-triax.sqlite')) # translate the surface away and pack it again with sphere, but without the oriented bounding box (useOBB=False) # Here, we need 20k spheres (with more or less the same result) surf.translate(0,0,1); O.bodies.append(pack.gtsSurface2Facets(surf,color=(1,0,0))) O.bodies.append(pack.randomDensePack(pack.inGtsSurface(surf),radius=3e-2,rRelFuzz=1e-1,memoizeDb='/tmp/gts-triax-packings.sqlite',useOBB=False)) from yade import qt qt.View()
# pts=pack.revolutionSurfaceMeridians([[(pt[0],pt[1]+2e-3*theta) for pt in poly] for theta in thetas],thetas # pts=pack.revolutionSurfaceMeridians([[(pt[0],pt[1]+1e-2*theta) for pt in poly] for theta in thetas],thetas,origin=Vector3(0,-.05,.1),orientation=Quaternion((1,1,0),pi/4)) # connect meridians to make surfaces # caps will close it at the beginning and the end # threshold will merge points closer than 1e-4; this is important: we want it to be closed for filling surf=pack.sweptPolylines2gtsSurface(pts,capStart=True,capEnd=True,threshold=1e-4) # add the surface as facets to the simulation, to make it visible O.bodies.append(pack.gtsSurface2Facets(surf,color=(1,0,1))) # now fill the inGtsSurface predicate constructed form the same surface with sphere packing generated by TriaxialTest # with given radius and standard deviation (see documentation of pack.randomDensePack) # # The memoizeDb will save resulting packing into given file and next time, if you run with the same # parameters (or parameters that can be scaled to the same one), # it will load the packing instead of running the triaxial compaction again. # Try running for the second time to see the speed difference! memoizeDb='/tmp/gts-triax-packings.sqlite' O.bodies.append(pack.randomDensePack(pack.inGtsSurface(surf),radius=5e-3,rRelFuzz=1e-4,memoizeDb=memoizeDb)) # We could also fill the horse with triaxial packing, but have nice approximation, the triaxial would run terribly long, # since horse discard most volume of its bounding box # Here, we would use a very crude one, however if 1: import gts horse=gts.read(open('horse.coarse.gts')) #; horse.scale(.25,.25,.25) O.bodies.append(pack.gtsSurface2Facets(horse)) O.bodies.append(pack.randomDensePack(pack.inGtsSurface(horse),radius=5e-3,memoizeDb=memoizeDb)) horse.translate(.07,0,0) O.bodies.append(pack.gtsSurface2Facets(horse)) # specifying spheresInCell makes the packing periodic, with the given number of spheres, proportions being equal to that of the predicate O.bodies.append(pack.randomDensePack(pack.inGtsSurface(horse),radius=1e-3,spheresInCell=2000,memoizeDb=memoizeDb))
""" from numpy import arange from yade import pack import pylab # define the section shape as polygon in 2d; repeat first point at the end to close the polygon sq2=sqrt(2) poly=((3+.1,0),(3+0,.1),(3+sq2,.1+sq2),(3+.1+sq2,sq2),(3+.1,0)) #pylab.plot(*zip(*poly)); pylab.xlim(xmin=0); pylab.grid(); pylab.title('Meridian of the revolution surface\n(close to continue)'); pylab.gca().set_aspect(aspect='equal',adjustable='box'); pylab.show() thetas=arange(0,pi/8,pi/24) pts=pack.revolutionSurfaceMeridians([poly for theta in thetas],thetas,origin=Vector3(-4,0,-1),orientation=Quaternion.Identity) surf=pack.sweptPolylines2gtsSurface(pts,capStart=True,capEnd=True,threshold=1e-4) O.bodies.append(pack.gtsSurface2Facets(surf,color=(1,0,1))) # fill this solid with triaxial packing; it will compute minimum-volume oriented bounding box # to minimize the number of throw-away spheres. # It does away with about 3k spheres for radius 3e-2 sp1=SpherePack() sp1=pack.randomDensePack(pack.inGtsSurface(surf),radius=3e-2,rRelFuzz=1e-1,memoizeDb='/tmp/gts-triax.sqlite',returnSpherePack=True) sp1.toSimulation() # translate the surface away and pack it again with sphere, but without the oriented bounding box (useOBB=False) # Here, we need 20k spheres (with more or less the same result) surf.translate(0,0,1); O.bodies.append(pack.gtsSurface2Facets(surf,color=(1,0,0))) sp2=SpherePack() sp2=pack.randomDensePack(pack.inGtsSurface(surf),radius=3e-2,rRelFuzz=1e-1,memoizeDb='/tmp/gts-triax-packings.sqlite',useOBB=False,returnSpherePack=True) sp2.toSimulation() from yade import qt qt.View()
from __future__ import print_function from yade import pack,qt import gts, locale locale.setlocale(locale.LC_ALL, 'en_US.UTF-8') #gts is locale-dependend. If, for example, german locale is used, gts.read()-function does not import floats normally ''' if you get "Error: unsupported locale setting" -> type as root: "dpkg-reconfigure locales" -> choose "en_US.UTF-8" (press space to choose) ''' s1=gts.read(open('horse.coarse.gts')) s2=gts.Surface(); s2.copy(s1); s2.translate(0.04,0,0) O.bodies.append(pack.gtsSurface2Facets(s1,color=(0,1,0))+pack.gtsSurface2Facets(s2,color=(1,0,0))) s12=gts.Surface(); s12.copy(s1.union(s2)); s12.translate(0,0,.1) radius=0.002 O.bodies.append(pack.gtsSurface2Facets(s12,color=(0,0,1))) qt.View() from time import time t0=time() O.bodies.append(pack.regularHexa(pack.inGtsSurface(s1) | pack.inGtsSurface(s2),radius,gap=0,color=(0,1,0))) t1=time() print('Using predicate union: %gs'%(t1-t0)) O.bodies.append(pack.regularHexa(pack.inGtsSurface(s12),radius,gap=0.,color=(1,0,0))) t2=time() print('Using surface union: %gs'%(t2-t1))
# -*- coding: utf-8 -*- from numpy import arange from yade import pack import pylab # define the section shape as polygon in 2d; repeat first point at the end to close the polygon sq2=sqrt(2) poly=((3+.1,0),(3+0,.1),(3+sq2,.1+sq2),(3+.1+sq2,sq2),(3+.1,0)) #pylab.plot(*zip(*poly)); pylab.xlim(xmin=0); pylab.grid(); pylab.title('Meridian of the revolution surface\n(close to continue)'); pylab.gca().set_aspect(aspect='equal',adjustable='box'); pylab.show() thetas=arange(0,pi/8,pi/24) pts=pack.revolutionSurfaceMeridians([poly for theta in thetas],thetas,origin=Vector3(-4,0,-1),orientation=Quaternion.Identity) surf=pack.sweptPolylines2gtsSurface(pts,capStart=True,capEnd=True,threshold=1e-4) O.bodies.append(pack.gtsSurface2Facets(surf,color=(1,0,1))) # fill this solid with triaxial packing; it will compute minimum-volume oriented bounding box # to minimize the number of throw-away spheres. # It does away with about 3k spheres for radius 3e-2 O.bodies.append(pack.randomDensePack(pack.inGtsSurface(surf),radius=3e-2,rRelFuzz=1e-1,memoizeDb='/tmp/gts-triax-packings.sqlite')) # translate the surface away and pack it again with sphere, but without the oriented bounding box (useOBB=False) # Here, we need 20k spheres (with more or less the same result) surf.translate(0,0,1); O.bodies.append(pack.gtsSurface2Facets(surf,color=(1,0,0))) O.bodies.append(pack.randomDensePack(pack.inGtsSurface(surf),radius=3e-2,rRelFuzz=1e-1,memoizeDb='/tmp/gts-triax-packings.sqlite',useOBB=False))
# connect meridians to make surfaces # caps will close it at the beginning and the end # threshold will merge points closer than 1e-4; this is important: we want it to be closed for filling surf=pack.sweptPolylines2gtsSurface(pts,capStart=True,capEnd=True,threshold=1e-4) # add the surface as facets to the simulation, to make it visible O.bodies.append(pack.gtsSurface2Facets(surf,color=(1,0,1))) # now fill the inGtsSurface predicate constructed form the same surface with sphere packing generated by TriaxialTest # with given radius and standard deviation (see documentation of pack.randomDensePack) # # The memoizeDb will save resulting packing into given file and next time, if you run with the same # parameters (or parameters that can be scaled to the same one), # it will load the packing instead of running the triaxial compaction again. # Try running for the second time to see the speed difference! memoizeDb='/tmp/gts-triax-packings.sqlite' sp=SpherePack() sp=pack.randomDensePack(pack.inGtsSurface(surf),radius=5e-3,rRelFuzz=1e-4,memoizeDb=memoizeDb,returnSpherePack=True) sp.toSimulation() # We could also fill the horse with triaxial packing, but have nice approximation, the triaxial would run terribly long, # since horse discard most volume of its bounding box # Here, we would use a very crude one, however if 1: import gts horse=gts.read(open('horse.coarse.gts')) #; horse.scale(.25,.25,.25) O.bodies.append(pack.gtsSurface2Facets(horse)) sp=pack.randomDensePack(pack.inGtsSurface(horse),radius=5e-3,memoizeDb=memoizeDb,returnSpherePack=True) sp.toSimulation() horse.translate(.07,0,0) O.bodies.append(pack.gtsSurface2Facets(horse)) # specifying spheresInCell makes the packing periodic, with the given number of spheres, proportions being equal to that of the predicate sp=pack.randomDensePack(pack.inGtsSurface(horse),radius=1e-3,spheresInCell=2000,memoizeDb=memoizeDb,returnSpherePack=True) sp.toSimulation()