yade-dev team mailing list archive
-
yade-dev team
-
Mailing list archive
-
Message #01034
[svn] r1690 - in trunk: core/containers extra gui gui/py pkg/common pkg/common/Engine/MetaEngine
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 *
+* olivier.galizzi@xxxxxxx *
+* *
+* 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 *
+* olivier.galizzi@xxxxxxx *
+* *
+* 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: SIMULATION.@.log)',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)+".@.log"
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 <eudoxos@xxxxxxxx>
+#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'],