def randomPeriPack(radius,initSize,rRelFuzz=0.0,memoizeDb=None): """Generate periodic dense packing. A cell of initSize is stuffed with as many spheres as possible, then we run periodic compression with PeriIsoCompressor, just like with randomDensePack. :param radius: mean sphere radius :param rRelFuzz: relative fuzz of sphere radius (equal distribution); see the same param for randomDensePack. :param initSize: initial size of the periodic cell. :return: SpherePack object, which also contains periodicity information. """ from math import pi from woo import core, dem sp=_getMemoizedPacking(memoizeDb,radius,rRelFuzz,initSize[0],initSize[1],initSize[2],fullDim=Vector3(0,0,0),wantPeri=True,fillPeriodic=False,spheresInCell=-1,memoDbg=True) if sp: return sp #oldScene=O.scene S=core.Scene(fields=[dem.DemField()]) sp=SpherePack() S.periodic=True S.cell.setBox(initSize) sp.makeCloud(Vector3().Zero,S.cell.size0,radius,rRelFuzz,-1,True) from woo import log log.setLevel('PeriIsoCompressor',log.DEBUG) S.engines=[dem.ForceResetter(),dem.InsertionSortCollider([dem.Bo1_Sphere_Aabb()],verletDist=.05*radius),dem.ContactLoop([dem.Cg2_Sphere_Sphere_L6Geom()],[dem.Cp2_FrictMat_FrictPhys()],[dem.Law2_L6Geom_FrictPhys_IdealElPl()],applyForces=True),dem.PeriIsoCompressor(charLen=2*radius,stresses=[-100e9,-1e8],maxUnbalanced=1e-2,doneHook='print "done"; S.stop();',globalUpdateInt=20,keepProportions=True),dem.Leapfrog(damping=.8)] mat=dem.FrictMat(young=30e9,tanPhi=.1,ktDivKn=.3,density=1e3) for s in sp: S.dem.par.add(utils.sphere(s[0],s[1],mat=mat)) S.dt=utils.pWaveDt(S) #O.timingEnabled=True S.run(); S.wait() ret=SpherePack() ret.fromDem(S,S.dem) _memoizePacking(memoizeDb,ret,radius,rRelFuzz,wantPeri=True,fullDim=Vector3(0,0,0)) # fullDim unused return ret
import sys sys.path.append('.') import clDem from minieigen import * from woo import utils m=utils.defaultMaterial() O.dem.par.append([ utils.wall((0,0,0),axis=2,material=m,fixed=True), utils.sphere((0,0,1.3),radius=1,material=m) ]) O.dem.par[-1].vel=(-1.,0,0) O.dem.par[-1].angVel=(0,1,0) # O.dem.par[-1].material.tanPhi=0. # no friction O.scene.dt=.003*utils.pWaveDt() O.scene.trackEnergy=True from woo.dem import * from woo.core import* O.scene.engines=[ #PyRunner('if len(O.dem.con)>0 and O.dem.con[0].real: O.pause()'), Gravity(gravity=(0,0,-10)), Leapfrog(damping=.05,reset=True), InsertionSortCollider([Bo1_Sphere_Aabb(),Bo1_Wall_Aabb()]), ContactLoop([Cg2_Sphere_Sphere_L6Geom(),Cg2_Wall_Sphere_L6Geom()],[Cp2_FrictMat_FrictPhys()],[Law2_L6Geom_FrictPhys_IdealElPl()],applyForces=True), ] import woo.qt woo.qt.View() O.scene.clDev=(1,0) # intel sim=woo.cld.CLDemField.wooToClDem(O.scene,stepPeriod=1,relTol=-1)
from woo import utils,pack from woo.dem import * from woo.core import * from minieigen import * woo.master.usesApi=10101 woo.master.scene=S=Scene(fields=[DemField(gravity=(0,0,-10))]) mat=utils.defaultMaterial() sp=pack.SpherePack() sp.makeCloud((4,4,4),(14,14,14),.4,rRelFuzz=.5) sp.toSimulation(S,mat=mat) S.dem.par.add([utils.wall(1,axis=2,sense=0,mat=mat,glAB=((-10,-1),(20,11))),]) S.periodic=True S.cell.setBox(20,20,20) S.engines=utils.defaultEngines(damping=.4) S.dtSafety=.5 S.dt=.5*utils.pWaveDt() # to compute oscillation freqs below # create cylinders for i,x in enumerate([-2,0,2,4,6,8,10.5,12,14]): c=InfCylinder.make((x,0,3),radius=.8,axis=1,mat=mat,glAB=(-1,11)) c.angVel=(0,2.*(i+1),0) # each of cylinders will move haronically along global x and z axes (not y) c.impose=AlignedHarmonicOscillations(freqs=(1./(10000.*S.dt),float('nan'),1/(((i%3)+3)*1000.*S.dt)),amps=(.3*(i%2+1),0,.4*(i%4+1))) S.dem.par.add(c,nodes=True) try: from woo import gl S.gl.wall.div=10 S.gl.infCylinder.wire=True except ImportError: pass S.saveTmp()
import woo from woo import utils,pack,plot from woo.dem import * from woo.core import * woo.master.scene=S=Scene(fields=[DemField(gravity=(0,0,-10))]) mat=woo.dem.PelletMat(young=1e6,tanPhi=.5,ktDivKn=.2,density=1000) if 1: sp=pack.SpherePack() sp.makeCloud((0,0,0),(10,10,10),.4,rRelFuzz=.5) sp.toSimulation(S,mat=mat) else: S.dem.par.add(utils.sphere((0,0,1),.5,mat=mat)) S.dem.par.add(utils.wall(0,axis=2,sense=1,mat=mat)) S.engines=utils.defaultEngines(damping=0.,cp2=Cp2_PelletMat_PelletPhys(),law=Law2_L6Geom_PelletPhys_Pellet(plastSplit=True))+[ PyRunner(1,'S.plot.addData(i=S.step,t=S.time,Eerr=(S.energy.relErr() if S.step>100 else 0),**S.energy)'), ] S.dt=.3*utils.pWaveDt(S) S.dem.collectNodes() S.trackEnergy=True S.saveTmp() S.plot.plots={'i':(S.energy,None,('Eerr','g--'))} S.plot.plot() S.run(500) #from woo import gl #gl.Gl1_Wall.div=10 #gl.Gl1_InfCylinder.wire=True
def makePeriodicFeedPack(dim,psd,lenAxis=0,damping=.3,porosity=.5,goal=.15,maxNum=-1,dontBlock=False,returnSpherePack=False,memoizeDir=None,clumps=None,gen=None): if memoizeDir and not dontBlock: # increase number at the end for every change in the algorithm to make old feeds incompatible params=str(dim)+str(psd)+str(goal)+str(damping)+str(porosity)+str(lenAxis)+str(clumps)+('' if not gen else gen.dumps(format='expr'))+'5' import hashlib paramHash=hashlib.sha1(params).hexdigest() memoizeFile=memoizeDir+'/'+paramHash+'.perifeed' print 'Memoize file is ',memoizeFile if os.path.exists(memoizeDir+'/'+paramHash+'.perifeed'): print 'Returning memoized result' if not gen: sp=SpherePack() sp.load(memoizeFile) if returnSpherePack: return sp return zip(*sp)+[sp.cellSize[lenAxis],] else: import woo.dem sp=woo.dem.ShapePack(loadFrom=memoizeFile) return sp p3=porosity**(1/3.) if psd: rMax=psd[-1][0] elif hasattr(gen,'psdPts'): rMax=gen.psdPts[-1][0] else: raise NotImplementedError('Generators without PSD do not inform about the biggest particle radius.') minSize=rMax*5 cellSize=Vector3(max(dim[0]/p3,minSize),max(dim[1]/p3,minSize),max(dim[2]/p3,minSize)) print 'dimension',dim print 'initial cell size',cellSize print 'psd=',psd import woo.core, woo.dem, math S=woo.core.Scene(fields=[woo.dem.DemField()]) S.periodic=True S.cell.setBox(cellSize) if gen: generator=gen elif not clumps: generator=woo.dem.PsdSphereGenerator(psdPts=psd,discrete=False,mass=True) else: generator=woo.dem.PsdClumpGenerator(psdPts=psd,discrete=False,mass=True,clumps=clumps) S.engines=[ woo.dem.InsertionSortCollider([woo.dem.Bo1_Sphere_Aabb()]), woo.dem.BoxInlet( box=((0,0,0),cellSize), maxMass=-1, maxNum=maxNum, generator=generator, massRate=0, maxAttempts=5000, materials=[woo.dem.FrictMat(density=1e3,young=1e7,ktDivKn=.2,tanPhi=math.tan(.5))], shooter=None, mask=1, ) ] S.one() print 'Created %d particles, compacting...'%(len(S.dem.par)) S.dt=.9*utils.pWaveDt(S,noClumps=True) S.dtSafety=.9 if clumps: warnings.warn('utils.pWaveDt called with noClumps=True (clumps ignored), the result (S.dt=%g) might be significantly off!'%S.dt) S.engines=[ woo.dem.PeriIsoCompressor(charLen=2*rMax,stresses=[-1e8,-1e6],maxUnbalanced=goal,doneHook='print "done"; S.stop();',globalUpdateInt=1,keepProportions=True,label='peri'), # plots only useful for debugging - uncomment if needed # woo.core.PyRunner(100,'S.plot.addData(i=S.step,unb=S.lab.peri.currUnbalanced,sig=S.lab.peri.sigma)'), woo.core.PyRunner(100,'print S.lab.peri.stresses[S.lab.peri.state], S.lab.peri.sigma, S.lab.peri.currUnbalanced'), ]+utils.defaultEngines(damping=damping,dynDtPeriod=100) S.plot.plots={'i':('unb'),' i':('sig_x','sig_y','sig_z')} if dontBlock: return S S.run(); S.wait() if gen: sp=woo.dem.ShapePack() else: sp=SpherePack() sp.fromDem(S,S.dem) print 'Packing size is',sp.cellSize sp.canonicalize() if not gen: sp.makeOverlapFree() print 'Loose packing size is',sp.cellSize cc,rr=[],[] inf=float('inf') boxMin=Vector3(0,0,0); boxMax=Vector3(dim) boxMin[lenAxis]=-inf boxMax[lenAxis]=inf box=AlignedBox3(boxMin,boxMax) sp2=sp.filtered(inAlignedBox(box)) print 'Box is ',box #for c,r in sp: # if c-Vector3(r,r,r) not in box or c+Vector3(r,r,r) not in box: continue # cc.append(c); rr.append(r) if memoizeDir or returnSpherePack or gen: #sp2=SpherePack() #sp2.fromList(cc,rr) #sp2.cellSize=sp.cellSize if memoizeDir: print 'Saving to',memoizeFile # print len(sp2) sp2.save(memoizeFile) if returnSpherePack or gen: return sp2 cc,rr=sp2.toCcRr() return cc,rr,sp2.cellSize[lenAxis]
from minieigen import * woo.master.usesApi = 10101 woo.master.scene = S = Scene(fields=[DemField(gravity=(0, 0, -10))]) mat = utils.defaultMaterial() sp = pack.SpherePack() sp.makeCloud((4, 4, 4), (14, 14, 14), .4, rRelFuzz=.5) sp.toSimulation(S, mat=mat) S.dem.par.add([ utils.wall(1, axis=2, sense=0, mat=mat, glAB=((-10, -1), (20, 11))), ]) S.periodic = True S.cell.setBox(20, 20, 20) S.engines = utils.defaultEngines( damping=.4) + [POVRayExport(out='/tmp/pov', stepPeriod=20)] S.dtSafety = .5 S.dt = .5 * utils.pWaveDt() # to compute oscillation freqs below # create cylinders for i, x in enumerate([-2, 0, 2, 4, 6, 8, 10.5, 12, 14]): c = InfCylinder.make((x, 0, 3), radius=.8, axis=1, mat=mat, glAB=(-1, 11)) c.angVel = (0, 4. * (i + 1), 0) # each of cylinders will move haronically along global x and z axes (not y) c.impose = AlignedHarmonicOscillations( freqs=(1. / (10000. * S.dt), float('nan'), 1 / (((i % 3) + 3) * 1000. * S.dt)), amps=(.3 * (i % 2 + 1), 0, .4 * (i % 4 + 1))) S.dem.par.add(c) try: from woo import gl S.gl.wall.div = 10 S.gl.infCylinder.wire = True
else: print "No suitable packing in database found, running",'PERIODIC compression' if wantPeri else 'triaxial' sys.stdout.flush() S=core.Scene(fields=[dem.DemField()]) if wantPeri: # x1,y1,z1 already computed above sp=SpherePack() S.periodic=True S.cell.setBox(x1,y1,z1) #print cloudPorosity,beta,gamma,N100,x1,y1,z1,S.cell.refSize #print x1,y1,z1,radius,rRelFuzz S.engines=[dem.ForceResetter(),dem.InsertionSortCollider([dem.Bo1_Sphere_Aabb()],verletDist=.05*radius),dem.ContactLoop([dem.Cg2_Sphere_Sphere_L6Geom()],[dem.Cp2_FrictMat_FrictPhys()],[dem.Law2_L6Geom_FrictPhys_IdealElPl()],applyForces=True),dem.Leapfrog(damping=.7,reset=False),dem.PeriIsoCompressor(charLen=2*radius,stresses=[-100e9,-1e8],maxUnbalanced=1e-2,doneHook='print "DONE"; S.stop();',globalUpdateInt=5,keepProportions=True,label='compressor')] num=sp.makeCloud(Vector3().Zero,S.cell.size0,radius,rRelFuzz,spheresInCell,True) mat=dem.FrictMat(young=30e9,tanPhi=.5,density=1e3,ktDivKn=.2) for s in sp: S.dem.par.add(utils.sphere(s[0],s[1],mat=mat)) S.dem.collectNodes() S.dt=.5*utils.pWaveDt(S) S.run(); S.wait() sp=SpherePack(); sp.fromDem(S,S.dem) #print 'Resulting cellSize',sp.cellSize,'proportions',sp.cellSize[1]/sp.cellSize[0],sp.cellSize[2]/sp.cellSize[0] # repetition to the required cell size will be done below, after memoizing the result else: raise RuntimError("Aperiodic compression not implemented.") assumedFinalDensity=0.6 V=(4/3)*pi*radius**3; N=assumedFinalDensity*fullDim[0]*fullDim[1]*fullDim[2]/V; TriaxialTest( numberOfGrains=int(N),radiusMean=radius,radiusStdDev=rRelFuzz, # upperCorner is just size ratio, if radiusMean is specified upperCorner=fullDim, ## no need to touch any the following noFiles=True,lowerCorner=[0,0,0],sigmaIsoCompaction=1e7,sigmaLateralConfinement=1e3,StabilityCriterion=.05,strainRate=.2,thickness=-1,maxWallVelocity=.1,wallOversizeFactor=1.5,autoUnload=True,autoCompressionActivation=False).load() log.setLevel('TriaxialCompressionEngine',log.WARN)
from woo.core import* from woo.dem import * import woo.gl from woo import utils S=woo.master.scene=Scene(fields=[DemField(gravity=(0,0,-10))]) S.dem.par.add([ utils.wall((0,0,0),axis=2,sense=1), utils.sphere((0,0,1),.2) ]) S.dem.par[1].vel=(0,1,0) S.dt=.7*utils.pWaveDt() S.engines=utils.defaultEngines()+[woo.dem.Tracer(num=512,compress=2,stepPeriod=10,compSkip=1)] S.saveTmp() import woo.qt woo.qt.View() S.run(2000)
from woo.dem import * from woo.core import * from miniEigen import * from math import * from woo import utils, pack S = woo.master.scene = Scene(fields=[DemField()]) m = FrictMat(young=1e6, density=1e3, ktDivKn=2., tanPhi=.5) for axis in 0, 1, 2: S.dem.par.append(utils.wall((0, 0, 0), axis=axis, mat=m, mask=0b011)) sp = pack.SpherePack() sp.load(sys.argv[1]) sp.cellSize = (0, 0, 0) # make the packing aperiodic sp.toSimulation(S, mat=m, mask=0b001) S.dem.collectNodes() S.dt = .3 * utils.pWaveDt() S.engines = utils.defaultEngines(gravity=(-4, -5, -10), damping=.4, verletDist=-.3) S.loneGroups = 0b010 # no contacts of walls with themselves S.run(2000) # S.wait()
import woo from woo.dem import * from woo.core import * from woo import * from woo import utils S=woo.master.scene=Scene(fields=[DemField(gravity=(0,0,-10))]) m=utils.defaultMaterial() S.dem.par.add([ Facet.make([(0,0,0),(1,0,0),(0,1,0)],halfThick=0.3,mat=m), Sphere.make((.2,.2,1),.3,mat=m) ]) S.engines=utils.defaultEngines(damping=.4) S.dt=.1*utils.pWaveDt(S) S.dem.collectNodes() S.saveTmp()
import sys sys.path.append('.') import clDem from minieigen import * from woo import utils m = utils.defaultMaterial() O.dem.par.append([ utils.wall((0, 0, 0), axis=2, material=m, fixed=True), utils.sphere((0, 0, 1.3), radius=1, material=m) ]) O.dem.par[-1].vel = (-1., 0, 0) O.dem.par[-1].angVel = (0, 1, 0) # O.dem.par[-1].material.tanPhi=0. # no friction O.scene.dt = .003 * utils.pWaveDt() O.scene.trackEnergy = True from woo.dem import * from woo.core import * O.scene.engines = [ #PyRunner('if len(O.dem.con)>0 and O.dem.con[0].real: O.pause()'), Gravity(gravity=(0, 0, -10)), Leapfrog(damping=.05, reset=True), InsertionSortCollider([Bo1_Sphere_Aabb(), Bo1_Wall_Aabb()]), ContactLoop([Cg2_Sphere_Sphere_L6Geom(), Cg2_Wall_Sphere_L6Geom()], [Cp2_FrictMat_FrictPhys()], [Law2_L6Geom_FrictPhys_IdealElPl()], applyForces=True), ] import woo.qt
m=FrictMat(young=1e6,density=1e3,tanPhi=0) import woo.pack sp=woo.pack.SpherePack() sp.makeCloud((2*r*margin,2*r*margin,2*r),((dim[0]-margin)*2*r,(dim[1]-margin)*2*r,dim[2]*2*r),r,rRelFuzz=.5) sp.toSimulation(material=m) for p in O.dem.par: p.vel=(0,0,-.05) O.dem.par.append([ utils.wall((0,0,2*r),sense=1,axis=2,material=m), utils.wall((0,0,0),sense=1,axis=0,material=m), utils.wall((0,0,0),sense=1,axis=1,material=m), ]) O.scene.dt=.5*utils.pWaveDt() O.scene.engines=[ InsertionSortCollider([Bo1_Sphere_Aabb(),Bo1_Wall_Aabb()],verletDist=.05*r), ContactLoop([Cg2_Sphere_Sphere_L6Geom(),Cg2_Wall_Sphere_L6Geom()], [Cp2_FrictMat_FrictPhys(ktDivKn=ktDivKn)], [Law2_L6Geom_FrictPhys_IdealElPl(noSlip=True)], applyForces=True ), Gravity(gravity=(-4,-5,-10)), Leapfrog(damping=.4,reset=True), ] O.timingEnabled=True O.scene.trackEnergy=True O.saveTmp()
from woo.core import * from woo.dem import * import woo.gl from woo import utils S = woo.master.scene = Scene(fields=[DemField(gravity=(0, 0, -10))]) S.dem.par.add( [utils.wall((0, 0, 0), axis=2, sense=1), utils.sphere((0, 0, 1), .2)]) S.dem.par[1].vel = (0, 1, 0) S.dt = .7 * utils.pWaveDt() S.engines = utils.defaultEngines() + [ woo.dem.Tracer(num=512, compress=2, stepPeriod=10, compSkip=1) ] S.saveTmp() import woo.qt woo.qt.View() S.run(2000)
"""This example demonstrates GTS (http://gts.sourceforge.net/) opportunities for creating surfaces VTU-files are created in /tmp directory after simulation. If you open those with paraview (or other VTK-based) program, you can create video, make screenshots etc.""" import woo from woo import * from woo.dem import * from woo.core import * from numpy import linspace from woo import pack,qt,utils from minieigen import * from math import * S=woo.master.scene=Scene(fields=[DemField(gravity=(0,0,-9.81))]) thetas=linspace(0,2*pi,num=16,endpoint=True) meridians=pack.revolutionSurfaceMeridians([[Vector2(3+rad*sin(th),10*rad+rad*cos(th)) for th in thetas] for rad in linspace(1,2,num=10)],linspace(0,pi,num=10)) surf=pack.sweptPolylines2gtsSurface(meridians+[[Vector3(5*sin(-th),-10+5*cos(-th),30) for th in thetas]]) S.dem.par.add(pack.gtsSurface2Facets(surf)) sp=pack.SpherePack() sp.makeCloud(Vector3(-1,-9,30),Vector3(1,-13,32),.2,rRelFuzz=.3) S.dem.par.add([utils.sphere(c,r) for c,r in sp]) S.engines=utils.defaultEngines()+[VtkExport(stepPeriod=100,what=VtkExport.spheres|VtkExport.mesh,out='/tmp/p1-')] S.dt=utils.pWaveDt(S) qt.Controller() qt.View() S.saveTmp() S.run(8500)