yade-dev team mailing list archive
-
yade-dev team
-
Mailing list archive
-
Message #01138
[svn] r1721 - in trunk: core lib pkg/dem pkg/dem/DataClass/InteractionGeometry pkg/dem/Engine/EngineUnit pkg/snow/Engine scripts/test
Author: eudoxos
Date: 2009-03-17 16:14:49 +0100 (Tue, 17 Mar 2009)
New Revision: 1721
Added:
trunk/pkg/dem/DataClass/InteractionGeometry/Dem3DofGeom_FacetSphere.cpp
trunk/pkg/dem/DataClass/InteractionGeometry/Dem3DofGeom_FacetSphere.hpp
trunk/scripts/test/Dem3DofGeom.py
Modified:
trunk/core/Collider.cpp
trunk/lib/SConscript
trunk/pkg/dem/DataClass/InteractionGeometry/Dem3DofGeom_SphereSphere.cpp
trunk/pkg/dem/DataClass/InteractionGeometry/Dem3DofGeom_SphereSphere.hpp
trunk/pkg/dem/DataClass/InteractionGeometry/DemXDofGeom.hpp
trunk/pkg/dem/Engine/EngineUnit/InteractingFacet2InteractingSphere4SpheresContactGeometry.cpp
trunk/pkg/dem/Engine/EngineUnit/InteractingSphere2InteractingSphere4SpheresContactGeometry.hpp
trunk/pkg/dem/SConscript
trunk/pkg/snow/Engine/Ef2_InteractingBox_BssSnowGrain_makeIstSnowLayersContact.cpp
Log:
1. Preliminary version for sphere-facet collisions with total formulation (moderately tested).
2. Same for sphere-sphere collision.
3. test script for facet-sphere collision geometry.
Modified: trunk/core/Collider.cpp
===================================================================
--- trunk/core/Collider.cpp 2009-03-16 00:20:35 UTC (rev 1720)
+++ trunk/core/Collider.cpp 2009-03-17 15:14:49 UTC (rev 1721)
@@ -33,6 +33,7 @@
if(!I->isReal && !I->isNew) return false; // should be deleted
assert(false); // unreachable
+ return false;
}
bool Collider::mayCollide(const Body* b1, const Body* b2){
Modified: trunk/lib/SConscript
===================================================================
--- trunk/lib/SConscript 2009-03-16 00:20:35 UTC (rev 1720)
+++ trunk/lib/SConscript 2009-03-17 15:14:49 UTC (rev 1721)
@@ -113,8 +113,9 @@
['opengl/FpsTracker.cpp',
'opengl/GLTextLabel.cpp',
'opengl/GLWindow.cpp',
- 'opengl/GLWindowsManager.cpp'],
- LIBS=env['LIBS']+['glut']),
+ 'opengl/GLWindowsManager.cpp',
+ 'opengl/GLUtils.cpp'],
+ LIBS=env['LIBS']+['glut','$QGLVIEWER_LIB']),
env.SharedLibrary('XMLFormatManager',
Added: trunk/pkg/dem/DataClass/InteractionGeometry/Dem3DofGeom_FacetSphere.cpp
===================================================================
--- trunk/pkg/dem/DataClass/InteractionGeometry/Dem3DofGeom_FacetSphere.cpp 2009-03-16 00:20:35 UTC (rev 1720)
+++ trunk/pkg/dem/DataClass/InteractionGeometry/Dem3DofGeom_FacetSphere.cpp 2009-03-17 15:14:49 UTC (rev 1721)
@@ -0,0 +1,135 @@
+#include "Dem3DofGeom_FacetSphere.hpp"
+#include<yade/pkg-common/InteractingSphere.hpp>
+#include<yade/pkg-common/InteractingFacet.hpp>
+YADE_PLUGIN("Dem3DofGeom_FacetSphere","GLDraw_Dem3DofGeom_FacetSphere","ef2_Facet_Sphere_Dem3DofGeom");
+
+CREATE_LOGGER(Dem3DofGeom_FacetSphere);
+Dem3DofGeom_FacetSphere::~Dem3DofGeom_FacetSphere(){}
+
+void Dem3DofGeom_FacetSphere::setTgPlanePts(const Vector3r& p1new, const Vector3r& p2new){
+ // FIXME: not tested yet
+ TRVAR3(cp1pt,cp2rel,contPtInTgPlane2()-contPtInTgPlane1());
+ cp1pt=se31.orientation.Conjugate()*(turnPlanePt(p1new,normal,se31.orientation*localFacetNormal)+contactPoint-se31.position);
+ cp2rel=se32.orientation.Conjugate()*Dem3DofGeom_SphereSphere::rollPlanePtToSphere(p2new,effR2,-normal);
+ TRVAR3(cp1pt,cp2rel,contPtInTgPlane2()-contPtInTgPlane1());
+}
+
+void Dem3DofGeom_FacetSphere::relocateContactPoints(const Vector3r& p1, const Vector3r& p2){
+ //TRVAR2(p2.Length(),effR2);
+ if(p2.SquaredLength()>pow(effR2,2)){
+ setTgPlanePts(Vector3r::ZERO,p2-p1);
+ }
+}
+
+CREATE_LOGGER(ef2_Facet_Sphere_Dem3DofGeom);
+bool ef2_Facet_Sphere_Dem3DofGeom::go(const shared_ptr<InteractingGeometry>& cm1, const shared_ptr<InteractingGeometry>& cm2, const Se3r& se31, const Se3r& se32, const shared_ptr<Interaction>& c){
+ InteractingFacet* facet=static_cast<InteractingFacet*>(cm1.get());
+ Real sphereRadius=static_cast<InteractingSphere*>(cm2.get())->radius;
+ // begin facet-local coordinates
+ Vector3r contactLine=se31.orientation.Conjugate()*(se32.position-se31.position);
+ Vector3r normal=facet->nf;
+ Real L=normal.Dot(contactLine); // height/depth of sphere's center from facet's plane
+ if(L>sphereRadius && !c->isReal) return false; // sphere too far away from the plane
+
+ Vector3r contactPt=contactLine-L*normal; // projection of sphere's center to facet's plane (preliminary contact point)
+ const Vector3r* edgeNormals=facet->ne; // array[3] of edge normals (in facet plane)
+ int edgeMax=0; Real distMax=edgeNormals[0].Dot(contactPt);
+ for(int i=1; i<3; i++){
+ Real dist=edgeNormals[i].Dot(contactPt);
+ if(distMax<dist){edgeMax=i; distMax=dist;}
+ }
+ //TRVAR2(distMax,edgeMax);
+ // OK, what's the logic here? Copying from IF2IS4SCG…
+ Real sphereRReduced=shrinkFactor*sphereRadius;
+ Real inCircleR=facet->icr-sphereRReduced;
+ Real penetrationDepth;
+ if(inCircleR<0){inCircleR=facet->icr; sphereRReduced=0;}
+ if(distMax<inCircleR){// contact with facet's surface
+ penetrationDepth=sphereRadius-L;
+ normal.Normalize();
+ } else { // contact with the edge
+ contactPt+=edgeNormals[edgeMax]*(inCircleR-distMax);
+ //TRVAR3(edgeNormals[edgeMax],inCircleR,distMax);
+ // contact with vertex no. edgeMax
+ if (contactPt.Dot(edgeNormals[(edgeMax-1)%3])>inCircleR) contactPt=facet->vu[edgeMax]*(facet->vl[edgeMax]-sphereRReduced);
+ // contact with vertex no. edgeMax+1
+ else if(contactPt.Dot(edgeNormals[edgeMax=(edgeMax+1)%3])>inCircleR) contactPt=facet->vu[edgeMax]*(facet->vl[edgeMax]-sphereRReduced);
+ normal=contactLine-contactPt;
+ //TRVAR4(contactLine,contactPt,normal,normal.Length());
+ //TRVAR3(se31.orientation*contactLine,se31.position+se31.orientation*contactPt,se31.orientation*normal);
+ penetrationDepth=sphereRadius-normal.Normalize();
+ //TRVAR1(penetrationDepth);
+ }
+ // end facet-local coordinates
+
+ if(penetrationDepth<0 && !c->isReal) return false;
+
+ shared_ptr<Dem3DofGeom_FacetSphere> fs;
+ Vector3r normalGlob=se31.orientation*normal;
+ if(c->interactionGeometry) fs=YADE_PTR_CAST<Dem3DofGeom_FacetSphere>(c->interactionGeometry);
+ else {
+ fs=shared_ptr<Dem3DofGeom_FacetSphere>(new Dem3DofGeom_FacetSphere());
+ c->interactionGeometry=fs;
+ fs->effR2=sphereRadius-penetrationDepth;
+ fs->refLength=fs->effR2;
+ fs->cp1pt=contactPt; // facet-local intial contact point
+ fs->localFacetNormal=normal;
+ fs->cp2rel.Align(Vector3r::UNIT_X,se32.orientation.Conjugate()*(-normalGlob)); // initial sphere-local center-contactPt orientation WRT +x
+ fs->cp2rel.Normalize();
+ }
+ fs->se31=se31; fs->se32=se32;
+ fs->normal=normalGlob;
+ fs->contactPoint=se32.position+(-normalGlob)*(sphereRadius-penetrationDepth);
+ if(c->isNew){
+ TRVAR1(penetrationDepth);
+ TRVAR3(fs->refLength,fs->cp1pt,fs->localFacetNormal);
+ TRVAR3(fs->effR2,fs->cp2rel,fs->normal);
+ TRVAR2(fs->se31.orientation,fs->se32.orientation);
+ TRVAR2(fs->contPtInTgPlane1(),fs->contPtInTgPlane2());
+ }
+ return true;
+}
+
+#include<yade/lib-opengl/OpenGLWrapper.hpp>
+#include<yade/lib-opengl/GLUtils.hpp>
+
+bool GLDraw_Dem3DofGeom_FacetSphere::normal=false;
+bool GLDraw_Dem3DofGeom_FacetSphere::rolledPoints=false;
+bool GLDraw_Dem3DofGeom_FacetSphere::unrolledPoints=false;
+bool GLDraw_Dem3DofGeom_FacetSphere::shear=false;
+bool GLDraw_Dem3DofGeom_FacetSphere::shearLabel=false;
+
+void GLDraw_Dem3DofGeom_FacetSphere::go(const shared_ptr<InteractionGeometry>& ig, const shared_ptr<Interaction>& ip, const shared_ptr<Body>& b1, const shared_ptr<Body>& b2, bool wireFrame){
+ Dem3DofGeom_FacetSphere* fs = static_cast<Dem3DofGeom_FacetSphere*>(ig.get());
+ //const Se3r& se31=b1->physicalParameters->dispSe3,se32=b2->physicalParameters->dispSe3;
+ const Se3r& se31=b1->physicalParameters->se3,se32=b2->physicalParameters->se3;
+ const Vector3r& pos1=se31.position; const Vector3r& pos2=se32.position;
+ const Quaternionr& ori1=se31.orientation; const Quaternionr& ori2=se32.orientation;
+ const Vector3r& contPt=fs->contactPoint;
+
+ if(normal){
+ GLUtils::GLDrawArrow(contPt,contPt+fs->refLength*fs->normal); // normal of the contact
+ }
+ // sphere center to point on the sphere
+ if(rolledPoints){
+ //cerr<<pos1<<" "<<pos1+ori1*fs->cp1pt<<" "<<contPt<<endl;
+ GLUtils::GLDrawLine(pos1+ori1*fs->cp1pt,contPt,Vector3r(0,.5,1));
+ GLUtils::GLDrawLine(pos2,pos2+(ori2*fs->cp2rel*Vector3r::UNIT_X*fs->effR2),Vector3r(0,1,.5));
+ }
+ // contact point to projected points
+ if(unrolledPoints||shear){
+ Vector3r ptTg1=fs->contPtInTgPlane1(), ptTg2=fs->contPtInTgPlane2();
+ if(unrolledPoints){
+ //TRVAR3(ptTg1,ptTg2,ss->normal)
+ GLUtils::GLDrawLine(contPt,contPt+ptTg1,Vector3r(0,.5,1));
+ GLUtils::GLDrawLine(contPt,contPt+ptTg2,Vector3r(0,1,.5)); GLUtils::GLDrawLine(pos2,contPt+ptTg2,Vector3r(0,1,.5));
+ }
+ if(shear){
+ GLUtils::GLDrawLine(contPt+ptTg1,contPt+ptTg2,Vector3r(1,1,1));
+ if(shearLabel) GLUtils::GLDrawNum(fs->displacementT().Length(),contPt,Vector3r(1,1,1));
+ }
+ }
+}
+
+
+
Added: trunk/pkg/dem/DataClass/InteractionGeometry/Dem3DofGeom_FacetSphere.hpp
===================================================================
--- trunk/pkg/dem/DataClass/InteractionGeometry/Dem3DofGeom_FacetSphere.hpp 2009-03-16 00:20:35 UTC (rev 1720)
+++ trunk/pkg/dem/DataClass/InteractionGeometry/Dem3DofGeom_FacetSphere.hpp 2009-03-17 15:14:49 UTC (rev 1721)
@@ -0,0 +1,72 @@
+#pragma once
+#include<yade/pkg-dem/DemXDofGeom.hpp>
+// for static roll/unroll functions in Dem3DofGeom_SphereSphere
+#include<yade/pkg-dem/Dem3DofGeom_SphereSphere.hpp>
+
+class Dem3DofGeom_FacetSphere: public Dem3DofGeom{
+ //! turn planePt in plane with normal0 around line passing through origin to plane with normal1
+ static Vector3r turnPlanePt(const Vector3r& planePt, const Vector3r& normal0, const Vector3r& normal1){ Quaternionr q; q.Align(normal0,normal1); return q*planePt; }
+
+ Vector3r contPtInTgPlane1() const { return turnPlanePt(se31.position+se31.orientation*cp1pt-contactPoint,se31.orientation*localFacetNormal,normal); }
+ Vector3r contPtInTgPlane2() const { return Dem3DofGeom_SphereSphere::unrollSpherePtToPlane(se32.orientation*cp2rel,effR2,-normal);}
+
+ public:
+ Dem3DofGeom_FacetSphere(){createIndex();}
+ virtual ~Dem3DofGeom_FacetSphere();
+ /******* API ********/
+ virtual Real displacementN(){ return (se32.position-contactPoint).Length()-refLength;}
+ virtual Vector3r displacementT(){ relocateContactPoints(); return contPtInTgPlane2()-contPtInTgPlane1(); }
+ virtual Real slipToDisplacementTMax(Real displacementTMax){ LOG_FATAL("Not implemented yet."); throw; }
+ /***** end API ******/
+
+ void setTgPlanePts(const Vector3r&, const Vector3r&);
+ void relocateContactPoints(){ relocateContactPoints(contPtInTgPlane1(),contPtInTgPlane2()); }
+ void relocateContactPoints(const Vector3r& p1, const Vector3r& p2);
+ //! reference contact point on the facet in facet-local coords
+ Vector3r cp1pt;
+ //! orientation between +x and the reference contact point (on the sphere) in sphere-local coords
+ Quaternionr cp2rel;
+ //! positions and orientations of both bodies; updated at every iteration
+ Se3r se31, se32;
+ //! unit normal of the facet plane in facet-local coordinates
+ Vector3r localFacetNormal;
+ // effective radius of sphere
+ Real effR2;
+ REGISTER_ATTRIBUTES(Dem3DofGeom,(cp1pt)(cp2rel)(se31)(se32)(localFacetNormal)(effR2) );
+ REGISTER_CLASS_AND_BASE(Dem3DofGeom_FacetSphere,Dem3DofGeom);
+ DECLARE_LOGGER;
+ friend class GLDraw_Dem3DofGeom_FacetSphere;
+ friend class ef2_Facet_Sphere_Dem3DofGeom;
+};
+REGISTER_SERIALIZABLE(Dem3DofGeom_FacetSphere);
+
+#include<yade/pkg-common/GLDrawFunctors.hpp>
+class GLDraw_Dem3DofGeom_FacetSphere:public GLDrawInteractionGeometryFunctor{
+ public:
+ virtual void go(const shared_ptr<InteractionGeometry>&,const shared_ptr<Interaction>&,const shared_ptr<Body>&,const shared_ptr<Body>&,bool wireFrame);
+ static bool normal,rolledPoints,unrolledPoints,shear,shearLabel;
+ RENDERS(Dem3DofGeom_FacetSphere);
+ REGISTER_CLASS_AND_BASE(GLDraw_Dem3DofGeom_FacetSphere,GLDrawInteractionGeometryFunctor);
+ REGISTER_ATTRIBUTES(GLDrawInteractionGeometryFunctor, (normal)(rolledPoints)(unrolledPoints)(shear)(shearLabel) );
+};
+REGISTER_SERIALIZABLE(GLDraw_Dem3DofGeom_FacetSphere);
+
+#include<yade/pkg-common/InteractionGeometryEngineUnit.hpp>
+class ef2_Facet_Sphere_Dem3DofGeom:public InteractionGeometryEngineUnit{
+ public:
+ virtual bool go(const shared_ptr<InteractingGeometry>& cm1, const shared_ptr<InteractingGeometry>& cm2, const Se3r& se31, const Se3r& se32, const shared_ptr<Interaction>& c);
+ virtual bool goReverse( const shared_ptr<InteractingGeometry>& cm1, const shared_ptr<InteractingGeometry>& cm2, const Se3r& se31, const Se3r& se32, const shared_ptr<Interaction>& c){
+ c->swapOrder(); return go(cm2,cm1,se32,se31,c);
+ LOG_ERROR("!! goReverse maybe doesn't work in ef2_Facet_Sphere_Dem3DofGeom. InteractionGeometryMetaEngine should swap interaction members first and call go(...) afterwards.");
+ }
+ //! Reduce the facet's size, probably to avoid singularities at common facets' edges (?)
+ Real shrinkFactor;
+ ef2_Facet_Sphere_Dem3DofGeom(): shrinkFactor(0.) {}
+ FUNCTOR2D(InteractingFacet,InteractingSphere);
+ DEFINE_FUNCTOR_ORDER_2D(InteractingFacet,InteractingSphere);
+ REGISTER_CLASS_AND_BASE(ef2_Facet_Sphere_Dem3DofGeom,InteractionGeometryEngineUnit);
+ REGISTER_ATTRIBUTES(InteractionGeometryEngineUnit,(shrinkFactor));
+ DECLARE_LOGGER;
+};
+REGISTER_SERIALIZABLE(ef2_Facet_Sphere_Dem3DofGeom);
+
Modified: trunk/pkg/dem/DataClass/InteractionGeometry/Dem3DofGeom_SphereSphere.cpp
===================================================================
--- trunk/pkg/dem/DataClass/InteractionGeometry/Dem3DofGeom_SphereSphere.cpp 2009-03-16 00:20:35 UTC (rev 1720)
+++ trunk/pkg/dem/DataClass/InteractionGeometry/Dem3DofGeom_SphereSphere.cpp 2009-03-17 15:14:49 UTC (rev 1721)
@@ -1,5 +1,9 @@
#include "Dem3DofGeom_SphereSphere.hpp"
+#include<yade/pkg-common/InteractingSphere.hpp>
+YADE_PLUGIN("Dem3DofGeom_SphereSphere","GLDraw_Dem3DofGeom_SphereSphere","ef2_Sphere_Sphere_Dem3DofGeom");
+
+
Dem3DofGeom_SphereSphere::~Dem3DofGeom_SphereSphere(){}
/*! Project point from sphere surface to tangent plane,
@@ -25,17 +29,17 @@
*
* @param planePt point on the tangent plane, with origin at the contact point (i.e. at sphere center + normal*radius)
* @param radius sphere radius
- * @param planeNorma _unit_ vector pointing away from sphere center
+ * @param planeNormal _unit_ vector pointing away from sphere center
* @returns orientation that transforms +x axis to the vector between sphere center and point on the sphere that corresponds to planePt.
*
* @note It is not checked whether planePt relly lies on the tangent plane. If not, result will be incorrect.
*/
Quaternionr Dem3DofGeom_SphereSphere::rollPlanePtToSphere(const Vector3r& planePt, const Real& radius, const Vector3r& planeNormal){
- Vector3r axis=planeNormal.Cross(planePt); axis.Normalize();
- Real angle=planePt.Length()/radius;
- Quaternionr normal2pt(axis,angle);
- Quaternionr ret; ret.Align(Vector3r::UNIT_X,normal2pt*planeNormal);
- return ret;
+ Vector3r axis=planeNormal.Cross(planePt); axis.Normalize();
+ Real angle=planePt.Length()/radius;
+ Quaternionr normal2pt(axis,angle);
+ Quaternionr ret; ret.Align(Vector3r::UNIT_X,normal2pt*planeNormal);
+ return ret;
}
@@ -84,3 +88,90 @@
}
+#include<yade/lib-opengl/OpenGLWrapper.hpp>
+#include<yade/lib-opengl/GLUtils.hpp>
+
+
+
+bool GLDraw_Dem3DofGeom_SphereSphere::normal=false;
+bool GLDraw_Dem3DofGeom_SphereSphere::rolledPoints=false;
+bool GLDraw_Dem3DofGeom_SphereSphere::unrolledPoints=false;
+bool GLDraw_Dem3DofGeom_SphereSphere::shear=false;
+bool GLDraw_Dem3DofGeom_SphereSphere::shearLabel=false;
+
+void GLDraw_Dem3DofGeom_SphereSphere::go(const shared_ptr<InteractionGeometry>& ig, const shared_ptr<Interaction>& ip, const shared_ptr<Body>& b1, const shared_ptr<Body>& b2, bool wireFrame){
+ Dem3DofGeom_SphereSphere* ss = static_cast<Dem3DofGeom_SphereSphere*>(ig.get());
+ //const Se3r& se31=b1->physicalParameters->dispSe3,se32=b2->physicalParameters->dispSe3;
+ const Se3r& se31=b1->physicalParameters->se3,se32=b2->physicalParameters->se3;
+ const Vector3r& pos1=se31.position,pos2=se32.position;
+ Vector3r& contPt=ss->contactPoint;
+
+ if(normal){
+ GLUtils::GLDrawArrow(contPt,contPt+ss->normal*.5*ss->refLength); // normal of the contact
+ }
+ #if 0
+ // never used, since bending/torsion not used
+ //Vector3r contPt=se31.position+(ss->effR1/ss->refLength)*(se32.position-se31.position); // must be recalculated to not be unscaled if scaling displacements ...
+ GLUtils::GLDrawLine(pos1,pos2,Vector3r(.5,.5,.5));
+ Vector3r bend; Real tors;
+ ss->bendingTorsionRel(bend,tors);
+ GLUtils::GLDrawLine(contPt,contPt+10*ss->radius1*(bend+ss->normal*tors),Vector3r(1,0,0));
+ #if 0
+ GLUtils::GLDrawNum(bend[0],contPt-.2*ss->normal*ss->radius1,Vector3r(1,0,0));
+ GLUtils::GLDrawNum(bend[1],contPt,Vector3r(0,1,0));
+ GLUtils::GLDrawNum(bend[2],contPt+.2*ss->normal*ss->radius1,Vector3r(0,0,1));
+ GLUtils::GLDrawNum(tors,contPt+.5*ss->normal*ss->radius2,Vector3r(1,1,0));
+ #endif
+ #endif
+ // sphere center to point on the sphere
+ if(rolledPoints){
+ GLUtils::GLDrawLine(pos1,pos1+(ss->ori1*ss->cp1rel*Vector3r::UNIT_X*ss->effR1),Vector3r(0,.5,1));
+ GLUtils::GLDrawLine(pos2,pos2+(ss->ori2*ss->cp2rel*Vector3r::UNIT_X*ss->effR2),Vector3r(0,1,.5));
+ }
+ //TRVAR4(pos1,ss->ori1,pos2,ss->ori2);
+ //TRVAR2(ss->cp2rel,pos2+(ss->ori2*ss->cp2rel*Vector3r::UNIT_X*ss->effR2));
+ // contact point to projected points
+ if(unrolledPoints||shear){
+ Vector3r ptTg1=ss->contPtInTgPlane1(), ptTg2=ss->contPtInTgPlane2();
+ if(unrolledPoints){
+ //TRVAR3(ptTg1,ptTg2,ss->normal)
+ GLUtils::GLDrawLine(contPt,contPt+ptTg1,Vector3r(0,.5,1)); GLUtils::GLDrawLine(pos1,contPt+ptTg1,Vector3r(0,.5,1));
+ GLUtils::GLDrawLine(contPt,contPt+ptTg2,Vector3r(0,1,.5)); GLUtils::GLDrawLine(pos2,contPt+ptTg2,Vector3r(0,1,.5));
+ }
+ if(shear){
+ GLUtils::GLDrawLine(contPt+ptTg1,contPt+ptTg2,Vector3r(1,1,1));
+ if(shearLabel) GLUtils::GLDrawNum(ss->displacementT().Length(),contPt,Vector3r(1,1,1));
+ }
+ }
+}
+
+CREATE_LOGGER(ef2_Sphere_Sphere_Dem3DofGeom);
+
+bool ef2_Sphere_Sphere_Dem3DofGeom::go(const shared_ptr<InteractingGeometry>& cm1, const shared_ptr<InteractingGeometry>& cm2, const Se3r& se31, const Se3r& se32, const shared_ptr<Interaction>& c){
+ InteractingSphere *s1=static_cast<InteractingSphere*>(cm1.get()), *s2=static_cast<InteractingSphere*>(cm2.get());
+ Vector3r normal=se32.position-se31.position;
+ Real penetrationDepthSq=pow(distanceFactor*(s1->radius+s2->radius),2)-normal.SquaredLength();
+ if (penetrationDepthSq<0 && !c->isReal) return false;
+
+ Real dist=normal.Normalize(); /* Normalize() works in-place and returns length before normalization; from here, normal is unit vector */
+ shared_ptr<Dem3DofGeom_SphereSphere> ss;
+ if(c->interactionGeometry) ss=YADE_PTR_CAST<Dem3DofGeom_SphereSphere>(c->interactionGeometry);
+ else {
+ ss=shared_ptr<Dem3DofGeom_SphereSphere>(new Dem3DofGeom_SphereSphere());
+ c->interactionGeometry=ss;
+ // constants
+ ss->refLength=dist;
+ Real penetrationDepth=s1->radius+s2->radius-ss->refLength;
+ ss->effR1=s1->radius-.5*penetrationDepth; ss->effR2=s2->radius-.5*penetrationDepth;
+ // for bending only: ss->initRelOri12=se31.orientation.Conjugate()*se32.orientation;
+ // quasi-constants
+ ss->cp1rel.Align(Vector3r::UNIT_X,se31.orientation.Conjugate()*normal);
+ ss->cp2rel.Align(Vector3r::UNIT_X,se32.orientation.Conjugate()*(-normal));
+ ss->cp1rel.Normalize(); ss->cp2rel.Normalize();
+ }
+ ss->normal=normal;
+ ss->contactPoint=se31.position+(ss->effR1-.5*(ss->refLength-dist))*ss->normal;
+ ss->se31=se31; ss->se32=se32;
+ return true;
+}
+
Modified: trunk/pkg/dem/DataClass/InteractionGeometry/Dem3DofGeom_SphereSphere.hpp
===================================================================
--- trunk/pkg/dem/DataClass/InteractionGeometry/Dem3DofGeom_SphereSphere.hpp 2009-03-16 00:20:35 UTC (rev 1720)
+++ trunk/pkg/dem/DataClass/InteractionGeometry/Dem3DofGeom_SphereSphere.hpp 2009-03-17 15:14:49 UTC (rev 1721)
@@ -15,15 +15,17 @@
public:
//! Positions and orientations of both spheres; must be updated at every iteration by the geom functor
Se3r se31, se32;
- const Vector3r& pos1, pos2; const Quaternionr& ori1, ori2;
+ //! relative orientation of the contact point with regards to sphere-local +x axis (quasi-constant)
Quaternionr cp1rel, cp2rel;
- Dem3DofGeom_SphereSphere(): pos1(se31.position), pos2(se32.position), ori1(se31.orientation), ori2(se32.orientation){}
+ //! shorthands
+ const Vector3r &pos1; const Quaternionr &ori1; const Vector3r &pos2; const Quaternionr &ori2;
+ Dem3DofGeom_SphereSphere(): pos1(se31.position), ori1(se31.orientation), pos2(se32.position), ori2(se32.orientation){createIndex();}
~Dem3DofGeom_SphereSphere();
//! effective radii of spheres for this interaction; can be smaller/larger than actual radii, but quasi-constant throughout the interaction life
Real effR1, effR2;
/********* API **********/
- Real displacementN(){ return (pos2-pos2).Length()-refLength; }
+ Real displacementN(){ return (pos2-pos1).Length()-refLength; }
Vector3r displacementT() {
// enabling automatic relocation decreases overall simulation speed by about 3%; perhaps: bool largeStrains ... ?
#if 1
@@ -35,7 +37,37 @@
Real slipToDisplacementTMax(Real displacementTMax);
/********* end API ***********/
- REGISTER_ATTRIBUTES(Dem3DofGeom,(se31)(se32)(effR1)(effR2));
+ REGISTER_ATTRIBUTES(Dem3DofGeom,(se31)(se32)(effR1)(effR2)(cp1rel)(cp2rel));
+ REGISTER_CLASS_AND_BASE(Dem3DofGeom_SphereSphere,Dem3DofGeom);
+ friend class GLDraw_Dem3DofGeom_SphereSphere;
+ friend class ef2_Sphere_Sphere_Dem3DofGeom;
};
REGISTER_SERIALIZABLE(Dem3DofGeom_SphereSphere);
+#include<yade/pkg-common/GLDrawFunctors.hpp>
+class GLDraw_Dem3DofGeom_SphereSphere:public GLDrawInteractionGeometryFunctor{
+ public:
+ virtual void go(const shared_ptr<InteractionGeometry>&,const shared_ptr<Interaction>&,const shared_ptr<Body>&,const shared_ptr<Body>&,bool wireFrame);
+ static bool normal,rolledPoints,unrolledPoints,shear,shearLabel;
+ //RENDERS(Dem3DofGeom_SphereSphere);
+ //REGISTER_CLASS_AND_BASE(GLDraw_Dem3DofGeom_SphereSphere,GLDrawInteractionGeometryFunctor);
+ REGISTER_ATTRIBUTES(GLDrawInteractionGeometryFunctor,(normal)(rolledPoints)(unrolledPoints)(shear)(shearLabel));
+};
+REGISTER_SERIALIZABLE(GLDraw_Dem3DofGeom_SphereSphere);
+
+#include<yade/pkg-common/InteractionGeometryEngineUnit.hpp>
+class ef2_Sphere_Sphere_Dem3DofGeom:public InteractionGeometryEngineUnit{
+ public:
+ virtual bool go(const shared_ptr<InteractingGeometry>& cm1, const shared_ptr<InteractingGeometry>& cm2, const Se3r& se31, const Se3r& se32, const shared_ptr<Interaction>& c);
+ virtual bool goReverse( const shared_ptr<InteractingGeometry>&, const shared_ptr<InteractingGeometry>&, const Se3r&, const Se3r&, const shared_ptr<Interaction>&){throw runtime_error("goReverse on symmetric functor should never be called!");}
+ //! Factor of sphere radius such that sphere "touch" if their centers are not further than distanceFactor*(r1+r2); defaults to 1.
+ Real distanceFactor;
+ ef2_Sphere_Sphere_Dem3DofGeom(): distanceFactor(1.) {}
+ FUNCTOR2D(InteractingSphere,InteractingSphere);
+ DEFINE_FUNCTOR_ORDER_2D(InteractingSphere,InteractingSphere);
+ REGISTER_CLASS_AND_BASE(ef2_Sphere_Sphere_Dem3DofGeom,InteractionGeometryEngineUnit);
+ REGISTER_ATTRIBUTES(InteractionGeometryEngineUnit,(distanceFactor));
+ DECLARE_LOGGER;
+};
+REGISTER_SERIALIZABLE(ef2_Sphere_Sphere_Dem3DofGeom);
+
Modified: trunk/pkg/dem/DataClass/InteractionGeometry/DemXDofGeom.hpp
===================================================================
--- trunk/pkg/dem/DataClass/InteractionGeometry/DemXDofGeom.hpp 2009-03-16 00:20:35 UTC (rev 1720)
+++ trunk/pkg/dem/DataClass/InteractionGeometry/DemXDofGeom.hpp 2009-03-17 15:14:49 UTC (rev 1721)
@@ -13,21 +13,27 @@
Vector3r normal;
//! some reference point for the interaction
Vector3r contactPoint;
+ //! make strain go to -∞ for length going to zero
+ bool logCompression;
// API that needs to be implemented in derived classes
- virtual Real displacementN()=0;
- virtual Vector3r displacementT()=0;
- virtual Real slipToDisplacementTMax(Real displacementTMax)=0; // plasticity
+ virtual Real displacementN(){throw;}
+ virtual Vector3r displacementT(){throw;}
+ virtual Real slipToDisplacementTMax(Real displacementTMax){throw;}; // plasticity
// end API
- Real strainN(){return displacementN()/refLength;}
+ Real strainN(){
+ //if(!logCompression)
+ return displacementN()/refLength;
+ //else{Real dn=displacementN(); }
+ }
Vector3r strainT(){return displacementT()/refLength;}
Real slipToStrainTMax(Real strainTMax){return slipToDisplacementTMax(strainTMax*refLength)/refLength;}
REGISTER_CLASS_AND_BASE(Dem3DofGeom,InteractionGeometry);
REGISTER_ATTRIBUTES(InteractionGeometry,(refLength)(normal)(contactPoint));
};
-//REGISTER_SERIALIZABLE(Dem3DofGeom);
+REGISTER_SERIALIZABLE(Dem3DofGeom);
#if 0
/*! Abstract class for providing torsion and bending, in addition to inherited normal and shear strains. */
Modified: trunk/pkg/dem/Engine/EngineUnit/InteractingFacet2InteractingSphere4SpheresContactGeometry.cpp
===================================================================
--- trunk/pkg/dem/Engine/EngineUnit/InteractingFacet2InteractingSphere4SpheresContactGeometry.cpp 2009-03-16 00:20:35 UTC (rev 1720)
+++ trunk/pkg/dem/Engine/EngineUnit/InteractingFacet2InteractingSphere4SpheresContactGeometry.cpp 2009-03-17 15:14:49 UTC (rev 1721)
@@ -36,7 +36,7 @@
{
InteractingFacet* facet = static_cast<InteractingFacet*>(cm1.get());
/* could be written as (needs to be tested):
- * Vector3r cl=se32.orientation.Conjugate()*(se32.position-se32.position);
+ * Vector3r cl=se31.orientation.Conjugate()*(se32.position-se31.position);
*/
Matrix3r facetAxisT; se31.orientation.ToRotationMatrix(facetAxisT);
Matrix3r facetAxis = facetAxisT.Transpose();
Modified: trunk/pkg/dem/Engine/EngineUnit/InteractingSphere2InteractingSphere4SpheresContactGeometry.hpp
===================================================================
--- trunk/pkg/dem/Engine/EngineUnit/InteractingSphere2InteractingSphere4SpheresContactGeometry.hpp 2009-03-16 00:20:35 UTC (rev 1720)
+++ trunk/pkg/dem/Engine/EngineUnit/InteractingSphere2InteractingSphere4SpheresContactGeometry.hpp 2009-03-17 15:14:49 UTC (rev 1721)
@@ -33,7 +33,7 @@
FUNCTOR2D(InteractingSphere,InteractingSphere);
- //FIXME: what is this good for?!
+ // needed for the dispatcher, even if it is symmetric
DEFINE_FUNCTOR_ORDER_2D(InteractingSphere,InteractingSphere);
protected :
Modified: trunk/pkg/dem/SConscript
===================================================================
--- trunk/pkg/dem/SConscript 2009-03-16 00:20:35 UTC (rev 1720)
+++ trunk/pkg/dem/SConscript 2009-03-17 15:14:49 UTC (rev 1721)
@@ -29,6 +29,10 @@
env.Install('$PREFIX/lib/yade$SUFFIX/pkg-dem',[
+ 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('SQLiteRecorder',
['Engine/StandAloneEngine/SQLiteRecorder.cpp'],
LIBS=env['LIBS']+['sqlite3x']),
Modified: trunk/pkg/snow/Engine/Ef2_InteractingBox_BssSnowGrain_makeIstSnowLayersContact.cpp
===================================================================
--- trunk/pkg/snow/Engine/Ef2_InteractingBox_BssSnowGrain_makeIstSnowLayersContact.cpp 2009-03-16 00:20:35 UTC (rev 1720)
+++ trunk/pkg/snow/Engine/Ef2_InteractingBox_BssSnowGrain_makeIstSnowLayersContact.cpp 2009-03-17 15:14:49 UTC (rev 1721)
@@ -231,7 +231,8 @@
//return true;
#else
- std::cerr << "ERROR: full version of wm3 library is needed\n";
+ LOG_FATAL("Using miniWm3; recompile with full Wm3 support to make snow folly functional.");
+ throw runtime_error("full wm3 required (message above).");
#endif
}
// if(! m1->depths[id2].empty()) m1->depths[id2].clear();
@@ -435,7 +436,8 @@
//return true;
#else
- std::cerr << "ERROR: full version of wm3 library is needed\n";
+ LOG_FATAL("Using miniWm3; recompile with full Wm3 support to make snow folly functional.");
+ throw runtime_error("full wm3 required (message above).");
#endif
}
if(! m1->depths[id2].empty()) m1->depths[id2].clear();
Added: trunk/scripts/test/Dem3DofGeom.py
===================================================================
--- trunk/scripts/test/Dem3DofGeom.py 2009-03-16 00:20:35 UTC (rev 1720)
+++ trunk/scripts/test/Dem3DofGeom.py 2009-03-17 15:14:49 UTC (rev 1721)
@@ -0,0 +1,39 @@
+
+O.bodies.append([
+ #utils.sphere([0,0,0],1,dynamic=False,color=(0,1,0),wire=True),
+ utils.facet(([2,2,1],[-2,0,1],[2,-2,1]),dynamic=False,color=(0,1,0),wire=False),
+ utils.sphere([-1,0,2],1,dynamic=True,color=(1,0,0),wire=True),
+])
+O.engines=[
+ MetaEngine('BoundingVolumeMetaEngine',[
+ EngineUnit('InteractingSphere2AABB'),
+ EngineUnit('InteractingFacet2AABB'),
+ ]),
+ StandAloneEngine('PersistentSAPCollider'),
+ MetaEngine('InteractionGeometryMetaEngine',[
+ EngineUnit('ef2_Sphere_Sphere_Dem3DofGeom'),
+ EngineUnit('ef2_Facet_Sphere_Dem3DofGeom')
+ ]),
+ #DeusExMachina('GravityEngine',{'gravity':[0,0,-10]}),
+ DeusExMachina('RotationEngine',{'rotationAxis':[0,1,0],'angularVelocity':10,'subscribedBodies':[1]}),
+ DeusExMachina('TranslationEngine',{'translationAxis':[1,0,0],'velocity':10,'subscribedBodies':[1]}),
+ #DeusExMachina('NewtonsDampedLaw')
+]
+O.miscParams=[
+ Generic('GLDraw_Dem3DofGeom_SphereSphere',{'normal':True,'rolledPoints':True,'unrolledPoints':True,'shear':True,'shearLabel':True}),
+ Generic('GLDraw_Dem3DofGeom_FacetSphere',{'normal':False,'rolledPoints':True,'unrolledPoints':True,'shear':True,'shearLabel':True}),
+ Generic('GLDrawSphere',{'glutUse':True})
+]
+
+try:
+ from yade import qt
+ renderer=qt.Renderer()
+ renderer['Body_wire']=True
+ renderer['Interaction_geometry']=True
+ qt.Controller()
+ qt.View()
+except ImportError: pass
+
+O.dt=1e-6
+O.saveTmp('init')
+O.run(50)