def estimateStress(strain,cutoff=0.): """Use summed stored energy in contacts to compute macroscopic stress over the same volume, provided known strain.""" # E=(1/2)σεAl # global stored energy # σ=EE/(.5εAl)=EE/(.5εV) from woo import utils dim=utils.aabbDim(cutoff,centers=False) return utils.elasticEnergy(utils.aabbExtrema(cutoff))/(.5*strain*dim[0]*dim[1]*dim[2])
def plotDirections(aabb=(),mask=0,bins=20,numHist=True,noShow=False): """Plot 3 histograms for distribution of interaction directions, in yz,xz and xy planes and (optional but default) histogram of number of interactions per body. :returns: If *noShow* is ``False``, displays the figure and returns nothing. If *noShow*, the figure object is returned without being displayed (works the same way as :obj:`woo.plot.plot`). """ import pylab,math from woo import utils for axis in [0,1,2]: d=utils.interactionAnglesHistogram(axis,mask=mask,bins=bins,aabb=aabb) fc=[0,0,0]; fc[axis]=1. subp=pylab.subplot(220+axis+1,polar=True); # 1.1 makes small gaps between values (but the column is a bit decentered) pylab.bar(d[0],d[1],width=math.pi/(1.1*bins),fc=fc,alpha=.7,label=['yz','xz','xy'][axis]) #pylab.title(['yz','xz','xy'][axis]+' plane') pylab.text(.5,.25,['yz','xz','xy'][axis],horizontalalignment='center',verticalalignment='center',transform=subp.transAxes,fontsize='xx-large') if numHist: pylab.subplot(224,polar=False) nums,counts=utils.bodyNumInteractionsHistogram(aabb if len(aabb)>0 else utils.aabbExtrema()) avg=sum([nums[i]*counts[i] for i in range(len(nums))])/(1.*sum(counts)) pylab.bar(nums,counts,fc=[1,1,0],alpha=.7,align='center') pylab.xlabel('Interactions per body (avg. %g)'%avg) pylab.axvline(x=avg,linewidth=3,color='r') pylab.ylabel('Body count') if noShow: return pylab.gcf() else: pylab.show()
# 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( [Ig2_Sphere_Sphere_Dem3DofGeom(distFactor=intRadius,label='ss2d3dg') if not scGeom else Ig2_Sphere_Sphere_ScGeom(interactionDetectionFactor=intRadius,label='ss2sc')], [Ip2_CpmMat_CpmMat_CpmPhys()], [Law2_Dem3DofGeom_CpmPhys_Cpm(epsSoft=0) if not scGeom else Law2_ScGeom_CpmPhys_Cpm()], ), NewtonIntegrator(damping=damping,label='damper'), CpmStateUpdater(realPeriod=1), UniaxialStrainer(strainRate=strainRateTension,axis=axis,asymmetry=0,posIds=posIds,negIds=negIds,crossSectionArea=crossSectionArea,blockDisplacements=False,blockRotations=False,setSpeeds=setSpeeds,label='strainer'), PyRunner(virtPeriod=1e-6/strainRateTension,realPeriod=1,command='addPlotData()',label='plotDataCollector',initRun=True),
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),