Author: eudoxos
Date: 2009-02-22 21:08:45 +0100 (Sun, 22 Feb 2009)
New Revision: 1680

Modified:
   trunk/SConstruct
   trunk/core/BexContainer.hpp
   trunk/core/Omega.hpp
   trunk/extra/Brefcom.cpp
   trunk/extra/clump/Shop.cpp
   trunk/extra/clump/Shop.hpp
   trunk/extra/usct/UniaxialStrainControlledTest.cpp
   trunk/gui/py/_utils.cpp
   trunk/gui/py/yadeControl.cpp
   trunk/pkg/common/Engine/DeusExMachina/GravityEngines.cpp
   trunk/pkg/common/Engine/MetaEngine/ConstitutiveLaw.hpp
   
trunk/pkg/common/Engine/StandAloneEngine/PhysicalActionContainerInitializer.cpp
   trunk/pkg/dem/Engine/DeusExMachina/NewtonsDampedLaw.cpp
   trunk/pkg/dem/Engine/DeusExMachina/TriaxialStressController.cpp
   trunk/pkg/dem/Engine/DeusExMachina/TriaxialStressController.hpp
   
trunk/pkg/dem/Engine/EngineUnit/Spheres_Viscoelastic_SimpleViscoelasticContactLaw.cpp
   trunk/pkg/dem/Engine/StandAloneEngine/ElasticContactLaw.cpp
Log:
1. Add BexContainer (same interface, but separate implementation) in openMP 
flavor.
2. openmp=0 is the default for scons now (for some time), since openMP 
BexContainer gives about 7% slowdown and thus is not useful before at least 
some engines are parallelized as well.
3. Removed getting references to Force/Torque from BexContainer, since that 
breaks concurrency. Instead, addForce/addTorque must be used. If you need to 
read back with getForce/getTorque, you have to call sync() (expensive!!) 
beforehand, which will compute summary values for all bodies; if you forget, 
exception will be thrown. Note that sync() is invalidated at next write 
operation.
4. Adapted a few constitutive laws and other engines for the changes mentiones 
here.



Modified: trunk/SConstruct
===================================================================
--- trunk/SConstruct    2009-02-22 13:08:47 UTC (rev 1679)
+++ trunk/SConstruct    2009-02-22 20:08:45 UTC (rev 1680)
@@ -102,8 +102,8 @@
 print '@@@ Using profile',profile,'('+optsFile+') @@@'
 
 # defaults for various profiles
-if profile=='default': 
defOptions={'debug':1,'variant':'','optimize':0,'openmp':True}
-elif profile=='opt': 
defOptions={'debug':0,'variant':'-opt','optimize':1,'openmp':True}
+if profile=='default': 
defOptions={'debug':1,'variant':'','optimize':0,'openmp':False}
+elif profile=='opt': 
defOptions={'debug':0,'variant':'-opt','optimize':1,'openmp':False}
 else: defOptions={'debug':0,'optimize':0,'variant':profile,'openmp':True}
 
 
@@ -390,7 +390,7 @@
 ### COMPILER
 if env['debug']: env.Append(CXXFLAGS='-ggdb3',CPPDEFINES=['YADE_DEBUG'])
 else: env.Append(CXXFLAGS='-O2')
-if env['openmp']: env.Append(CXXFLAGS='-fopenmp',LIBS='gomp')
+if env['openmp']: 
env.Append(CXXFLAGS='-fopenmp',LIBS='gomp',CPPDEFINES='YADE_OPENMP')
 if env['optimize']:
        env.Append(CXXFLAGS=Split('-O3 -ffast-math -march=%s'%env['march']),
                
CPPDEFINES=[('YADE_CAST','static_cast'),('YADE_PTR_CAST','static_pointer_cast'),'NDEBUG'])

Modified: trunk/core/BexContainer.hpp
===================================================================
--- trunk/core/BexContainer.hpp 2009-02-22 13:08:47 UTC (rev 1679)
+++ trunk/core/BexContainer.hpp 2009-02-22 20:08:45 UTC (rev 1680)
@@ -7,6 +7,83 @@
 // for body_id_t
 #include<yade/core/Interaction.hpp>
 
+#ifdef YADE_OPENMP
+
+#include<omp.h>
+
+class BexContainer{
+       private:
+               typedef std::vector<Vector3r> vvector;
+               std::vector<vvector> _forceData;
+               std::vector<vvector> _torqueData;
+               vvector _force, _torque;
+               size_t size;
+               int nThreads;
+               bool synced;
+               boost::mutex globalMutex;
+
+               inline void ensureSize(body_id_t id){
+                       assert(nThreads>omp_get_thread_num());
+                       if (size<=(size_t)id) 
resize(min((size_t)1.5*(id+100),(size_t)(id+2000)));
+               }
+
+               inline void ensureSynced(){ if(!synced) throw 
runtime_error("BexContainer not thread-synchronized; call sync() first!"); }
+       public:
+               BexContainer(): size(0), synced(true){
+                       nThreads=omp_get_max_threads();
+                       for(int i=0; i<nThreads; i++){
+                               _forceData.push_back(vvector()); 
_torqueData.push_back(vvector());
+                       }
+               }
+
+               /* To be benchmarked: sum thread data in getForce/getTorque 
upon request for each body individually instead of by the sync() function 
globally */
+               const Vector3r& getForce(body_id_t id)         { 
ensureSize(id); ensureSynced(); return _force[id]; }
+               void  addForce(body_id_t id, const Vector3r& f){ 
ensureSize(id); synced=false;   _forceData[omp_get_thread_num()][id]+=f;}
+               const Vector3r& getTorque(body_id_t id)        { 
ensureSize(id); ensureSynced(); return _torque[id]; }
+               void addTorque(body_id_t id, const Vector3r& f){ 
ensureSize(id); synced=false;   _torqueData[omp_get_thread_num()][id]+=f;}
+
+               /* Sum contributions from all threads, save to the 0th thread 
storage.
+                * Locks globalMutex, since one thread modifies other threads' 
data.
+                * Must be called before get* methods are used. Exception is 
thrown otherwise, since data are not consistent.
+                */
+               inline void sync(){
+                       if(synced) return;
+                       boost::mutex::scoped_lock lock(globalMutex);
+                       // #pragma omp parallel for private(sumF,sumT,thread);
+                       for(size_t id=0; id<size; id++){
+                               Vector3r sumF(Vector3r::ZERO), 
sumT(Vector3r::ZERO);
+                               for(int thread=0; thread<omp_get_max_threads(); 
thread++){ sumF+=_forceData[thread][id]; sumT+=_torqueData[thread][id];}
+                               _force[id]=sumF; _torque[id]=sumT;
+                       }
+                       synced=true;
+               }
+
+               /* Change size of containers (number of bodies).
+                * Locks globalMutex, since on threads modifies other threads' 
data.
+                * Called very rarely (a few times at the beginning of the 
simulation)
+                */
+               void resize(size_t newSize){
+                       boost::mutex::scoped_lock lock(globalMutex);
+                       if(size>=newSize) return; // in case on thread was 
waiting for resize, but it was already satisfied by another one
+                       for(int thread=0; thread<nThreads; thread++){
+                               _forceData [thread].resize(newSize);
+                               _torqueData[thread].resize(newSize);
+                       }
+                       _force.resize(newSize); _torque.resize(newSize);
+                       size=newSize;
+               }
+
+               void reset(){
+                       for(int thread=0; thread<nThreads; thread++){
+                               memset(_forceData [thread][0], 
0,sizeof(Vector3r)*size);
+                               
memset(_torqueData[thread][0],0,sizeof(Vector3r)*size);
+                       }
+                       memset(_force [0], 0,sizeof(Vector3r)*size); 
memset(_torque[0], 0,sizeof(Vector3r)*size);
+                       synced=true;
+               }
+};
+
+#else
 /* 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:
@@ -22,21 +99,22 @@
                std::vector<Vector3r> _force;
                std::vector<Vector3r> _torque;
                size_t size;
+               inline void ensureSize(body_id_t id){ if(size<=(size_t)id) 
resize(min((size_t)1.5*(id+100),(size_t)(id+2000)));}
        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]; }
+               const Vector3r& getForce(body_id_t id){ensureSize(id); return 
_force[id];}
+               void  addForce(body_id_t id,const Vector3r& f){ensureSize(id); 
_force[id]+=f;}
+               const Vector3r& getTorque(body_id_t id){ensureSize(id); return 
_torque[id];}
+               void  addTorque(body_id_t id,const Vector3r& t){ensureSize(id); 
_torque[id]+=t;}
                //! Set all bex's to zero
                void reset(){
                        memset(_force[0], 0,sizeof(Vector3r)*size);
                        memset(_torque[0],0,sizeof(Vector3r)*size);
                }
+               //! No-op for API compatibility with the threaded version
+               void sync(){return;}
                /*! Resize the container; this happens automatically,
-                * but you may want to set the size beforehand to avoid resizes 
as the simulation grows.
-                */
+                * 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);
@@ -44,3 +122,6 @@
                        std::cerr<<"[DEBUG] BexContainer: Resized to 
"<<size<<std::endl;
                }
 };
+
+
+#endif

Modified: trunk/core/Omega.hpp
===================================================================
--- trunk/core/Omega.hpp        2009-02-22 13:08:47 UTC (rev 1679)
+++ trunk/core/Omega.hpp        2009-02-22 20:08:45 UTC (rev 1680)
@@ -167,6 +167,7 @@
                Omega& operator=(const Omega&);
 
        FRIEND_SINGLETON(Omega);
+       friend class pyOmega;
 };
 
 

Modified: trunk/extra/Brefcom.cpp
===================================================================
--- trunk/extra/Brefcom.cpp     2009-02-22 13:08:47 UTC (rev 1679)
+++ trunk/extra/Brefcom.cpp     2009-02-22 20:08:45 UTC (rev 1680)
@@ -12,7 +12,8 @@
 CREATE_LOGGER(BrefcomGlobalCharacteristics);
 
 void BrefcomGlobalCharacteristics::compute(MetaBody* rb, bool useMaxForce){
-       Shop::Bex::initCache();
+       //Shop::Bex::initCache();
+       rb->bex.sync();
 
        // 1. reset volumetric strain (cummulative in the next loop)
        // 2. get maximum force on a body and sum of all forces (for averaging)
@@ -21,7 +22,7 @@
        BrefcomPhysParams* 
bpp(YADE_CAST<BrefcomPhysParams*>(b->physicalParameters.get()));
                bpp->epsVolumetric=0;
                bpp->numContacts=0;
-               currF=Shop::Bex::force(b->id,rb).Length(); 
maxF=max(currF,maxF); sumF+=currF;
+               currF=rb->bex.getForce(b->id).Length(); maxF=max(currF,maxF); 
sumF+=currF;
        }
        Real meanF=sumF/rb->bodies->size(); 
 
@@ -124,10 +125,10 @@
 CREATE_LOGGER(BrefcomLaw);
 
 void BrefcomLaw::applyForce(const Vector3r& force, const body_id_t& id1, const 
body_id_t& id2){
-       Shop::Bex::force(id1,rootBody)+=force;
-       Shop::Bex::force(id2,rootBody)-=force;
-       
Shop::Bex::momentum(id1,rootBody)+=(contGeom->contactPoint-contGeom->pos1).Cross(force);
-       
Shop::Bex::momentum(id2,rootBody)+=(contGeom->contactPoint-contGeom->pos2).Cross(-force);
+       rootBody->bex.addForce(id1,force);
+       rootBody->bex.addForce(id2,-force);
+       
rootBody->bex.addTorque(id1,(contGeom->contactPoint-contGeom->pos1).Cross(force));
+       
rootBody->bex.addTorque(id2,(contGeom->contactPoint-contGeom->pos2).Cross(-force));
 }
 
 CREATE_LOGGER(ef2_Spheres_Brefcom_BrefcomLaw);

Modified: trunk/extra/clump/Shop.cpp
===================================================================
--- trunk/extra/clump/Shop.cpp  2009-02-22 13:08:47 UTC (rev 1679)
+++ trunk/extra/clump/Shop.cpp  2009-02-22 20:08:45 UTC (rev 1680)
@@ -39,7 +39,6 @@
 
 #include<yade/pkg-common/Force.hpp>
 #include<yade/pkg-common/Momentum.hpp>
-#include<yade/pkg-dem/GlobalStiffness.hpp>
 /*class InteractingSphere2AABB;
 class InteractingBox2AABB;
 class MetaInteractingGeometry;
@@ -87,18 +86,16 @@
 
 int Shop::Bex::forceIdx=-1;
 int Shop::Bex::momentumIdx=-1;
-int Shop::Bex::globalStiffnessIdx=-1;
 
 void Shop::Bex::initCache(){
        if(Shop::Bex::forceIdx<0){
                Shop::Bex::forceIdx=shared_ptr<PhysicalAction>(new 
Force())->getClassIndex();
                Shop::Bex::momentumIdx=shared_ptr<PhysicalAction>(new 
Momentum())->getClassIndex();
-               Shop::Bex::globalStiffnessIdx=shared_ptr<PhysicalAction>(new 
GlobalStiffness())->getClassIndex();
        }
 }
 #ifdef BEX_CONTAINER
-       Vector3r& Shop::Bex::force(body_id_t id,MetaBody* rb){ return 
rb->bex.force(id);}
-       Vector3r& Shop::Bex::momentum(body_id_t id,MetaBody* rb){ return 
rb->bex.force(id);}
+       const Vector3r& Shop::Bex::force(body_id_t id,MetaBody* rb){  
rb->bex.sync();  return rb->bex.getForce(id);}
+       const Vector3r& Shop::Bex::momentum(body_id_t id,MetaBody* rb){ 
rb->bex.sync(); return rb->bex.getTorque(id);}
 #else
        #define 
__BEX_ACCESS(retType,shopBexMember,bexClass,bexIdx,bexAttribute) retType& 
Shop::Bex::shopBexMember(body_id_t id,MetaBody* mb){ assert(bexIdx>=0); 
shared_ptr<PhysicalActionContainer> 
pac=(mb?mb:Omega::instance().getRootBody().get())->physicalActions; 
/*if((long)pac->size()<=id) throw invalid_argument("No " #shopBexMember " for 
#"+lexical_cast<string>(id)+" 
(max="+lexical_cast<string>(((long)pac->size()-1))+")");*/ return 
static_pointer_cast<bexClass>(pac->find(id,bexIdx))->bexAttribute; }
        __BEX_ACCESS(Vector3r,force,Force,forceIdx,force);
@@ -110,10 +107,17 @@
  *
  * Shop::Bex::initCache must have been called at some point. */
 void Shop::applyForceAtContactPoint(const Vector3r& force, const Vector3r& 
contPt, body_id_t id1, const Vector3r& pos1, body_id_t id2, const Vector3r& 
pos2, MetaBody* rootBody){
+#ifdef BEX_CONTAINER
+       rootBody->bex.addForce(id1,force);
+       rootBody->bex.addForce(id2,-force);
+       rootBody->bex.addTorque(id1,(contPt-pos1).Cross(force));
+       rootBody->bex.addTorque(id2,-(contPt-pos2).Cross(force));
+#else
        Shop::Bex::force(id1,rootBody)+=force;
        Shop::Bex::force(id2,rootBody)-=force;
        Shop::Bex::momentum(id1,rootBody)+=(contPt-pos1).Cross(force);
        Shop::Bex::momentum(id2,rootBody)-=(contPt-pos2).Cross(force);
+#endif
 }
 
 
@@ -124,7 +128,12 @@
        Real sumF=0,maxF=0,currF;
        FOREACH(const shared_ptr<Body>& b, *rb->bodies){
                if(!b->isDynamic) continue;
-               currF=Shop::Bex::force(b->id,rb).Length(); 
maxF=max(currF,maxF); sumF+=currF;
+               #ifdef BEX_CONTAINER
+                       LOG_FATAL("No implemented with BEX_CONTAINER yet");
+                       abort();
+               #else
+                       currF=Shop::Bex::force(b->id,rb).Length(); 
maxF=max(currF,maxF); sumF+=currF;
+               #endif
        }
        Real meanF=sumF/rb->bodies->size(); 
        // get max force on contacts

Modified: trunk/extra/clump/Shop.hpp
===================================================================
--- trunk/extra/clump/Shop.hpp  2009-02-22 13:08:47 UTC (rev 1679)
+++ trunk/extra/clump/Shop.hpp  2009-02-22 20:08:45 UTC (rev 1680)
@@ -86,12 +86,15 @@
                 */
                class Bex{
                        public:
-                       static int forceIdx,momentumIdx,globalStiffnessIdx;
+                       static int forceIdx,momentumIdx;
                        static void initCache();
-                       static Vector3r& force(body_id_t, MetaBody* mb=NULL);
-                       static Vector3r& momentum(body_id_t, MetaBody* mb=NULL);
-                       static Vector3r& globalStiffness(body_id_t, MetaBody* 
mb=NULL);
-                       static Vector3r& globalRStiffness(body_id_t, MetaBody* 
mb=NULL);
+                       #ifdef BEX_CONTAINER
+                               static const Vector3r& force(body_id_t, 
MetaBody* mb=NULL);
+                               static const Vector3r& momentum(body_id_t, 
MetaBody* mb=NULL);
+                       #else
+                               static Vector3r& force(body_id_t, MetaBody* 
mb=NULL);
+                               static Vector3r& momentum(body_id_t, MetaBody* 
mb=NULL);
+                       #endif
                };
 
                //! Estimate timestep based on P-wave propagation speed

Modified: trunk/extra/usct/UniaxialStrainControlledTest.cpp
===================================================================
--- trunk/extra/usct/UniaxialStrainControlledTest.cpp   2009-02-22 13:08:47 UTC 
(rev 1679)
+++ trunk/extra/usct/UniaxialStrainControlledTest.cpp   2009-02-22 20:08:45 UTC 
(rev 1680)
@@ -129,8 +129,9 @@
 void UniaxialStrainer::computeAxialForce(MetaBody* rootBody){
        sumPosForces=sumNegForces=0;
        #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];
+               rootBody->bex.sync();
+               FOREACH(body_id_t id, negIds) 
sumNegForces+=rootBody->bex.getForce(id)[axis];
+               FOREACH(body_id_t id, posIds) 
sumNegForces-=rootBody->bex.getForce(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];

Modified: trunk/gui/py/_utils.cpp
===================================================================
--- trunk/gui/py/_utils.cpp     2009-02-22 13:08:47 UTC (rev 1679)
+++ trunk/gui/py/_utils.cpp     2009-02-22 20:08:45 UTC (rev 1680)
@@ -187,14 +187,19 @@
  * projected onto axis.
  */
 Real sumBexTorques(int mask, python::tuple _axis, python::tuple _axisPt){
+       shared_ptr<MetaBody> rb=Omega::instance().getRootBody();
        Shop::Bex::initCache();
-       shared_ptr<MetaBody> rb=Omega::instance().getRootBody();
-       Real ret;
+       Real ret=0;
        Vector3r axis=tuple2vec(_axis), axisPt=tuple2vec(_axisPt);
        FOREACH(const shared_ptr<Body> b, *rb->bodies){
                if(!b->maskOk(mask)) continue;
-               const Vector3r& m=Shop::Bex::momentum(b->getId(),rb.get());
-               const Vector3r& f=Shop::Bex::force(b->getId(),rb.get());
+               #ifdef BEX_CONTAINER
+                       const Vector3r& m=rb->bex.getTorque(b->getId());
+                       const Vector3r& f=rb->bex.getForce(b->getId());
+               #else
+                       const Vector3r& 
m=Shop::Bex::momentum(b->getId(),rb.get());
+                       const Vector3r& f=Shop::Bex::force(b->getId(),rb.get());
+               #endif
                Vector3r r=b->physicalParameters->se3.position-axisPt;
                ret+=axis.Dot(m+r.Cross(f));
        }
@@ -213,7 +218,11 @@
        Vector3r direction=tuple2vec(_direction);
        FOREACH(const shared_ptr<Body> b, *rb->bodies){
                if(!b->maskOk(mask)) continue;
-               const Vector3r& f=Shop::Bex::force(b->getId(),rb.get());
+               #ifdef BEX_CONTAINER
+                       const Vector3r& f=rb->bex.getForce(b->getId());
+               #else
+                       const Vector3r& f=Shop::Bex::force(b->getId(),rb.get());
+               #endif
                ret+=direction.Dot(f);
        }
        return ret;

Modified: trunk/gui/py/yadeControl.cpp
===================================================================
--- trunk/gui/py/yadeControl.cpp        2009-02-22 13:08:47 UTC (rev 1679)
+++ trunk/gui/py/yadeControl.cpp        2009-02-22 20:08:45 UTC (rev 1680)
@@ -387,8 +387,8 @@
 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]);}
+               python::tuple force_get(long id){  MetaBody* 
rb=Omega::instance().getRootBody().get(); rb->bex.sync(); Vector3r 
f=rb->bex.getForce(id); return python::make_tuple(f[0],f[1],f[2]); }
+               python::tuple torque_get(long id){ MetaBody* 
rb=Omega::instance().getRootBody().get(); rb->bex.sync(); Vector3r 
m=rb->bex.getTorque(id); return python::make_tuple(m[0],m[1],m[2]);}
 };
 #endif
 
@@ -459,13 +459,13 @@
        void loadTmp(string mark){ load(":memory:"+mark);}
        void tmpToFile(string mark, string filename){
                // FIXME: memSavedSimulations are private, but I don't want to 
recompile all yade now; move it to public and uncomment these few lines at some 
point
-               // if(OMEGA.memSavedSimulations.count(":memory:"+mark)==0) 
throw runtime_error("No memory-saved simulation named "+mark);
+               if(OMEGA.memSavedSimulations.count(":memory:"+mark)==0) throw 
runtime_error("No memory-saved simulation named "+mark);
                iostreams::filtering_ostream out;
                if(boost::algorithm::ends_with(filename,".bz2")) 
out.push(iostreams::bzip2_compressor());
                out.push(iostreams::file_sink(filename));
                if(!out.good()) throw runtime_error("Error while opening file 
`"+filename+"' for writing.");
                LOG_INFO("Saving :memory:"<<mark<<" to "<<filename);
-               //out<<OMEGA.memSavedSimulations[":memory:"+mark];
+               out<<OMEGA.memSavedSimulations[":memory:"+mark];
        }
 
 

Modified: trunk/pkg/common/Engine/DeusExMachina/GravityEngines.cpp
===================================================================
--- trunk/pkg/common/Engine/DeusExMachina/GravityEngines.cpp    2009-02-22 
13:08:47 UTC (rev 1679)
+++ trunk/pkg/common/Engine/DeusExMachina/GravityEngines.cpp    2009-02-22 
20:08:45 UTC (rev 1680)
@@ -25,7 +25,7 @@
                shared_ptr<ParticleParameters> 
p=YADE_PTR_CAST<ParticleParameters>(b->physicalParameters);
                if(p!=0) //not everything derives from ParticleParameters; this 
line was    assert(p); - Janek
 #ifdef BEX_CONTAINER
-                       ncb->bex.force(b->getId())+=gravity*p->mass;
+                       ncb->bex.addForce(b->getId(),gravity*p->mass);
 #else
                        
static_cast<Force*>(ncb->physicalActions->find(b->getId(),cachedForceClassIndex).get())->force+=gravity*p->mass;
 #endif
@@ -39,8 +39,8 @@
                Real 
F=accel*YADE_PTR_CAST<ParticleParameters>(b->physicalParameters)->mass;
                Vector3r 
toCenter=centralPos-b->physicalParameters->se3.position; toCenter.Normalize();
 #ifdef BEX_CONTAINER
-               rootBody->bex.force(b->getId())+=F*toCenter;
-               if(reciprocal) rootBody->bex.force(centralBody)-=F*toCenter;
+               rootBody->bex.addForce(b->getId(),F*toCenter);
+               if(reciprocal) rootBody->bex.addForce(centralBody,-F*toCenter);
 #else
                
static_cast<Force*>(rootBody->physicalActions->find(b->getId(),cachedForceClassIndex).get())->force+=F*toCenter;
                if(reciprocal) 
static_cast<Force*>(rootBody->physicalActions->find(centralBody,cachedForceClassIndex).get())->force-=F*toCenter;
@@ -59,7 +59,7 @@
                Vector3r closestAxisPoint=(x2-x1) * /* t */ 
(-(x1-x0).Dot(x2-x1))/((x2-x1).SquaredLength());
                Vector3r toAxis=closestAxisPoint-x0; toAxis.Normalize();
 #ifdef BEX_CONTAINER
-               rootBody->bex.force(b->getId())+=acceleration*myMass*toAxis;
+               rootBody->bex.addForce(b->getId(),acceleration*myMass*toAxis);
 #else
                
static_pointer_cast<Force>(rootBody->physicalActions->find(b->getId(),cachedForceClassIndex))->force+=acceleration*myMass*toAxis;
                //if(b->getId()==20){ 
TRVAR3(toAxis,acceleration*myMass*toAxis,static_pointer_cast<Force>(rootBody->physicalActions->find(b->getId(),cachedForceClassIndex))->force);
 }

Modified: trunk/pkg/common/Engine/MetaEngine/ConstitutiveLaw.hpp
===================================================================
--- trunk/pkg/common/Engine/MetaEngine/ConstitutiveLaw.hpp      2009-02-22 
13:08:47 UTC (rev 1679)
+++ trunk/pkg/common/Engine/MetaEngine/ConstitutiveLaw.hpp      2009-02-22 
20:08:45 UTC (rev 1680)
@@ -23,8 +23,8 @@
         * is done only if the derived ConstitutiveLaw says 
NEEDS_BEX("Force","Momentum"), for example.
         */
 #ifdef BEX_CONTAINER
-       inline Vector3r& bodyForce(const body_id_t id, MetaBody* rb) const { 
return rb->bex.force(id); }
-       inline Vector3r& bodyTorque(const body_id_t id, MetaBody* rb) const { 
return rb->bex.torque(id);}
+       void addForce (const body_id_t id, const Vector3r& f,MetaBody* 
rb){rb->bex.addForce (id,f);}
+       void addTorque(const body_id_t id, const Vector3r& t,MetaBody* 
rb){rb->bex.addTorque(id,t);}
 #else
        Vector3r& bodyForce(const body_id_t id, MetaBody* rb) const { return 
static_pointer_cast<Force>(rb->physicalActions->find(id,forceIdx))->force; }
        Vector3r& bodyTorque(const body_id_t id, MetaBody* rb) const { return 
static_pointer_cast<Momentum>(rb->physicalActions->find(id,torqueIdx))->momentum;}
@@ -33,9 +33,9 @@
        /*! 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){
                #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);
+                       rb->bex.addForce(id1,force); 
rb->bex.addForce(id2,-force);
+                       rb->bex.addTorque(id1,(contactPoint-pos1).Cross(force));
+                       
rb->bex.addTorque(id2,-(contactPoint-pos2).Cross(force));
                #else
                        bodyForce(id1,rb)+=force; bodyForce(id2,rb)-=force;
                        bodyTorque(id1,rb)+=(contactPoint-pos1).Cross(force);

Modified: 
trunk/pkg/common/Engine/StandAloneEngine/PhysicalActionContainerInitializer.cpp
===================================================================
--- 
trunk/pkg/common/Engine/StandAloneEngine/PhysicalActionContainerInitializer.cpp 
    2009-02-22 13:08:47 UTC (rev 1679)
+++ 
trunk/pkg/common/Engine/StandAloneEngine/PhysicalActionContainerInitializer.cpp 
    2009-02-22 20:08:45 UTC (rev 1680)
@@ -32,6 +32,9 @@
 void PhysicalActionContainerInitializer::action(MetaBody* ncb)
 {
        #ifdef BEX_CONTAINER
+               // this is not necessary, since BexContainer grows upon 
requests.
+               // But it takes about 10 resizes to get to 2000 bodies (only at 
the beginning), so you can save a few milliseconds here
+               ncb->bex.resize(ncb->bodies->size());
                return;
        #endif
        list<string> allNames;

Modified: trunk/pkg/dem/Engine/DeusExMachina/NewtonsDampedLaw.cpp
===================================================================
--- trunk/pkg/dem/Engine/DeusExMachina/NewtonsDampedLaw.cpp     2009-02-22 
13:08:47 UTC (rev 1679)
+++ trunk/pkg/dem/Engine/DeusExMachina/NewtonsDampedLaw.cpp     2009-02-22 
20:08:45 UTC (rev 1680)
@@ -31,17 +31,22 @@
 
 void NewtonsDampedLaw::applyCondition ( MetaBody * ncb )
 {
+       #ifdef BEX_CONTAINER
+               #ifdef YADE_OPENMP
+                       ncb->bex.sync();
+               #endif
+       #endif
        FOREACH(const shared_ptr<Body>& b, *ncb->bodies){
                if (!b->isDynamic) continue;
                
                RigidBodyParameters* rb = 
YADE_CAST<RigidBodyParameters*>(b->physicalParameters.get());
                unsigned int id = b->getId();
                #ifdef BEX_CONTAINER
-                       Vector3r& m = ncb->bex.torque(id);
-                       Vector3r& f = ncb->bex.force(id);
+                       const Vector3r& m=ncb->bex.getTorque(id);
+                       const Vector3r& f=ncb->bex.getForce(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;
+                       const Vector3r& m = ( static_cast<Momentum*> ( 
ncb->physicalActions->find ( id, momentumClassIndex ).get() ) )->momentum;
+                       const Vector3r& f = ( static_cast<Force*> ( 
ncb->physicalActions->find ( id, forceClassIndex ).get() ) )->force;
                #endif
 
                Real dt = Omega::instance().getTimeStep();

Modified: trunk/pkg/dem/Engine/DeusExMachina/TriaxialStressController.cpp
===================================================================
--- trunk/pkg/dem/Engine/DeusExMachina/TriaxialStressController.cpp     
2009-02-22 13:08:47 UTC (rev 1679)
+++ trunk/pkg/dem/Engine/DeusExMachina/TriaxialStressController.cpp     
2009-02-22 20:08:45 UTC (rev 1680)
@@ -198,7 +198,10 @@
 {
        //cerr << "TriaxialStressController::applyCondition" << endl;
        
+       // sync thread storage of BexContainer
+       ncb->bex.sync();
        
+       
        shared_ptr<BodyContainer>& bodies = ncb->bodies;
        
        

Modified: trunk/pkg/dem/Engine/DeusExMachina/TriaxialStressController.hpp
===================================================================
--- trunk/pkg/dem/Engine/DeusExMachina/TriaxialStressController.hpp     
2009-02-22 13:08:47 UTC (rev 1679)
+++ trunk/pkg/dem/Engine/DeusExMachina/TriaxialStressController.hpp     
2009-02-22 20:08:45 UTC (rev 1680)
@@ -33,7 +33,7 @@
                bool firstRun;
                inline const Vector3r getForce(MetaBody* rb, body_id_t id){
                        #ifdef BEX_CONTAINER
-                               return rb->bex.force(id);
+                               return rb->bex.getForce(id); // needs sync, 
which is done at the beginning of applyCondition
                        #else
                                return 
static_cast<Force*>(rb->physicalActions->find(id,ForceClassIndex).get())->force 
                         
                        #endif

Modified: 
trunk/pkg/dem/Engine/EngineUnit/Spheres_Viscoelastic_SimpleViscoelasticContactLaw.cpp
===================================================================
--- 
trunk/pkg/dem/Engine/EngineUnit/Spheres_Viscoelastic_SimpleViscoelasticContactLaw.cpp
       2009-02-22 13:08:47 UTC (rev 1679)
+++ 
trunk/pkg/dem/Engine/EngineUnit/Spheres_Viscoelastic_SimpleViscoelasticContactLaw.cpp
       2009-02-22 20:08:45 UTC (rev 1680)
@@ -67,8 +67,8 @@
        }
 
        Vector3r f                              = phys->normalForce + 
shearForce;
-       bodyForce (id1,rootBody) -= f;
-       bodyForce (id2,rootBody) += f;
-       bodyTorque(id1,rootBody) -= c1x.Cross(f);
-       bodyTorque(id2,rootBody) += c2x.Cross(f);
+       addForce (id1,-f,rootBody);
+       addForce (id2, f,rootBody);
+       addTorque(id1,-c1x.Cross(f),rootBody);
+       addTorque(id2, c2x.Cross(f),rootBody);
 }

Modified: trunk/pkg/dem/Engine/StandAloneEngine/ElasticContactLaw.cpp
===================================================================
--- trunk/pkg/dem/Engine/StandAloneEngine/ElasticContactLaw.cpp 2009-02-22 
13:08:47 UTC (rev 1679)
+++ trunk/pkg/dem/Engine/StandAloneEngine/ElasticContactLaw.cpp 2009-02-22 
20:08:45 UTC (rev 1680)
@@ -44,10 +44,15 @@
                
Shop::applyForceAtContactPoint(force,contGeom->contactPoint,i->getId1(),contGeom->pos1,i->getId2(),contGeom->pos2,rb);
 
                Vector3r bendAbs; Real torsionAbs; 
contGeom->bendingTorsionAbs(bendAbs,torsionAbs);
-               
Shop::Bex::momentum(i->getId1(),rb)+=contGeom->normal*torsionAbs*ktor;
-               
Shop::Bex::momentum(i->getId2(),rb)-=contGeom->normal*torsionAbs*ktor;
-               Shop::Bex::momentum(i->getId1(),rb)+=bendAbs*kb;
-               Shop::Bex::momentum(i->getId2(),rb)-=bendAbs*kb;
+               #ifdef BEX_CONTAINER
+                       rb->bex.addTorque(i->getId1(), 
contGeom->normal*torsionAbs*ktor+bendAbs*kb);
+                       
rb->bex.addTorque(i->getId2(),-contGeom->normal*torsionAbs*ktor-bendAbs*kb);
+               #else
+                       
Shop::Bex::momentum(i->getId1(),rb)+=contGeom->normal*torsionAbs*ktor;
+                       
Shop::Bex::momentum(i->getId2(),rb)-=contGeom->normal*torsionAbs*ktor;
+                       Shop::Bex::momentum(i->getId1(),rb)+=bendAbs*kb;
+                       Shop::Bex::momentum(i->getId2(),rb)-=bendAbs*kb;
+               #endif
        }
 }
 
@@ -170,10 +175,10 @@
        
                        Vector3r f                              = 
currentContactPhysics->normalForce + shearForce;
                        #ifdef BEX_CONTAINER
-                               ncb->bex.force(id1)-=f;
-                               ncb->bex.force(id2)+=f;
-                               ncb->bex.torque(id1)-=c1x.Cross(f);
-                               ncb->bex.torque(id2)+=c2x.Cross(f);
+                               ncb->bex.addForce (id1,-f);
+                               ncb->bex.addForce (id2,+f);
+                               ncb->bex.addTorque(id1,-c1x.Cross(f));
+                               ncb->bex.addTorque(id2, c2x.Cross(f));
                        #else
                                static_cast<Force*>   ( 
ncb->physicalActions->find( id1 , actionForceIndex).get() )->force    -= f;
                                static_cast<Force*>   ( 
ncb->physicalActions->find( id2 , actionForceIndex ).get() )->force    += f;


_______________________________________________
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