def gridNode(center, radius, dynamic=None, fixed=False, wire=False, color=None, highlight=False, material=-1): """ Create a :yref:`GridNode` which is needed to set up :yref:`GridConnections<GridConnection>`. See documentation of :yref:`yade.utils.sphere` for meaning of parameters. :return: Body object with the :yref:`gridNode` :yref:`shape<Body.shape>`. """ b = Body() b.shape = GridNode(radius=radius, color=color if color else utils.randomColor(), wire=wire, highlight=highlight) #V=(4./3)*math.pi*radius**3 # will be overwritten by the connection V = 0. geomInert = (2. / 5.) * V * radius**2 # will be overwritten by the connection utils._commonBodySetup(b, V, Vector3(geomInert, geomInert, geomInert), material, pos=center, dynamic=dynamic, fixed=fixed) b.aspherical = False b.bounded = False b.mask = 0 # avoid contact detection with the nodes. Manual interaction will be set for them in "gridConnection" below. return b
def stl(file, dynamic=None, fixed=True, wire=True, color=None, highlight=False, noBound=False, material=-1): """ Import geometry from stl file, return list of created facets.""" imp = STLImporter() facets = imp.ymport(file) for b in facets: b.shape.color = color if color else utils.randomColor() b.shape.wire = wire b.shape.highlight = highlight pos = b.state.pos utils._commonBodySetup(b, 0, Vector3(0, 0, 0), material=material, pos=pos, noBound=noBound, dynamic=dynamic, fixed=fixed) b.aspherical = False return facets
def polyhedra(material, size=Vector3(1, 1, 1), seed=None, v=[], mask=1, fixed=False, color=[-1, -1, -1]): """create polyhedra, one can specify vertices directly, or leave it empty for random shape. :param Material material: material of new body :param Vector3 size: size of new body (see Polyhedra docs) :param float seed: seed for random operations :param [Vector3] v: list of body vertices (see Polyhedra docs) """ b = Body() random.seed(seed) b.aspherical = True if len(v) > 0: b.shape = Polyhedra(v=v) else: b.shape = Polyhedra(size=size, seed=random.randint(0, 1E6)) if color[0] == -1: b.shape.color = randomColor(seed=random.randint(0, 1E6)) else: b.shape.color = color b.mat = material b.state.mass = b.mat.density * b.shape.GetVolume() b.state.inertia = b.shape.GetInertia() * b.mat.density b.state.ori = b.shape.GetOri() b.state.pos = b.shape.GetCentroid() b.mask = mask if fixed: b.state.blockedDOFs = 'xyzXYZ' return b
def chainedCylinder(begin=Vector3(0, 0, 0), end=Vector3(1., 0., 0.), radius=0.2, dynamic=None, fixed=False, wire=False, color=None, highlight=False, material=-1, mask=1): """ Create and connect a chainedCylinder with given parameters. The shape generated by repeted calls of this function is the Minkowski sum of polyline and sphere. :param Real radius: radius of sphere in the Minkowski sum. :param Vector3 begin: first point positioning the line in the Minkowski sum :param Vector3 last: last point positioning the line in the Minkowski sum In order to build a correct chain, last point of element of rank N must correspond to first point of element of rank N+1 in the same chain (with some tolerance, since bounding boxes will be used to create connections. :return: Body object with the :yref:`ChainedCylinder` :yref:`shape<Body.shape>`. .. note:: :yref:`ChainedCylinder` is deprecated and will be removed in the future, use :yref:`GridConnection` instead. See :yref:`yade.gridpfacet.cylinder` and :yref:`yade.gridpfacet.cylinderConnection`. """ import warnings warnings.warn( '\033[1;31mchainedCylinder is deprecated and will be removed in the future, use GridConnection instead. See examples/grids/CohesiveGridConnectionSphere.py.\033[1;0m', category=UserWarning) segment = end - begin b = Body() b.shape = ChainedCylinder(radius=radius, length=segment.norm(), color=color if color else utils.randomColor(), wire=wire, highlight=highlight) b.shape.segment = segment V = 2 * (4. / 3) * math.pi * radius**3 geomInert = (2. / 5.) * V * radius**2 + b.shape.length * b.shape.length * 2 * ( 4. / 3) * math.pi * radius**3 b.state = ChainedState() b.state.addToChain(O.bodies.append(b)) utils._commonBodySetup(b, V, Vector3(geomInert, geomInert, geomInert), material, pos=begin, resetState=False, dynamic=dynamic, fixed=fixed) b.mask = mask b.bound = Aabb(color=[0, 1, 0]) b.state.ori.setFromTwoVectors(Vector3(0., 0., 1.), segment) if (end == begin): b.state.ori = Quaternion((1, 0, 0), 0) return b
def interaction_element(material,nodepairs,elementshape,radius=0.0015,dynamic=None,fixed=True,wire=False,color=Vector3(1,0,0),highlight=False,mask=1): # triangles for drawing(node indices) #faces=[Vector3(0,1,3),Vector3(1,2,3),Vector3(2,0,3),Vector3(0,1,2)] faces=[]; shape=elementshape() shape.color=color if color else randomColor(); [body_,nodes_]=finite_element(material,shape,nodepairs,faces,radius,interface=True) return [body_,nodes_]
def tetrahedral_element(material,nodes,elementshape,radius=0.0015,dynamic=None,fixed=True,wire=False,color=Vector3(1,0,0),highlight=False,mask=1): # triangles for drawing(node indices) #faces are in the format [face_vertex0,face_vertex1,face_vertex2,opposite_vertex] faces=[Vector3(1,2,0),Vector3(2,1,3),Vector3(2,0,3),Vector3(3,1,0)] shape=elementshape() shape.color=color if color else randomColor(); [body_,nodes_]=finite_element(material,shape,nodes,faces,radius) return [body_,nodes_]
def stl(file, dynamic=None,fixed=True,wire=True,color=None,highlight=False,noBound=False,material=-1): """ Import geometry from stl file, return list of created facets.""" imp = STLImporter() facets=imp.ymport(file) for b in facets: b.shape.color=color if color else utils.randomColor() b.shape.wire=wire b.shape.highlight=highlight pos=b.state.pos utils._commonBodySetup(b,0,Vector3(0,0,0),material=material,pos=pos,noBound=noBound,dynamic=dynamic,fixed=fixed) b.aspherical=False return facets
def chainedCylinder( begin=Vector3(0, 0, 0), end=Vector3(1.0, 0.0, 0.0), radius=0.2, dynamic=None, fixed=False, wire=False, color=None, highlight=False, material=-1, mask=1, ): """ Create and connect a chainedCylinder with given parameters. The shape generated by repeted calls of this function is the Minkowski sum of polyline and sphere. :param Real radius: radius of sphere in the Minkowski sum. :param Vector3 begin: first point positioning the line in the Minkowski sum :param Vector3 last: last point positioning the line in the Minkowski sum In order to build a correct chain, last point of element of rank N must correspond to first point of element of rank N+1 in the same chain (with some tolerance, since bounding boxes will be used to create connections. :return: Body object with the :yref:`ChainedCylinder` :yref:`shape<Body.shape>`. """ segment = end - begin b = Body() b.shape = ChainedCylinder( radius=radius, length=segment.norm(), color=color if color else utils.randomColor(), wire=wire, highlight=highlight, ) b.shape.segment = segment V = 2 * (4.0 / 3) * math.pi * radius ** 3 geomInert = (2.0 / 5.0) * V * radius ** 2 + b.shape.length * b.shape.length * 2 * (4.0 / 3) * math.pi * radius ** 3 b.state = ChainedState() b.state.addToChain(O.bodies.append(b)) utils._commonBodySetup( b, V, Vector3(geomInert, geomInert, geomInert), material, pos=begin, resetState=False, dynamic=dynamic, fixed=fixed, ) b.mask = mask b.bound = Aabb(color=[0, 1, 0]) b.state.ori.setFromTwoVectors(Vector3(0.0, 0.0, 1.0), segment) if end == begin: b.state.ori = Quaternion((1, 0, 0), 0) return b
def gridConnection(id1,id2,radius,wire=False,color=None,highlight=False,material=-1,mask=1,cellDist=None): """ Create a :yref:`GridConnection` by connecting two :yref:`GridNodes<GridNode>`. :param id1,id2: the two :yref:`GridNodes<GridNode>` forming the cylinder. :param float radius: radius of the cylinder. Note that the radius needs to be the same as the one for the :yref:`GridNodes<GridNode>`. :param Vector3 cellDist: for periodic boundary conditions, see :yref:`Interaction.cellDist`. Note: periodic boundary conditions for gridConnections are not yet implemented! See documentation of :yref:`yade.utils.sphere` for meaning of other parameters. :return: Body object with the :yref:`GridConnection` :yref:`shape<Body.shape>`. .. note:: The material of the :yref:`GridNodes<GridNode>` will be used to set the constitutive behaviour of the internal connection, i.e., the constitutive behaviour of the cylinder. The material of the :yref:`GridConnection` is used for interactions with other (external) bodies. """ b=Body() b.shape=GridConnection(radius=radius,color=color if color else utils.randomColor(),wire=wire,highlight=highlight) sph1=O.bodies[id1] ; sph2=O.bodies[id2] i=createInteraction(id1,id2) nodeMat=sph1.material b.shape.node1=sph1 ; b.shape.node2=sph2 sph1.shape.addConnection(b) ; sph2.shape.addConnection(b) if(O.periodic): if(cellDist!=None): i.cellDist=cellDist segt=sph2.state.pos + O.cell.hSize*i.cellDist - sph1.state.pos else: segt=sph2.state.pos - sph1.state.pos L=segt.norm() V=0.5*L*math.pi*radius**2 geomInert=(2./5.)*V*radius**2 utils._commonBodySetup(b,V,Vector3(geomInert,geomInert,geomInert),material,pos=sph1.state.pos,dynamic=False,fixed=True) sph1.state.mass = sph1.state.mass + V*nodeMat.density sph2.state.mass = sph2.state.mass + V*nodeMat.density for k in [0,1,2]: sph1.state.inertia[k] = sph1.state.inertia[k] + geomInert*nodeMat.density sph2.state.inertia[k] = sph2.state.inertia[k] + geomInert*nodeMat.density b.aspherical=False if O.periodic: i.phys.unp= -(sph2.state.pos + O.cell.hSize*i.cellDist - sph1.state.pos).norm() + sph1.shape.radius + sph2.shape.radius b.shape.periodic=True b.shape.cellDist=i.cellDist else: i.phys.unp= -(sph2.state.pos - sph1.state.pos).norm() + sph1.shape.radius + sph2.shape.radius i.geom.connectionBody=b I=math.pi*(2.*radius)**4/64. E=nodeMat.young i.phys.kn=E*math.pi*(radius**2)/L i.phys.kr=E*I/L i.phys.ks=12.*E*I/(L**3) G=E/(2.*(1+nodeMat.poisson)) i.phys.ktw=2.*I*G/L b.mask=mask return b
def gridNode(center,radius,dynamic=None,fixed=False,wire=False,color=None,highlight=False,material=-1): """ Create a :yref:`GridNode` which is needed to set up :yref:`GridConnections<GridConnection>`. See documentation of :yref:`yade.utils.sphere` for meaning of parameters. :return: Body object with the :yref:`gridNode` :yref:`shape<Body.shape>`. """ b=Body() b.shape=GridNode(radius=radius,color=color if color else utils.randomColor(),wire=wire,highlight=highlight) #V=(4./3)*math.pi*radius**3 # will be overwritten by the connection V=0. geomInert=(2./5.)*V*radius**2 # will be overwritten by the connection utils._commonBodySetup(b,V,Vector3(geomInert,geomInert,geomInert),material,pos=center,dynamic=dynamic,fixed=fixed) b.aspherical=False b.bounded=False b.mask=0 # avoid contact detection with the nodes. Manual interaction will be set for them in "gridConnection" below. return b
poisson=poisson, density=4800, sigmaT=sigmaT, crackOpening=crackOpening, epsCrackOnset=epsCrackOnset, poisson=poisson, isoPrestress=isoPrestress)) sphDict = pickle.load(open(packingFile)) from yade import pack sp = pack.SpherePack() sp.fromList(sphDict['spheres']) sp.cellSize = sphDict['cell'] import numpy avgRadius = numpy.average([r for c, r in sp]) O.bodies.append([utils.sphere(c, r, color=utils.randomColor()) for c, r in sp]) O.periodic = True #O.cell.setBox=sp.cellSize #doesnt work correctly, periodic cell is too big!!!! O.cell.refSize = sp.cellSize axis = 2 ax1 = (axis + 1) % 3 ax2 = (axis + 2) % 3 O.dt = dtSafety * utils.PWaveTimeStep() import yade.plot as yp O.engines = [ ForceResetter(), InsertionSortCollider([ Bo1_Sphere_Aabb(aabbEnlargeFactor=intRadius, label='is2aabb'), ]),
import cPickle as pickle pickle.dump(dd,open(packingFile,'w')) # # load the packing (again); # import cPickle as pickle concreteId=O.materials.append(CpmMat(young=young, frictionAngle=frictionAngle, poisson=poisson, density=4800, sigmaT=sigmaT, crackOpening=crackOpening, epsCrackOnset=epsCrackOnset, poisson=poisson, isoPrestress=isoPrestress)) sphDict=pickle.load(open(packingFile)) from yade import pack sp=pack.SpherePack() sp.fromList(sphDict['spheres']) sp.cellSize=sphDict['cell'] import numpy avgRadius=numpy.average([r for c,r in sp]) O.bodies.append([utils.sphere(c,r,color=utils.randomColor()) for c,r in sp]) O.periodic=True #O.cell.setBox=sp.cellSize #doesnt work correctly, periodic cell is too big!!!! O.cell.refSize=sp.cellSize axis=2 ax1=(axis+1)%3 ax2=(axis+2)%3 O.dt=dtSafety*utils.PWaveTimeStep() import yade.plot as yp O.engines=[ ForceResetter(), InsertionSortCollider([Bo1_Sphere_Aabb(aabbEnlargeFactor=intRadius,label='is2aabb'),]), #,sweepLength=.05*avgRadius,nBins=5,binCoeff=5), InteractionLoop(
def chainedCylinder(begin=Vector3(0,0,0),end=Vector3(1.,0.,0.),radius=0.2,dynamic=None,fixed=False,wire=False,color=None,highlight=False,material=-1,mask=1): """ Create and connect a chainedCylinder with given parameters. The shape generated by repeted calls of this function is the Minkowski sum of polyline and sphere. :param Real radius: radius of sphere in the Minkowski sum. :param Vector3 begin: first point positioning the line in the Minkowski sum :param Vector3 last: last point positioning the line in the Minkowski sum In order to build a correct chain, last point of element of rank N must correspond to first point of element of rank N+1 in the same chain (with some tolerance, since bounding boxes will be used to create connections. :return: Body object with the :yref:`ChainedCylinder` :yref:`shape<Body.shape>`. .. note:: :yref:`ChainedCylinder` is deprecated and will be removed in the future, use :yref:`GridConnection` instead. See :yref:`yade.gridpfacet.cylinder` and :yref:`yade.gridpfacet.cylinderConnection`. """ import warnings warnings.warn('\033[1;31mchainedCylinder is deprecated and will be removed in the future, use GridConnection instead. See examples/grids/CohesiveGridConnectionSphere.py.\033[1;0m',category=UserWarning) segment=end-begin b=Body() b.shape=ChainedCylinder(radius=radius,length=segment.norm(),color=color if color else utils.randomColor(),wire=wire,highlight=highlight) b.shape.segment=segment V=2*(4./3)*math.pi*radius**3 geomInert=(2./5.)*V*radius**2+b.shape.length*b.shape.length*2*(4./3)*math.pi*radius**3 b.state=ChainedState() b.state.addToChain(O.bodies.append(b)) utils._commonBodySetup(b,V,Vector3(geomInert,geomInert,geomInert),material,pos=begin,resetState=False,dynamic=dynamic,fixed=fixed) b.mask=mask b.bound=Aabb(color=[0,1,0]) b.state.ori.setFromTwoVectors(Vector3(0.,0.,1.),segment) if (end == begin): b.state.ori = Quaternion((1,0,0),0) return b
def gridConnection(id1, id2, radius, wire=False, color=None, highlight=False, material=-1, mask=1, cellDist=None): """ Create a :yref:`GridConnection` by connecting two :yref:`GridNodes<GridNode>`. :param id1,id2: already with :yref:`GridConnections<GridConnection>` connected :yref:`GridNodes<GridNode>` :param bool wire: if ``True``, top and bottom facet are shown as skeleton; otherwise facets are filled. :param Vector3-or-None color: color of the PFacet; random color will be assigned if ``None``. :param Vector3 cellDist: for periodic boundary conditions, see :yref:`Interaction.cellDist`. Note: periodic boundary conditions are not yet implemented! See documentation of :yref:`yade.utils.sphere` for meaning of other parameters. :return: Body object with the :yref:`PFacet<PFacet>` :yref:`shape<Body.shape>`. .. note:: :yref:`GridNodes<GridNode>` and :yref:`GridConnections<GridConnection>` need to have the same radius. This is also the radius used to create the :yref:`PFacet<PFacet>` """ b = Body() b.shape = GridConnection( radius=radius, color=color if color else utils.randomColor(), wire=wire, highlight=highlight ) sph1 = O.bodies[id1] sph2 = O.bodies[id2] i = createInteraction(id1, id2) nodeMat = sph1.material b.shape.node1 = sph1 b.shape.node2 = sph2 sph1.shape.addConnection(b) sph2.shape.addConnection(b) if O.periodic: if cellDist != None: i.cellDist = cellDist segt = sph2.state.pos + O.cell.hSize * i.cellDist - sph1.state.pos else: segt = sph2.state.pos - sph1.state.pos L = segt.norm() V = 0.5 * L * math.pi * radius ** 2 geomInert = (2.0 / 5.0) * V * radius ** 2 utils._commonBodySetup( b, V, Vector3(geomInert, geomInert, geomInert), material, pos=sph1.state.pos, dynamic=False, fixed=True ) sph1.state.mass = sph1.state.mass + V * nodeMat.density sph2.state.mass = sph2.state.mass + V * nodeMat.density for k in [0, 1, 2]: sph1.state.inertia[k] = sph1.state.inertia[k] + geomInert * nodeMat.density sph2.state.inertia[k] = sph2.state.inertia[k] + geomInert * nodeMat.density b.aspherical = False if O.periodic: i.phys.unp = ( -(sph2.state.pos + O.cell.hSize * i.cellDist - sph1.state.pos).norm() + sph1.shape.radius + sph2.shape.radius ) b.shape.periodic = True b.shape.cellDist = i.cellDist else: i.phys.unp = -(sph2.state.pos - sph1.state.pos).norm() + sph1.shape.radius + sph2.shape.radius i.geom.connectionBody = b I = math.pi * (2.0 * radius) ** 4 / 64.0 E = nodeMat.young i.phys.kn = E * math.pi * (radius ** 2) / L i.phys.kr = E * I / L i.phys.ks = 12.0 * E * I / (L ** 3) G = E / (2.0 * (1 + nodeMat.poisson)) i.phys.ktw = 2.0 * I * G / L b.mask = mask return b
def node(center,radius,dynamic=None,fixed=True,wire=False,color=None,highlight=False,material=-1,mask=1): """Create sphere with given parameters; mass and inertia computed automatically. Last assigned material is used by default (*material* = -1), and utils.defaultMaterial() will be used if no material is defined at all. :param Vector3 center: center :param float radius: radius :param float dynamic: deprecated, see "fixed" :param float fixed: generate the body with all DOFs blocked? :param material: specify :yref:`Body.material`; different types are accepted: * int: O.materials[material] will be used; as a special case, if material==-1 and there is no shared materials defined, utils.defaultMaterial() will be assigned to O.materials[0] * string: label of an existing material that will be used * :yref:`Material` instance: this instance will be used * callable: will be called without arguments; returned Material value will be used (Material factory object, if you like) :param int mask: :yref:`Body.mask` for the body :param wire: display as wire sphere? :param highlight: highlight this body in the viewer? :param Vector3-or-None: body's color, as normalized RGB; random color will be assigned if ``None``. :return: A Body instance with desired characteristics. Creating default shared material if none exists neither is given:: >>> O.reset() >>> from yade import utils >>> len(O.materials) 0 >>> s0=utils.sphere([2,0,0],1) >>> len(O.materials) 1 Instance of material can be given:: >>> s1=utils.sphere([0,0,0],1,wire=False,color=(0,1,0),material=ElastMat(young=30e9,density=2e3)) >>> s1.shape.wire False >>> s1.shape.color Vector3(0,1,0) >>> s1.mat.density 2000.0 Material can be given by label:: >>> O.materials.append(FrictMat(young=10e9,poisson=.11,label='myMaterial')) 1 >>> s2=utils.sphere([0,0,2],1,material='myMaterial') >>> s2.mat.label 'myMaterial' >>> s2.mat.poisson 0.11 Finally, material can be a callable object (taking no arguments), which returns a Material instance. Use this if you don't call this function directly (for instance, through yade.pack.randomDensePack), passing only 1 *material* parameter, but you don't want material to be shared. For instance, randomized material properties can be created like this: >>> import random >>> def matFactory(): return ElastMat(young=1e10*random.random(),density=1e3+1e3*random.random()) ... >>> s3=utils.sphere([0,2,0],1,material=matFactory) >>> s4=utils.sphere([1,2,0],1,material=matFactory) """ b=Body() b.shape=Node(radius=radius,color=color if color else randomColor(),wire=wire,highlight=highlight) V=(4./3)*math.pi*radius**3 geomInert=(2./5.)*V*radius**2 _commonBodySetup(b,V,Vector3(geomInert,geomInert,geomInert),material,pos=center,dynamic=dynamic,fixed=fixed,blockedDOFs='XYZ') b.aspherical=False b.mask=mask b.bounded=True return b