# use the ScGeom variant scGeom=False ) from woo.params.table import * if 'description' in O.tags.keys(): O.tags['id']=O.tags['id']+O.tags['description'] # make geom; the dimensions are hard-coded here; could be in param table if desired # z-oriented hyperboloid, length 20cm, diameter 10cm, skirt 8cm # using spheres 7mm of diameter concreteId=O.materials.append(CpmMat(young=young,frictionAngle=frictionAngle,poisson=poisson,density=4800,sigmaT=sigmaT,relDuctility=relDuctility,epsCrackOnset=epsCrackOnset,G_over_E=G_over_E,isoPrestress=isoPrestress)) spheres=pack.randomDensePack(pack.inHyperboloid((0,0,-.5*specimenLength),(0,0,.5*specimenLength),.25*specimenLength,.17*specimenLength),spheresInCell=2000,radius=sphereRadius,memoizeDb='/tmp/triaxPackCache.sqlite',material=concreteId) #spheres=pack.randomDensePack(pack.inAlignedBox((-.25*specimenLength,-.25*specimenLength,-.5*specimenLength),(.25*specimenLength,.25*specimenLength,.5*specimenLength)),spheresInCell=2000,radius=sphereRadius,memoizeDb='/tmp/triaxPackCache.sqlite') O.bodies.append(spheres) bb=utils.uniaxialTestFeatures() negIds,posIds,axis,crossSectionArea=bb['negIds'],bb['posIds'],bb['axis'],bb['area'] O.dt=dtSafety*utils.PWaveTimeStep() print 'Timestep',O.dt mm,mx=[pt[axis] for pt in utils.aabbExtrema()] coord_25,coord_50,coord_75=mm+.25*(mx-mm),mm+.5*(mx-mm),mm+.75*(mx-mm) area_25,area_50,area_75=utils.approxSectionArea(coord_25,axis),utils.approxSectionArea(coord_50,axis),utils.approxSectionArea(coord_75,axis) O.engines=[ ForceResetter(), InsertionSortCollider([Bo1_Sphere_Aabb(aabbEnlargeFactor=intRadius,label='is2aabb'),],sweepLength=.05*sphereRadius,nBins=5,binCoeff=5), InteractionLoop(
# 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))
(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))
from woo import * from woo.core import * from woo.dem import * from minieigen import * from woo import pack,log import woo log.setLevel('PeriIsoCompressor',log.DEBUG) """Simple script to create tunnel with random dense packing of spheres. The tunnel is difference between an axis-aligned box and cylinder, or which axis is going through the bottom wall (-z) of the box. The tunnel hole is oriented along +y, the face is in the xz plane. The first you run this scipt, a few minutes is neede to generate the packing. It is saved in /tmp/triaxPackCache.sqlite and at next time it will be only loaded (fast). """ # set some geometry parameters: domain box size, tunnel radius, radius of particles boxSize=Vector3(5,8,5) tunnelRad=2 rSphere=.1 # construct spatial predicate as difference of box and cylinder: # (see scripts/test/pack-predicates.py for details) pred=pack.inAlignedBox((-.5*boxSize[0],-.5*boxSize[1],0),(.5*boxSize[0],.5*boxSize[1],boxSize[2])) - pack.inCylinder((-.5*boxSize[0],0,0),(.5*boxSize[0],0,0),tunnelRad) # Use the predicate to generate sphere packing inside pack.randomDensePack(pred,radius=rSphere,rRelFuzz=.3,memoizeDb='/tmp/triaxPackCache.sqlite',spheresInCell=3000).toSimulation(woo.master.scene) from woo import qt qt.Controller() qt.View()
# using spheres 7mm of diameter concreteId = O.materials.append( CpmMat(young=young, frictionAngle=frictionAngle, poisson=poisson, density=4800, sigmaT=sigmaT, relDuctility=relDuctility, epsCrackOnset=epsCrackOnset, G_over_E=G_over_E, isoPrestress=isoPrestress)) spheres = pack.randomDensePack(pack.inHyperboloid( (0, 0, -.5 * specimenLength), (0, 0, .5 * specimenLength), .25 * specimenLength, .17 * specimenLength), spheresInCell=2000, radius=sphereRadius, memoizeDb='/tmp/triaxPackCache.sqlite', material=concreteId) #spheres=pack.randomDensePack(pack.inAlignedBox((-.25*specimenLength,-.25*specimenLength,-.5*specimenLength),(.25*specimenLength,.25*specimenLength,.5*specimenLength)),spheresInCell=2000,radius=sphereRadius,memoizeDb='/tmp/triaxPackCache.sqlite') O.bodies.append(spheres) bb = utils.uniaxialTestFeatures() negIds, posIds, axis, crossSectionArea = bb['negIds'], bb['posIds'], bb[ 'axis'], bb['area'] O.dt = dtSafety * utils.PWaveTimeStep() print 'Timestep', O.dt mm, mx = [pt[axis] for pt in utils.aabbExtrema()] coord_25, coord_50, coord_75 = mm + .25 * (mx - mm), mm + .5 * ( mx - mm), mm + .75 * (mx - mm) area_25, area_50, area_75 = utils.approxSectionArea(
log.setLevel('PeriIsoCompressor', log.DEBUG) """Simple script to create tunnel with random dense packing of spheres. The tunnel is difference between an axis-aligned box and cylinder, or which axis is going through the bottom wall (-z) of the box. The tunnel hole is oriented along +y, the face is in the xz plane. The first you run this scipt, a few minutes is neede to generate the packing. It is saved in /tmp/triaxPackCache.sqlite and at next time it will be only loaded (fast). """ # set some geometry parameters: domain box size, tunnel radius, radius of particles boxSize = Vector3(5, 8, 5) tunnelRad = 2 rSphere = .1 # construct spatial predicate as difference of box and cylinder: # (see scripts/test/pack-predicates.py for details) pred = pack.inAlignedBox( (-.5 * boxSize[0], -.5 * boxSize[1], 0), (.5 * boxSize[0], .5 * boxSize[1], boxSize[2])) - pack.inCylinder( (-.5 * boxSize[0], 0, 0), (.5 * boxSize[0], 0, 0), tunnelRad) # Use the predicate to generate sphere packing inside pack.randomDensePack(pred, radius=rSphere, rRelFuzz=.3, memoizeDb='/tmp/triaxPackCache.sqlite', spheresInCell=3000).toSimulation(woo.master.scene) from woo import qt qt.Controller() qt.View()
# -*- coding: utf-8 -*- from numpy import arange from woo 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))