def checkUnbalanced(): ubMaxF = utils.unbalancedForce(True) ubAvgF = utils.unbalancedForce(False) if ((ubMaxF > alMaxF) | (ubAvgF > alAvgF)): print 'Unbalanced Force = checkPorosity Fail' return False else: return True
def addPlotData(): # this function adds current values to the history of data, under the names specified plot.addData(Time=O.time, Torque1=utils.sumTorques, CoordinationNumber=utils.avgNumInteractions(), Unbalancedforce=utils.unbalancedForce(), **O.energy)
def recorder(): yade.plot.addData({ 'i': O.iter, 'eps': strainer.strain, 'sigma': strainer.avgStress, 'tc': interactionLaw.nbTensCracks, 'sc': interactionLaw.nbShearCracks, 'tce': interactionLaw.totalTensCracksE, 'sce': interactionLaw.totalShearCracksE, 'cSurf': interactionLaw.totalCracksSurface, 'unbF': utils.unbalancedForce() }) yade.plot.saveDataTxt(OUTPUT)
def recorder(): global epsXX, epsYY epsXX = (O.bodies[xPoint].state.pos[0] - x0) / (x0 - 0.5 * X) epsYY = (O.bodies[yPoint].state.pos[1] - y0) / (y0 - 0.5 * Y) yade.plot.addData({ 'i': O.iter, 'eps': strainer.strain, 'sigma': strainer.avgStress, 'epsXX': epsXX, 'epsYY': epsYY, 'tc': interactionLaw.nbTensCracks, 'sc': interactionLaw.nbShearCracks, 'unbF': utils.unbalancedForce() }) yade.plot.saveDataTxt(OUTPUT)
def recorder(): global ex0, ey0, ez0 crackVolume = crackSurface = 0 for i in O.interactions: if i.phys.isBroken: crackVolume += i.phys.crossSection * i.phys.crackJointAperture crackSurface += i.phys.crossSection yade.plot.addData(t=O.time, i=O.iter, ex=triax.strain[0] - ex0, ey=triax.strain[1] - ey0, ez=triax.strain[2] - ez0, sx=triax.stress(triax.wall_right_id)[0], sy=triax.stress(triax.wall_top_id)[1], sz=triax.stress(triax.wall_front_id)[2], p=flow.getPorePressure( (xinf + X / 2., yinf + Y / 2., zinf + Z / 2.)), tc=interactionLaw.nbTensCracks, sc=interactionLaw.nbShearCracks, p32=crackSurface, p33=crackVolume, unbF=utils.unbalancedForce()) yade.plot.saveDataTxt(OUT)
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 ) : O.run(100,True) sp=SpherePack(); sp.fromSimulation() O.switchScene() ### !! _memoizePacking(memoizeDb,sp,radius,rRelFuzz,wantPeri,fullDim) if wantPeri: sp.cellFill(Vector3(fullDim[0],fullDim[1],fullDim[2])) if orientation: sp.cellSize=(0,0,0); # reset periodicity to avoid warning when rotating periodic packing sp.rotate(*orientation.toAxisAngle()) return filterSpherePack(predicate,sp,material=material,color=color,returnSpherePack=returnSpherePack) 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.
def randomDensePack(predicate, radius, material=-1, dim=None, cropLayers=0, rRelFuzz=0., spheresInCell=0, memoizeDb=None, useOBB=False, memoDbg=False, color=None, returnSpherePack=None, seed=0): """Generator of random dense packing with given geometry properties, using TriaxialTest (aperiodic) or PeriIsoCompressor (periodic). The periodicity depens on whether the spheresInCell parameter is given. *O.switchScene()* magic is used to have clean simulation for TriaxialTest without deleting the original simulation. This function therefore should never run in parallel with some code accessing your simulation. :param predicate: solid-defining predicate for which we generate packing :param spheresInCell: if given, the packing will be periodic, with given number of spheres in the periodic cell. :param radius: mean radius of spheres :param rRelFuzz: relative fuzz of the radius -- e.g. radius=10, rRelFuzz=.2, then spheres will have radii 10 ± (10*.2)), with an uniform distribution. 0 by default, meaning all spheres will have exactly the same radius. :param cropLayers: (aperiodic only) how many layers of spheres will be added to the computed dimension of the box so that there no (or not so much, at least) boundary effects at the boundaries of the predicate. :param dim: dimension of the packing, to override dimensions of the predicate (if it is infinite, for instance) :param memoizeDb: name of sqlite database (existent or nonexistent) to find an already generated packing or to store the packing that will be generated, if not found (the technique of caching results of expensive computations is known as memoization). Fuzzy matching is used to select suitable candidate -- packing will be scaled, rRelFuzz and dimensions compared. Packing that are too small are dictarded. From the remaining candidate, the one with the least number spheres will be loaded and returned. :param useOBB: effective only if a inGtsSurface predicate is given. If true (not default), oriented bounding box will be computed first; it can reduce substantially number of spheres for the triaxial compression (like 10× depending on how much asymmetric the body is), see examples/gts-horse/gts-random-pack-obb.py :param memoDbg: show packings that are considered and reasons why they are rejected/accepted :param returnSpherePack: see the corresponding argument in :yref:`yade.pack.filterSpherePack` :return: SpherePack object with spheres, filtered by the predicate. """ import sqlite3, os.path, pickle, time, sys, numpy from math import pi from yade import _packPredicates wantPeri = (spheresInCell > 0) if 'inGtsSurface' in dir(_packPredicates) and type( predicate) == inGtsSurface and useOBB: center, dim, orientation = gtsSurfaceBestFitOBB(predicate.surf) print( "Best-fit oriented-bounding-box computed for GTS surface, orientation is", orientation) dim *= 2 # gtsSurfaceBestFitOBB returns halfSize else: if not dim: dim = predicate.dim() if max(dim) == float('inf'): raise RuntimeError( "Infinite predicate and no dimension of packing requested.") center = predicate.center() orientation = None if not wantPeri: fullDim = tuple([dim[i] + 4 * cropLayers * radius for i in (0, 1, 2)]) else: # compute cell dimensions now, as they will be compared to ones stored in the db # they have to be adjusted to not make the cell to small WRT particle radius fullDim = dim cloudPorosity = 0.25 # assume this number for the initial cloud (can be underestimated) beta, gamma = fullDim[1] / fullDim[0], fullDim[2] / fullDim[ 0] # ratios β=y₀/x₀, γ=z₀/x₀ N100 = spheresInCell / cloudPorosity # number of spheres for cell being filled by spheres without porosity x1 = radius * (1 / (beta * gamma) * N100 * (4 / 3.) * pi)**(1 / 3.) y1, z1 = beta * x1, gamma * x1 vol0 = x1 * y1 * z1 maxR = radius * (1 + rRelFuzz) x1 = max(x1, 8 * maxR) y1 = max(y1, 8 * maxR) z1 = max(z1, 8 * maxR) vol1 = x1 * y1 * z1 N100 *= vol1 / vol0 # volume might have been increased, increase number of spheres to keep porosity the same sp = _getMemoizedPacking(memoizeDb, radius, rRelFuzz, x1, y1, z1, fullDim, wantPeri, fillPeriodic=True, spheresInCell=spheresInCell, memoDbg=False) if sp: if orientation: sp.cellSize = ( 0, 0, 0) # resetting cellSize avoids warning when rotating sp.rotate(*orientation.toAxisAngle()) return filterSpherePack(predicate, sp, material=material, returnSpherePack=returnSpherePack) 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()], 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.0 / 3.0) * pi * radius**3.0 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, seed=seed, ## no need to touch any the following noFiles=True, lowerCorner=[0, 0, 0], sigmaIsoCompaction=-4e4, sigmaLateralConfinement=-5e2, compactionFrictionDeg=1, StabilityCriterion=.02, strainRate=.2, thickness=0, maxWallVelocity=.1, wallOversizeFactor=1.5, autoUnload=True, autoCompressionActivation=False, internalCompaction=True).load() while (numpy.isnan(utils.unbalancedForce()) or utils.unbalancedForce() > 0.005): O.run(500, True) sp = SpherePack() sp.fromSimulation() O.switchScene() ### !! _memoizePacking(memoizeDb, sp, radius, rRelFuzz, wantPeri, fullDim) if wantPeri: sp.cellFill(Vector3(fullDim[0], fullDim[1], fullDim[2])) if orientation: sp.cellSize = (0, 0, 0) # reset periodicity to avoid warning when rotating periodic packing sp.rotate(*orientation.toAxisAngle()) return filterSpherePack(predicate, sp, material=material, color=color, returnSpherePack=returnSpherePack)
def randomDensePack(predicate, radius, material=-1, dim=None, cropLayers=0, rRelFuzz=0., spheresInCell=0, memoizeDb=None, useOBB=True, memoDbg=False, color=None, returnSpherePack=None): """Generator of random dense packing with given geometry properties, using TriaxialTest (aperiodic) or PeriIsoCompressor (periodic). The periodicity depens on whether the spheresInCell parameter is given. *O.switchScene()* magic is used to have clean simulation for TriaxialTest without deleting the original simulation. This function therefore should never run in parallel with some code accessing your simulation. :param predicate: solid-defining predicate for which we generate packing :param spheresInCell: if given, the packing will be periodic, with given number of spheres in the periodic cell. :param radius: mean radius of spheres :param rRelFuzz: relative fuzz of the radius -- e.g. radius=10, rRelFuzz=.2, then spheres will have radii 10 ± (10*.2)). 0 by default, meaning all spheres will have exactly the same radius. :param cropLayers: (aperiodic only) how many layers of spheres will be added to the computed dimension of the box so that there no (or not so much, at least) boundary effects at the boundaries of the predicate. :param dim: dimension of the packing, to override dimensions of the predicate (if it is infinite, for instance) :param memoizeDb: name of sqlite database (existent or nonexistent) to find an already generated packing or to store the packing that will be generated, if not found (the technique of caching results of expensive computations is known as memoization). Fuzzy matching is used to select suitable candidate -- packing will be scaled, rRelFuzz and dimensions compared. Packing that are too small are dictarded. From the remaining candidate, the one with the least number spheres will be loaded and returned. :param useOBB: effective only if a inGtsSurface predicate is given. If true (default), oriented bounding box will be computed first; it can reduce substantially number of spheres for the triaxial compression (like 10× depending on how much asymmetric the body is), see scripts/test/gts-triax-pack-obb.py. :param memoDbg: show packigns that are considered and reasons why they are rejected/accepted :param returnSpherePack: see :yref:`filterSpherePack` :return: SpherePack object with spheres, filtered by the predicate. """ import sqlite3, os.path, cPickle, time, sys, _packPredicates, numpy from math import pi wantPeri = (spheresInCell > 0) if 'inGtsSurface' in dir(_packPredicates) and type( predicate) == inGtsSurface and useOBB: center, dim, orientation = gtsSurfaceBestFitOBB(predicate.surf) print "Best-fit oriented-bounding-box computed for GTS surface, orientation is", orientation dim *= 2 # gtsSurfaceBestFitOBB returns halfSize else: if not dim: dim = predicate.dim() if max(dim) == float('inf'): raise RuntimeError( "Infinite predicate and no dimension of packing requested.") center = predicate.center() orientation = None if not wantPeri: fullDim = tuple([dim[i] + 4 * cropLayers * radius for i in 0, 1, 2]) else: # compute cell dimensions now, as they will be compared to ones stored in the db # they have to be adjusted to not make the cell to small WRT particle radius fullDim = dim cloudPorosity = 0.25 # assume this number for the initial cloud (can be underestimated) beta, gamma = fullDim[1] / fullDim[0], fullDim[2] / fullDim[ 0] # ratios β=y₀/x₀, γ=z₀/x₀ N100 = spheresInCell / cloudPorosity # number of spheres for cell being filled by spheres without porosity x1 = radius * (1 / (beta * gamma) * N100 * (4 / 3.) * pi)**(1 / 3.) y1, z1 = beta * x1, gamma * x1 vol0 = x1 * y1 * z1 maxR = radius * (1 + rRelFuzz) x1 = max(x1, 8 * maxR) y1 = max(y1, 8 * maxR) z1 = max(z1, 8 * maxR) vol1 = x1 * y1 * z1 N100 *= vol1 / vol0 # volume might have been increased, increase number of spheres to keep porosity the same sp = _getMemoizedPacking( memoizeDb, radius, rRelFuzz, x1, y1, z1, fullDim, wantPeri, fillPeriodic=True, spheresInCell=spheresInCell, memoDbg=False) if sp: if orientation: sp.cellSize = ( 0, 0, 0) # resetting cellSize avoids warning when rotating sp.rotate(*orientation.toAxisAngle()) return filterSpherePack( predicate, sp, material=material, returnSpherePack=returnSpherePack) 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): O.run(100, True) sp = SpherePack() sp.fromSimulation() O.switchScene() ### !! _memoizePacking(memoizeDb, sp, radius, rRelFuzz, wantPeri, fullDim) if wantPeri: sp.cellFill(Vector3(fullDim[0], fullDim[1], fullDim[2])) if orientation: sp.cellSize = (0, 0, 0) # reset periodicity to avoid warning when rotating periodic packing sp.rotate(*orientation.toAxisAngle()) return filterSpherePack( predicate, sp, material=material, color=color, returnSpherePack=returnSpherePack)