← Back to team overview

yade-dev team mailing list archive

[svn] r1749 - in trunk: gui/py pkg/dem pkg/dem/Engine/StandAloneEngine

 

Author: eudoxos
Date: 2009-04-06 23:40:30 +0200 (Mon, 06 Apr 2009)
New Revision: 1749

Added:
   trunk/pkg/dem/Engine/StandAloneEngine/FacetTopologyAnalyzer.cpp
   trunk/pkg/dem/Engine/StandAloneEngine/FacetTopologyAnalyzer.hpp
Modified:
   trunk/gui/py/_utils.cpp
   trunk/pkg/dem/SConscript
Log:
1. Add working version of facet adjacency finder (to get their mutual angle at edge)



Modified: trunk/gui/py/_utils.cpp
===================================================================
--- trunk/gui/py/_utils.cpp	2009-04-06 15:45:13 UTC (rev 1748)
+++ trunk/gui/py/_utils.cpp	2009-04-06 21:40:30 UTC (rev 1749)
@@ -176,8 +176,7 @@
     return d;
 }
 
-
-/* Sum moments acting on bodies within mask.
+/*!Sum moments acting on given bodies
  *
  * @param mask is Body::groupMask that must match for a body to be taken in account.
  * @param axis is the direction of axis with respect to which the moment is calculated.
@@ -187,13 +186,13 @@
  * is position relative to axisPt; moment from moment is m; such moment per body is
  * projected onto axis.
  */
-Real sumBexTorques(int mask, python::tuple _axis, python::tuple _axisPt){
+Real sumBexTorques(python::tuple ids, python::tuple _axis, python::tuple _axisPt){
 	shared_ptr<MetaBody> rb=Omega::instance().getRootBody();
 	rb->bex.sync();
 	Real ret=0;
-	Vector3r axis=tuple2vec(_axis), axisPt=tuple2vec(_axisPt);
-	FOREACH(const shared_ptr<Body> b, *rb->bodies){
-		if(!b->maskOk(mask)) continue;
+	Vector3r axis=tuple2vec(_axis), axisPt=tuple2vec(_axisPt); size_t len=python::len(ids);
+	for(size_t i=0; i<len; i++){
+		const Body* b=(*rb->bodies)[python::extract<int>(ids[i])].get();
 		const Vector3r& m=rb->bex.getTorque(b->getId());
 		const Vector3r& f=rb->bex.getForce(b->getId());
 		Vector3r r=b->physicalParameters->se3.position-axisPt;
@@ -207,14 +206,14 @@
  * @param direction direction in which forces are summed
  *
  */
-Real sumBexForces(int mask, python::tuple _direction){
+Real sumBexForces(python::tuple ids, python::tuple _direction){
 	shared_ptr<MetaBody> rb=Omega::instance().getRootBody();
 	rb->bex.sync();
 	Real ret=0;
-	Vector3r direction=tuple2vec(_direction);
-	FOREACH(const shared_ptr<Body> b, *rb->bodies){
-		if(!b->maskOk(mask)) continue;
-		const Vector3r& f=rb->bex.getForce(b->getId());
+	Vector3r direction=tuple2vec(_direction); size_t len=python::len(ids);
+	for(size_t i=0; i<len; i++){
+		body_id_t id=python::extract<int>(ids[i]);
+		const Vector3r& f=rb->bex.getForce(id);
 		ret+=direction.Dot(f);
 	}
 	return ret;

Added: trunk/pkg/dem/Engine/StandAloneEngine/FacetTopologyAnalyzer.cpp
===================================================================
--- trunk/pkg/dem/Engine/StandAloneEngine/FacetTopologyAnalyzer.cpp	2009-04-06 15:45:13 UTC (rev 1748)
+++ trunk/pkg/dem/Engine/StandAloneEngine/FacetTopologyAnalyzer.cpp	2009-04-06 21:40:30 UTC (rev 1749)
@@ -0,0 +1,42 @@
+#include"FacetTopologyAnalyzer.hpp"
+#include<yade/pkg-common/InteractingFacet.hpp>
+#include<yade/core/MetaBody.hpp>
+#include<yade/core/Body.hpp>
+void FacetTopologyAnalyzer::action(MetaBody* rb){
+	LOG_DEBUG("Projection axis for analysis is "<<projectionAxis);
+	vector<shared_ptr<VertexData> > vv;
+	// minimum facet edge length (tolerance scale)
+	Real minSqLen=0;
+	FOREACH(const shared_ptr<Body>& b, *rb->bodies){
+		shared_ptr<InteractingFacet> f=dynamic_pointer_cast<InteractingFacet>(b->interactingGeometry);
+		if(!f) continue;
+		const Vector3r& pos=b->physicalParameters->se3.position;
+		for(size_t i=0; i<3; i++){
+			vv.push_back(shared_ptr<VertexData>(new VertexData(b->getId(),i,f->vertices[i]+pos,(f->vertices[i]+pos).Dot(projectionAxis))));
+			minSqLen=min(minSqLen,(f->vertices[i]-f->vertices[(i+1)%3]).SquaredLength());
+		}
+	}
+	LOG_DEBUG("Added data for "<<vv.size()<<" vertices ("<<vv.size()/3.<<" facets).");
+	Real tolerance=sqrt(minSqLen)*relTolerance;
+	LOG_DEBUG("Absolute tolerance is "<<tolerance);
+	sort(vv.begin(),vv.end(),VertexComparator());
+	size_t nVertices=vv.size(), j;
+	for(size_t i=0; i<nVertices; i++){
+		j=i;
+		while(++j<nVertices && (vv[j]->coord-vv[i]->coord)<tolerance){
+			shared_ptr<VertexData> &vi=vv[i], &vj=vv[j];
+			if(abs(vi->pos[0]-vj->pos[0])<tolerance &&
+				abs(vi->pos[1]-vj->pos[1])<tolerance &&
+				abs(vi->pos[2]-vj->pos[2])<tolerance &&
+				(vi->pos-vj->pos).SquaredLength()<tolerance*tolerance){
+				// OK, these two vertices touch
+				LOG_DEBUG("Vertices "<<vi->id<<"/"<<vi->vertexNo<<" and "<<vj->id<<"/"<<vj->vertexNo<<" close enough.");
+				// add vertex to the nextIndetical of the one that has lower index; the one that is added will have isLowestIndex=false
+				if(vi->index<vj->index){ vi->nextIdentical.push_back(vj); vj->isLowestIndex=false; }
+				else{                    vj->nextIdentical.push_back(vi); vi->isLowestIndex=false; }
+			}
+		}
+	}
+	/* TODO: create vertex clusters of touching vertices; find what facets they belong to; find whether facets that touch have common edges; compute mutual angle between faces on edge and save that to InteractingFacet */
+}
+

Added: trunk/pkg/dem/Engine/StandAloneEngine/FacetTopologyAnalyzer.hpp
===================================================================
--- trunk/pkg/dem/Engine/StandAloneEngine/FacetTopologyAnalyzer.hpp	2009-04-06 15:45:13 UTC (rev 1748)
+++ trunk/pkg/dem/Engine/StandAloneEngine/FacetTopologyAnalyzer.hpp	2009-04-06 21:40:30 UTC (rev 1749)
@@ -0,0 +1,46 @@
+// 2009 © Václav Šmilauer <eudoxos@xxxxxxxx>
+#pragma once
+#include<yade/core/StandAloneEngine.hpp>
+/*! Initializer for filling adjacency geometry data for facets.
+ *
+ * Common vertices and common edges are identified and mutual angle between facet faces
+ * is written to InteractingFacet instances.
+ * If facets don't move with respect to each other, this must be done only at the beginning.
+ */
+class FacetTopologyAnalyzer: public StandAloneEngine{
+	struct VertexData{
+		VertexData(body_id_t _id, int _vertexNo, Vector3r _pos, Real _coord): id(_id), vertexNo(_vertexNo), coord(_coord), pos(_pos){index=3*id+vertexNo; isLowestIndex=true;}
+		//! Facet (body id) that we represent
+		body_id_t id;
+		//! vertex number within this Facet
+		int vertexNo;
+		//! projected coordinate along projectionAxis
+		Real coord;
+		//! global coordinates
+		Vector3r pos;
+		//! index of this vertex (canonical ordering)
+		size_t index;
+		//! is this vertex the first one in the "identity" graph?
+		bool isLowestIndex;
+		//! vertices that are "identical" with this one, but have higer indices
+		vector<shared_ptr<VertexData> > nextIdentical;
+	};
+	struct VertexComparator{
+		bool operator()(const shared_ptr<VertexData>& v1, const shared_ptr<VertexData>& v2){return v1->coord<v2->coord;}
+	};
+
+	public:
+		//! Axis along which to do the initial vertex sort
+		Vector3r projectionAxis;
+		//! maximum distance of "identical" vertices, relative to maximum facet size
+		Real relTolerance;
+	void action(MetaBody*); 
+	FacetTopologyAnalyzer(): projectionAxis(Vector3r::UNIT_X), relTolerance(1e-4) {}
+	DECLARE_LOGGER;
+	REGISTER_CLASS_AND_BASE(FacetTopologyAnalyzer,StandAloneEngine);
+	REGISTER_ATTRIBUTES(StandAloneEngine, /* none */);
+};
+REGISTER_SERIALIZABLE(FacetTopologyAnalyzer);
+
+
+

Modified: trunk/pkg/dem/SConscript
===================================================================
--- trunk/pkg/dem/SConscript	2009-04-06 15:45:13 UTC (rev 1748)
+++ trunk/pkg/dem/SConscript	2009-04-06 21:40:30 UTC (rev 1749)
@@ -30,7 +30,9 @@
 	env.SharedLibrary('Dem3DofGeom_SphereSphere',['DataClass/InteractionGeometry/Dem3DofGeom_SphereSphere.cpp'],LIBS=env['LIBS']+['RigidBodyParameters','InteractingSphere','yade-opengl']),
 	env.SharedLibrary('Dem3DofGeom_FacetSphere',['DataClass/InteractionGeometry/Dem3DofGeom_FacetSphere.cpp'],LIBS=env['LIBS']+['RigidBodyParameters','InteractingSphere','InteractingFacet','yade-opengl','Dem3DofGeom_SphereSphere']),
 
+	env.SharedLibrary('FacetTopologyAnalyzer',['Engine/StandAloneEngine/FacetTopologyAnalyzer.cpp'],LIBS=env['LIBS']+['InteractingFacet']),
 
+
 	env.SharedLibrary('SQLiteRecorder',
 		['Engine/StandAloneEngine/SQLiteRecorder.cpp'],
 		LIBS=env['LIBS']+['sqlite3x']),