← Back to team overview

yade-dev team mailing list archive

[svn] r1675 - in trunk: core extra/usct gui/py pkg/common/Engine/MetaEngine pkg/common/Engine/StandAloneEngine pkg/dem/Engine/DeusExMachina

 

Author: eudoxos
Date: 2009-02-21 14:51:28 +0100 (Sat, 21 Feb 2009)
New Revision: 1675

Added:
   trunk/core/BexContainer.hpp
Modified:
   trunk/core/MetaBody.hpp
   trunk/core/PhysicalActionContainer.hpp
   trunk/extra/usct/UniaxialStrainControlledTest.cpp
   trunk/gui/py/yadeControl.cpp
   trunk/pkg/common/Engine/MetaEngine/ConstitutiveLaw.hpp
   trunk/pkg/common/Engine/StandAloneEngine/PhysicalActionContainerInitializer.cpp
   trunk/pkg/common/Engine/StandAloneEngine/PhysicalActionContainerReseter.cpp
   trunk/pkg/dem/Engine/DeusExMachina/NewtonsDampedLaw.cpp
Log:
1. Add new non-generic Bex container. For non-optimized build, it increased the speed by about 11% (9:35 vs. 8:49) as compared to PhysicalActionVectorVector.

This breaks simulations that don't use it as it is enabled by default (once I test the build with PhysicalActionContainer disabled, it will be again disabled by default) and depends on whether BEX_CONTAINER is #defined in core/PhysicalActionContainer.hpp.

Constitutive laws using dispatcher and ConstitutiveLaw::applyForceAtContactPoint need no further changes. No changes for python scripts necessary either.

Please migrate other code soon.



Added: trunk/core/BexContainer.hpp
===================================================================
--- trunk/core/BexContainer.hpp	2009-02-20 22:56:45 UTC (rev 1674)
+++ trunk/core/BexContainer.hpp	2009-02-21 13:51:28 UTC (rev 1675)
@@ -0,0 +1,46 @@
+// 2009 © Václav Šmilauer <eudoxos@xxxxxxxx>
+#pragma once
+
+#include<string.h>
+#include<vector>
+#include<Wm3Vector3.h>
+// for body_id_t
+#include<yade/core/Interaction.hpp>
+
+/* Container for Body External Variables (bex), typically forces and torques from interactions.
+ * Values should be reset at every iteration by BexResetter.
+ * If you want to add your own bex, there are 4 steps:
+ *
+ * 	1. Create storage vector
+ * 	2. Create accessor function
+ * 	3. Update the resize function
+ * 	4. Update the reset function
+ *
+ */
+class BexContainer {
+	private:
+		std::vector<Vector3r> _force;
+		std::vector<Vector3r> _torque;
+		size_t size;
+	public:
+		BexContainer(): size(0){}
+		inline void ensureSize(body_id_t id){ if(size<=(size_t)id) resize(min((size_t)1.5*(id+100),(size_t)(id+2000)));}
+		//! Get writable reference to force acting on body # id
+		inline Vector3r& force(body_id_t id){ ensureSize(id); return _force[id]; }
+		//! Get writable reference to torque acting on body # id
+		inline Vector3r& torque(body_id_t id){ ensureSize(id); return _torque[id]; }
+		//! Set all bex's to zero
+		void reset(){
+			memset(_force[0], 0,sizeof(Vector3r)*size);
+			memset(_torque[0],0,sizeof(Vector3r)*size);
+		}
+		/*! Resize the container; this happens automatically,
+		 * but you may want to set the size beforehand to avoid resizes as the simulation grows.
+		 */
+		void resize(size_t newSize){
+			_force.resize(newSize);
+			_torque.resize(newSize);
+			size=newSize;
+			std::cerr<<"[DEBUG] BexContainer: Resized to "<<size<<std::endl;
+		}
+};

Modified: trunk/core/MetaBody.hpp
===================================================================
--- trunk/core/MetaBody.hpp	2009-02-20 22:56:45 UTC (rev 1674)
+++ trunk/core/MetaBody.hpp	2009-02-21 13:51:28 UTC (rev 1675)
@@ -14,6 +14,7 @@
 #include"BodyContainer.hpp"
 #include"Engine.hpp"
 #include"DisplayParameters.hpp"
+#include"PhysicalActionContainer.hpp"
 //#include"groupRelationData.hpp"
 
 class MetaBody : public Body
@@ -25,6 +26,9 @@
 		__attribute__((__deprecated__)) shared_ptr<InteractionContainer>	persistentInteractions; // disappear, reappear according to physical (or any other non-spatial) criterion
 		shared_ptr<InteractionContainer>	transientInteractions;	// disappear, reappear according to spatial criterion
 		shared_ptr<PhysicalActionContainer>	physicalActions;
+		#ifdef BEX_CONTAINER
+			BexContainer bex;
+		#endif
 		vector<shared_ptr<Serializable> > miscParams; // will set static parameters during deserialization (primarily for GLDraw functors which otherwise have no attribute access)
 		//! tags like mp3 tags: author, date, version, description etc.
 		list<string> tags;

Modified: trunk/core/PhysicalActionContainer.hpp
===================================================================
--- trunk/core/PhysicalActionContainer.hpp	2009-02-20 22:56:45 UTC (rev 1674)
+++ trunk/core/PhysicalActionContainer.hpp	2009-02-21 13:51:28 UTC (rev 1675)
@@ -14,6 +14,13 @@
 #include<yade/core/PhysicalAction.hpp>
 #include<iostream>
 
+// experimental
+#define BEX_CONTAINER
+
+#ifdef BEX_CONTAINER
+	#include<yade/core/BexContainer.hpp>
+#endif
+
 using namespace boost;
 using namespace std;
 

Modified: trunk/extra/usct/UniaxialStrainControlledTest.cpp
===================================================================
--- trunk/extra/usct/UniaxialStrainControlledTest.cpp	2009-02-20 22:56:45 UTC (rev 1674)
+++ trunk/extra/usct/UniaxialStrainControlledTest.cpp	2009-02-21 13:51:28 UTC (rev 1675)
@@ -128,8 +128,13 @@
 
 void UniaxialStrainer::computeAxialForce(MetaBody* rootBody){
 	sumPosForces=sumNegForces=0;
-	FOREACH(body_id_t id, negIds) sumNegForces+=Shop::Bex::force(id)[axis];
-	FOREACH(body_id_t id, posIds) sumPosForces-=Shop::Bex::force(id)[axis];
+	#ifdef BEX_CONTAINER
+		FOREACH(body_id_t id, negIds) sumNegForces+=rootBody->bex.force(id)[axis];
+		FOREACH(body_id_t id, posIds) sumNegForces-=rootBody->bex.force(id)[axis];
+	#else
+		FOREACH(body_id_t id, negIds) sumNegForces+=Shop::Bex::force(id)[axis];
+		FOREACH(body_id_t id, posIds) sumPosForces-=Shop::Bex::force(id)[axis];
+	#endif
 }
 
 /***************************************** USCTGen **************************/

Modified: trunk/gui/py/yadeControl.cpp
===================================================================
--- trunk/gui/py/yadeControl.cpp	2009-02-20 22:56:45 UTC (rev 1674)
+++ trunk/gui/py/yadeControl.cpp	2009-02-21 13:51:28 UTC (rev 1675)
@@ -383,9 +383,16 @@
 	python::tuple force_get(long id){ Shop::Bex::initCache(); Vector3r f=Shop::Bex::force(id); return python::make_tuple(f[0],f[1],f[2]);}
 	python::tuple momentum_get(long id){ Shop::Bex::initCache(); Vector3r m=Shop::Bex::momentum(id); return python::make_tuple(m[0],m[1],m[2]);}
 };
+#ifdef BEX_CONTAINER
+class pyBexContainer{
+	public:
+		pyBexContainer(){}
+		python::tuple force_get(long id){ Vector3r& f=Omega::instance().getRootBody()->bex.force(id); return python::make_tuple(f[0],f[1],f[2]); }
+		python::tuple torque_get(long id){ Vector3r& m=Omega::instance().getRootBody()->bex.torque(id); return python::make_tuple(m[0],m[1],m[2]);}
+};
+#endif
 
 
-
 class pyOmega{
 	private:
 		// can be safely removed now, since pyOmega makes an empty rootBody in the constructor, if there is none
@@ -516,9 +523,14 @@
 	
 	pyBodyContainer bodies_get(void){assertRootBody(); return pyBodyContainer(OMEGA.getRootBody()->bodies); }
 	pyInteractionContainer interactions_get(void){assertRootBody(); return pyInteractionContainer(OMEGA.getRootBody()->transientInteractions); }
+	
+	#ifdef BEX_CONTAINER
+		pyBexContainer actions_get(void){return pyBexContainer();}
+	#else
+		pyPhysicalActionContainer actions_get(void){return pyPhysicalActionContainer(OMEGA.getRootBody()->physicalActions); }
+	#endif
+	
 
-	pyPhysicalActionContainer actions_get(void){return pyPhysicalActionContainer(OMEGA.getRootBody()->physicalActions); }
-
 	boost::python::list listChildClasses(const string& base){
 		boost::python::list ret;
 		for(map<string,DynlibDescriptor>::const_iterator di=Omega::instance().getDynlibsDescriptor().begin();di!=Omega::instance().getDynlibsDescriptor().end();++di) if (Omega::instance().isInheritingFrom((*di).first,base)) ret.append(di->first);
@@ -633,8 +645,13 @@
 		.def("__getitem__",&pyPhysicalActionContainer::pyGetitem)
 		.def("f",&pyPhysicalActionContainer::force_get)
 		.def("m",&pyPhysicalActionContainer::momentum_get);
-	
 
+	#ifdef BEX_CONTAINER
+	boost::python::class_<pyBexContainer>("BexContainer",python::init<pyBexContainer&>())
+		.def("f",&pyBexContainer::force_get)
+		.def("m",&pyBexContainer::torque_get);
+	#endif
+
 	BASIC_PY_PROXY_WRAPPER(pyStandAloneEngine,"StandAloneEngine");
 	BASIC_PY_PROXY_WRAPPER(pyMetaEngine,"MetaEngine")
 		.add_property("functors",&pyMetaEngine::functors_get,&pyMetaEngine::functors_set)

Modified: trunk/pkg/common/Engine/MetaEngine/ConstitutiveLaw.hpp
===================================================================
--- trunk/pkg/common/Engine/MetaEngine/ConstitutiveLaw.hpp	2009-02-20 22:56:45 UTC (rev 1674)
+++ trunk/pkg/common/Engine/MetaEngine/ConstitutiveLaw.hpp	2009-02-21 13:51:28 UTC (rev 1675)
@@ -26,9 +26,15 @@
 	Vector3r& bodyTorque(const body_id_t id, MetaBody* rb) const { return static_pointer_cast<Momentum>(rb->physicalActions->find(id,torqueIdx))->momentum;}
 	/*! Convenience function to apply force and torque from one force at contact point. Not sure if this is the right place for it. */
 	void applyForceAtContactPoint(const Vector3r& force, const Vector3r& contactPoint, const body_id_t id1, const Vector3r& pos1, const body_id_t id2, const Vector3r& pos2, MetaBody* rb){
-		bodyForce(id1,rb)+=force; bodyForce(id2,rb)-=force;
-		bodyTorque(id1,rb)+=(contactPoint-pos1).Cross(force);
-		bodyTorque(id2,rb)-=(contactPoint-pos2).Cross(force);
+		#ifdef BEX_CONTAINER
+			rb->bex.force(id1)+=force; rb->bex.force(id2)-=force;
+			rb->bex.torque(id1)+=(contactPoint-pos1).Cross(force);
+			rb->bex.torque(id2)-=(contactPoint-pos2).Cross(force);
+		#else
+			bodyForce(id1,rb)+=force; bodyForce(id2,rb)-=force;
+			bodyTorque(id1,rb)+=(contactPoint-pos1).Cross(force);
+			bodyTorque(id2,rb)-=(contactPoint-pos2).Cross(force);
+		#endif
 	}
 };
 REGISTER_SERIALIZABLE(ConstitutiveLaw);

Modified: trunk/pkg/common/Engine/StandAloneEngine/PhysicalActionContainerInitializer.cpp
===================================================================
--- trunk/pkg/common/Engine/StandAloneEngine/PhysicalActionContainerInitializer.cpp	2009-02-20 22:56:45 UTC (rev 1674)
+++ trunk/pkg/common/Engine/StandAloneEngine/PhysicalActionContainerInitializer.cpp	2009-02-21 13:51:28 UTC (rev 1675)
@@ -31,6 +31,9 @@
 
 void PhysicalActionContainerInitializer::action(MetaBody* ncb)
 {
+	#ifdef BEX_CONTAINER
+		return;
+	#endif
 	list<string> allNames;
 	// copy physical action names that were passed by the user directly
 	allNames.insert(allNames.end(),physicalActionNames.begin(),physicalActionNames.end());

Modified: trunk/pkg/common/Engine/StandAloneEngine/PhysicalActionContainerReseter.cpp
===================================================================
--- trunk/pkg/common/Engine/StandAloneEngine/PhysicalActionContainerReseter.cpp	2009-02-20 22:56:45 UTC (rev 1674)
+++ trunk/pkg/common/Engine/StandAloneEngine/PhysicalActionContainerReseter.cpp	2009-02-21 13:51:28 UTC (rev 1675)
@@ -20,7 +20,11 @@
 
 void PhysicalActionContainerReseter::action(MetaBody* ncb)
 {
-	ncb->physicalActions->reset();
+	#ifdef BEX_CONTAINER
+		ncb->bex.reset();
+	#else
+		ncb->physicalActions->reset();
+	#endif
 }
 
 

Modified: trunk/pkg/dem/Engine/DeusExMachina/NewtonsDampedLaw.cpp
===================================================================
--- trunk/pkg/dem/Engine/DeusExMachina/NewtonsDampedLaw.cpp	2009-02-20 22:56:45 UTC (rev 1674)
+++ trunk/pkg/dem/Engine/DeusExMachina/NewtonsDampedLaw.cpp	2009-02-21 13:51:28 UTC (rev 1675)
@@ -36,8 +36,13 @@
 		
 		RigidBodyParameters* rb = YADE_CAST<RigidBodyParameters*>(b->physicalParameters.get());
 		unsigned int id = b->getId();
-		Vector3r& m = ( static_cast<Momentum*> ( ncb->physicalActions->find ( id, momentumClassIndex ).get() ) )->momentum;
-		Vector3r& f = ( static_cast<Force*> ( ncb->physicalActions->find ( id, forceClassIndex ).get() ) )->force;
+		#ifdef BEX_CONTAINER
+			Vector3r& m = ncb->bex.torque(id);
+			Vector3r& f = ncb->bex.force(id);
+		#else
+			Vector3r& m = ( static_cast<Momentum*> ( ncb->physicalActions->find ( id, momentumClassIndex ).get() ) )->momentum;
+			Vector3r& f = ( static_cast<Force*> ( ncb->physicalActions->find ( id, forceClassIndex ).get() ) )->force;
+		#endif
 
 		Real dt = Omega::instance().getTimeStep();
 




Follow ups