← Back to team overview

yade-dev team mailing list archive

[svn] r1522 - trunk/gui/py

 

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
-