Example #1
0
	def testUserCreatedInteraction(self):
		O.engines=[
				ForceResetter(),
				InsertionSortCollider([Bo1_Sphere_Aabb(),Bo1_Facet_Aabb(),Bo1_Box_Aabb()],label="collider"),
				InteractionLoop(
					[Ig2_Sphere_Sphere_ScGeom(),Ig2_Facet_Sphere_ScGeom(),Ig2_Box_Sphere_ScGeom()],
					[Ip2_FrictMat_FrictMat_FrictPhys()],	#for linear model only
					[Law2_ScGeom_FrictPhys_CundallStrack(label="law")],	#for linear model only
					label="interactionLoop"
				),
				GlobalStiffnessTimeStepper(timeStepUpdateInterval=10,label="timeStepper"),
				NewtonIntegrator(label="newton")
			]
		O.bodies.append([utils.sphere((0,0,0),0.5),
			utils.sphere((2,0,0),0.5), #(0,1) no overlap , no contacts
			utils.sphere((0.9,0.9,0),0.5), #(0,2) overlapping bounds, no contacts
			utils.sphere((-0.99,0,0),0.5)]) #(0,3) overlaping + contact
		O.dt=0
		O.dynDt=False
		O.step()
		i=utils.createInteraction(0,1)
		self.assert_(i.iterBorn==1 and i.iterMadeReal==1)
		j=utils.createInteraction(0,2)
		self.assert_(j.iterBorn==1 and j.iterMadeReal==1)
		self.assertRaises(RuntimeError,lambda: utils.createInteraction(0,3))
Example #2
0
	def testErasedAndNewlyCreatedSphere(self):
		"Bodies: The bug is described in LP:1001194. If the new body was created after deletion of previous, it has no bounding box"
		O.reset()
		id1 = O.bodies.append(utils.sphere([0.0, 0.0, 0.0],0.5))
		id2 = O.bodies.append(utils.sphere([0.0, 2.0, 0.0],0.5))
		O.engines=[
			ForceResetter(),
			InsertionSortCollider([Bo1_Sphere_Aabb()]),
			InteractionLoop(
				[Ig2_Sphere_Sphere_L3Geom()],
				[Ip2_FrictMat_FrictMat_FrictPhys()],
				[Law2_L3Geom_FrictPhys_ElPerfPl()]
			),
			NewtonIntegrator(damping=0.1,gravity=(0,0,-9.81))
		]
		O.dt=.5e-4*utils.PWaveTimeStep()
		#Before first step the bodies should not have bounds
		self.assert_(O.bodies[id1].bound==None and O.bodies[id2].bound==None)
		O.run(1, True)
		#After first step the bodies should have bounds
		self.assert_(O.bodies[id1].bound!=None and O.bodies[id2].bound!=None)
		#Add 3rd body
		id3 = O.bodies.append(utils.sphere([0.0, 4.0, 0.0],0.5))
		O.run(1, True)
		self.assert_(O.bodies[id1].bound!=None and O.bodies[id2].bound!=None and O.bodies[id3].bound!=None)
		#Remove 3rd body
		O.bodies.erase(id3)
		O.run(1, True)
		#Add 4th body
		id4 = O.bodies.append(utils.sphere([0.0, 6.0, 0.0],0.5))
		O.run(1, True)
		self.assert_(O.bodies[id1].bound!=None and O.bodies[id2].bound!=None and O.bodies[id4].bound!=None)
Example #3
0
 def SpherePack_toSimulation(self,rot=Matrix3.Identity,**kw):
   """Append spheres directly to the simulation. In addition calling :yref:`O.bodies.append<BodyContainer.append>`,
 this method also appropriately sets periodic cell information of the simulation.
 
   >>> from yade import pack; from math import *
   >>> sp=pack.SpherePack()
 
 Create random periodic packing with 20 spheres:
 
   >>> sp.makeCloud((0,0,0),(5,5,5),rMean=.5,rRelFuzz=.5,periodic=True,num=20)
   20
 
 Virgin simulation is aperiodic:
 
   >>> O.reset()
   >>> O.periodic
   False
 
 Add generated packing to the simulation, rotated by 45° along +z
 
   >>> sp.toSimulation(rot=Quaternion((0,0,1),pi/4),color=(0,0,1))
   [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
 
 Periodic properties are transferred to the simulation correctly, including rotation (this could be avoided by explicitly passing "hSize=O.cell.hSize" as an argument):
 
   >>> O.periodic
   True
   >>> O.cell.refSize
   Vector3(5,5,5)
   >>> O.cell.hSize
   Matrix3(3.53553,-3.53553,0, 3.53553,3.53553,0, 0,0,5)
 
 The current state (even if rotated) is taken as mechanically undeformed, i.e. with identity transformation:
 
   >>> O.cell.trsf
   Matrix3(1,0,0, 0,1,0, 0,0,1)
 
 :param Quaternion/Matrix3 rot: rotation of the packing, which will be applied on spheres and will be used to set :yref:`Cell.trsf` as well.
 :param \*\*kw: passed to :yref:`yade.utils.sphere`
 :return: list of body ids added (like :yref:`O.bodies.append<BodyContainer.append>`)
 """
   if isinstance(rot,Quaternion): rot=rot.toRotationMatrix()
   assert(isinstance(rot,Matrix3))
   if self.isPeriodic: O.periodic=True
   if self.cellSize!=Vector3.Zero and self.isPeriodic:
     O.cell.hSize=rot*Matrix3(self.cellSize[0],0,0, 0,self.cellSize[1],0, 0,0,self.cellSize[2])
     O.cell.trsf=Matrix3.Identity
   if not self.hasClumps():
     return O.bodies.append([utils.sphere(rot*c,r,**kw) for c,r in self])
   else:
     standalone,clumps=self.getClumps()
     ids=O.bodies.append([utils.sphere(rot*c,r,**kw) for c,r in self]) # append all spheres first
     clumpIds=[]
     userColor='color' in kw
     for clump in clumps:
       clumpIds.append(O.bodies.clump(clump)) # clump spheres with given ids together, creating the clump object as well
       # make all spheres within one clump a single color, unless color was specified by the user
       if not userColor:
         for i in clump[1:]: O.bodies[i].shape.color=O.bodies[clump[0]].shape.color
     return ids+clumpIds
Example #4
0
	def setUp(self):
		O.reset()
		r1,r2,p0,p1=1,.5,Vector3.Zero,Vector3(0,0,3)
		self.idC,(self.id1,self.id2)=O.bodies.appendClumped([
			utils.sphere(p0,r1),
			utils.sphere(p1,r2)
		])
Example #5
0
	def setUp(self):
		# common setup for all tests in this class
		O.reset()
		O.materials.append([
			FrictMat(young=1,label='materialZero'),
			ElastMat(young=100,label='materialOne')
		])
		O.bodies.append([
			utils.sphere([0,0,0],.5,material=0),
			utils.sphere([1,1,1],.5,material=0),
			utils.sphere([1,1,1],.5,material=1)
		])
Example #6
0
File: pbc.py Project: tufubin/trunk
	def setUp(self):
		O.reset(); O.periodic=True;
		O.cell.setBox(2.5,2.5,3)
		self.cellDist=Vector3i(0,0,10) # how many cells away we go
		self.relDist=Vector3(0,.999999999999999999,0) # rel position of the 2nd ball within the cell
		self.initVel=Vector3(0,0,5)
		O.bodies.append(utils.sphere((1,1,1),.5))
		self.initPos=Vector3([O.bodies[0].state.pos[i]+self.relDist[i]+self.cellDist[i]*O.cell.refSize[i] for i in (0,1,2)])
		O.bodies.append(utils.sphere(self.initPos,.5))
		#print O.bodies[1].state.pos
		O.bodies[1].state.vel=self.initVel
		O.engines=[NewtonIntegrator(warnNoForceReset=False)]
		O.cell.velGrad=Matrix3(0,0,0, 0,0,0, 0,0,-1)
		O.dt=0 # do not change positions with dt=0 in NewtonIntegrator, but still update velocities from velGrad
Example #7
0
def gengeo(mntable,shift=Vector3.Zero,scale=1.0,**kw):
	""" Imports geometry from LSMGenGeo library and creates spheres.
	Since 2012 the package is available in Debian/Ubuntu and known as python-demgengeo
	http://packages.qa.debian.org/p/python-demgengeo.html

	:Parameters:
		`mntable`: mntable
			object, which creates by LSMGenGeo library, see example
		`shift`: [float,float,float]
			[X,Y,Z] parameter moves the specimen.
		`scale`: float
			factor scales the given data.
		`**kw`: (unused keyword arguments)
				is passed to :yref:`yade.utils.sphere`
	
	LSMGenGeo library allows one to create pack of spheres
	with given [Rmin:Rmax] with null stress inside the specimen.
	Can be useful for Mining Rock simulation.
	
	Example: :ysrc:`examples/packs/packs.py`, usage of LSMGenGeo library in :ysrc:`examples/test/genCylLSM.py`.
	
	* https://answers.launchpad.net/esys-particle/+faq/877
	* http://www.access.edu.au/lsmgengeo_python_doc/current/pythonapi/html/GenGeo-module.html
	* https://svn.esscc.uq.edu.au/svn/esys3/lsm/contrib/LSMGenGeo/"""
	try:
		from GenGeo import MNTable3D,Sphere
	except ImportError:
		from gengeo import MNTable3D,Sphere
	ret=[]
	sphereList=mntable.getSphereListFromGroup(0)
	for i in range(0, len(sphereList)):
		r=sphereList[i].Radius()
		c=sphereList[i].Centre()
		ret.append(utils.sphere([shift[0]+scale*float(c.X()),shift[1]+scale*float(c.Y()),shift[2]+scale*float(c.Z())],scale*float(r),**kw))
	return ret
Example #8
0
def filterSpherePack(predicate, spherePack, returnSpherePack=None, **kw):
    """Using given SpherePack instance, return spheres the satisfy predicate.
	The packing will be recentered to match the predicate and warning is given if the predicate
	is larger than the packing."""
    if returnSpherePack == None:
        warnings.warn(
            'The default behavior will change; specify returnSpherePack=True for the new behavior, and False to get rid of this warning (your code will break in the future, however). The returned SpherePack object can be added to the simulation using SpherePack.toSimulation()',
            category=FutureWarning)
        returnSpherePack = False
    mn, mx = predicate.aabb()
    dimP, centP = predicate.dim(), predicate.center()
    dimS, centS = spherePack.dim(), spherePack.center()
    if dimP[0] > dimS[0] or dimP[1] > dimS[1] or dimP[2] > dimS[2]:
        warnings.warn(
            "Packing's dimension (%s) doesn't fully contain dimension of the predicate (%s)."
            % (dimS, dimP))
    spherePack.translate(centP - centS)
    if returnSpherePack:
        ret = SpherePack()
        for c, r in spherePack:
            if predicate(c, r): ret.add(c, r)
        return ret
    else:
        # return particles to be added to O.bodies
        ret = []
        for s in spherePack:
            if predicate(s[0], s[1]):
                ret += [utils.sphere(s[0], radius=s[1], **kw)]
        return ret
Example #9
0
def regularHexa(predicate, radius, gap, **kw):
    """Return set of spheres in regular hexagonal grid, clipped inside solid given by predicate.
	Created spheres will have given radius and will be separated by gap space."""
    ret = []
    a = 2 * radius + gap
    # thanks to Nasibeh Moradi for finding bug here:
    # http://www.mail-archive.com/yade-users@lists.launchpad.net/msg01424.html
    hy, hz = a * sqrt(3) / 2., a * sqrt(6) / 3.
    mn, mx = predicate.aabb()
    dim = [mx[i] - mn[i] for i in 0, 1, 2]
    if (max(dim) == float('inf')):
        raise ValueError(
            "Aabb of the predicate must not be infinite (didn't you use union | instead of intersection & for unbounded predicate such as notInNotch?"
        )
    ii, jj, kk = [
        range(0,
              int(dim[0] / a) + 1),
        range(0,
              int(dim[1] / hy) + 1),
        range(0,
              int(dim[2] / hz) + 1)
    ]
    for i, j, k in itertools.product(ii, jj, kk):
        x, y, z = mn[0] + radius + i * a, mn[1] + radius + j * hy, mn[
            2] + radius + k * hz
        if j % 2 == 0: x += a / 2. if k % 2 == 0 else -a / 2.
        if k % 2 != 0:
            x += a / 2.
            y += hy / 2.
        if predicate((x, y, z), radius):
            ret += [utils.sphere((x, y, z), radius=radius, **kw)]
    return ret
Example #10
0
def randomPeriPack(radius,initSize,rRelFuzz=0.0,memoizeDb=None,noPrint=False):
	"""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
	sp=_getMemoizedPacking(memoizeDb,radius,rRelFuzz,initSize[0],initSize[1],initSize[2],fullDim=Vector3(0,0,0),wantPeri=True,fillPeriodic=False,spheresInCell=-1,memoDbg=True,noPrint=noPrint)
	if sp: return sp
	O.switchScene(); O.resetThisScene()
	sp=SpherePack()
	O.periodic=True
	#O.cell.refSize=initSize
	O.cell.setBox(initSize)
	sp.makeCloud(Vector3().Zero,O.cell.refSize,radius,rRelFuzz,-1,True)
	O.engines=[ForceResetter(),InsertionSortCollider([Bo1_Sphere_Aabb()],nBins=2,verletDist=.05*radius),InteractionLoop([Ig2_Sphere_Sphere_ScGeom()],[Ip2_FrictMat_FrictMat_FrictPhys()],[Law2_ScGeom_FrictPhys_CundallStrack()]),PeriIsoCompressor(charLen=2*radius,stresses=[-100e9,-1e8],maxUnbalanced=1e-2,doneHook='O.pause();',globalUpdateInt=20,keepProportions=True),NewtonIntegrator(damping=.8)]
	O.materials.append(FrictMat(young=30e9,frictionAngle=.1,poisson=.3,density=1e3))
	for s in sp: O.bodies.append(utils.sphere(s[0],s[1]))
	O.dt=utils.PWaveTimeStep()
	O.timingEnabled=True
	O.run(); O.wait()
	ret=SpherePack()
	ret.fromSimulation()
	_memoizePacking(memoizeDb,ret,radius,rRelFuzz,wantPeri=True,fullDim=Vector3(0,0,0),noPrint=noPrint) # fullDim unused
	O.switchScene()
	return ret
Example #11
0
	def testEraseBodiesInInteraction(self):
		O.reset()
		id1 = O.bodies.append(utils.sphere([0.5,0.5,0.0+0.095],.1))
		id2 = O.bodies.append(utils.sphere([0.5,0.5,0.0+0.250],.1))
		O.engines=[
			ForceResetter(),
			InsertionSortCollider([Bo1_Sphere_Aabb()]),
			InteractionLoop(
				[Ig2_Sphere_Sphere_L3Geom()],
				[Ip2_FrictMat_FrictMat_FrictPhys()],
				[Law2_L3Geom_FrictPhys_ElPerfPl()]
			),
			NewtonIntegrator(damping=0.1,gravity=(0,0,-9.81))
		]
		O.dt=.5e-4*utils.PWaveTimeStep()
		O.step()
		O.bodies.erase(id1)
		O.step()
Example #12
0
def textExt(fileName,format='x_y_z_r',shift=Vector3.Zero,scale=1.0,attrs=[],**kw):
	"""Load sphere coordinates from file in specific format, returns a list of corresponding bodies; that may be inserted to the simulation with O.bodies.append().
	
	:param str filename: file name
	:param str format: the name of output format. Supported `x_y_z_r`(default), `x_y_z_r_matId`, 'x_y_z_r_attrs'
	:param [float,float,float] shift: [X,Y,Z] parameter moves the specimen.
	:param float scale: factor scales the given data.
	:param list attrs: attrs read from file if export.textExt(format='x_y_z_r_attrs') were used ('passed by refernece' style)
	:param \*\*kw: (unused keyword arguments) is passed to :yref:`yade.utils.sphere`
	:returns: list of spheres.

	Lines starting with # are skipped
	"""
	infile = open(fileName,"r")
	lines = infile.readlines()
	infile.close()
	ret=[]
	for line in lines:
		data = line.split()
		if (data[0] == "#format"):
			format=data[1]
			continue
		elif (data[0][0] == "#"): continue
		
		if (format=='x_y_z_r'):
			pos = Vector3(float(data[0]),float(data[1]),float(data[2]))
			ret.append(utils.sphere(shift+scale*pos,scale*float(data[3]),**kw))
		elif (format=='x_y_z_r_matId'):
			pos = Vector3(float(data[0]),float(data[1]),float(data[2]))
			ret.append(utils.sphere(shift+scale*pos,scale*float(data[3]),material=int(data[4]),**kw))
		
		elif (format=='id_x_y_z_r_matId'):
			pos = Vector3(float(data[1]),float(data[2]),float(data[3]))
			ret.append(utils.sphere(shift+scale*pos,scale*float(data[4]),material=int(data[5]),**kw))

		elif (format=='x_y_z_r_attrs'):
			pos = Vector3(float(data[0]),float(data[1]),float(data[2]))
			s = utils.sphere(shift+scale*pos,scale*float(data[3]),**kw)
			ret.append(s)
			attrs.append(data[4:])
			
		else:
			raise RuntimeError("Please, specify a correct format output!");
	return ret
Example #13
0
def regularOrtho(predicate,radius,gap,**kw):
	"""Return set of spheres in regular orthogonal grid, clipped inside solid given by predicate.
	Created spheres will have given radius and will be separated by gap space."""
	ret=[]
	mn,mx=predicate.aabb()
	if(max([mx[i]-mn[i] for i in 0,1,2])==float('inf')): raise ValueError("Aabb of the predicate must not be infinite (didn't you use union | instead of intersection & for unbounded predicate such as notInNotch?");
	xx,yy,zz=[arange(mn[i]+radius,mx[i]-radius,2*radius+gap) for i in 0,1,2]
	for xyz in itertools.product(xx,yy,zz):
		if predicate(xyz,radius): ret+=[utils.sphere(xyz,radius=radius,**kw)]
	return ret
Example #14
0
def textClumps(fileName,shift=Vector3.Zero,discretization=0,orientation=Quaternion((0,1,0),0.0),scale=1.0,**kw):
	"""Load clumps-members from file, insert them to the simulation.
	
	:param str filename: file name
	:param str format: the name of output format. Supported `x_y_z_r`(default), `x_y_z_r_clumpId`
	:param [float,float,float] shift: [X,Y,Z] parameter moves the specimen.
	:param float scale: factor scales the given data.
	:param \*\*kw: (unused keyword arguments) is passed to :yref:`yade.utils.sphere`
	:returns: list of spheres.

	Lines starting with # are skipped
	"""
	infile = open(fileName,"r")
	lines = infile.readlines()
	infile.close()
	ret=[]
	
	curClump=[]
	newClumpId = -1
	
	for line in lines:
		data = line.split()
		if (data[0][0] == "#"): continue
		pos = orientation*Vector3(float(data[0]),float(data[1]),float(data[2]))
	
		if (newClumpId<0 or newClumpId==int(data[4])):
			idD = curClump.append(utils.sphere(shift+scale*pos,scale*float(data[3]),**kw))
			newClumpId = int(data[4])
		else:
			newClumpId = int(data[4])
			ret.append(O.bodies.appendClumped(curClump,discretization=discretization))
			curClump=[]
			idD = curClump.append(utils.sphere(shift+scale*pos,scale*float(data[3]),**kw))
	
	if (len(curClump)<>0):
		ret.append(O.bodies.appendClumped(curClump,discretization=discretization))
	
	# Set the mask to a clump the same as the first member of it
	for i in range(len(ret)):
		O.bodies[ret[i][0]].mask = O.bodies[ret[i][1][0]].mask
	return ret
Example #15
0
def textExt(fileName,format='x_y_z_r',shift=Vector3.Zero,scale=1.0,**kw):
	"""Load sphere coordinates from file in specific format, create spheres, insert them to the simulation.
	
	:Parameters:
		`filename`: string
		`format`:
			the name of output format. Supported `x_y_z_r`(default), `x_y_z_r_matId`
		`shift`: [float,float,float]
			[X,Y,Z] parameter moves the specimen.
		`scale`: float
			factor scales the given data.
		`**kw`: (unused keyword arguments)
				is passed to :yref:`yade.utils.sphere`
	:Returns: list of spheres.
	Lines starting with # are skipped
	"""
	infile = open(fileName,"r")
	lines = infile.readlines()
	infile.close()
	ret=[]
	for line in lines:
		data = line.split()
		if (data[0] == "#format"):
			format=data[1]
			continue
		elif (data[0][0] == "#"): continue
		
		if (format=='x_y_z_r'):
			pos = Vector3(float(data[0]),float(data[1]),float(data[2]))
			ret.append(utils.sphere(shift+scale*pos,scale*float(data[3]),**kw))
		elif (format=='x_y_z_r_matId'):
			pos = Vector3(float(data[0]),float(data[1]),float(data[2]))
			ret.append(utils.sphere(shift+scale*pos,scale*float(data[3]),material=int(data[4]),**kw))
		
		elif (format=='id_x_y_z_r_matId'):
			pos = Vector3(float(data[1]),float(data[2]),float(data[3]))
			ret.append(utils.sphere(shift+scale*pos,scale*float(data[4]),material=int(data[5]),**kw))
			
		else:
			raise RuntimeError("Please, specify a correct format output!");
	return ret
def fill_cylinder_with_spheres(sphereRadius,cylinderRadius,cylinderHeight,cylinderOrigin,cylinderSlope):
	spheresCount=0
	for h in xrange(0,int(cylinderHeight/sphereRadius/2)):
			for r in xrange(1,int(cylinderRadius/sphereRadius/2)):
				dfi = asin(0.5/r)*2
				for a in xrange(0,int(6.28/dfi)):
					x = cylinderOrigin[0]+2*r*sphereRadius*cos(dfi*a)
					y = cylinderOrigin[1]+2*r*sphereRadius*sin(dfi*a)
					z = cylinderOrigin[2]+h*2*sphereRadius
					s=utils.sphere([x,y*cos(cylinderSlope)+z*sin(cylinderSlope),z*cos(cylinderSlope)-y*sin(cylinderSlope)],sphereRadius)
					O.bodies.append(s)
					spheresCount+=1
	return spheresCount
Example #17
0
File: pack.py Project: DEMANY/trunk
def regularHexa(predicate,radius,gap,**kw):
	"""Return set of spheres in regular hexagonal grid, clipped inside solid given by predicate.
	Created spheres will have given radius and will be separated by gap space."""
	ret=[]
	a=2*radius+gap
	hy,hz=a*sqrt(3)/2.,a*sqrt(6)/3.
	mn,mx=predicate.aabb()
	dim=[mx[i]-mn[i] for i in 0,1,2]
	if(max(dim)==float('inf')): raise ValueError("Aabb of the predicate must not be infinite (didn't you use union | instead of intersection & for unbounded predicate such as notInNotch?");
	ii,jj,kk=[range(0,int(dim[0]/a)+1),range(0,int(dim[1]/hy)+1),range(0,int(dim[2]/hz)+1)]
	for i,j,k in itertools.product(ii,jj,kk):
		#Simple HCP-lattice packing
		#http://en.wikipedia.org/wiki/Close-packing_of_equal_spheres#Simple_hcp_lattice
		coordSph = Vector3((2*i + ((j + k) % 2 ) ),
											(sqrt(3.)*(j + 1./3.*(k % 2))),
											(2.*sqrt(6.)/3.*k))*(a/2.0) + mn
		if predicate(coordSph,radius): ret+=[utils.sphere(coordSph,radius=radius,**kw)]
	if (len(ret)==0):
		warnings.warn('No spheres are produced by regularHexa-function',category=RuntimeWarning)
	return ret
Example #18
0
def gengeoFile(fileName="file.geo",shift=Vector3.Zero,scale=1.0,orientation=Quaternion((0,1,0),0.0),**kw):
	""" Imports geometry from LSMGenGeo .geo file and creates spheres. 
	Since 2012 the package is available in Debian/Ubuntu and known as python-demgengeo
	http://packages.qa.debian.org/p/python-demgengeo.html
	
	:Parameters:
		`filename`: string
			file which has 4 colums [x, y, z, radius].
		`shift`: Vector3
			Vector3(X,Y,Z) parameter moves the specimen.
		`scale`: float
			factor scales the given data.
		`orientation`: quaternion
			orientation of the imported geometry
		`**kw`: (unused keyword arguments)
				is passed to :yref:`yade.utils.sphere`
	:Returns: list of spheres.
	
	LSMGenGeo library allows one to create pack of spheres
	with given [Rmin:Rmax] with null stress inside the specimen.
	Can be useful for Mining Rock simulation.
	
	Example: :ysrc:`examples/packs/packs.py`, usage of LSMGenGeo library in :ysrc:`examples/test/genCylLSM.py`.
	
	* https://answers.launchpad.net/esys-particle/+faq/877
	* http://www.access.edu.au/lsmgengeo_python_doc/current/pythonapi/html/GenGeo-module.html
	* https://svn.esscc.uq.edu.au/svn/esys3/lsm/contrib/LSMGenGeo/"""
	from yade.utils import sphere

	infile = open(fileName,"r")
	lines = infile.readlines()
	infile.close()

	numSpheres = int(lines[6].split()[0])
	ret=[]
	for line in lines[7:numSpheres+7]:
		data = line.split()
		pos = orientation*Vector3(float(data[0]),float(data[1]),float(data[2]))
		ret.append(utils.sphere(shift+scale*pos,scale*float(data[3]),**kw))
	return ret
Example #19
0
File: core.py Project: yade/trunk
	def testMatchMakerCollisions(self):
		fr = 0.5;rho=2000
		tc = 0.001; en = 0.5; et = 0.5;
		mat1 = O.materials.append(ViscElMat(frictionAngle=fr,tc=tc,en=en,et=et,density=rho))
		mat2 = O.materials.append(ViscElMat(frictionAngle=fr,tc=tc,en=en,et=et,density=rho))
		mat3 = O.materials.append(ViscElMat(frictionAngle=fr,tc=tc,en=en,et=et,density=rho))
		r1 = 0.002381
		r2 = 0.002381
		id11 = O.bodies.append(utils.sphere(center=[0,0,0],radius=r1,material=mat1,fixed=True,color=[0,0,1]))
		id12 = O.bodies.append(utils.sphere(center=[0,0,(r1+r2)],radius=r2,material=mat2,fixed=False,color=[0,0,1]))
		
		id21 = O.bodies.append(utils.sphere(center=[3*r1,0,0],radius=r1,material=mat1,fixed=True,color=[0,1,0]))
		id22 = O.bodies.append(utils.sphere(center=[3*r1,0,(r1+r2)],radius=r2,material=mat3,fixed=False,color=[0,1,0]))
		
		id31 = O.bodies.append(utils.sphere(center=[6*r1,0,0],radius=r1,material=mat2,fixed=True,color=[1,0,0]))
		id32 = O.bodies.append(utils.sphere(center=[6*r1,0,(r1+r2)],radius=r2,material=mat3,fixed=False,color=[1,0,0]))
		
		O.engines = [
			ForceResetter(),
			InsertionSortCollider([Bo1_Sphere_Aabb()],verletDist=r1*10.0),
			InteractionLoop(
				[Ig2_Sphere_Sphere_ScGeom()],
				[Ip2_ViscElMat_ViscElMat_ViscElPhys( 
					en=MatchMaker(matches=((mat1,mat2,.1),(mat1,mat3,.2),(mat2,mat3,.4))),
					et=MatchMaker(matches=((mat1,mat2,.7),(mat1,mat3,.8),(mat2,mat3,.9))),
					frictAngle=MatchMaker(matches=((mat1,mat2,.1),(mat1,mat3,.2),(mat2,mat3,.3)))
				)],
				[Law2_ScGeom_ViscElPhys_Basic()],
				),
			NewtonIntegrator(damping=0,gravity=[0,0,-9.81]),
		]
		
		O.step()
		self.assertTrue((atan(O.interactions[id11,id12].phys.tangensOfFrictionAngle)-0.1)==0)
		self.assertTrue((atan(O.interactions[id21,id22].phys.tangensOfFrictionAngle)-0.2)==0)
		self.assertTrue((atan(O.interactions[id31,id32].phys.tangensOfFrictionAngle)-0.3)==0)
		
		self.assertTrue(round(O.interactions[id11,id12].phys.cn, 3) - 0.26 == 0)
		self.assertTrue(round(O.interactions[id21,id22].phys.cn, 3) - 0.182 == 0)
		self.assertTrue(round(O.interactions[id31,id32].phys.cn, 3) - 0.104 == 0)

		self.assertTrue(round(O.interactions[id11,id12].phys.cs, 3) - 0.012== 0)
		self.assertTrue(round(O.interactions[id21,id22].phys.cs, 3) - 0.007 == 0)
		self.assertTrue(round(O.interactions[id31,id32].phys.cs, 3) - 0.003 == 0)
Example #20
0
	def testKinematicEngines(self):
		'Engines: kinematic engines'
		tolerance = 1e-5
		rotIndex=1.0
		angVelTemp = pi/rotIndex
		O.reset()
		id_fixed_transl = O.bodies.append(utils.sphere((0.0,0.0,0.0),1.0,fixed=True))
		id_nonfixed_transl = O.bodies.append(utils.sphere((0.0,5.0,0.0),1.0,fixed=False))
		id_fixed_rot = O.bodies.append(utils.sphere((0.0,10.0,10.0),1.0,fixed=True))
		id_nonfixed_rot = O.bodies.append(utils.sphere((0.0,15.0,10.0),1.0,fixed=False))
		id_fixed_helix = O.bodies.append(utils.sphere((0.0,20.0,10.0),1.0,fixed=True))
		id_nonfixed_helix = O.bodies.append(utils.sphere((0.0,25.0,10.0),1.0,fixed=False))
		O.engines=[
			TranslationEngine(velocity = 1.0, translationAxis = [1.0,0,0], ids = [id_fixed_transl]),
			TranslationEngine(velocity = 1.0, translationAxis = [1.0,0,0], ids = [id_nonfixed_transl]),
			RotationEngine(angularVelocity = pi/angVelTemp, rotationAxis = [0.0,1.0,0.0], rotateAroundZero = True, zeroPoint = [0.0,0.0,0.0], ids = [id_fixed_rot]),
			RotationEngine(angularVelocity = pi/angVelTemp, rotationAxis = [0.0,1.0,0.0], rotateAroundZero = True, zeroPoint = [0.0,5.0,0.0], ids = [id_nonfixed_rot]),
			HelixEngine(angularVelocity = pi/angVelTemp, rotationAxis = [0.0,1.0,0.0], linearVelocity = 1.0, zeroPoint = [0.0,0.0,0.0], ids = [id_fixed_helix]),
			HelixEngine(angularVelocity = pi/angVelTemp, rotationAxis = [0.0,1.0,0.0], linearVelocity = 1.0, zeroPoint = [0.0,5.0,0.0], ids = [id_nonfixed_helix]),
			ForceResetter(),
			NewtonIntegrator()
		]
		O.dt = 1.0
		for i in range(0,2):
			O.step()
			self.assertTrue(abs(O.bodies[id_fixed_transl].state.pos[0] - O.iter) < tolerance)												#Check translation of fixed bodies
			self.assertTrue(abs(O.bodies[id_nonfixed_transl].state.pos[0] - O.iter) < tolerance)										#Check translation of nonfixed bodies
			
			self.assertTrue(abs(O.bodies[id_fixed_rot].state.pos[0]-10.0*sin(pi/angVelTemp*O.iter))<tolerance)			#Check rotation of fixed bodies X
			self.assertTrue(abs(O.bodies[id_fixed_rot].state.pos[2]-10.0*cos(pi/angVelTemp*O.iter))<tolerance)			#Check rotation of fixed bodies Y
			self.assertTrue(abs(O.bodies[id_fixed_rot].state.ori.toAxisAngle()[1]-Quaternion(Vector3(0.0,1.0,0.0),pi/angVelTemp*O.iter).toAxisAngle()[1])<tolerance)		#Check rotation of fixed bodies, angle
			
			self.assertTrue(abs(O.bodies[id_nonfixed_rot].state.pos[0] - 10*sin(pi/angVelTemp*O.iter))<tolerance)		#Check rotation of nonfixed bodies X
			self.assertTrue(abs(O.bodies[id_nonfixed_rot].state.pos[2] - 10*cos(pi/angVelTemp*O.iter))<tolerance)		#Check rotation of nonfixed bodies Y
			self.assertTrue(abs(O.bodies[id_nonfixed_rot].state.ori.toAxisAngle()[1]-Quaternion(Vector3(0.0,1.0,0.0),pi/angVelTemp*O.iter).toAxisAngle()[1])<tolerance)		#Check rotation of nonfixed bodies, angle
						
			self.assertTrue(abs(O.bodies[id_fixed_helix].state.pos[0] - 10*sin(pi/angVelTemp*O.iter))<tolerance)		#Check helixEngine of fixed bodies X
			self.assertTrue(abs(O.bodies[id_fixed_helix].state.pos[2] - 10*cos(pi/angVelTemp*O.iter))<tolerance)		#Check helixEngine of fixed bodies Y
			self.assertTrue(abs(O.bodies[id_fixed_helix].state.pos[1]-20.0 - O.iter)<tolerance)		#Check helixEngine of fixed bodies Z
			
			self.assertTrue(abs(O.bodies[id_nonfixed_helix].state.pos[0] - 10*sin(pi/angVelTemp*O.iter))<tolerance)		#Check helixEngine of nonfixed bodies X
			self.assertTrue(abs(O.bodies[id_nonfixed_helix].state.pos[2] - 10*cos(pi/angVelTemp*O.iter))<tolerance)		#Check helixEngine of nonfixed bodies Y
			self.assertTrue(abs(O.bodies[id_nonfixed_helix].state.pos[1]-25.0 - O.iter)<tolerance)		#Check helixEngine of nonfixed bodies Z
Example #21
0
Rs=0.02 # mean particle radius
Rf=0.01 # dispersion (Rs±Rf*Rs)
nSpheres=1000# number of particles

# Create geometry
pln=Plane( (-.5, -.5, 0), (.5, -.5, -.05), (.5, .5, 0), (-.5, .5, -.05) ); 
plnIds=O.bodies.append(pack.gtsSurface2Facets(pln.faces(),material=facetMat,color=(0,1,0)))

fct=Plane( (-.25, -.25, .5), (.25, -.25, .5), (.25, .25, .5), (-.25, .25, .5) ); 
fctIds=O.bodies.append(pack.gtsSurface2Facets(fct.faces(),material=facetMat,color=(1,0,0),noBound=True))

# Create spheres
sp=pack.SpherePack(); 
sp.makeCloud(Vector3(-.5, -.5, 0),Vector3(.5, .5, .2), Rs, Rf, int(nSpheres), False)
spheres=O.bodies.append([utils.sphere(s[0],s[1],color=(0.929,0.412,0.412),material=dfltSpheresMat) for s in sp])
for id in spheres:
	s=O.bodies[id]
	p=utils.getViscoelasticFromSpheresInteraction(s.state['mass'],tc,en,es)
	s.mat['kn'],s.mat['cn'],s.mat['ks'],s.mat['cs']=p['kn'],p['cn'],p['ks'],p['cs']

# Create engines
O.engines=[
	ForceResetter(),
	InsertionSortCollider([Bo1_Sphere_Aabb(),Bo1_Facet_Aabb()]),
	InteractionLoop(
		[Ig2_Sphere_Sphere_ScGeom(), Ig2_Facet_Sphere_ScGeom()],
		[Ip2_ViscElMat_ViscElMat_ViscElPhys()],
		[Law2_ScGeom_ViscElPhys_Basic()],
	),
	GravityEngine(gravity=[0,0,-9.81]),
Example #22
0
	InteractionLoop(
		[Ig2_Sphere_Sphere_ScGeom(),Ig2_Box_Sphere_ScGeom()],
		[Ip2_FrictMat_FrictMat_FrictPhys()],
		[Law2_ScGeom_FrictPhys_CundallStrack()]
	),
	NewtonIntegrator(damping=.2,gravity=(0,0,-9.81)),
	###
	### NOTE this extra engine:
	###
	### You want snapshot to be taken every 1 sec (realTimeLim) or every 50 iterations (iterLim),
	### whichever comes soones. virtTimeLim attribute is unset, hence virtual time period is not taken into account.
	PyRunner(iterPeriod=20,command='myAddPlotData()')
]
from yade import utils
O.bodies.append(utils.box(center=[0,0,0],extents=[.5,.5,.5],fixed=True,color=[1,0,0]))
O.bodies.append(utils.sphere([0,0,2],1,color=[0,1,0]))
O.dt=.002*utils.PWaveTimeStep()


############################################
##### now the part pertaining to plots #####
############################################

from math import *
from yade import plot
## we will have 2 plots:
## 1. t as function of i (joke test function)
## 2. i as function of t on left y-axis ('|||' makes the separation) and z_sph, v_sph (as green circles connected with line) and z_sph_half again as function of t
plot.plots={'i':('t'),'t':('z_sph',None,('v_sph','go-'),'z_sph_half')}

## this function is called by plotDataCollector
Example #23
0
"""
Show basic wall functionality (infinite axis-aligned planes).
"""
from yade import utils
O.materials.append(FrictMat(young=30e9,density=1000,poisson=.2,frictionAngle=.5)
O.bodies.append([
	utils.wall(1,axis=2,sense=-1),
	utils.wall(-5,axis=0,sense=1),
	utils.wall(1,axis=1),
	utils.wall((1,0,0),0),
	utils.sphere([0,0,0],.5),
	utils.sphere([-5,-4,-3],.5)
])
Gl1_Wall(div=10)

from yade import qt
qt.Controller()
qt.View()


O.engines=[
	ForceResetter(),
	InsertionSortCollider([Bo1_Sphere_Aabb(),Bo1_Facet_Aabb(),Bo1_Wall_Aabb()]),
	InteractionLoop(
		[Ig2_Sphere_Sphere_Dem3DofGeom(),Ig2_Facet_Sphere_Dem3DofGeom(),Ig2_Wall_Sphere_Dem3DofGeom()],
		[Ip2_FrictMat_FrictMat_FrictPhys()],
		[Law2_Dem3DofGeom_FrictPhys_CundallStrack()],
	),
	GravityEngine(gravity=[1e2,1e2,1e2]),
	NewtonIntegrator(damping=0.01),
	]
from yade import utils

sphereRadius=0.1
tc=0.001# collision time 
en=1  # normal restitution coefficient
es=1  # tangential restitution coefficient
density=2700
frictionAngle=radians(35)# 
params=utils.getViscoelasticFromSpheresInteraction(tc,en,es)
sphereMat=O.materials.append(ViscElMat(density=density,frictionAngle=frictionAngle,**params))


# Spheres
sphId=O.bodies.append([
	utils.sphere( (0.4,0.5,0.5), 0.1, material=sphereMat),
	utils.sphere( (0.6,0.5,0.5), 0.1, material=sphereMat)
	])
O.bodies[sphId[-1]].state.vel=(0.5,0,0)
O.bodies[sphId[0]].state.vel=(-0.5,0,0)

## Engines 
O.engines=[
	ForceResetter(),
	InsertionSortCollider([Bo1_Sphere_Aabb(),Bo1_Facet_Aabb()]),
	InteractionLoop(
		[Ig2_Sphere_Sphere_ScGeom()],
		[Ip2_ViscElMat_ViscElMat_ViscElPhys()],
		[Law2_ScGeom_ViscElPhys_Basic()],
	),
	NewtonIntegrator(damping=0),
Example #25
0
# -*- coding: utf-8 -*-


O.engines=[
	ForceResetter(),
	InsertionSortCollider([Bo1_Sphere_Aabb(),]),
	IGeomDispatcher([Ig2_Sphere_Sphere_Dem3DofGeom()]),
	IPhysDispatcher([Ip2_2xFrictMat_CSPhys()]),
	LawDispatcher([Law2_Dem3Dof_CSPhys_CundallStrack()]),
	NewtonIntegrator(damping = 0.01,gravity=[0,0,-9.81])
]

from yade import utils

O.bodies.append(utils.sphere([0,0,6],1,fixed=False, color=[0,1,0]))
O.bodies.append(utils.sphere([0,0,0],1,fixed=True, color=[0,0,1]))
O.dt=.2*utils.PWaveTimeStep()

from yade import qt
qt.Controller()
qt.View()
Example #26
0
	def setUp(self):
		O.reset()
		self.count=100
		O.bodies.append([utils.sphere([random.random(),random.random(),random.random()],random.random()) for i in range(0,self.count)])
		random.seed()
Example #27
0
# define piecewise lineare stress-strain curve
strainStressValues=[(0.0019230769,2.5e8),(0.0192,3.2195e8),(0.05,3.8292e8),(0.15,5.1219e8),(0.25,5.5854e8),(0.3,5.6585e8),(0.35,5.6585e8)]
# elastic material properties
particleVolume = 4./3.*pow(radius,3)*pi
particleMass = 3.9/1000.
density = particleMass/particleVolume
young = strainStressValues[0][1] / strainStressValues[0][0]
poisson = 0.3


#### material definition
netMat = O.materials.append(WireMat(young=young,poisson=poisson,frictionAngle=radians(30),density=density,isDoubleTwist=False,diameter=d,strainStressValues=strainStressValues,lambdaEps=0.4,lambdak=0.21))


#### create boddies, default: dynamic=True
O.bodies.append( utils.sphere([0,0,0], radius, wire=False, color=[1,0,0], highlight=False, material=netMat) )
O.bodies.append( utils.sphere([0,a,0], radius, wire=False, color=[0,1,0], highlight=False, material=netMat) )

FixedSphere=O.bodies[0]
MovingSphere=O.bodies[1]

FixedSphere.dynamic=True
MovingSphere.dynamic=True


#### initialize values for UniaxialStrainer
bb = utils.uniaxialTestFeatures(axis=1)
negIds,posIds,axis,crossSectionArea=bb['negIds'],bb['posIds'],bb['axis'],bb['area']
strainRateTension = 1./a
setSpeeds = True
# facets material
params=utils.getViscoelasticFromSpheresInteraction(tc,en,es)
facetMat=O.materials.append(ViscElMat(frictionAngle=frictionAngle,**params)) # **params sets kn, cn, ks, cs
# default spheres material
dfltSpheresMat=O.materials.append(ViscElMat(density=density,frictionAngle=frictionAngle,**params)) 

O.dt=.05*tc # time step

Rs=0.1 # particle radius

# Create geometry
box = O.bodies.append(geom.facetBox((0,0,0),(1,1,1),wallMask=31,material=facetMat))

# Create clumps...
for j in xrange(10):
	clpId,sphId=O.bodies.appendClumped([utils.sphere(Vector3(0,Rs*2*i,(j+1)*Rs*2),Rs,material=dfltSpheresMat) for i in xrange(4)])
	

# ... and spheres
sphAloneId=O.bodies.append( [utils.sphere( Vector3(0.5,Rs*2*i,(j+1)*Rs*2), Rs, material=dfltSpheresMat) for i in xrange(4) ] )

# Create engines
O.engines=[
	ForceResetter(),
	InsertionSortCollider([Bo1_Sphere_Aabb(),Bo1_Facet_Aabb()]),
	InteractionLoop(
		[Ig2_Sphere_Sphere_ScGeom(), Ig2_Facet_Sphere_ScGeom()],
		[Ip2_ViscElMat_ViscElMat_ViscElPhys()],
		[Law2_ScGeom_ViscElPhys_Basic()],
	),
	NewtonIntegrator(damping=0,gravity=[0,0,-9.81]),
Example #29
0
def hexaNet( radius, cornerCoord=[0,0,0], xLength=1., yLength=0.5, mos=0.08, a=0.04, b=0.04, startAtCorner=True, isSymmetric=False, **kw ):
	"""Definition of the particles for a hexagonal wire net in the x-y-plane for the WireMatPM.

	:param radius: radius of the particle
	:param cornerCoord: coordinates of the lower left corner of the net
	:param xLenght: net length in x-direction
	:param yLenght: net length in y-direction
	:param mos: mesh opening size (horizontal distance between the double twists)
	:param a: length of double-twist 
	:param b: height of single wire section
	:param startAtCorner: if true the generation starts with a double-twist at the lower left corner
	:param isSymmetric: defines if the net is symmetric with respect to the y-axis

	:return: set of spheres which defines the net (net) and exact dimensions of the net (lx,ly).
	
	note::
	This packing works for the WireMatPM only. The particles at the corner are always generated first. For examples on how to use this packing see examples/WireMatPM. In order to create the proper interactions for the net the interaction radius has to be adapted in the simulation.

	"""
	# check input dimension
	if(xLength<mos): raise ValueError("xLength must be greater than mos!");
	if(yLength<2*a+b): raise ValueError("yLength must be greater than 2*a+b!");
	xstart = cornerCoord[0]
	ystart = cornerCoord[1]
	z = cornerCoord[2]
	ab = a+b
	# number of double twisted sections in y-direction and real length ly
	ny = int( (yLength-a)/ab ) + 1
	ly = ny*a+(ny-1)*b
	jump=0
	# number of sections in x-direction and real length lx
	if isSymmetric:
		nx = int( xLength/mos ) + 1
		lx = (nx-1)*mos
		if not startAtCorner:
			nx+=-1
	else:
		nx = int( (xLength-0.5*mos)/mos ) + 1
		lx = (nx-1)*mos+0.5*mos
	net = []
	# generate corner particles
	if startAtCorner:
		if (ny%2==0): # if ny even no symmetry in y-direction
			net+=[utils.sphere((xstart,ystart+ly,z),radius=radius,**kw)] # upper left corner
			if isSymmetric:
				net+=[utils.sphere((xstart+lx,ystart+ly,z),radius=radius,**kw)] # upper right corner
			else:
				net+=[utils.sphere((xstart+lx,ystart,z),radius=radius,**kw)] # lower right corner
		else: # if ny odd symmetry in y-direction
			if not isSymmetric:
				net+=[utils.sphere((xstart+lx,ystart,z),radius=radius,**kw)] # lower right corner
				net+=[utils.sphere((xstart+lx,ystart+ly,z),radius=radius,**kw)] # upper right corner
		jump=1
	else: # do not start at corner
		if (ny%2==0): # if ny even no symmetry in y-direction
			net+=[utils.sphere((xstart,ystart,z),radius=radius,**kw)] # lower left corner
			if isSymmetric:
				net+=[utils.sphere((xstart+lx,ystart,z),radius=radius,**kw)] # lower right corner
			else:
				net+=[utils.sphere((xstart+lx,ystart+ly,z),radius=radius,**kw)] # upper right corner
		else: # if ny odd symmetry in y-direction
			net+=[utils.sphere((xstart,ystart,z),radius=radius,**kw)] # lower left corner
			net+=[utils.sphere((xstart,ystart+ly,z),radius=radius,**kw)] # upper left corner
			if isSymmetric:
				net+=[utils.sphere((xstart+lx,ystart,z),radius=radius,**kw)] # lower right corner
				net+=[utils.sphere((xstart+lx,ystart+ly,z),radius=radius,**kw)] # upper right corner
		xstart+=0.5*mos
	# generate other particles
	if isSymmetric:
		for i in range(ny):
			y = ystart + i*ab
			for j in range(nx):
				x = xstart + j*mos
				# add two particles of one vertical section (double-twist)
				net+=[utils.sphere((x,y,z),radius=radius,**kw)]
				net+=[utils.sphere((x,y+a,z),radius=radius,**kw)]
			# set values for next section
			xstart = xstart - 0.5*mos*pow(-1,i+jump)
			nx = int(nx + 1*pow(-1,i+jump))
	else:
		for i in range(ny):
			y = ystart + i*ab
			for j in range(nx):
				x = xstart + j*mos
				# add two particles of one vertical section (double-twist)
				net+=[utils.sphere((x,y,z),radius=radius,**kw)]
				net+=[utils.sphere((x,y+a,z),radius=radius,**kw)]
			# set values for next section
			xstart = xstart - 0.5*mos*pow(-1,i+jump)
	return [net,lx,ly]
Example #30
0
		else: print "No suitable packing in database found, running",'PERIODIC compression' if wantPeri else 'triaxial'
		sys.stdout.flush()
	O.switchScene(); O.resetThisScene() ### !!
	if wantPeri:
		# x1,y1,z1 already computed above
		sp=SpherePack()
		O.periodic=True
		#O.cell.refSize=(x1,y1,z1)
		O.cell.setBox((x1,y1,z1))
		#print cloudPorosity,beta,gamma,N100,x1,y1,z1,O.cell.refSize
		#print x1,y1,z1,radius,rRelFuzz
		O.materials.append(FrictMat(young=3e10,density=2400))
		num=sp.makeCloud(Vector3().Zero,O.cell.refSize,radius,rRelFuzz,spheresInCell,True)
		O.engines=[ForceResetter(),InsertionSortCollider([Bo1_Sphere_Aabb()],nBins=5,verletDist=.05*radius),InteractionLoop([Ig2_Sphere_Sphere_ScGeom()],[Ip2_FrictMat_FrictMat_FrictPhys()],[Law2_ScGeom_FrictPhys_CundallStrack()]),PeriIsoCompressor(charLen=2*radius,stresses=[-100e9,-1e8],maxUnbalanced=1e-2,doneHook='O.pause();',globalUpdateInt=5,keepProportions=True),NewtonIntegrator(damping=.6)]
		O.materials.append(FrictMat(young=30e9,frictionAngle=.5,poisson=.3,density=1e3))
		for s in sp: O.bodies.append(utils.sphere(s[0],s[1]))
		O.dt=utils.PWaveTimeStep()
		O.run(); O.wait()
		sp=SpherePack(); sp.fromSimulation()
		#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:
		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=1e5,compactionFrictionDeg=1,StabilityCriterion=.05,strainRate=.2,thickness=-1,maxWallVelocity=.1,wallOversizeFactor=1.5,autoUnload=True,autoCompressionActivation=False).load()
		while ( numpy.isnan(utils.unbalancedForce()) or utils.unbalancedForce()>0.005 ) :