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 <[email protected]>
+#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();
 


_______________________________________________
Mailing list: https://launchpad.net/~yade-dev
Post to     : [email protected]
Unsubscribe : https://launchpad.net/~yade-dev
More help   : https://help.launchpad.net/ListHelp

Reply via email to