Author: eudoxos
Date: 2009-02-25 15:25:55 +0100 (Wed, 25 Feb 2009)
New Revision: 1690

Added:
   trunk/core/containers/InteractionHashMap.cpp
   trunk/core/containers/InteractionHashMap.hpp
   trunk/pkg/common/Engine/MetaEngine/InteractionDispatchers.cpp
   trunk/pkg/common/Engine/MetaEngine/InteractionDispatchers.hpp
Modified:
   trunk/extra/Brefcom.cpp
   trunk/gui/SConscript
   trunk/gui/py/timing.py
   trunk/gui/py/utils.py
   trunk/gui/py/yade-multi
   trunk/gui/py/yadeControl.cpp
   trunk/pkg/common/SConscript
Log:
1. New InteractionDispatchers class that has one common loop for 
InteractionGeometryMetaEngine, InteractionPhysicsMetaEngine and 
ConstitutiveLawDispatcher. It can be used from python like this:
  
 O.engines=[..., 
InteractionDispatchers([EngineUnit('geomFunctor1'),EngineUnit('geomFunctor2')],[EngineUnit('physFunctor1'),...],[EngineUnit('ConstitutiveLaw1'),...])

Gives about 5% of speedups, but not yet measured exactly.

2. Fix InteractionHashMap. I forgot to svn add... Sorry
3. Fix all other compilation problems with/without NO_BEX, with/without openmp 
(hopefully.
4. yade-multi now passes parameters that are all uppercase (with numbers and 
underscores) as env. vars to the process (think OMP_NUM_THREADS).


Added: trunk/core/containers/InteractionHashMap.cpp
===================================================================
--- trunk/core/containers/InteractionHashMap.cpp        2009-02-24 13:13:14 UTC 
(rev 1689)
+++ trunk/core/containers/InteractionHashMap.cpp        2009-02-25 14:25:55 UTC 
(rev 1690)
@@ -0,0 +1,169 @@
+/*************************************************************************
+*  Copyright (C) 2004 by Olivier Galizzi                                 *
+*  [email protected]                                               *
+*                                                                        *
+*  This program is free software; it is licensed under the terms of the  *
+*  GNU General Public License v2 or later. See file LICENSE for details. *
+*************************************************************************/
+
+#include "InteractionHashMap.hpp"
+
+InteractionHashMapIterator::InteractionHashMapIterator() : 
InteractionContainerIterator()
+{
+
+}
+
+
+InteractionHashMapIterator::~InteractionHashMapIterator()
+{
+
+}
+
+
+bool InteractionHashMapIterator::isDifferent(const 
InteractionContainerIterator& i)
+{
+       return (hmii != static_cast<const InteractionHashMapIterator&>(i).hmii 
);
+}
+
+
+void InteractionHashMapIterator::increment()
+{
+       ++hmii;
+}
+
+
+void InteractionHashMapIterator::affect(const InteractionContainerIterator& i)
+{
+       hmii = static_cast<const InteractionHashMapIterator&>(i).hmii;
+}
+
+
+shared_ptr<Interaction> InteractionHashMapIterator::getValue()
+{
+       return (*hmii).second;
+}
+
+
+shared_ptr<InteractionContainerIterator> 
InteractionHashMapIterator::createPtr()
+{
+       return shared_ptr<InteractionContainerIterator>(new 
InteractionHashMapIterator());
+}
+
+
+/***********************************************************************/
+/***********************************************************************/
+/***********************************************************************/
+/***********************************************************************/
+
+InteractionHashMap::InteractionHashMap()
+{
+       clear();
+}
+
+
+InteractionHashMap::~InteractionHashMap()
+{
+}
+
+
+bool InteractionHashMap::insert(shared_ptr<Interaction>& i)
+{
+       boost::mutex::scoped_lock lock(drawloopmutex);
+
+       body_id_t id1 = i->getId1();
+       body_id_t id2 = i->getId2();
+       if (id1>id2)
+               swap(id1,id2);
+
+       return interactions.insert( IHashMap::value_type( 
pair<body_id_t,body_id_t>(id1,id2) , i )).second;
+}
+
+
+bool InteractionHashMap::insert(body_id_t id1,body_id_t id2)
+{
+       shared_ptr<Interaction> i(new Interaction(id1,id2) );
+       return insert(i);       
+}
+
+
+void InteractionHashMap::clear()
+{
+       boost::mutex::scoped_lock lock(drawloopmutex);
+
+       interactions.clear();
+}
+
+
+bool InteractionHashMap::erase(body_id_t id1,body_id_t id2)
+{
+       boost::mutex::scoped_lock lock(drawloopmutex);
+
+       if (id1>id2)
+               swap(id1,id2);
+
+       unsigned int oldSize = interactions.size();
+       pair<body_id_t,body_id_t> p(id1,id2);
+       unsigned int size = interactions.erase(p);
+
+       return size!=oldSize;
+
+}
+
+
+const shared_ptr<Interaction>& InteractionHashMap::find(body_id_t 
id1,body_id_t id2)
+{
+       if (id1>id2)
+               swap(id1,id2);
+
+       IHashMap::iterator hmii = 
interactions.find(pair<body_id_t,body_id_t>(id1,id2));
+       if (hmii!=interactions.end())
+               return (*hmii).second;
+       else
+       {
+               empty = shared_ptr<Interaction>(); 
+               return empty;
+       }
+}
+
+
+InteractionContainer::iterator InteractionHashMap::begin()
+{
+       shared_ptr<InteractionHashMapIterator> it(new 
InteractionHashMapIterator());
+       it->hmii   = interactions.begin();
+
+       return InteractionContainer::iterator(it);
+}
+
+
+InteractionContainer::iterator InteractionHashMap::end()
+{
+       shared_ptr<InteractionHashMapIterator> it(new 
InteractionHashMapIterator());
+       it->hmii   = interactions.end();
+
+       return InteractionContainer::iterator(it);
+}
+
+
+// void InteractionHashMap::eraseCurrentAndGotoNextPotential()
+// {
+//     if (notAtEnd())
+//     {
+//             IHashMap::iterator tmpHmii=hmii;
+//             ++hmii;
+//             interactions.erase(tmpHmii);
+//     }
+// }
+// 
+// void InteractionHashMap::eraseCurrentAndGotoNext()
+// {
+//     IHashMap::iterator tmpHmii=hmii;        
+//     while (notAtEnd() && !((*hmii).second->isReal))
+//             ++hmii; 
+//     interactions.erase(tmpHmii);
+// }
+
+unsigned int InteractionHashMap::size()
+{
+       return interactions.size();
+}
+YADE_PLUGIN();

Added: trunk/core/containers/InteractionHashMap.hpp
===================================================================
--- trunk/core/containers/InteractionHashMap.hpp        2009-02-24 13:13:14 UTC 
(rev 1689)
+++ trunk/core/containers/InteractionHashMap.hpp        2009-02-25 14:25:55 UTC 
(rev 1690)
@@ -0,0 +1,83 @@
+/*************************************************************************
+*  Copyright (C) 2004 by Olivier Galizzi                                 *
+*  [email protected]                                               *
+*                                                                        *
+*  This program is free software; it is licensed under the terms of the  *
+*  GNU General Public License v2 or later. See file LICENSE for details. *
+*************************************************************************/
+
+#pragma once
+
+#include<yade/core/InteractionContainer.hpp>
+#include<yade/core/Interaction.hpp>
+#include<ext/hash_map>
+#include<vector>
+#include"InteractionHashMap.hpp"
+
+using namespace std;
+using namespace __gnu_cxx;
+
+
+
+
+struct eqPair
+{
+       bool operator()(const pair<body_id_t,body_id_t>& p1, const 
pair<body_id_t,body_id_t>& p2) const
+       {
+               return (p1.first==p2.first && p1.second==p2.second);
+       }
+};
+
+struct hashPair
+{
+       unsigned int operator()(const pair<body_id_t,body_id_t>& p) const
+       {
+               return ((unsigned int)p.first+(unsigned int)p.second)%182501621;
+       }
+};
+
+typedef hash_map<pair<body_id_t,body_id_t>, shared_ptr<Interaction>, hashPair, 
eqPair > IHashMap;
+
+class InteractionHashMap : public InteractionContainer
+{
+       private :
+               IHashMap interactions;
+               shared_ptr<Interaction> empty;
+
+       public :
+               InteractionHashMap();
+               virtual ~InteractionHashMap();
+
+               virtual bool insert(body_id_t id1,body_id_t id2);
+               virtual bool insert(shared_ptr<Interaction>& i);
+               virtual void clear();
+               virtual bool erase(body_id_t id1,body_id_t id2);
+               virtual const shared_ptr<Interaction>& find(body_id_t 
id1,body_id_t id2);
+       
+               virtual InteractionContainer::iterator begin();
+               virtual InteractionContainer::iterator end();
+       
+               virtual unsigned int size();
+
+       REGISTER_CLASS_NAME(InteractionHashMap);
+       REGISTER_BASE_CLASS_NAME(InteractionContainer);
+};
+
+class InteractionHashMapIterator : public InteractionContainerIterator 
+{
+       public :
+               IHashMap::iterator hmii;
+
+               InteractionHashMapIterator();
+               ~InteractionHashMapIterator();
+
+               virtual bool isDifferent(const InteractionContainerIterator& i);
+               virtual void affect(const InteractionContainerIterator& i);
+               virtual void increment();
+               virtual shared_ptr<Interaction> getValue();
+               virtual shared_ptr<InteractionContainerIterator> createPtr();
+
+};
+
+REGISTER_SERIALIZABLE(InteractionHashMap);
+

Modified: trunk/extra/Brefcom.cpp
===================================================================
--- trunk/extra/Brefcom.cpp     2009-02-24 13:13:14 UTC (rev 1689)
+++ trunk/extra/Brefcom.cpp     2009-02-25 14:25:55 UTC (rev 1690)
@@ -13,7 +13,7 @@
 
 void BrefcomGlobalCharacteristics::compute(MetaBody* rb, bool useMaxForce){
        //Shop::Bex::initCache();
-       #if BEX_CONTAINER
+       #ifdef BEX_CONTAINER
                rb->bex.sync();
        #else
                throw runtime_error("Brefcom can run only with BexContainer");
@@ -159,9 +159,13 @@
        /* const Real& transStrainCoeff(BC->transStrainCoeff); const Real& 
epsTrans(BC->epsTrans); const Real& xiShear(BC->xiShear); */
        Real& omega(BC->omega); Real& sigmaN(BC->sigmaN);  Vector3r& 
sigmaT(BC->sigmaT); Real& Fn(BC->Fn); Vector3r& Fs(BC->Fs); // for python access
 
+       #define NNAN(a) assert(!isnan(a));
+       #define NNANV(v) assert(!isnan(v[0])); assert(!isnan(v[1])); 
assert(!isnan(v[2]));
+
        assert(contGeom->hasShear);
        //timingDeltas->checkpoint("setup");
        epsN=contGeom->epsN(); epsT=contGeom->epsT();
+       NNAN(epsN); NNANV(epsT);
        // already in SpheresContactGeometry:
        // contGeom->relocateContactPoints(); // allow very large mutual 
rotations
        if(logStrain && epsN<0){ Real epsN0=epsN; epsN=log(epsN0+1); 
epsT*=epsN/epsN0; }
@@ -181,8 +185,6 @@
                LOG_DEBUG("Contact #"<<I->getId1()<<"=#"<<I->getId2()<<" is 
damaged over thershold ("<<omega<<">"<<omegaThreshold<<") and has been deleted 
(isReal="<<I->isReal<<")");
                return;
        }
-       #define NNAN(a) assert(!isnan(a));
-       #define NNANV(v) assert(!isnan(v[0])); assert(!isnan(v[1])); 
assert(!isnan(v[2]));
        // store Fn (and Fs?), for use with GlobalStiffnessCounter?
        NNAN(sigmaN); NNANV(sigmaT); NNAN(crossSection);
 

Modified: trunk/gui/SConscript
===================================================================
--- trunk/gui/SConscript        2009-02-24 13:13:14 UTC (rev 1689)
+++ trunk/gui/SConscript        2009-02-25 14:25:55 UTC (rev 1690)
@@ -65,6 +65,7 @@
                                'InteractionPhysicsMetaEngine',
                                'PhysicalParametersMetaEngine',
                                'ConstitutiveLawDispatcher',
+                               'InteractionDispatchers',
                                'STLImporter',
                                'ParallelEngine'
                        ],

Modified: trunk/gui/py/timing.py
===================================================================
--- trunk/gui/py/timing.py      2009-02-24 13:13:14 UTC (rev 1689)
+++ trunk/gui/py/timing.py      2009-02-25 14:25:55 UTC (rev 1690)
@@ -19,9 +19,9 @@
        raw=[]
        raw.append(label)
        raw.append(str(count) if count>=0 else '')
-       raw.append((str(time/1000)+u'μs') if time>=0 else '')
+       raw.append((str(time/1000)+u'us') if time>=0 else '')
        raw.append(('%6.2f%%'%(time*100./totalTime)) if totalTime>0 else '')
-       return ' '.join([
+       return u' '.join([
                (sp+raw[0]).ljust(_statCols['label']),
                (raw[1]+negSp).rjust(_statCols['count']),
                (raw[2]+negSp).rjust(_statCols['time']),
@@ -40,7 +40,7 @@
 def _engines_stats(engines,totalTime,level):
        lines=0; hereLines=0
        for e in engines:
-               if e.__class__.__name__!='EngineUnit': print 
_formatLine('"'+e['label']+'"' if e['label'] else 
e.name,e.execTime,e.execCount,totalTime,level); lines+=1; hereLines+=1
+               if e.__class__.__name__!='EngineUnit': print 
_formatLine(u'"'+e['label']+'"' if e['label'] else 
e.name,e.execTime,e.execCount,totalTime,level); lines+=1; hereLines+=1
                if e.timingDeltas: 
                        if e.__class__.__name__=='EngineUnit':
                                print _formatLine(e.name,-1,-1,-1,level); 
lines+=1; hereLines+=1
@@ -48,6 +48,10 @@
                        else: execTime=e.execTime
                        lines+=_delta_stats(e.timingDeltas,execTime,level+1)
                if e.__class__.__name__=='MetaEngine': 
lines+=_engines_stats(e.functors,e.execTime,level+1)
+               if e.__class__.__name__=='InteractionDispatcher':
+                       
lines+=_engines_stats(e.geomDispatcher.functors,e.execTime,level+1)
+                       
lines+=_engines_stats(e.physDispatcher.functors,e.execTime,level+1)
+                       
lines+=_engines_stats(e.constLawDispatcher.functors,e.execTime,level+1)
                elif e.__class__.__name__=='ParallelEngine': 
lines+=_engines_stats(e.slave,e.execTime,level+1)
        if hereLines>1:
                print _formatLine('TOTAL',totalTime,-1,totalTime,level); 
lines+=1

Modified: trunk/gui/py/utils.py
===================================================================
--- trunk/gui/py/utils.py       2009-02-24 13:13:14 UTC (rev 1689)
+++ trunk/gui/py/utils.py       2009-02-25 14:25:55 UTC (rev 1690)
@@ -306,7 +306,7 @@
        mainloop.run()
        pipeline.set_state(gst.STATE_NULL); pipeline.get_state()
 
-def readParamsFromTable(tableFileLine=None,noTableOk=False,**kw):
+def 
readParamsFromTable(tableFileLine=None,noTableOk=False,unknownOk=False,**kw):
        """
        Read parameters from a file and assign them to __builtin__ variables.
 
@@ -346,8 +346,8 @@
                for i in range(len(names)):
                        if names[i]=='description': 
o.tags['description']=values[i]
                        else:
-                               if names[i] not in kw.keys(): raise 
NameError("Parameter `%s' has no default value assigned"%names[i])
-                               kw.pop(names[i])
+                               if names[i] not in kw.keys() and not unknownOk: 
raise NameError("Parameter `%s' has no default value assigned"%names[i])
+                               if names[i] in kw.keys(): kw.pop(names[i])
                                eq="%s=%s"%(names[i],values[i])
                                exec('__builtin__.%s=%s'%(names[i],values[i])); 
tagsParams+=['%s=%s'%(names[i],values[i])]; dictParams[names[i]]=values[i]
        defaults=[]

Modified: trunk/gui/py/yade-multi
===================================================================
--- trunk/gui/py/yade-multi     2009-02-24 13:13:14 UTC (rev 1689)
+++ trunk/gui/py/yade-multi     2009-02-25 14:25:55 UTC (rev 1690)
@@ -106,7 +106,7 @@
 
 parser=optparse.OptionParser(usage='%prog [options] TABLE SIMULATION.py\n\n  
%prog runs yade simulation multiple times with different parameters.\n  See 
http://yade.wikia.com/wiki/ScriptParametricStudy for details.')
 parser.add_option('-j',dest='maxJobs',type='int',help="Maximum number of 
simultaneous jobs to run (default: number of cores, i.e. 
%d)"%getNumCores(),metavar='NUM',default=getNumCores())
-parser.add_option('--log',dest='logFormat',help='Format of log files -- must 
contain a % or @, which will be replaced by line number or by description 
column respectively (default: SIMULATION.%.log)',metavar='FORMAT')
+parser.add_option('--log',dest='logFormat',help='Format of log files -- must 
contain a % or @, which will be replaced by line number or by description 
column respectively (default: [email protected])',metavar='FORMAT')
 parser.add_option('-l','--lines',dest='lineList',help='Lines of TABLE to use, 
in the format 2,3-5,8,11-13 (default: all available lines in 
TABLE)',metavar='LIST')
 parser.add_option('--nice',dest='nice',type='int',help='Nice value of spawned 
jobs (default: 10)',default=10)
 parser.add_option('--executable',dest='executable',help='Name of the program 
to run (default: %s)'%sys.argv[0][:-6],default=sys.argv[0][:-6],metavar='FILE') 
## strip the '-multi' extension
@@ -118,14 +118,24 @@
        parser.print_help()
        sys.exit(1)
 table,simul=args[0:2]
-if not logFormat: logFormat=(simul[:-3] if simul[-3:]=='.py' else 
simul)+".%.log"
+if not logFormat: logFormat=(simul[:-3] if simul[-3:]=='.py' else 
simul)+"[email protected]"
 if (not '%' in logFormat) and ('@' not in logFormat): raise StandardError("Log 
string must contain at least one of `%', `@'")
 
 print "Will run `%s' on `%s' with nice value %d, output redirected to `%s', %d 
jobs at a time."%(executable,simul,nice,logFormat,maxJobs)
 
 ll=['']+open(table,'r').readlines()
 availableLines=[i for i in range(len(ll)) if not 
re.match(r'^\s*(#.*)?$',ll[i][:-1]) and i>1]
+print availableLines
 
+# read actual data
+values={}
+headings=ll[1].split()
+for l in availableLines:
+       val={}
+       for i in range(len(headings)):
+               val[i]=ll[l].split()[i]
+       values[l]=val
+
 print "Will use table `%s', with available lines"%(table),', '.join([str(i) 
for i in availableLines])+'.'
 
 if lineList:
@@ -145,9 +155,9 @@
 print "Will use lines ",', '.join([str(i) for i in useLines])+'.'
 # find column where description is
 try:
-       idColumn=ll[1].split().index('description')
+       idColumn=headings.index('description')
        idStrings={}
-       for i in useLines: idStrings[i]=ll[i].split()[idColumn] # textual 
descripion of respective lines 
+       for i in useLines: idStrings[i]=values[i][idColumn] # textual 
descripion of respective lines 
        print idStrings
 except ValueError:
        idColumn=None
@@ -158,7 +168,11 @@
 for i,l in enumerate(useLines):
        logFile=logFormat.replace('%',str(l))
        if idStrings: logFile=logFile.replace('@',idStrings[l])
-       jobs.append(JobInfo(i,idStrings[l] if idStrings else 
'#'+str(i),'PARAM_TABLE=%s:%d nice -n %d %s -N PythonUI -- -n -x %s > %s 
2>&1'%(table,l,nice,executable,simul,logFile),logFile))
+       else: logFile=logFile.replace('@',str(l))
+       envVars=[]
+       for col,head in enumerate(headings):
+               if re.match('^[A-Z_]+[A-Z0-9_]+',head): 
envVars+=['%s=%s'%(head,values[l][col])]
+       jobs.append(JobInfo(i,idStrings[l] if idStrings else 
'#'+str(i),'PARAM_TABLE=%s:%d %s nice -n %d %s -N PythonUI -- -n -x %s > %s 
2>&1'%(table,l,' '.join(envVars),nice,executable,simul,logFile),logFile))
 
 print "Job summary:"
 for job in jobs:

Modified: trunk/gui/py/yadeControl.cpp
===================================================================
--- trunk/gui/py/yadeControl.cpp        2009-02-24 13:13:14 UTC (rev 1689)
+++ trunk/gui/py/yadeControl.cpp        2009-02-25 14:25:55 UTC (rev 1690)
@@ -43,6 +43,7 @@
 #include<yade/pkg-common/InteractionPhysicsMetaEngine.hpp>
 #include<yade/pkg-common/PhysicalParametersMetaEngine.hpp>
 #include<yade/pkg-common/ConstitutiveLawDispatcher.hpp>
+#include<yade/pkg-common/InteractionDispatchers.hpp>
 #include<yade/pkg-common/PhysicalActionDamper.hpp>
 #include<yade/pkg-common/PhysicalActionApplier.hpp>
 #include<yade/pkg-common/MetaInteractingGeometry.hpp>
@@ -228,7 +229,6 @@
        python::object timingDeltas_get(){return 
proxee->timingDeltas?python::object(pyTimingDeltas(proxee->timingDeltas)):python::object();}
 BASIC_PY_PROXY_TAIL;
 
-
 BASIC_PY_PROXY_HEAD(pyMetaEngine,MetaEngine)
                // additional constructor
                pyMetaEngine(string clss, python::list functors){init(clss); 
functors_set(functors);}
@@ -273,11 +273,24 @@
        PY_PROXY_TIMING
 BASIC_PY_PROXY_TAIL;
 
+BASIC_PY_PROXY_HEAD(pyInteractionDispatchers,InteractionDispatchers)
+       pyInteractionDispatchers(python::list geomFunctors, python::list 
physFunctors, python::list constLawFunctors){
+               init("InteractionDispatchers");
+               pyMetaEngine(proxee->geomDispatcher).functors_set(geomFunctors);
+               pyMetaEngine(proxee->physDispatcher).functors_set(physFunctors);
+               
pyMetaEngine(proxee->constLawDispatcher).functors_set(constLawFunctors);
+       }
+       pyMetaEngine geomDispatcher_get(void){ return 
pyMetaEngine(proxee->geomDispatcher);}
+       pyMetaEngine physDispatcher_get(void){ return 
pyMetaEngine(proxee->physDispatcher);}
+       pyMetaEngine constLawDispatcher_get(void){ return 
pyMetaEngine(proxee->constLawDispatcher);}
+       PY_PROXY_TIMING
+BASIC_PY_PROXY_TAIL;
+
 python::list anyEngines_get(const vector<shared_ptr<Engine> >& engContainer){
        python::list ret; 
        FOREACH(const shared_ptr<Engine>& eng, engContainer){
                #define APPEND_ENGINE_IF_POSSIBLE(engineType,pyEngineType) { 
shared_ptr<engineType> e=dynamic_pointer_cast<engineType>(eng); if(e) { 
ret.append(pyEngineType(e)); continue; } }
-               APPEND_ENGINE_IF_POSSIBLE(MetaEngine,pyMetaEngine); 
APPEND_ENGINE_IF_POSSIBLE(StandAloneEngine,pyStandAloneEngine); 
APPEND_ENGINE_IF_POSSIBLE(DeusExMachina,pyDeusExMachina); 
APPEND_ENGINE_IF_POSSIBLE(ParallelEngine,pyParallelEngine); 
+               
APPEND_ENGINE_IF_POSSIBLE(InteractionDispatchers,pyInteractionDispatchers); 
APPEND_ENGINE_IF_POSSIBLE(MetaEngine,pyMetaEngine); 
APPEND_ENGINE_IF_POSSIBLE(StandAloneEngine,pyStandAloneEngine); 
APPEND_ENGINE_IF_POSSIBLE(DeusExMachina,pyDeusExMachina); 
APPEND_ENGINE_IF_POSSIBLE(ParallelEngine,pyParallelEngine); 
                throw std::runtime_error("Unknown engine type: 
`"+eng->getClassName()+"' (only MetaEngine, StandAloneEngine, DeusExMachina and 
ParallelEngine are supported)");
        }
        return ret;
@@ -289,7 +302,7 @@
        engContainer.clear();
        for(int i=0; i<len; i++){
                #define PUSH_BACK_ENGINE_IF_POSSIBLE(pyEngineType) 
if(python::extract<pyEngineType>(PySequence_GetItem(egs.ptr(),i)).check()){ 
pyEngineType e=python::extract<pyEngineType>(PySequence_GetItem(egs.ptr(),i)); 
engContainer.push_back(e.proxee); /* cerr<<"added "<<e.pyStr()<<", a 
"<<#pyEngineType<<endl; */ continue; }
-               PUSH_BACK_ENGINE_IF_POSSIBLE(pyStandAloneEngine); 
PUSH_BACK_ENGINE_IF_POSSIBLE(pyMetaEngine); 
PUSH_BACK_ENGINE_IF_POSSIBLE(pyDeusExMachina); 
PUSH_BACK_ENGINE_IF_POSSIBLE(pyParallelEngine);
+               PUSH_BACK_ENGINE_IF_POSSIBLE(pyStandAloneEngine); 
PUSH_BACK_ENGINE_IF_POSSIBLE(pyMetaEngine); 
PUSH_BACK_ENGINE_IF_POSSIBLE(pyDeusExMachina); 
PUSH_BACK_ENGINE_IF_POSSIBLE(pyParallelEngine); 
PUSH_BACK_ENGINE_IF_POSSIBLE(pyInteractionDispatchers);
                throw std::runtime_error("Encountered unknown engine type 
(unable to extract from python object)");
        }
 }
@@ -707,6 +720,12 @@
                .def(python::init<python::list>());
        BASIC_PY_PROXY_WRAPPER(pyDeusExMachina,"DeusExMachina")
                TIMING_PROPS(pyDeusExMachina);
+       
BASIC_PY_PROXY_WRAPPER(pyInteractionDispatchers,"InteractionDispatchers")
+               .def(python::init<python::list,python::list,python::list>())
+               
.add_property("geomDispatcher",&pyInteractionDispatchers::geomDispatcher_get)
+               
.add_property("physDispatcher",&pyInteractionDispatchers::physDispatcher_get)
+               
.add_property("constLawDispatcher",&pyInteractionDispatchers::constLawDispatcher_get)
+               TIMING_PROPS(pyInteractionDispatchers);
        BASIC_PY_PROXY_WRAPPER(pyEngineUnit,"EngineUnit")
                .add_property("timingDeltas",&pyEngineUnit::timingDeltas_get)
                .add_property("bases",&pyEngineUnit::bases_get);

Added: trunk/pkg/common/Engine/MetaEngine/InteractionDispatchers.cpp
===================================================================
--- trunk/pkg/common/Engine/MetaEngine/InteractionDispatchers.cpp       
2009-02-24 13:13:14 UTC (rev 1689)
+++ trunk/pkg/common/Engine/MetaEngine/InteractionDispatchers.cpp       
2009-02-25 14:25:55 UTC (rev 1690)
@@ -0,0 +1,32 @@
+#include"InteractionDispatchers.hpp"
+
+YADE_PLUGIN("InteractionDispatchers");
+
+InteractionDispatchers::InteractionDispatchers(){
+       geomDispatcher=shared_ptr<InteractionGeometryMetaEngine>(new 
InteractionGeometryMetaEngine);
+       physDispatcher=shared_ptr<InteractionPhysicsMetaEngine>(new 
InteractionPhysicsMetaEngine);
+       constLawDispatcher=shared_ptr<ConstitutiveLawDispatcher>(new 
ConstitutiveLawDispatcher);
+}
+
+void InteractionDispatchers::action(MetaBody* rootBody){
+       #ifdef YADE_OPENMP
+               const long size=rootBody->interactions->size();
+               #pragma omp parallel for
+               for(long i=0; i<size; i++){
+                       const shared_ptr<Interaction>& 
I=(*rootBody->interactions)[i];
+       #else
+               FOREACH(shared_ptr<Interaction> I, *rootBody->interactions){
+       #endif
+                       // InteractionGeometryMetaEngine
+                       const shared_ptr<Body>& 
b1=Body::byId(I->getId1(),rootBody);
+                       const shared_ptr<Body>& 
b2=Body::byId(I->getId2(),rootBody);
+                       I->isReal =
+                               b1->interactingGeometry && 
b2->interactingGeometry && // some bodies do not have interactingGeometry
+                               
geomDispatcher->operator()(b1->interactingGeometry, b2->interactingGeometry, 
b1->physicalParameters->se3, b2->physicalParameters->se3,I);
+                       if(!I->isReal) continue;
+                       // InteractionPhysicsMetaEngine
+                       physDispatcher->operator()(b1->physicalParameters, 
b2->physicalParameters,I);
+                       // ConstitutiveLawDispatcher
+                       
constLawDispatcher->operator()(I->interactionGeometry,I->interactionPhysics,I.get(),rootBody);
+               }
+}

Added: trunk/pkg/common/Engine/MetaEngine/InteractionDispatchers.hpp
===================================================================
--- trunk/pkg/common/Engine/MetaEngine/InteractionDispatchers.hpp       
2009-02-24 13:13:14 UTC (rev 1689)
+++ trunk/pkg/common/Engine/MetaEngine/InteractionDispatchers.hpp       
2009-02-25 14:25:55 UTC (rev 1690)
@@ -0,0 +1,22 @@
+// 2009 © Václav Šmilauer <[email protected]>
+#pragma once
+#include<yade/core/StandAloneEngine.hpp>
+#include<yade/pkg-common/InteractionGeometryMetaEngine.hpp>
+#include<yade/pkg-common/InteractionPhysicsMetaEngine.hpp>
+#include<yade/pkg-common/ConstitutiveLawDispatcher.hpp>
+
+class InteractionDispatchers: public StandAloneEngine {
+       public:
+               InteractionDispatchers();
+               virtual void action(MetaBody*);
+               shared_ptr<InteractionGeometryMetaEngine> geomDispatcher;
+               shared_ptr<InteractionPhysicsMetaEngine> physDispatcher;
+               shared_ptr<ConstitutiveLawDispatcher> constLawDispatcher;
+               
REGISTER_CLASS_AND_BASE(InteractionDispatchers,StandAloneEngine);
+               REGISTER_ATTRIBUTES(StandAloneEngine,
+                       (geomDispatcher)
+                       (physDispatcher)
+                       (constLawDispatcher)
+               );
+};
+REGISTER_SERIALIZABLE(InteractionDispatchers);

Modified: trunk/pkg/common/SConscript
===================================================================
--- trunk/pkg/common/SConscript 2009-02-24 13:13:14 UTC (rev 1689)
+++ trunk/pkg/common/SConscript 2009-02-25 14:25:55 UTC (rev 1690)
@@ -104,6 +104,7 @@
        
env.SharedLibrary('PhysicalActionApplier',['Engine/MetaEngine/PhysicalActionApplier.cpp']),
        
env.SharedLibrary('PhysicalActionDamper',['Engine/MetaEngine/PhysicalActionDamper.cpp']),
        
env.SharedLibrary('ConstitutiveLawDispatcher',['Engine/MetaEngine/ConstitutiveLawDispatcher.cpp'],LIBS=env['LIBS']+['Force','Momentum']),
+       
env.SharedLibrary('InteractionDispatchers',['Engine/MetaEngine/InteractionDispatchers.cpp'],LIBS=env['LIBS']+['InteractionGeometryMetaEngine','InteractionPhysicsMetaEngine','ConstitutiveLawDispatcher']),
        
env.SharedLibrary('InteractingBox2AABB',['Engine/EngineUnit/InteractingBox2AABB.cpp'],
                
LIBS=env['LIBS']+['BoundingVolumeMetaEngine','InteractingBox','AABB','Box',]),
        
env.SharedLibrary('MetaInteractingGeometry2AABB',['Engine/EngineUnit/MetaInteractingGeometry2AABB.cpp'],


_______________________________________________
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