← Back to team overview

yade-dev team mailing list archive

[Branch ~yade-dev/yade/trunk] Rev 2491: 1. Add menu entry for the dbg package (yes, it really does not show up, dunno why either)

 

------------------------------------------------------------
revno: 2491
committer: Václav Šmilauer <eu@xxxxxxxx>
branch nick: yade
timestamp: Sat 2010-10-16 20:31:17 +0200
message:
  1. Add menu entry for the dbg package (yes, it really does not show up, dunno why either)
  2. Add plasticity to Law2_L3Geom_FrictPhys_ElPerfPl, add convenience function to apply local forces
added:
  debian/yade-dbg.menu-template
modified:
  debian/rules
  debian/yade-dbg.postinst-template
  debian/yade-dbg.prerm-template
  debian/yade.menu-template
  pkg/common/Cylinder.cpp
  pkg/common/Dispatching.hpp
  pkg/dem/DomainLimiter.cpp
  pkg/dem/HertzMindlin.cpp
  pkg/dem/Ig2_Box_Sphere_ScGeom.cpp
  pkg/dem/Ig2_Facet_Sphere_ScGeom.cpp
  pkg/dem/Ig2_Sphere_Sphere_ScGeom.cpp
  pkg/dem/L3Geom.cpp
  pkg/dem/L3Geom.hpp
  pkg/dem/ScGeom.cpp
  pkg/dem/ScGeom.hpp
  py/mathWrap/miniEigen.cpp
  scripts/debian-prep
  scripts/test/ResetRandomPosition.py
  scripts/test/callback.py
  scripts/test/chained-cylinder-spring.py
  scripts/test/clump.py
  scripts/test/collider-stride.py
  scripts/test/collider-sweep-simple.py
  scripts/test/dispatcher-torture.py
  scripts/test/facet-sphere.py
  scripts/test/flat-collider.py
  scripts/test/insertion-sort-collider.py
  scripts/test/interpolating-force.py
  scripts/test/law-test.py
  scripts/test/peri3d.py
  scripts/test/periodic-compress.py
  scripts/test/periodic-grow.py
  scripts/test/periodic-shear.py
  scripts/test/periodic-simple-shear.py
  scripts/test/periodic-simple.py
  scripts/test/periodic-triax-velgrad.py
  scripts/test/periodic-triax.py
  scripts/test/remove-body.py
  scripts/test/triax-basic.py
  scripts/test/wall.py


--
lp:yade
https://code.launchpad.net/~yade-dev/yade/trunk

Your team Yade developers is subscribed to branch lp:yade.
To unsubscribe from this branch go to https://code.launchpad.net/~yade-dev/yade/trunk/+edit-subscription
=== modified file 'debian/rules'
--- debian/rules	2010-10-15 16:49:26 +0000
+++ debian/rules	2010-10-16 18:31:17 +0000
@@ -101,7 +101,7 @@
 #	dh_installman -p yade${_VERSION}-dbg yade${_VERSION}-dbg.1 yade${_VERSION}-dbg-batch.1
 	dh_link
 	dh_strip --exclude=yade${_VERSION}-dbg   # don't strip the debug package
-#	dh_compress
+	dh_compress --all --exclude=/usr/share/doc # don't compress documentation and examples
 	dh_fixperms
 #	dh_perl
 	dh_makeshlibs

=== added file 'debian/yade-dbg.menu-template'
--- debian/yade-dbg.menu-template	1970-01-01 00:00:00 +0000
+++ debian/yade-dbg.menu-template	2010-10-16 18:31:17 +0000
@@ -0,0 +1,9 @@
+?package(yade@_VERSION@):\
+	needs="X11"\
+	section="Applications/Science/Physics"\
+	title="Yade (@SNAPSHOT@ @VERSION@)"\
+	command="x-terminal-emulator -T 'Yade @SNAPSHOT@ @VERSION@ (debug)' -x /usr/bin/yade@_VERSION@ -- debug"\
+	icon=/usr/share/pixmaps/yade32x32.xpm\
+	icon16x16=/usr/share/pixmaps/yade16x16.xpm\
+	icon32x32=/usr/share/pixmaps/yade32x32.xpm
+

=== modified file 'debian/yade-dbg.postinst-template'
--- debian/yade-dbg.postinst-template	2010-09-23 14:20:14 +0000
+++ debian/yade-dbg.postinst-template	2010-10-16 18:31:17 +0000
@@ -20,7 +20,6 @@
 
 case "$1" in
     configure)
-	 	update-alternatives --install /usr/bin/yade-dbg yade-dbg /usr/bin/yade@_VERSION@-dbg @PRIORITY@ --slave /usr/bin/yade-dbg-batch yade-dbg-batch /usr/bin/yade@_VERSION@-dbg-batch --slave /usr/share/man/man1/yade-dbg.1.gz yade-dbg.1.gz /usr/share/man/man1/yade@_VERSION@xxxxxxxxx --slave /usr/share/man/man1/yade-dbg-batch.1.gz yade-dbg-batch.1.gz /usr/share/man/man1/yade@_VERSION@xxxxxxxxxxxxxxx
     ;;
 
     abort-upgrade|abort-remove|abort-deconfigure)

=== modified file 'debian/yade-dbg.prerm-template'
--- debian/yade-dbg.prerm-template	2010-01-09 13:13:52 +0000
+++ debian/yade-dbg.prerm-template	2010-10-16 18:31:17 +0000
@@ -19,7 +19,6 @@
 
 case "$1" in
     remove|upgrade|deconfigure)
-        update-alternatives --remove yade-dbg /usr/bin/yade@_VERSION@-dbg
     ;;
 
     failed-upgrade)

=== modified file 'debian/yade.menu-template'
--- debian/yade.menu-template	2010-10-10 12:36:14 +0000
+++ debian/yade.menu-template	2010-10-16 18:31:17 +0000
@@ -1,8 +1,8 @@
 ?package(yade@_VERSION@):\
 	needs="X11"\
-	section="Applications/Science/Engineering"\
-	title="yade@_VERSION@"\
-	command="/usr/bin/yade@_VERSION@"\
+	section="Applications/Science/Physics"\
+	title="Yade (@SNAPSHOT@ @VERSION@)"\
+	command="x-terminal-emulator -T 'Yade @SNAPSHOT@ @VERSION@' -x /usr/bin/yade@_VERSION@"\
 	icon=/usr/share/pixmaps/yade32x32.xpm\
 	icon16x16=/usr/share/pixmaps/yade16x16.xpm\
 	icon32x32=/usr/share/pixmaps/yade32x32.xpm

=== modified file 'pkg/common/Cylinder.cpp'
--- pkg/common/Cylinder.cpp	2010-10-13 16:23:08 +0000
+++ pkg/common/Cylinder.cpp	2010-10-16 18:31:17 +0000
@@ -58,7 +58,7 @@
 		scm->penetrationDepth=penetrationDepth;
 		scm->radius1=s1->radius;
 		scm->radius2=s2->radius;
-		scm->precompute(state1,state2,scene,c,normal,isNew,true);
+		scm->precompute(state1,state2,scene,c,normal,isNew,shift2,true);
 		return true;
 	}
 	return false;
@@ -121,7 +121,7 @@
 	bs1->length=length;
 	bs1->chainedOrientation.setFromTwoVectors(Vector3r::UnitZ(),bchain1.ori.conjugate()*segt);
 #endif
-	scm->precompute(state1,state2,scene,c,segt/length,isNew,true);
+	scm->precompute(state1,state2,scene,c,segt/length,isNew,shift2,true);
 
 	//Set values that will be considered in Ip2 functor, geometry (precomputed) is really defined with values above
 	scm->radius1 = scm->radius2 = bs1->initLength*0.5;

=== modified file 'pkg/common/Dispatching.hpp'
--- pkg/common/Dispatching.hpp	2010-10-14 17:21:34 +0000
+++ pkg/common/Dispatching.hpp	2010-10-16 18:31:17 +0000
@@ -70,11 +70,6 @@
 		addForce(id1, force,scene); addTorque(id1, (contactPoint-pos1).cross(force),scene);
 		addForce(id2,-force,scene); addTorque(id2,-(contactPoint-pos2).cross(force),scene);
 	}
-	/*! Convenience function to apply force and torque from one force, given branch vectors from body centroids (x1,x2) to contact point cp, i.e. cp-x1, cp-x2. */
-	void applyForceAtBranch(const Vector3r& force, const Body::id_t id1, const Vector3r& cx1, const Body::id_t id2, const Vector3r& cx2){
-		addForce(id1, force,scene); addTorque(id1,cx1.cross( force),scene);
-		addForce(id2,-force,scene); addTorque(id2,cx2.cross(-force),scene);
-	}
 	YADE_CLASS_BASE_DOC(LawFunctor,Functor,"Functor for applying constitutive laws on :yref:`interactions<Interaction>`.");
 };
 REGISTER_SERIALIZABLE(LawFunctor);

=== modified file 'pkg/dem/DomainLimiter.cpp'
--- pkg/dem/DomainLimiter.cpp	2010-10-15 16:49:26 +0000
+++ pkg/dem/DomainLimiter.cpp	2010-10-16 18:31:17 +0000
@@ -37,7 +37,10 @@
 	// update path points
 	_pathU.clear(); _pathU.push_back(Vector3r::Zero());
 	_pathR.clear(); _pathR.push_back(Vector3r::Zero());
-	for(size_t i=0; i<pathSize; i++) { _pathU.push_back(i<path.size()?path[i]:*(path.rbegin())); _pathR.push_back(i<rotPath.size()?rotPath[i]:*(rotPath.rbegin())); }
+	for(size_t i=0; i<pathSize; i++) {
+		_pathU.push_back(i<path.size()?path[i]:(path.empty()?Vector3r::Zero():*(path.rbegin())));
+		_pathR.push_back(i<rotPath.size()?rotPath[i]:(rotPath.empty()?Vector3r::Zero():*(rotPath.rbegin())));
+	}
 	// update time points from distances, repeat last distance if shorter than path
 	_pathT.clear(); _pathT.push_back(0);
 	for(size_t i=0; i<pathSteps.size(); i++) _pathT.push_back(_pathT[i]+pathSteps[i]);
@@ -78,6 +81,7 @@
 	if(state1->blockedDOFs!=State::DOF_ALL) { LOG_INFO("Blocking all DOFs for #"<<id1); state1->blockedDOFs=State::DOF_ALL;}
 	if(state2->blockedDOFs!=State::DOF_ALL) { LOG_INFO("Blocking all DOFs for #"<<id2); state2->blockedDOFs=State::DOF_ALL;}
 
+
 	if(step>*(_pathT.rbegin())){
 		LOG_INFO("Last step done, setting zero velocities on #"<<id1<<", #"<<id2<<".");
 		state1->vel=state1->angVel=state2->vel=state2->angVel=Vector3r::Zero();
@@ -86,6 +90,7 @@
 		return;
 	}
 	/* initialize or update local axes and trsf */
+	rotGeom=Vector3r(NaN,NaN,NaN); // this is meaningful only with l6geom
 	if(!l3Geom){
 		axX=gsc->normal; /* just in case */ axX.normalize();
 		if(doInit){ // initialization of the new interaction
@@ -100,7 +105,6 @@
 				scGeom->rotate(shearTot);
 				shearTot+=scGeom->shearIncrement();
 				ptGeom=Vector3r(-scGeom->penetrationDepth,shearTot.dot(axY),shearTot.dot(axZ));
-				rotGeom=Vector3r(NaN,NaN,NaN);
 			}
 			else{ // d3dGeom
 				throw runtime_error("LawTester: Dem3DofGeom not yet supported.");

=== modified file 'pkg/dem/HertzMindlin.cpp'
--- pkg/dem/HertzMindlin.cpp	2010-10-13 16:23:08 +0000
+++ pkg/dem/HertzMindlin.cpp	2010-10-16 18:31:17 +0000
@@ -180,8 +180,9 @@
 	Vector3r shearIncrement;
 	if(nonLin>1){
 		State *de1=Body::byId(id1,scene)->state.get(), *de2=Body::byId(id2,scene)->state.get();	
+		Vector3r shift2=scene->isPeriodic ? Vector3r(scene->cell->Hsize*contact->cellDist.cast<Real>()) : Vector3r::Zero();
 		Vector3r shiftVel=scene->isPeriodic ? Vector3r(scene->cell->velGrad*scene->cell->Hsize*contact->cellDist.cast<Real>()) : Vector3r::Zero();
-		Vector3r incidentV = geom->getIncidentVel(de1, de2, scene->dt, shiftVel, /*preventGranularRatcheting*/ nonLin>2 );	
+		Vector3r incidentV = geom->getIncidentVel(de1, de2, scene->dt, shift2, shiftVel, /*preventGranularRatcheting*/ nonLin>2 );	
 		Vector3r incidentVn = geom->normal.dot(incidentV)*geom->normal; // contact normal velocity
 		Vector3r incidentVs = incidentV-incidentVn; // contact shear velocity
 		shearIncrement=incidentVs*scene->dt;
@@ -278,13 +279,14 @@
 	
 	Vector3r& shearElastic = phys->shearElastic; // reference for shearElastic force
 	// Define shift to handle periodicity
+	Vector3r shift2   = scene->isPeriodic ? Vector3r(                      scene->cell->Hsize *contact->cellDist.cast<Real>()) : Vector3r::Zero();
 	Vector3r shiftVel = scene->isPeriodic ? Vector3r((scene->cell->velGrad*scene->cell->Hsize)*contact->cellDist.cast<Real>()) : Vector3r::Zero();
 	// 1. Rotate shear force
 	shearElastic = scg->rotate(shearElastic);
 	Vector3r prev_FsElastic = shearElastic; // save shear force at previous time step
 	// 2. Get incident velocity, get shear and normal components
 	// FIXME: Concerning the possibility to avoid granular ratcheting, it is not clear how this works in the case of HM. See the thread http://www.mail-archive.com/yade-users@xxxxxxxxxxxxxxxxxxx/msg01947.html
-	Vector3r incidentV = scg->getIncidentVel(de1, de2, dt, shiftVel, preventGranularRatcheting);	
+	Vector3r incidentV = scg->getIncidentVel(de1, de2, dt, shift2, shiftVel, preventGranularRatcheting);	
 	Vector3r incidentVn = scg->normal.dot(incidentV)*scg->normal; // contact normal velocity
 	Vector3r incidentVs = incidentV - incidentVn; // contact shear velocity
 	// 3. Get shear force (incrementally)

=== modified file 'pkg/dem/Ig2_Box_Sphere_ScGeom.cpp'
--- pkg/dem/Ig2_Box_Sphere_ScGeom.cpp	2010-10-13 16:23:08 +0000
+++ pkg/dem/Ig2_Box_Sphere_ScGeom.cpp	2010-10-16 18:31:17 +0000
@@ -108,7 +108,7 @@
 		scm->radius1 = s->radius;
 		scm->radius2 = s->radius;
 		c->geom = scm;
-		scm->precompute(state1,state2,scene,c,normal,isNew,true);
+		scm->precompute(state1,state2,scene,c,normal,isNew,shift2,true);
 	} else { // outside
 		Vector3r cOnBox_box = boxAxisT*cOnBox_boxLocal; // projection of sphere's center on closest box surface - relative to box's origin, but GLOBAL orientation!
 		Vector3r cOnBox_sphere = cOnBox_box-relPos21; // same, but origin in sphere's center
@@ -147,7 +147,7 @@
 		scm->radius1 = s->radius;
 		scm->radius2 = s->radius;
 		c->geom = scm;
-		scm->precompute(state1,state2,scene,c,-cOnBox_sphere,isNew,true);
+		scm->precompute(state1,state2,scene,c,-cOnBox_sphere,isNew,shift2,true);
 	}
 	return true;
 }

=== modified file 'pkg/dem/Ig2_Facet_Sphere_ScGeom.cpp'
--- pkg/dem/Ig2_Facet_Sphere_ScGeom.cpp	2010-10-13 16:23:08 +0000
+++ pkg/dem/Ig2_Facet_Sphere_ScGeom.cpp	2010-10-16 18:31:17 +0000
@@ -107,7 +107,7 @@
 		scm->radius1 = 2*sphereRadius;
 		scm->radius2 = sphereRadius;
 		if (isNew) c->geom = scm;
-		scm->precompute(state1,state2,scene,c,normal,isNew,true);
+		scm->precompute(state1,state2,scene,c,normal,isNew,shift2,true);
 		return true;
 	}
 	return false;

=== modified file 'pkg/dem/Ig2_Sphere_Sphere_ScGeom.cpp'
--- pkg/dem/Ig2_Sphere_Sphere_ScGeom.cpp	2010-10-13 16:23:08 +0000
+++ pkg/dem/Ig2_Sphere_Sphere_ScGeom.cpp	2010-10-16 18:31:17 +0000
@@ -39,7 +39,7 @@
 		scm->penetrationDepth=penetrationDepth;
 		scm->radius1=s1->radius;
 		scm->radius2=s2->radius;
-		scm->precompute(state1,state2,scene,c,normal,isNew,avoidGranularRatcheting);
+		scm->precompute(state1,state2,scene,c,normal,isNew,shift2,avoidGranularRatcheting);
 		return true;
 	}
 	return false;

=== modified file 'pkg/dem/L3Geom.cpp'
--- pkg/dem/L3Geom.cpp	2010-10-15 16:49:26 +0000
+++ pkg/dem/L3Geom.cpp	2010-10-16 18:31:17 +0000
@@ -2,9 +2,26 @@
 #include<yade/pkg-dem/L3Geom.hpp>
 #include<yade/pkg-common/Sphere.hpp>
 
-YADE_PLUGIN((L3Geom)(Ig2_Sphere_Sphere_L3Geom_Inc)(Law2_L3Geom_FrictPhys_Linear)(Law2_L6Geom_FrictPhys_Linear));
+YADE_PLUGIN((L3Geom)(Ig2_Sphere_Sphere_L3Geom_Inc)(Law2_L3Geom_FrictPhys_ElPerfPl)(Law2_L6Geom_FrictPhys_Linear));
 
 L3Geom::~L3Geom(){}
+void L3Geom::applyLocalForceTorque(const Vector3r& localF, const Vector3r& localT, const Interaction* I, Scene* scene, NormShearPhys* nsp) const {
+	Vector3r globF=trsf.transpose()*localF; // trsf is orthonormal, therefore inverse==transpose
+	Vector3r x1c(normal*(refR1+.5*u[0])), x2c(normal*(refR1+.5*u[0]));
+	if(nsp){ nsp->normalForce=normal*globF.dot(normal); nsp->shearForce=globF-nsp->normalForce; }
+	Vector3r globT=Vector3r::Zero();
+	// add torque, if any
+	if(localT!=Vector3r::Zero()){	globT=trsf.transpose()*localT; }
+	// apply force and torque
+	scene->forces.addForce(I->getId1(), globF); scene->forces.addTorque(I->getId1(),x1c.cross( globF)+globT);
+	scene->forces.addForce(I->getId2(),-globF); scene->forces.addTorque(I->getId2(),x2c.cross(-globF)-globT);
+}
+
+void L3Geom::applyLocalForce(const Vector3r& localF, const Interaction* I, Scene* scene, NormShearPhys* nsp) const {
+	applyLocalForceTorque(localF,Vector3r::Zero(),I,scene,nsp);
+}
+
+
 L6Geom::~L6Geom(){}
 
 bool Ig2_Sphere_Sphere_L3Geom_Inc::go(const shared_ptr<Shape>& s1, const shared_ptr<Shape>& s2, const State& state1, const State& state2, const Vector3r& shift2, const bool& force, const shared_ptr<Interaction>& I){
@@ -130,26 +147,33 @@
 };
 
 
-void Law2_L3Geom_FrictPhys_Linear::go(shared_ptr<IGeom>& ig, shared_ptr<IPhys>& ip, Interaction* I){
-	const shared_ptr<L3Geom> geom=static_pointer_cast<L3Geom>(ig); const shared_ptr<FrictPhys> phys=static_pointer_cast<FrictPhys>(ip);
-	// compute force:
-	Vector3r localF=geom->u.cwise()*Vector3r(phys->kn,phys->ks,phys->ks);
-	// transform back to global coords
-	Vector3r globalF=Quaternionr(geom->trsf).conjugate()*localF;
-	// only for keeping track of the force
-	phys->normalForce=geom->normal*globalF.dot(geom->normal); phys->shearForce=globalF-phys->normalForce;
-	// apply force and torque
-	applyForceAtBranch(globalF,I->getId1(),geom->normal*(geom->refR1+.5*geom->u[0]),I->getId2(),-geom->normal*(geom->refR1+.5*geom->u[0]));
+void Law2_L3Geom_FrictPhys_ElPerfPl::go(shared_ptr<IGeom>& ig, shared_ptr<IPhys>& ip, Interaction* I){
+	L3Geom* geom=static_cast<L3Geom*>(ig.get()); FrictPhys* phys=static_cast<FrictPhys*>(ip.get());
+
+	// compute force
+	Vector3r localF=geom->relU().cwise()*Vector3r(phys->kn,phys->ks,phys->ks);
+	// break if necessary
+	if(localF[0]>0 && !noBreak){ scene->interactions->requestErase(I->getId1(),I->getId2()); }
+
+	if(!noSlip){
+		// plastic slip, if necessary
+		Real maxFs=localF[0]*phys->tangensOfFrictionAngle; Vector2r Fs=Vector2r::Map(&localF[1]);
+		if(Fs.squaredNorm()>maxFs*maxFs){
+			Real ratio=sqrt(maxFs*maxFs/Fs.squaredNorm());
+			geom->u0+=(1-ratio)*Vector3r(0,geom->relU()[1],geom->relU()[2]); // increment plastic displacement
+			Fs*=ratio; // decrement shear force value;
+		}
+	}
+	// apply force: this converts the force to global space, updates NormShearPhys::{normal,shear}Force, applies to particles
+	geom->applyLocalForce(localF,I,scene,phys);
 }
 
 void Law2_L6Geom_FrictPhys_Linear::go(shared_ptr<IGeom>& ig, shared_ptr<IPhys>& ip, Interaction* I){
-	// same as for L3Geom, except of the torque term
-	const shared_ptr<L6Geom> geom=static_pointer_cast<L6Geom>(ig); const shared_ptr<FrictPhys> phys=static_pointer_cast<FrictPhys>(ip);
-	Vector3r localF=geom->u.cwise()*Vector3r(phys->kn,phys->ks,phys->ks);
-	Vector3r localT=charLen*(geom->phi.cwise()*Vector3r(phys->kn,phys->ks,phys->ks));
-	Quaternionr invTrsf=Quaternionr(geom->trsf).conjugate();
-	Vector3r globalF=invTrsf*localF, globalT=invTrsf*localT;
-	phys->normalForce=geom->normal*globalF.dot(geom->normal); phys->shearForce=globalF-phys->normalForce;
-	applyForceAtBranch(globalF,I->getId1(),geom->normal*(geom->refR1+.5*geom->u[0]),I->getId2(),-geom->normal*(geom->refR1+.5*geom->u[0]));
-	scene->forces.addTorque(I->getId1(),globalT); scene->forces.addTorque(I->getId2(),-globalT);
+	L6Geom* geom=static_cast<L6Geom*>(ig.get()); FrictPhys* phys=static_cast<FrictPhys*>(ip.get());
+
+	// simple linear relationships
+	Vector3r localF=geom->relU().cwise()*Vector3r(phys->kn,phys->ks,phys->ks);
+	Vector3r localT=charLen*(geom->relPhi().cwise()*Vector3r(phys->kn,phys->ks,phys->ks));
+
+	geom->applyLocalForceTorque(localF,localT,I,scene,phys);
 }

=== modified file 'pkg/dem/L3Geom.hpp'
--- pkg/dem/L3Geom.hpp	2010-10-15 16:49:26 +0000
+++ pkg/dem/L3Geom.hpp	2010-10-16 18:31:17 +0000
@@ -11,9 +11,19 @@
 	const Real& uN;
 	const Vector2r& uT; 
 	virtual ~L3Geom();
+
+	// utility function
+	// TODO: currently supposes body's centroids are conencted with distance*normal
+	// that will not be true for sphere+facet and others, watch out!
+	// the force is oriented as applied to particle #1
+	void applyLocalForce(const Vector3r& f, const Interaction* I, Scene* scene, NormShearPhys* nsp=NULL) const;
+	void applyLocalForceTorque(const Vector3r& f, const Vector3r& t, const Interaction* I, Scene* scene, NormShearPhys* nsp=NULL) const;
+
+	Vector3r relU() const{ return u-u0; }
+
 	YADE_CLASS_BASE_DOC_ATTRS_INIT_CTOR_PY(L3Geom,GenericSpheresContact,"Geometry of contact given in local coordinates with 3 degress of freedom: normal and two in shear plane. [experimental]",
 		((Vector3r,u,Vector3r::Zero(),,"Displacement components, in local coordinates. |yupdate|"))
-		// ((Vector3r,u0,Vector3r::Zero(),,"Zero displacement value; u0 will be always subtracted from the *geometrical* displacement by appropriate :yref:`IGeomFunctor`, resulting in *u*. This value can be changed for instance\n\n#. by :yref:`IGeomFunctor`, e.g. to take in account large shear displacement value unrepresentable by underlying geomeric algorithm based on quaternions)\n#. by :yref:`LawFunctor`, to account for normal equilibrium position different from zero geometric overlap (set once, just after the interaction is created)\n#. by :yref:`LawFunctor` to account for plastic slip.\n\n.. note:: Never set an absolute value of *u0*, only increment, since both :yref:`IGeomFunctor` and :yref:`LawFunctor` use it. If you need to keep track of plastic deformation, store it in :yref:`IPhys` isntead (this might be changed: have *u0* for :yref:`LawFunctor` exclusively, and a separate value stored (when that is needed) inside classes deriving from :yref:`L3Geom`."))
+		((Vector3r,u0,Vector3r::Zero(),,"Zero displacement value; u0 should be always subtracted from the *geometrical* displacement *u* computed by appropriate :yref:`IGeomFunctor`, resulting in *u*. This value can be changed for instance\n\n#. by :yref:`IGeomFunctor`, e.g. to take in account large shear displacement value unrepresentable by underlying geomeric algorithm based on quaternions)\n#. by :yref:`LawFunctor`, to account for normal equilibrium position different from zero geometric overlap (set once, just after the interaction is created)\n#. by :yref:`LawFunctor` to account for plastic slip.\n\n.. note:: Never set an absolute value of *u0*, only increment, since both :yref:`IGeomFunctor` and :yref:`LawFunctor` use it. If you need to keep track of plastic deformation, store it in :yref:`IPhys` isntead (this might be changed: have *u0* for :yref:`LawFunctor` exclusively, and a separate value stored (when that is needed) inside classes deriving from :yref:`L3Geom`."))
 		/* Is it better to store trsf as Matrix3 or Quaternion?
 			* Quaternions are much easier to re-normalize, which we should do to avoid numerical drift.
 			* Multiplication of vector with quaternion is internally done by converting to matrix first, anyway
@@ -36,8 +46,10 @@
 
 struct L6Geom: public L3Geom{
 	virtual ~L6Geom();
+	Vector3r relPhi() const{ return phi-phi0; }
 	YADE_CLASS_BASE_DOC_ATTRS(L6Geom,L3Geom,"Geoemtric of contact in local coordinates with 6 degrees of freedom. [experimental]",
 		((Vector3r,phi,Vector3r::Zero(),,"Rotation components, in local coordinates. |yupdate|"))
+		((Vector3r,phi0,Vector3r::Zero(),,"Zero rotation, should be always subtracted from *phi* to get the value. See :yref:`L3Geom.u0`."))
 	);
 };
 REGISTER_SERIALIZABLE(L6Geom);
@@ -69,18 +81,20 @@
 REGISTER_SERIALIZABLE(Ig2_Sphere_Sphere_L6Geom_Inc);
 
 
-struct Law2_L3Geom_FrictPhys_Linear: public LawFunctor{
+struct Law2_L3Geom_FrictPhys_ElPerfPl: public LawFunctor{
 	virtual void go(shared_ptr<IGeom>&, shared_ptr<IPhys>&, Interaction*);
 	FUNCTOR2D(L3Geom,FrictPhys);
-	YADE_CLASS_BASE_DOC(Law2_L3Geom_FrictPhys_Linear,LawFunctor,"Basic law for testing :yref:`L3Geom` -- linear in both normal and shear sense, without slip or breakage.");
+	YADE_CLASS_BASE_DOC_ATTRS(Law2_L3Geom_FrictPhys_ElPerfPl,LawFunctor,"Basic law for testing :yref:`L3Geom`; it bears no cohesion (unless *noBreak* is ``True``), and plastic slip obeys the Mohr-Coulomb criterion (unless *noSlip* is ``True``).",
+		((bool,noBreak,false,,"Do not break contacts when particles separate."))
+		((bool,noSlip,false,,"No plastic slipping."))
+	);
 };
-REGISTER_SERIALIZABLE(Law2_L3Geom_FrictPhys_Linear);
-
-
-struct Law2_L6Geom_FrictPhys_Linear: public LawFunctor{
+REGISTER_SERIALIZABLE(Law2_L3Geom_FrictPhys_ElPerfPl);
+
+struct Law2_L6Geom_FrictPhys_Linear: public Law2_L3Geom_FrictPhys_ElPerfPl{
 	virtual void go(shared_ptr<IGeom>&, shared_ptr<IPhys>&, Interaction*);
 	FUNCTOR2D(L6Geom,FrictPhys);
-	YADE_CLASS_BASE_DOC_ATTRS(Law2_L6Geom_FrictPhys_Linear,LawFunctor,"Basic law for testing :yref:`L3Geom` -- linear in both normal and shear sense, without slip or breakage.",
+	YADE_CLASS_BASE_DOC_ATTRS(Law2_L6Geom_FrictPhys_Linear,Law2_L3Geom_FrictPhys_ElPerfPl,"Basic law for testing :yref:`L6Geom` -- linear in both normal and shear sense, without slip or breakage.",
 		((Real,charLen,1,,"Characteristic length with the meaning of the stiffness ratios bending/shear and torsion/normal."))
 	);
 };

=== modified file 'pkg/dem/ScGeom.cpp'
--- pkg/dem/ScGeom.cpp	2010-10-13 16:23:08 +0000
+++ pkg/dem/ScGeom.cpp	2010-10-16 18:31:17 +0000
@@ -20,7 +20,7 @@
 }
 
 //!Precompute data needed for rotating tangent vectors attached to the interaction
-void ScGeom::precompute(const State& rbp1, const State& rbp2, const Scene* scene, const shared_ptr<Interaction>& c, const Vector3r& currentNormal, bool isNew, bool avoidGranularRatcheting){
+void ScGeom::precompute(const State& rbp1, const State& rbp2, const Scene* scene, const shared_ptr<Interaction>& c, const Vector3r& currentNormal, bool isNew, const Vector3r& shift2, bool avoidGranularRatcheting){
 	if(!isNew) {
 		orthonormal_axis = normal.cross(currentNormal);
 		Real angle = scene->dt*0.5*normal.dot(rbp1.angVel + rbp2.angVel);
@@ -29,13 +29,13 @@
 	//Update contact normal
 	normal=currentNormal;
 	//Precompute shear increment
-	Vector3r relativeVelocity=getIncidentVel(&rbp1,&rbp2,scene->dt,scene->isPeriodic ? Vector3r(scene->cell->velGrad*scene->cell->Hsize*c->cellDist.cast<Real>()) : Vector3r::Zero(),avoidGranularRatcheting);
+	Vector3r relativeVelocity=getIncidentVel(&rbp1,&rbp2,scene->dt,shift2,scene->isPeriodic ? Vector3r(scene->cell->velGrad*scene->cell->Hsize*c->cellDist.cast<Real>()) : Vector3r::Zero(),avoidGranularRatcheting);
 	//keep the shear part only
 	relativeVelocity = relativeVelocity-normal.dot(relativeVelocity)*normal;
 	shearInc = relativeVelocity*scene->dt;
 }
 
-Vector3r ScGeom::getIncidentVel(const State* rbp1, const State* rbp2, Real dt, const Vector3r& shiftVel, bool avoidGranularRatcheting){
+Vector3r ScGeom::getIncidentVel(const State* rbp1, const State* rbp2, Real dt, const Vector3r& shift2, const Vector3r& shiftVel, bool avoidGranularRatcheting){
 	Vector3r& x = contactPoint;
 	Vector3r c1x, c2x;
 	if(avoidGranularRatcheting){
@@ -61,7 +61,7 @@
 	} else {
 		// FIXME: It is correct for sphere-sphere and sphere-facet contact
 		c1x = (x - rbp1->pos);
-		c2x = (x - rbp2->pos);
+		c2x = (x - rbp2->pos + shift2);
 	}
 	Vector3r relativeVelocity = (rbp2->vel+rbp2->angVel.cross(c2x)) - (rbp1->vel+rbp1->angVel.cross(c1x));
 	//update relative velocity for interactions across periods
@@ -71,7 +71,7 @@
 
 Vector3r ScGeom::getIncidentVel(const State* rbp1, const State* rbp2, Real dt, bool avoidGranularRatcheting){
 	//Just pass null shift to the periodic version
-	return getIncidentVel(rbp1,rbp2,dt,Vector3r::Zero(),avoidGranularRatcheting);
+	return getIncidentVel(rbp1,rbp2,dt,Vector3r::Zero(),Vector3r::Zero(),avoidGranularRatcheting);
 }
 
 Vector3r ScGeom::getIncidentVel_py(shared_ptr<Interaction> i, bool avoidGranularRatcheting){
@@ -79,6 +79,7 @@
 	Scene* scene=Omega::instance().getScene().get();
 	return getIncidentVel(Body::byId(i->getId1(),scene)->state.get(),Body::byId(i->getId2(),scene)->state.get(),
 		scene->dt,
-		scene->isPeriodic ? Vector3r(scene->cell->velGrad*scene->cell->Hsize*i->cellDist.cast<Real>()) : Vector3r::Zero(),
+		scene->isPeriodic ? Vector3r(                     scene->cell->Hsize*i->cellDist.cast<Real>()): Vector3r::Zero(), // shift2
+		scene->isPeriodic ? Vector3r(scene->cell->velGrad*scene->cell->Hsize*i->cellDist.cast<Real>()) : Vector3r::Zero(), // shiftVel
 		avoidGranularRatcheting);
 }

=== modified file 'pkg/dem/ScGeom.hpp'
--- pkg/dem/ScGeom.hpp	2010-10-13 16:23:08 +0000
+++ pkg/dem/ScGeom.hpp	2010-10-16 18:31:17 +0000
@@ -27,14 +27,14 @@
 		virtual ~ScGeom();
 		
 		//!precompute values of shear increment and interaction rotation data. Update contact normal to the vurrentNormal value. Precondition : the value of normal is not updated outside (and before) this function.
-		void precompute(const State& rbp1, const State& rbp2, const Scene* scene, const shared_ptr<Interaction>& c, const Vector3r& currentNormal, bool isNew, bool avoidGranularRatcheting=true);
+		void precompute(const State& rbp1, const State& rbp2, const Scene* scene, const shared_ptr<Interaction>& c, const Vector3r& currentNormal, bool isNew, const Vector3r& shift2, bool avoidGranularRatcheting=true);
 
 		//! Rotates a "shear" vector to keep track of contact orientation. Returns reference of the updated vector.
 		Vector3r& rotate(Vector3r& tangentVector) const;
 		const Vector3r& shearIncrement() const {return shearInc;}
 
 		// Add method which returns the impact velocity (then, inside the contact law, this can be split into shear and normal component). Handle periodicity.
-		Vector3r getIncidentVel(const State* rbp1, const State* rbp2, Real dt, const Vector3r& shiftVel, bool avoidGranularRatcheting=true);
+		Vector3r getIncidentVel(const State* rbp1, const State* rbp2, Real dt, const Vector3r& shiftVel, const Vector3r& shift2, bool avoidGranularRatcheting=true);
 		// Implement another version of getIncidentVel which does not handle periodicity.
 		Vector3r getIncidentVel(const State* rbp1, const State* rbp2, Real dt, bool avoidGranularRatcheting=true);
 		

=== modified file 'py/mathWrap/miniEigen.cpp'
--- py/mathWrap/miniEigen.cpp	2010-10-15 16:49:26 +0000
+++ py/mathWrap/miniEigen.cpp	2010-10-16 18:31:17 +0000
@@ -55,7 +55,7 @@
 // pickling support
 struct Matrix3r_pickle: bp::pickle_suite{static bp::tuple getinitargs(const Matrix3r& x){ return bp::make_tuple(x(0,0),x(0,1),x(0,2),x(1,0),x(1,1),x(1,2),x(2,0),x(2,1),x(2,2));} };
 struct Quaternionr_pickle: bp::pickle_suite{static bp::tuple getinitargs(const Quaternionr& x){ return bp::make_tuple(x.w(),x.x(),x.y(),x.z());} };
-struct Vector6r_pickle: bp::pickle_suite{static bp::tuple getinitargs(const Vector3r& x){ return bp::make_tuple(x[0],x[1],x[2],x[3],x[4],x[5]);} };
+struct Vector6r_pickle: bp::pickle_suite{static bp::tuple getinitargs(const Vector6r& x){ return bp::make_tuple(x[0],x[1],x[2],x[3],x[4],x[5]);} };
 struct Vector3r_pickle: bp::pickle_suite{static bp::tuple getinitargs(const Vector3r& x){ return bp::make_tuple(x[0],x[1],x[2]);} };
 struct Vector3i_pickle: bp::pickle_suite{static bp::tuple getinitargs(const Vector3i& x){ return bp::make_tuple(x[0],x[1],x[2]);} };
 struct Vector2r_pickle: bp::pickle_suite{static bp::tuple getinitargs(const Vector2r& x){ return bp::make_tuple(x[0],x[1]);} };
@@ -180,6 +180,7 @@
 		.def_pickle(Matrix3r_pickle())
 		//
 		.def("determinant",&Matrix3r::determinant)
+		.def("trace",&Matrix3r::trace)
 		.def("inverse",&Matrix3r_inverse)
 		.def("transpose",&Matrix3r_transpose)
 		.def("polarDecomposition",&Matrix3r_polarDecomposition)

=== modified file 'scripts/debian-prep'
--- scripts/debian-prep	2010-10-10 12:36:14 +0000
+++ scripts/debian-prep	2010-10-16 18:31:17 +0000
@@ -38,6 +38,7 @@
 	('yade.prerm-template','yade-%s.prerm'%VERSION),
 	('yade-dbg.prerm-template','yade-%s-dbg.prerm'%VERSION),
 	('yade.menu-template','yade-%s.menu'%VERSION),
+	('yade-dbg.menu-template','yade-%s-dbg.menu'%VERSION),
 	('control-template','control')]:
 		copyReplace('debian/'+f1,'debian/'+f2)
 

=== modified file 'scripts/test/ResetRandomPosition.py'
--- scripts/test/ResetRandomPosition.py	2010-09-27 17:47:59 +0000
+++ scripts/test/ResetRandomPosition.py	2010-10-16 18:31:17 +0000
@@ -49,7 +49,7 @@
 	InteractionLoop(
 		[Ig2_Sphere_Sphere_ScGeom(), Ig2_Facet_Sphere_ScGeom()],
 		[Ip2_ViscElMat_ViscElMat_ViscElPhys()],
-		[Law2_Spheres_Viscoelastic_SimpleViscoelastic()],
+		[Law2_ScGeom_ViscElPhys_Basic()],
 	),
 	GravityEngine(gravity=[0,0,-9.81]),
 	NewtonIntegrator(damping=0),

=== modified file 'scripts/test/callback.py'
--- scripts/test/callback.py	2010-09-27 17:47:59 +0000
+++ scripts/test/callback.py	2010-10-16 18:31:17 +0000
@@ -9,7 +9,7 @@
 	InteractionLoop(
 		[Ig2_Sphere_Sphere_ScGeom()],
 		[Ip2_FrictMat_FrictMat_FrictPhys()],
-		[Law2_ScGeom_FrictPhys_Basic()]
+		[Law2_ScGeom_FrictPhys_CundallStrack()]
 	),
 	GravityEngine(gravity=(0,0,-9.81)),
 	NewtonIntegrator(label='newton')

=== modified file 'scripts/test/chained-cylinder-spring.py'
--- scripts/test/chained-cylinder-spring.py	2010-09-27 17:47:59 +0000
+++ scripts/test/chained-cylinder-spring.py	2010-10-16 18:31:17 +0000
@@ -21,7 +21,7 @@
 	InteractionLoop(
 		[Ig2_ChainedCylinder_ChainedCylinder_ScGeom(),Ig2_Sphere_ChainedCylinder_CylScGeom()],
 		[Ip2_2xCohFrictMat_CohFrictPhys(setCohesionNow=True,setCohesionOnNewContacts=True,normalCohesion=1e13,shearCohesion=1e13)],
-		[Law2_ScGeom_CohFrictPhys_ElasticPlastic(momentRotationLaw=True,label='law')]
+		[Law2_ScGeom_CohFrictPhys_CohesionMoment(momentRotationLaw=True,label='law')]
 	),
 	## Apply gravity
 	GravityEngine(gravity=[0,-9.81,0]),

=== modified file 'scripts/test/clump.py'
--- scripts/test/clump.py	2010-09-27 17:47:59 +0000
+++ scripts/test/clump.py	2010-10-16 18:31:17 +0000
@@ -7,7 +7,7 @@
 	InteractionLoop(
 		[Ig2_Sphere_Sphere_ScGeom(),Ig2_Box_Sphere_ScGeom()],
 		[Ip2_FrictMat_FrictMat_FrictPhys()],
-		[Law2_ScGeom_FrictPhys_Basic()]
+		[Law2_ScGeom_FrictPhys_CundallStrack()]
 	),
 	GravityEngine(gravity=[0,0,-9.81]),
 	NewtonIntegrator(damping=.2,exactAsphericalRot=True)

=== modified file 'scripts/test/collider-stride.py'
--- scripts/test/collider-stride.py	2010-09-27 17:47:59 +0000
+++ scripts/test/collider-stride.py	2010-10-16 18:31:17 +0000
@@ -15,7 +15,7 @@
 	InteractionLoop(
 		[Ig2_Facet_Sphere_Dem3DofGeom(),Ig2_Sphere_Sphere_Dem3DofGeom()],
 		[Ip2_FrictMat_FrictMat_FrictPhys()],
-		[Law2_Dem3DofGeom_FrictPhys_Basic()],
+		[Law2_Dem3DofGeom_FrictPhys_CundallStrack()],
 	),
 	GravityEngine(gravity=[0,0,-100]),
 	NewtonIntegrator(damping=0)

=== modified file 'scripts/test/collider-sweep-simple.py'
--- scripts/test/collider-sweep-simple.py	2010-09-27 17:47:59 +0000
+++ scripts/test/collider-sweep-simple.py	2010-10-16 18:31:17 +0000
@@ -7,7 +7,7 @@
 	InteractionLoop(
 		[Ig2_Sphere_Sphere_Dem3DofGeom(),Ig2_Facet_Sphere_Dem3DofGeom()],
 		[Ip2_FrictMat_FrictMat_FrictPhys()],
-		[Law2_Dem3DofGeom_FrictPhys_Basic()],
+		[Law2_Dem3DofGeom_FrictPhys_CundallStrack()],
 	),
 	GravityEngine(gravity=[0,0,-1e4]),
 	NewtonIntegrator(damping=.1)

=== modified file 'scripts/test/dispatcher-torture.py'
--- scripts/test/dispatcher-torture.py	2010-09-30 18:00:41 +0000
+++ scripts/test/dispatcher-torture.py	2010-10-16 18:31:17 +0000
@@ -19,8 +19,8 @@
 	Dispatch('IPhys',('Material','Material')),
 	Dispatch('Bound',('Shape','Bound')),
 	Dispatch('GlBound',('Bound',)),
-	Dispatch('GlInteractionGeometry',('IGeom',)),
-	Dispatch('GlInteractionPhysics',('IPhys',)),
+	Dispatch('GlIGeom',('IGeom',)),
+	Dispatch('GlIPhys',('IPhys',)),
 	Dispatch('GlShape',('Shape',)),
 	#Dispatch('GlState',('State',)) # broken for now
 ]

=== modified file 'scripts/test/facet-sphere.py'
--- scripts/test/facet-sphere.py	2010-09-27 17:47:59 +0000
+++ scripts/test/facet-sphere.py	2010-10-16 18:31:17 +0000
@@ -9,7 +9,7 @@
 	InteractionLoop(
 		[Ig2_Facet_Sphere_Dem3DofGeom()],
 		[Ip2_FrictMat_FrictMat_FrictPhys()],
-		[Law2_Dem3DofGeom_FrictPhys_Basic()],
+		[Law2_Dem3DofGeom_FrictPhys_CundallStrack()],
 	),
 	GravityEngine(gravity=[0,0,-10]),
 	NewtonIntegrator(damping=0.01),

=== modified file 'scripts/test/flat-collider.py'
--- scripts/test/flat-collider.py	2010-09-27 17:47:59 +0000
+++ scripts/test/flat-collider.py	2010-10-16 18:31:17 +0000
@@ -10,7 +10,7 @@
 	InteractionLoop(
 		[Ig2_Sphere_Sphere_Dem3DofGeom()],
 		[Ip2_FrictMat_FrictMat_FrictPhys()],
-		[Law2_Dem3DofGeom_FrictPhys_Basic()],
+		[Law2_Dem3DofGeom_FrictPhys_CundallStrack()],
 	),
 	GravityEngine(gravity=[0,0,-10]),
 	NewtonIntegrator(damping=0.4),

=== modified file 'scripts/test/insertion-sort-collider.py'
--- scripts/test/insertion-sort-collider.py	2010-09-27 17:47:59 +0000
+++ scripts/test/insertion-sort-collider.py	2010-10-16 18:31:17 +0000
@@ -3,7 +3,7 @@
 o.engines=[
 	ForceResetter(),
 	InsertionSortCollider([Bo1_Sphere_Aabb(),Bo1_Box_Aabb(),Bo1_Facet_Aabb()]),
-	InteractionLoop([Ig2_Facet_Sphere_Dem3DofGeom()],[Ip2_FrictMat_FrictMat_FrictPhys()],[Law2_Dem3DofGeom_FrictPhys_Basic()],),
+	InteractionLoop([Ig2_Facet_Sphere_Dem3DofGeom()],[Ip2_FrictMat_FrictMat_FrictPhys()],[Law2_Dem3DofGeom_FrictPhys_CundallStrack()],),
 	GravityEngine(gravity=[0,0,-10]),
 	NewtonIntegrator(damping=0.01),
 ]

=== modified file 'scripts/test/interpolating-force.py'
--- scripts/test/interpolating-force.py	2010-09-27 17:47:59 +0000
+++ scripts/test/interpolating-force.py	2010-10-16 18:31:17 +0000
@@ -20,7 +20,7 @@
 	InteractionLoop(
 		[Ig2_Sphere_Sphere_ScGeom()],
 		[Ip2_FrictMat_FrictMat_FrictPhys()],
-		[Law2_ScGeom_FrictPhys_Basic()]
+		[Law2_ScGeom_FrictPhys_CundallStrack()]
 	),
 	# subscribedBodies: what bodies is force applied to
 	# direction: direction of the force (normalized automatically), constant

=== modified file 'scripts/test/law-test.py'
--- scripts/test/law-test.py	2010-10-14 17:21:34 +0000
+++ scripts/test/law-test.py	2010-10-16 18:31:17 +0000
@@ -29,25 +29,32 @@
 
 O.engines=[
 	ForceResetter(),
-	PyRunner(iterPeriod=1,command='import time; time.sleep(.01)'),
+	#PyRunner(iterPeriod=1,command='import time; time.sleep(.005)'),
 	InsertionSortCollider([Bo1_Sphere_Aabb()]),
 	InteractionLoop(
-		[Ig2_Sphere_Sphere_ScGeom()],	[Ip2_FrictMat_FrictMat_FrictPhys()], [Law2_ScGeom_FrictPhys_Basic()]
-		# [Ig2_Sphere_Sphere_L3Geom_Inc()],[Ip2_FrictMat_FrictMat_FrictPhys()],[Law2_L3Geom_FrictPhys_Linear()] # use this line for L3Geom
+		#[Ig2_Sphere_Sphere_ScGeom()],	[Ip2_FrictMat_FrictMat_FrictPhys()], [Law2_ScGeom_FrictPhys_CundallStrack()]
+		[Ig2_Sphere_Sphere_L3Geom_Inc(approxMask=63)],[Ip2_FrictMat_FrictMat_FrictPhys()],[Law2_L3Geom_FrictPhys_ElPerfPl(noBreak=True,noSlip=False)] # use this line for L3Geom
 	),
+	#LawTester(ids=[0,1],rotPath=[(.2,0,0),(-.2,0,0),(0,0,0),(0,.2,0),(0,0,0),(0,0,.2),(0,0,0),
 	LawTester(ids=[0,1],path=[
 		(-1e-5,0,0),(-.1,0,0),(-.1,.1,0),(-1e-5,.1,0), # towards, shear, back to intial normal distance
 		(-.02,.1,.1),(-.02,-.1,.1),(-.02,-.1,-.1),(-.02,.1,-.1),(-.02,.1,.1), # go in square in the shear plane without changing normal deformation
 		(-1e-4,0,0) # back to the origin, but keep some overlap to not delete the interaction
-		],pathSteps=[50],doneHook='tester.dead=True; O.pause()',label='tester',rotWeight=.2,idWeight=.2),
+		],pathSteps=[100],doneHook='tester.dead=True; O.pause()',label='tester',rotWeight=.2,idWeight=.2),
 	PyRunner(iterPeriod=1,command='addPlotData()'),
 	NewtonIntegrator()
 ]
 
 def addPlotData():
 	i=O.interactions[0,1]
-	plot.addData(un=tester.ptOurs[0],us1=tester.ptOurs[1],us2=tester.ptOurs[2],ung=tester.ptGeom[0],us1g=tester.ptGeom[1],us2g=tester.ptGeom[2],i=O.iter,Fs=i.phys.shearForce.norm(),Fn=i.phys.normalForce.norm())
-plot.plots={'us1':('us2',),'Fn':('Fs',),'i':('un','us1','us2'),' i':('Fs','Fn'),'  i':('ung','us1g','us2g')}  #'ung','us1g','us2g'
+	plot.addData(
+		un=tester.ptOurs[0],us1=tester.ptOurs[1],us2=tester.ptOurs[2],
+		ung=tester.ptGeom[0],us1g=tester.ptGeom[1],us2g=tester.ptGeom[2],
+		phiX=tester.rotOurs[0],phiY=tester.rotOurs[1],phiZ=tester.rotOurs[2],
+		phiXg=tester.rotGeom[0],phiYg=tester.rotGeom[1],phiZg=tester.rotGeom[2],
+		i=O.iter,Fs=i.phys.shearForce.norm(),Fn=i.phys.normalForce.norm()
+	)
+plot.plots={'us1':('us2',),'Fn':('Fs',),'i':('un','us1','us2'),' i':('Fs','Fn'),'  i':('ung','us1g','us2g'),'i  ':('phiX','phiXg','phiY','phiYg','phiZ','phiZg')}  #'ung','us1g','us2g'
 plot.plot(subPlots=True)
 
 try:

=== modified file 'scripts/test/peri3d.py'
--- scripts/test/peri3d.py	2010-09-27 17:47:59 +0000
+++ scripts/test/peri3d.py	2010-10-16 18:31:17 +0000
@@ -11,7 +11,7 @@
 	InsertionSortCollider([Bo1_Sphere_Aabb(aabbEnlargeFactor=1.5,label='bo1s')]),
 	InteractionLoop(
 		[Ig2_Sphere_Sphere_Dem3DofGeom(distFactor=1.5,label='ig2ss')],
-		#[Ip2_FrictMat_FrictMat_FrictPhys()],[Law2_Dem3DofGeom_FrictPhys_Basic()]
+		#[Ip2_FrictMat_FrictMat_FrictPhys()],[Law2_Dem3DofGeom_FrictPhys_CundallStrack()]
 		[Ip2_CpmMat_CpmMat_CpmPhys()],[Law2_Dem3DofGeom_CpmPhys_Cpm()]
 
 	),

=== modified file 'scripts/test/periodic-compress.py'
--- scripts/test/periodic-compress.py	2010-09-27 17:47:59 +0000
+++ scripts/test/periodic-compress.py	2010-10-16 18:31:17 +0000
@@ -15,7 +15,7 @@
 	InteractionLoop(
 		[Ig2_Sphere_Sphere_Dem3DofGeom()],
 		[Ip2_FrictMat_FrictMat_FrictPhys()],
-		[Law2_Dem3DofGeom_FrictPhys_Basic()],
+		[Law2_Dem3DofGeom_FrictPhys_CundallStrack()],
 	),
 	PeriIsoCompressor(charLen=.5,stresses=[-50e9,-1e8],doneHook="print 'FINISHED'; O.pause() ",keepProportions=True),
 	NewtonIntegrator(damping=.4,homotheticCellResize=1)

=== modified file 'scripts/test/periodic-grow.py'
--- scripts/test/periodic-grow.py	2010-09-27 17:47:59 +0000
+++ scripts/test/periodic-grow.py	2010-10-16 18:31:17 +0000
@@ -9,7 +9,7 @@
 	InteractionLoop(
 		[Ig2_Sphere_Sphere_Dem3DofGeom()],
 		[Ip2_FrictMat_FrictMat_FrictPhys()],
-		[Law2_Dem3DofGeom_FrictPhys_Basic()],
+		[Law2_Dem3DofGeom_FrictPhys_CundallStrack()],
 	),
 	NewtonIntegrator(damping=.6,homotheticCellResize=1)
 ]

=== modified file 'scripts/test/periodic-shear.py'
--- scripts/test/periodic-shear.py	2010-09-27 17:47:59 +0000
+++ scripts/test/periodic-shear.py	2010-10-16 18:31:17 +0000
@@ -10,7 +10,7 @@
 	InteractionLoop(
 		[Ig2_Sphere_Sphere_Dem3DofGeom(),Ig2_Facet_Sphere_Dem3DofGeom()],
 		[Ip2_FrictMat_FrictMat_FrictPhys()],
-		[Law2_Dem3DofGeom_FrictPhys_Basic()]
+		[Law2_Dem3DofGeom_FrictPhys_CundallStrack()]
 	),
 	GravityEngine(gravity=(0,0,-10)),
 	NewtonIntegrator(),

=== modified file 'scripts/test/periodic-simple-shear.py'
--- scripts/test/periodic-simple-shear.py	2010-09-27 17:47:59 +0000
+++ scripts/test/periodic-simple-shear.py	2010-10-16 18:31:17 +0000
@@ -19,7 +19,7 @@
 	InteractionLoop(
 		[Ig2_Sphere_Sphere_Dem3DofGeom()],
 		[Ip2_FrictMat_FrictMat_FrictPhys()],
-		[Law2_Dem3DofGeom_FrictPhys_Basic()]
+		[Law2_Dem3DofGeom_FrictPhys_CundallStrack()]
 	),
 	PeriTriaxController(dynCell=True,mass=0.2,maxUnbalanced=0.01,relStressTol=0.02,goal=[-1e4,-1e4,0],stressMask=3,globUpdate=5,maxStrainRate=[1.,1.,1.],doneHook='triaxDone()',label='triax'),
 	NewtonIntegrator(damping=.2),

=== modified file 'scripts/test/periodic-simple.py'
--- scripts/test/periodic-simple.py	2010-09-27 17:47:59 +0000
+++ scripts/test/periodic-simple.py	2010-10-16 18:31:17 +0000
@@ -12,7 +12,7 @@
 	InteractionLoop(
 		[Ig2_Sphere_Sphere_Dem3DofGeom()],
 		[Ip2_FrictMat_FrictMat_FrictPhys()],
-		[Law2_Dem3DofGeom_FrictPhys_Basic()],
+		[Law2_Dem3DofGeom_FrictPhys_CundallStrack()],
 	),
 	GravityEngine(gravity=[0,0,-10]),
 	TranslationEngine(translationAxis=(1,0,0),velocity=10,subscribedBodies=[0]),

=== modified file 'scripts/test/periodic-triax-velgrad.py'
--- scripts/test/periodic-triax-velgrad.py	2010-09-27 17:47:59 +0000
+++ scripts/test/periodic-triax-velgrad.py	2010-10-16 18:31:17 +0000
@@ -21,7 +21,7 @@
 	InteractionLoop(
 		[Ig2_Sphere_Sphere_Dem3DofGeom()],
 		[Ip2_FrictMat_FrictMat_FrictPhys()],
-		[Law2_Dem3DofGeom_FrictPhys_Basic()]
+		[Law2_Dem3DofGeom_FrictPhys_CundallStrack()]
 	),
 	#PeriTriaxController(goal=[-1e3,-1e3,-1e3],stressMask=7,globUpdate=5,maxStrainRate=[5.,5.,5.],label='triax'),
 	NewtonIntegrator(damping=.6, homotheticCellResize=0),

=== modified file 'scripts/test/periodic-triax.py'
--- scripts/test/periodic-triax.py	2010-09-27 17:47:59 +0000
+++ scripts/test/periodic-triax.py	2010-10-16 18:31:17 +0000
@@ -19,7 +19,7 @@
 	InteractionLoop(
 		[Ig2_Sphere_Sphere_Dem3DofGeom()],
 		[Ip2_FrictMat_FrictMat_FrictPhys()],
-		[Law2_Dem3DofGeom_FrictPhys_Basic()]
+		[Law2_Dem3DofGeom_FrictPhys_CundallStrack()]
 	),
 	#PeriTriaxController(maxUnbalanced=0.01,relStressTol=0.02,goal=[-1e4,-1e4,0],stressMask=3,globUpdate=5,maxStrainRate=[1.,1.,1.],doneHook='triaxDone()',label='triax'),
 	#using cell inertia

=== modified file 'scripts/test/remove-body.py'
--- scripts/test/remove-body.py	2010-09-27 17:47:59 +0000
+++ scripts/test/remove-body.py	2010-10-16 18:31:17 +0000
@@ -12,7 +12,7 @@
 	InteractionLoop(
 		[Ig2_Facet_Sphere_Dem3DofGeom()],
 		[Ip2_FrictMat_FrictMat_FrictPhys()],
-		[Law2_Dem3DofGeom_FrictPhys_Basic()],
+		[Law2_Dem3DofGeom_FrictPhys_CundallStrack()],
 	),
 	GravityEngine(gravity=[0,0,-10]),
 	NewtonIntegrator(damping=0.01),

=== modified file 'scripts/test/triax-basic.py'
--- scripts/test/triax-basic.py	2010-09-27 17:47:59 +0000
+++ scripts/test/triax-basic.py	2010-10-16 18:31:17 +0000
@@ -46,7 +46,7 @@
 	InteractionLoop(
 		[Ig2_Sphere_Sphere_ScGeom(),Ig2_Box_Sphere_ScGeom()],
 		[Ip2_FrictMat_FrictMat_FrictPhys()],
-		[Law2_ScGeom_FrictPhys_Basic()]
+		[Law2_ScGeom_FrictPhys_CundallStrack()]
 	),
 	GlobalStiffnessTimeStepper(),
 	triax,

=== modified file 'scripts/test/wall.py'
--- scripts/test/wall.py	2010-09-27 17:47:59 +0000
+++ scripts/test/wall.py	2010-10-16 18:31:17 +0000
@@ -24,7 +24,7 @@
 	InteractionLoop(
 		[Ig2_Sphere_Sphere_Dem3DofGeom(),Ig2_Facet_Sphere_Dem3DofGeom(),Ig2_Wall_Sphere_Dem3DofGeom()],
 		[Ip2_FrictMat_FrictMat_FrictPhys()],
-		[Law2_Dem3DofGeom_FrictPhys_Basic()],
+		[Law2_Dem3DofGeom_FrictPhys_CundallStrack()],
 	),
 	GravityEngine(gravity=[1e2,1e2,1e2]),
 	NewtonIntegrator(damping=0.01),