Source code for woo.pre.toys

from minieigen import *
from woo.dem import *
import woo.core, woo.models
from math import *
import numpy


#class PourFeliciter(woo.core.Preprocessor,woo.pyderived.PyWooObject):
#    '''Showcase for custom packing predicates, and importing surfaces from STL.'''
#    _classTraits=None
#    _PAT=woo.pyderived.PyAttrTrait # less typing
#    _attrTraits=[
#    ]
#    def __new__(klass,**kw):
#        self=super().__new__(klass)
#        self.wooPyInit(PourFeliciter,woo.core.Preprocessor,**kw)
#        return self
#    def __init__(self,**kw):
#        woo.core.Preprocessor.__init__(self)
#        self.wooPyInit(PourFeliciter,woo.core.Preprocessor,**kw)
#    def __call__(self):
#        # preprocessor builds the simulation when called
#        pass

[docs]class NewtonsCradle(woo.core.Preprocessor,woo.pyderived.PyWooObject): '''Showcase for custom packing predicates, and importing surfaces from STL.''' _classTraits=None _PAT=woo.pyderived.PyAttrTrait # less typing _attrTraits=[ _PAT(int,'nSpheres',5,'Total number of spheres'), _PAT(int,'nFall',1,'The number of spheres which are out of the equilibrium position at the beginning.'), _PAT(float,'fallAngle',pi/4.,unit='deg',doc='Initial angle of falling spheres.'), _PAT(float,'rad',.005,unit='m',doc='Radius of spheres'), _PAT(Vector2,'cabHtWd',(.1,.1),unit='m',doc='Height and width of the suspension'), _PAT(float,'cabRad',.0005,unit='m',doc='Radius of the suspending cables'), _PAT(woo.models.ContactModelSelector,'model',woo.models.ContactModelSelector(name='Hertz',restitution=.99,numMat=(1,2),matDesc=['spheres','cables'],mats=[FrictMat(density=3e3,young=2e8),FrictMat(density=.001,young=2e8)]),doc='Select contact model. The first material is for spheres; the second, optional, material, is for the suspension cables.'), _PAT(Vector3,'gravity',(0,0,-9.81),'Gravity acceleration'), _PAT(int,'plotEvery',10,'How often to collect plot data'), _PAT(float,'dtSafety',.7,':obj:`woo.core.Scene.dtSafety`') ]
[docs] def __new__(klass,**kw): self=super().__new__(klass) self.wooPyInit(NewtonsCradle,woo.core.Preprocessor,**kw) return self
def __init__(self,**kw): woo.core.Preprocessor.__init__(self) self.wooPyInit(self.__class__,woo.core.Preprocessor,**kw)
[docs] def __call__(self): pre=self S=woo.core.Scene(fields=[DemField(gravity=pre.gravity)],dtSafety=self.dtSafety) S.pre=pre.deepcopy() # preprocessor builds the simulation when called xx=numpy.linspace(0,(pre.nSpheres-1)*2*pre.rad,num=pre.nSpheres) mat=pre.model.mats[0] cabMat=(pre.model.mats[1] if len(pre.model.mats)>1 else mat) ht=pre.cabHtWd[0] for i,x in enumerate(xx): color=min(.999,(x/xx[-1])) s=Sphere.make((x,0,0) if i>=pre.nFall else (x-ht*sin(pre.fallAngle),0,ht-ht*cos(pre.fallAngle)),radius=pre.rad,mat=mat,color=color) n=s.shape.nodes[0] S.dem.par.add(s) # sphere's node is integrated # S.dem.nodesAppend(n) for p in [Vector3(x,-pre.cabHtWd[1]/2,pre.cabHtWd[0]),Vector3(x,pre.cabHtWd[1]/2,pre.cabHtWd[0])]: t=Truss.make([n,p],radius=pre.cabRad,wire=False,color=color,mat=cabMat,fixed=None) t.shape.nodes[1].dem.blocked='xyzXYZ' S.dem.par.add(t) S.engines=DemField.minimalEngines(model=pre.model,dynDtPeriod=20)+[ IntraForce([In2_Truss_ElastMat()]), woo.core.PyRunner(self.plotEvery,'S.plot.addData(i=S.step,t=S.time,total=S.energy.total(),relErr=(S.energy.relErr() if S.step>1000 else 0),**S.energy)'), ] S.lab.dynDt.maxRelInc=1e-6 S.trackEnergy=True S.plot.plots={'i':('total','**S.energy')} return S