yade-dev team mailing list archive
-
yade-dev team
-
Mailing list archive
-
Message #00994
[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