Author: eudoxos
Date: 2008-09-22 17:14:44 +0200 (Mon, 22 Sep 2008)
New Revision: 1522

Modified:
   trunk/gui/py/_utils.cpp
   trunk/gui/py/eudoxos.py
   trunk/gui/py/utils.py
Log:
1. Move interaction direction distribution pie histograms to utils
2. Add plotting histogram of number of contacts to plotDirections()

  utils.plotDirections(utils.aabbExtrema()) # to do it on the whole specimen



Modified: trunk/gui/py/_utils.cpp
===================================================================
--- trunk/gui/py/_utils.cpp     2008-09-21 11:47:46 UTC (rev 1521)
+++ trunk/gui/py/_utils.cpp     2008-09-22 15:14:44 UTC (rev 1522)
@@ -131,6 +131,29 @@
 }
 
BOOST_PYTHON_FUNCTION_OVERLOADS(interactionAnglesHistogram_overloads,interactionAnglesHistogram,1,4);
 
+python::tuple bodyNumInteractionsHistogram(python::tuple aabb=python::tuple()){
+       Vector3r bbMin(Vector3r::ZERO), bbMax(Vector3r::ZERO); bool 
useBB=python::len(aabb)>0; 
if(useBB){bbMin=tuple2vec(extract<python::tuple>(aabb[0])());bbMax=tuple2vec(extract<python::tuple>(aabb[1])());}
+       const shared_ptr<MetaBody>& rb=Omega::instance().getRootBody();
+       vector<int> bodyNumInta; bodyNumInta.resize(rb->bodies->size(),-1 /* 
uninitialized */);
+       int maxInta=0;
+       FOREACH(const shared_ptr<Interaction>& i, *rb->transientInteractions){
+               if(!i->isReal) continue;
+               const body_id_t id1=i->getId1(), id2=i->getId2(); const 
shared_ptr<Body>& b1=Body::byId(id1,rb), b2=Body::byId(id2,rb);
+               if(useBB && 
isInBB(b1->physicalParameters->se3.position,bbMin,bbMax)) 
bodyNumInta[id1]=bodyNumInta[id1]>0?bodyNumInta[id1]+1:1;
+               if(useBB && 
isInBB(b2->physicalParameters->se3.position,bbMin,bbMax)) 
bodyNumInta[id2]=bodyNumInta[id2]>0?bodyNumInta[id2]+1:1;
+               
maxInta=max(max(maxInta,bodyNumInta[b1->getId()]),bodyNumInta[b2->getId()]);
+       }
+       vector<int> bins; bins.resize(maxInta+1);
+       for(size_t id=0; id<bodyNumInta.size(); id++){ if(bodyNumInta[id]>=0) 
bins[bodyNumInta[id]]+=1; }
+       python::list count,num;
+       for(size_t n=1; n<bins.size(); n++){
+               if(bins[n]==0) continue;
+               num.append(n); count.append(bins[n]);
+       }
+       return python::make_tuple(num,count);
+}
+BOOST_PYTHON_FUNCTION_OVERLOADS(bodyNumInteractionsHistogram_overloads,bodyNumInteractionsHistogram,0,1);
+
 python::tuple inscribedCircleCenter(python::list v0, python::list v1, 
python::list v2)
 {
        return 
vec2tuple(Shop::inscribedCircleCenter(Vector3r(python::extract<double>(v0[0]),python::extract<double>(v0[1]),python::extract<double>(v0[2])),
 
Vector3r(python::extract<double>(v1[0]),python::extract<double>(v1[1]),python::extract<double>(v1[2])),
 
Vector3r(python::extract<double>(v2[0]),python::extract<double>(v2[1]),python::extract<double>(v2[2]))));
@@ -144,6 +167,7 @@
        
def("coordsAndDisplacements",coordsAndDisplacements,coordsAndDisplacements_overloads(args("AABB")));
        def("setRefSe3",setRefSe3);
        
def("interactionAnglesHistogram",interactionAnglesHistogram,interactionAnglesHistogram_overloads(args("axis","mask","bins","aabb")));
+       
def("bodyNumInteractionsHistogram",bodyNumInteractionsHistogram,bodyNumInteractionsHistogram_overloads(args("aabb")));
        def("elasticEnergy",elasticEnergyInAABB);
        def("inscribedCircleCenter",inscribedCircleCenter);
 }

Modified: trunk/gui/py/eudoxos.py
===================================================================
--- trunk/gui/py/eudoxos.py     2008-09-21 11:47:46 UTC (rev 1521)
+++ trunk/gui/py/eudoxos.py     2008-09-22 15:14:44 UTC (rev 1522)
@@ -12,18 +12,6 @@
        dim=utils.aabbDim(cutoff)
        return 
utils.elasticEnergy(utils.aabbExtrema(cutoff))/(.5*strain*dim[0]*dim[1]*dim[2])
 
-def plotDirections(mask=0,bins=20,aabb=()):
-       "Plot 3 histograms for distribution of interaction directions, in yz,xz 
and xy planes."
-       import pylab,math
-       from yade 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.
-               pylab.subplot(220+axis+1,polar=True);
-               # 1.2 makes small gaps between values (but the column is 
decentered)
-               
pylab.bar(d[0],d[1],width=math.pi/(1.2*bins),fc=fc,alpha=.7,label=['yz','xz','xy'][axis])
-       pylab.show()
-
 def estimatePoissonYoung(principalAxis,stress=0,plot=False,cutoff=0.):
        """Estimate Poisson's ration given the "principal" axis of straining.
        For every base direction, homogenized strain is computed

Modified: trunk/gui/py/utils.py
===================================================================
--- trunk/gui/py/utils.py       2008-09-21 11:47:46 UTC (rev 1521)
+++ trunk/gui/py/utils.py       2008-09-22 15:14:44 UTC (rev 1522)
@@ -144,6 +144,43 @@
                
out.write('%g\t%g\t%g\t%g\n'%(b.phys['se3'][0],b.phys['se3'][1],b.phys['se3'][2],b.shape['radius']))
        out.close()
 
+def avgNumInteractions(cutoff=0.):
+       nums,counts=bodyNumInteractionsHistogram(aabbExtrema(cutoff))
+       return sum([nums[i]*counts[i] for i in 
range(len(nums))])/(1.*sum(counts))
+
+def plotNumInteractionsHistogram(cutoff=0.):
+       nums,counts=bodyNumInteractionsHistogram(aabbExtrema(cutoff))
+       import pylab
+       pylab.bar(nums,counts)
+       pylab.title('Number of interactions histogram, average %g 
(cutoff=%g)'%(avgNumInteractions(cutoff),cutoff))
+       pylab.xlabel('Number of interactions')
+       pylab.ylabel('Body count')
+       pylab.show()
+
+def plotDirections(aabb=(),mask=0,bins=20,numHist=True):
+       """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."""
+       import pylab,math
+       from yade 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')
+       pylab.show()
+
+
 def import_stl_geometry(file, begin=0, 
young=30e9,poisson=.3,frictionAngle=0.5236,wire=True):
                ## Import walls geometry from STL file
                imp = STLImporter()
@@ -161,48 +198,3 @@
                        o.bodies[i].mold.postProcessAttributes()
                return imp.number_of_facets
 
-def negPosExtremes(**kw): raise DeprecationWarning("negPosExtremes is 
deprecated, use negPosExtremalIds instead.")
-
-# reimplemented in _utils in c++ (results verified to be identical)
-if 0:
-       def negPosExtremes(axis,distFactor=1.1):
-               """Get 2 lists (negative and positive extremes) of sphere ids 
that are close to the boundary
-               in the direction of requested axis (0=x,1=y,2=z).
-
-               distFactor enlarges radius of the sphere, it can be considered 
'extremal' even if it doesn't touch the extreme.
-               """
-               inf=float('inf')
-               extremes=[inf,-inf]
-               ret=[[],[]]
-               o=Omega()
-               for b in o.bodies:
-                       
extremes[1]=max(extremes[1],+b.shape['radius']+b.phys['se3'][axis])
-                       
extremes[0]=min(extremes[0],-b.shape['radius']+b.phys['se3'][axis])
-               for b in o.bodies:
-                       if 
b.phys['se3'][axis]-b.shape['radius']*distFactor<=extremes[0]: 
ret[0].append(b.id)
-                       if 
b.phys['se3'][axis]+b.shape['radius']*distFactor>=extremes[1]: 
ret[1].append(b.id)
-               return ret
-       def aabbExtrema(consider=lambda body:True):
-               """return min and max points of an aabb around spherical 
packing (non-spheres are ignored)"""
-               inf=float('inf')
-               minimum,maximum=[inf,inf,inf],[-inf,-inf,-inf]
-               o=Omega()
-               for b in o.bodies:
-                       if consider(b) and b.shape.name=='Sphere':
-                               
minimum=[min(minimum[i],b.phys['se3'][i]-b.shape['radius']) for i in range(3)]
-                               
maximum=[max(maximum[i],b.phys['se3'][i]+b.shape['radius']) for i in range(3)]
-               return minimum,maximum
-       def PWaveTimeStep():
-               """Estimate timestep by the elastic wave propagation speed 
(p-wave).
-               
-               Multiply the value returned by some safety factor < 1, since 
shear waves are not taken into account here."""
-               o=Omega()
-               dt=float('inf')
-               for b in o.bodies:
-                       if not (b.phys and b.shape): continue
-                       if not (b.phys.has_key('young') and 
b.shape.has_key('radius')): continue
-                       
density=b.phys['mass']/((4./3.)*math.pi*b.shape['radius']**3)
-                       
thisDt=b.shape['radius']/math.sqrt(b.phys['young']/density)
-                       dt=min(dt,thisDt)
-               return dt
-


_______________________________________________
Mailing list: https://launchpad.net/~yade-dev
Post to     : [email protected]
Unsubscribe : https://launchpad.net/~yade-dev
More help   : https://help.launchpad.net/ListHelp

Reply via email to