Author: eudoxos
Date: 2009-08-03 21:56:37 +0200 (Mon, 03 Aug 2009)
New Revision: 1914

Added:
   trunk/examples/concrete/uniaxial/
   trunk/examples/concrete/uniaxial/rb.py
Modified:
   trunk/py/utils.py
Log:
1. Add an example of uniaxial tension-compression test for concrete (ready long 
time ago...)



Added: trunk/examples/concrete/uniaxial/rb.py
===================================================================
--- trunk/examples/concrete/uniaxial/rb.py      2009-08-03 18:53:26 UTC (rev 
1913)
+++ trunk/examples/concrete/uniaxial/rb.py      2009-08-03 19:56:37 UTC (rev 
1914)
@@ -0,0 +1,160 @@
+# -*- encoding=utf-8 -*-
+from __future__ import division
+
+from yade import utils,plot,pack
+import time, sys, os, copy
+
+"""
+A fairly complex script performing uniaxial tension-compression test on 
hyperboloid-shaped specimen.
+
+Most parameters of the model (and of the setup) can be read from table using 
yade-multi.
+
+After the simulation setup, tension loading is run and stresses are 
periodically saved for plotting
+as well as checked for getting below the maximum value so far. This indicates 
failure (see stopIfDamaged
+function). After failure in tension, the original setup is loaded anew and the 
sense of loading reversed.
+After failure in compression, strain-stress curves are saved via 
plot.saveGnuplot and we exit,
+giving some useful information like peak stresses in tension/compression.
+
+Running this script for the first time can take long time, as the specimen is 
prepared using triaxial
+compression. Next time, however, an attempt is made to load 
previously-generated packing 
+(from /tmp/triaxPackCache.sqlite) and this expensive procedure is avoided.
+
+The specimen length can be specified, its diameter is half of the length and 
skirt of the hyperboloid is 
+4/5 of the width.
+
+The particle size is constant and can be specified using the sphereRadius 
parameter.
+
+The 3d display has displacement scaling applied, so that the fracture looks 
more spectacular. The scale
+is 1000 for tension and 100 for compression.
+
+"""
+
+
+
+# default parameters or from table
+utils.readParamsFromTable(noTableOk=True, # unknownOk=True,
+       young=24e9,
+       poisson=.2,
+       G_over_E=.20,
+
+       sigmaT=3.5e6,
+       frictionAngle=atan(0.8),
+       epsCrackOnset=1e-4,
+       relDuctility=30,
+
+       intRadius=1.5,
+       dtSafety=.8,
+       damping=0.4,
+       strainRateTension=.1,
+       strainRateCompression=1,
+       setSpeeds=True,
+       # the packing has about 50% porosity, 2×2400==4800
+       density=4800,
+       # 1=tension, 2=compression (ANDed; 3=both)
+       doModes=3,
+
+       specimenLength=.2,
+       sphereRadius=3.5e-3,
+)
+
+if 'description' in O.tags.keys(): 
O.tags['id']=O.tags['id']+O.tags['description']
+
+
+# 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
+spheres=pack.triaxialPack(pack.inHyperboloid((0,0,-.5*specimenLength),(0,0,.5*specimenLength),.25*specimenLength,.2*specimenLength),radius=sphereRadius,memoizeDb='/tmp/triaxPackCache.sqlite',young=young,poisson=poisson,frictionAngle=frictionAngle,physParamsClass='CpmMat',density=density)
+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=[
+       BexResetter(),
+       
BoundingVolumeMetaEngine([InteractingSphere2AABB(aabbEnlargeFactor=intRadius),MetaInteractingGeometry2AABB()]),
+       InsertionSortCollider(),
+       InteractionDispatchers(
+               
[ef2_Sphere_Sphere_Dem3DofGeom(distanceFactor=intRadius,label='ss2d3dg')],
+               
[Ip2_CpmMat_CpmMat_CpmPhys(sigmaT=sigmaT,relDuctility=relDuctility,epsCrackOnset=epsCrackOnset,G_over_E=G_over_E)],
+               [Law2_Dem3DofGeom_CpmPhys_Cpm()],
+       ),
+       NewtonsDampedLaw(damping=damping,label='damper'),
+       CpmPhysDamageColorizer(realPeriod=1),
+       
UniaxialStrainer(strainRate=strainRateTension,axis=axis,asymmetry=0,posIds=posIds,negIds=negIds,crossSectionArea=crossSectionArea,blockDisplacements=False,blockRotations=False,setSpeeds=setSpeeds,label='strainer'),
+       
PeriodicPythonRunner(virtPeriod=3e-5/strainRateTension,realLim=5,command='addPlotData()',label='plotDataCollector'),
+       
PeriodicPythonRunner(realPeriod=4,command='stopIfDamaged()',label='damageChecker'),
+]
+O.miscParams=[GLDrawCpmPhys(dmgLabel=False,colorStrain=False,epsNLabel=False,epsT=False,epsTAxes=False,normal=False,contactLine=True)]
+
+plot.plots={'eps':('sigma','sigma.25','sigma.50','sigma.75')}
+plot.maxDataLen=4000
+
+O.saveTmp('initial');
+
+global mode
+mode='tension' if doModes & 1 else 'compression'
+
+def initTest():
+       global mode
+       print "init"
+       if O.iter>0:
+               O.wait();
+               O.loadTmp('initial')
+               print "Reversing plot data"; plot.reverseData()
+       strainer['strainRate']=abs(strainRateTension) if mode=='tension' else 
-abs(strainRateCompression)
+       try:
+               from yade import qt
+               renderer=qt.Renderer()
+               renderer['scaleDisplacements']=True
+               renderer['displacementScale']=(1000,1000,1000) if 
mode=='tension' else (100,100,100)
+       except ImportError: pass
+       print "init done, will now run."
+       O.run()
+
+def stopIfDamaged():
+       global mode
+       if O.iter<2 or not plot.data.has_key('sigma'): return # do nothing at 
the very beginning
+       sigma,eps=plot.data['sigma'],plot.data['eps']
+       extremum=max(sigma) if (strainer['strainRate']>0) else min(sigma)
+       minMaxRatio=0.5 if mode=='tension' else 0.5
+       if extremum==0: return
+       print O.tags['id'],mode,strainer['strain'],sigma[-1]
+       import sys;     sys.stdout.flush()
+       if abs(sigma[-1]/extremum)<minMaxRatio:
+               if mode=='tension' and doModes & 2: # only if compression is 
enabled
+                       mode='compression'
+                       print "Damaged, switching to compression... "; O.pause()
+                       # important! initTest must be launched in a separate 
thread;
+                       # otherwise O.load would wait for the iteration to 
finish,
+                       # but it would wait for initTest to return and deadlock 
would result
+                       import thread; thread.start_new_thread(initTest,())
+                       return
+               else:
+                       print "Damaged, stopping."
+                       ft,fc=max(sigma),min(sigma)
+                       print 'Strengths fc=%g, ft=%g, 
|fc/ft|=%g'%(fc,ft,abs(fc/ft))
+                       title=O.tags['description'] if 'description' in 
O.tags.keys() else O.tags['params']
+                       
print'gnuplot',plot.saveGnuplot(O.tags['id'],title=title)
+                       print 'Bye.'
+                       # O.pause()
+                       sys.exit(0)
+               
+def addPlotData():
+       
yade.plot.addData({'t':O.time,'i':O.iter,'eps':strainer['strain'],'sigma':strainer['avgStress'],
+               
'sigma.25':utils.forcesOnCoordPlane(coord_25,axis)[axis]/area_25,
+               
'sigma.50':utils.forcesOnCoordPlane(coord_50,axis)[axis]/area_50,
+               
'sigma.75':utils.forcesOnCoordPlane(coord_75,axis)[axis]/area_75,
+               })
+
+
+
+initTest()
+#while True: time.sleep(1)
+
+
+

Modified: trunk/py/utils.py
===================================================================
--- trunk/py/utils.py   2009-08-03 18:53:26 UTC (rev 1913)
+++ trunk/py/utils.py   2009-08-03 19:56:37 UTC (rev 1914)
@@ -465,8 +465,8 @@
        l=procStatus('VmData'); ll=l.split(); assert(ll[2]=='kB')
        return int(ll[1])
 
-def spheresFromFileUniaxial(filename,areaSections=10,**kw):
-       """Load spheres from file, but do some additional work useful for 
uniaxial test:
+def uniaxialTestFeatures(filename=None,areaSections=10,**kw):
+       """Get some data about the current packing useful for uniaxial test:
        
        1. Find the dimensions that is the longest (uniaxial loading axis)
        2. Find the minimum cross-section area of the speciment by examining 
several (areaSections)
@@ -475,9 +475,13 @@
        3. Find the bodies that are on the negative/positive boundary, to which 
the straining condition
                should be applied.
 
+       @param filename if given, spheres will be loaded from this file (ASCII 
format); if not, current simulation will be used.
+       @param areaSection number of section that will be used to estimate 
cross-section
+
        Returns dictionary with keys 'negIds', 'posIds', 'axis', 'area'.
        """
-       ids=spheresFromFile(filename,**kw)
+       if filename: ids=spheresFromFile(filename,**kw)
+       else: ids=[b.id for b in O.bodies]
        mm,mx=aabbExtrema()
        dim=aabbDim(); axis=dim.index(max(dim))
        import numpy


_______________________________________________
Mailing list: https://launchpad.net/~yade-dev
Post to     : yade-...@lists.launchpad.net
Unsubscribe : https://launchpad.net/~yade-dev
More help   : https://help.launchpad.net/ListHelp
_______________________________________________
yade-dev mailing list
yade-dev@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/yade-dev

Reply via email to