yade-dev team mailing list archive
-
yade-dev team
-
Mailing list archive
-
Message #01189
[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']),