Commit 3fa96631 authored by Václav Šmilauer's avatar Václav Šmilauer
Browse files

1. Dispatchers cleanup (will continue)

parent a5f724fd
......@@ -15,101 +15,7 @@ Functor::~Functor(){}; // vtable
#include<vector>
Dispatcher::~Dispatcher()
{
}
void Dispatcher::postProcessAttributes(bool deserializing)
{
Engine::postProcessAttributes(deserializing);
}
vector<vector<string> >& Dispatcher::getFunctorNames()
{
return functorNames;
}
void Dispatcher::clear()
{
functorNames.clear();
functorArguments.clear();
}
void Dispatcher::storeFunctorName(const string& baseClassName1, const string& libName, shared_ptr<Functor> eu)
{
vector<string> v;
v.push_back(baseClassName1);
v.push_back(libName);
functorNames.push_back(v);
storeFunctorArguments(eu);
}
void Dispatcher::storeFunctorName( const string& baseClassName1, const string& baseClassName2, const string& libName, shared_ptr<Functor> eu)
{
vector<string> v;
v.push_back(baseClassName1);
v.push_back(baseClassName2);
v.push_back(libName);
functorNames.push_back(v);
storeFunctorArguments(eu);
}
void Dispatcher::storeFunctorName( const string& baseClassName1, const string& baseClassName2, const string& baseClassName3, const string& libName, shared_ptr<Functor> eu)
{
vector<string> v;
v.push_back(baseClassName1);
v.push_back(baseClassName2);
v.push_back(baseClassName3);
v.push_back(libName);
functorNames.push_back(v);
storeFunctorArguments(eu);
}
void Dispatcher::storeFunctorArguments(shared_ptr<Functor> eu)
{
if (!eu)
return;
bool dupe = false;
FunctorListIterator it = functorArguments.begin();
FunctorListIterator itEnd = functorArguments.end();
for( ; it != itEnd ; ++it )
if( (*it)->getClassName() == eu->getClassName() )
dupe = true;
if (!dupe)
functorArguments.push_back(eu);
}
shared_ptr<Functor> Dispatcher::findFunctorArguments(const string& libName)
{
FunctorListIterator it = functorArguments.begin();
FunctorListIterator itEnd = functorArguments.end();
for( ; it != itEnd ; ++it )
if( (*it)->getClassName() == libName )
return *it;
return shared_ptr<Functor>();
}
Dispatcher::~Dispatcher(){}
//void Dispatcher::postProcessAttributes(bool deserializing){
// FOREACH(const shared_ptr<Functor>& f, functors) add(f);
//}
......@@ -17,28 +17,12 @@
class Dispatcher: public Engine
{
protected:
void storeFunctorArguments(shared_ptr<Functor> eu);
public :
vector<vector<string> >& getFunctorNames();
typedef list<shared_ptr<Functor> >::iterator FunctorListIterator;
//virtual void add( string , string , shared_ptr<Functor> eu = shared_ptr<Functor>()) {throw;}
//virtual void add( string , string , string , shared_ptr<Functor> eu = shared_ptr<Functor>()) {throw;}
virtual void add(shared_ptr<Functor> eu=shared_ptr<Functor>()) {throw;}
virtual void add(Functor*) {throw;}
virtual void add(string) {throw;}
//! Should be called by dispatcher before every loop (could be somehow optimized, since it will change very rarely)
void updateScenePtr() { FOREACH(shared_ptr<Functor> f, functorArguments){ f->scene=scene; } }
void storeFunctorName(const string& baseClassName1, const string& libName, shared_ptr<Functor> eu);
void storeFunctorName(const string& baseClassName1, const string& baseClassName2, const string& libName, shared_ptr<Functor> eu);
void storeFunctorName(const string& baseClassName1, const string& baseClassName2, const string& baseClassName3, const string& libName, shared_ptr<Functor> eu);
shared_ptr<Functor> findFunctorArguments(const string& libName);
void clear();
//! Should be called by the dispatcher before every loop (could be somehow optimized, since it will change very rarely)
void updateScenePtr() { FOREACH(shared_ptr<Functor> f, functors){ f->scene=scene; } }
void clear(){ functors.clear(); }
virtual ~Dispatcher();
......@@ -46,11 +30,15 @@ class Dispatcher: public Engine
virtual int getDimension() { throw; };
virtual string getBaseClassType(unsigned int ) { throw; };
virtual void postProcessAttributes(bool deserializing);
// emulate postProcessAttributes of real dispatchers that are never otherwise called; this hack will be removed once dispatchers are types on their own
virtual void Dispatcher_postProcessAttributes_deserializing(){ throw runtime_error("Dispatcher::Dispatcher_postProcessAttributes_deserializing should never be called (must be overridden in Dispatcher1D/Dispatcher2D)"); }
void postProcessAttributes(bool deserializing){
if(!deserializing) return;
Dispatcher_postProcessAttributes_deserializing();
}
YADE_CLASS_BASE_DOC_ATTRS(Dispatcher,Engine,"Engine dispatching control to its associated functors, based on types of argument it receives.",
((vector<vector<string> >,functorNames,,"Names of functor classes"))
((list<shared_ptr<Functor> >,functorArguments,,"Instances of functors"))
((list<shared_ptr<Functor> >,functors,,"Instances of functors"))
);
};
REGISTER_SERIALIZABLE(Dispatcher);
......@@ -58,7 +46,7 @@ REGISTER_SERIALIZABLE(Dispatcher);
// HELPER MACROS
// supposed to be passed to YADE_CLASS_BASE_DOC_ATTRS_PY in the 5th argument; takes class name as arg
#define YADE_PY_DISPATCHER(DispatcherT) .def("__init__",python::make_constructor(Dispatcher_ctor_list<DispatcherT>),"Construct with list of associated functors.").add_property("functors",&Dispatcher_functors_get<DispatcherT>,"Functors objects associated with this dispatcher.").def("dispMatrix",&DispatcherT::dump,python::arg("names")=true,"Return dictionary with contents of the dispatch matrix.").def("dispFunctor",&DispatcherT::getFunctor,"Return functor that would be dispatched for given argument(s); None if no dispatch; ambiguous dispatch throws.");
#define YADE_PY_DISPATCHER(DispatcherT) .def("__init__",python::make_constructor(Dispatcher_ctor_list<DispatcherT>),"Construct with list of associated functors.").add_property("functors",&Dispatcher_functors_get<DispatcherT>,&Dispatcher_functors_set<DispatcherT>,"Functors objects associated with this dispatcher.").def("dispMatrix",&DispatcherT::dump,python::arg("names")=true,"Return dictionary with contents of the dispatch matrix.").def("dispFunctor",&DispatcherT::getFunctor,"Return functor that would be dispatched for given argument(s); None if no dispatch; ambiguous dispatch throws.");
// HELPER FUNCTIONS
......@@ -67,7 +55,7 @@ REGISTER_SERIALIZABLE(Dispatcher);
This function exists solely for debugging, is quite slow: it has to traverse all classes and ask for inheritance information.
It should be used primarily to convert indices to names in Dispatcher::dictDispatchMatrix?D; since it relies on Omega for RTTI,
this code could not be in Dispatcher itself.
*/
s*/
template<class topIndexable>
std::string Dispatcher_indexToClassName(int idx){
scoped_ptr<topIndexable> top(new topIndexable);
......@@ -107,23 +95,30 @@ python::list Indexable_getClassIndices(const shared_ptr<TopIndexable> i, bool co
}
// Dispatcher is not a template, hence converting this into a real constructor would be complicated; keep it separated, at least for now...
//! Create dispatcher of given type, with functors given as list in argument
template<typename DispatcherT>
shared_ptr<DispatcherT> Dispatcher_ctor_list(const std::vector<shared_ptr<typename DispatcherT::functorType> >& functors){
shared_ptr<DispatcherT> instance(new DispatcherT);
FOREACH(shared_ptr<typename DispatcherT::functorType> functor,functors) instance->add(functor);
return instance;
}
//! Return functors of this dispatcher, as list of functors of appropriate type
template<typename DispatcherT>
std::vector<shared_ptr<typename DispatcherT::functorType> > Dispatcher_functors_get(shared_ptr<DispatcherT> self){
std::vector<shared_ptr<typename DispatcherT::functorType> > ret;
FOREACH(const shared_ptr<Functor>& functor, self->functorArguments){ shared_ptr<typename DispatcherT::functorType> functorRightType(dynamic_pointer_cast<typename DispatcherT::functorType>(functor)); if(!functorRightType) throw logic_error("Internal error: Dispatcher of type "+self->getClassName()+" did not contain Functor of the required type "+typeid(typename DispatcherT::functorType).name()+"?"); ret.push_back(functorRightType); }
FOREACH(const shared_ptr<Functor>& functor, self->functors){ shared_ptr<typename DispatcherT::functorType> functorRightType(dynamic_pointer_cast<typename DispatcherT::functorType>(functor)); if(!functorRightType) throw logic_error("Internal error: Dispatcher of type "+self->getClassName()+" did not contain Functor of the required type "+typeid(typename DispatcherT::functorType).name()+"?"); ret.push_back(functorRightType); }
return ret;
}
template<typename DispatcherT>
void Dispatcher_functors_set(shared_ptr<DispatcherT> self, std::vector<shared_ptr<typename DispatcherT::functorType> > functors){
self->clear();
FOREACH(const shared_ptr<typename DispatcherT::functorType>& item, functors) self->add(item);
}
// Dispatcher is not a template, hence converting this into a real constructor would be complicated; keep it separated, at least for now...
//! Create dispatcher of given type, with functors given as list in argument
template<typename DispatcherT>
shared_ptr<DispatcherT> Dispatcher_ctor_list(const std::vector<shared_ptr<typename DispatcherT::functorType> >& functors){
shared_ptr<DispatcherT> instance(new DispatcherT);
Dispatcher_functors_set<DispatcherT>(instance,functors);
return instance;
}
template
......@@ -162,39 +157,33 @@ class Dispatcher1D : public Dispatcher,
}
virtual void add(FunctorType* eu){ add(shared_ptr<FunctorType>(eu)); }
virtual void add(shared_ptr<FunctorType> eu){
storeFunctorName(eu->get1DFunctorType1(),eu->getClassName(),eu);
add1DEntry(eu->get1DFunctorType1(),eu->getClassName(),static_pointer_cast<FunctorType>(eu));
bool dupe=false; string eun=eu->getClassName();
FOREACH(const shared_ptr<Functor>& f, functors) { if(eun==f->getClassName()) dupe=true; }
if(!dupe) functors.push_back(eu);
add1DEntry(eu->get1DFunctorType1(),eu);
}
int getDimension() { return 1; }
virtual string getFunctorType()
{
virtual string getFunctorType(){
shared_ptr<FunctorType> eu(new FunctorType);
return eu->getClassName();
}
virtual string getBaseClassType(unsigned int i)
{
if (i==0)
{
shared_ptr<baseClass> bc(new baseClass);
return bc->getClassName();
}
else
return "";
virtual string getBaseClassType(unsigned int i){
if (i==0) { shared_ptr<baseClass> bc(new baseClass); return bc->getClassName(); }
else return "";
}
public :
void postProcessAttributes(bool deserializing)
{
Dispatcher::postProcessAttributes(deserializing);
if(deserializing)
{
for(unsigned int i=0;i<functorNames.size();i++)
add1DEntry(functorNames[i][0],functorNames[i][1],static_pointer_cast<FunctorType>(findFunctorArguments(functorNames[i][1])));
}
virtual void Dispatcher_postProcessAttributes_deserializing(){ Dispatcher1D::postProcessAttributes(true); }
// never gets called directly, but via the proxy above (hack)
void postProcessAttributes(bool deserializing){
if(!deserializing) return;
FOREACH(shared_ptr<Functor> f, functors) add(static_pointer_cast<FunctorType>(f));
}
public:
REGISTER_ATTRIBUTES(Dispatcher,);
REGISTER_CLASS_AND_BASE(Dispatcher1D,Dispatcher DynLibDispatcher);
};
......@@ -238,44 +227,31 @@ class Dispatcher2D : public Dispatcher,
virtual void add(FunctorType* eu){ add(shared_ptr<FunctorType>(eu)); }
/* add functor by shared pointer */
virtual void add(shared_ptr<FunctorType> eu){
storeFunctorName(eu->get2DFunctorType1(),eu->get2DFunctorType2(),eu->getClassName(),eu);
add2DEntry(eu->get2DFunctorType1(),eu->get2DFunctorType2(),eu->getClassName(),static_pointer_cast<FunctorType>(eu));
bool dupe=false; string eun=eu->getClassName();
FOREACH(const shared_ptr<Functor>& f, functors) { if(eun==f->getClassName()) dupe=true; }
if(!dupe) functors.push_back(eu);
add2DEntry(eu->get2DFunctorType1(),eu->get2DFunctorType2(),eu);
}
virtual int getDimension() { return 2; }
virtual string getFunctorType()
{
virtual string getFunctorType(){
shared_ptr<FunctorType> eu(new FunctorType);
return eu->getClassName();
}
virtual string getBaseClassType(unsigned int i)
{
if (i==0)
{
shared_ptr<baseClass1> bc(new baseClass1);
return bc->getClassName();
}
else if (i==1)
{
shared_ptr<baseClass2> bc(new baseClass2);
return bc->getClassName();
}
else
return "";
virtual string getBaseClassType(unsigned int i){
if (i==0){ shared_ptr<baseClass1> bc(new baseClass1); return bc->getClassName(); }
else if (i==1){ shared_ptr<baseClass2> bc(new baseClass2); return bc->getClassName();}
else return "";
}
virtual void Dispatcher_postProcessAttributes_deserializing(){ Dispatcher2D::postProcessAttributes(true); }
// never gets called directly, but via the proxy above (hack)
void postProcessAttributes(bool deserializing){
if(!deserializing) return;
FOREACH(shared_ptr<Functor> f, functors) add(static_pointer_cast<FunctorType>(f));
}
public:
void postProcessAttributes(bool deserializing)
{
Dispatcher::postProcessAttributes(deserializing);
if(deserializing)
{
for(unsigned int i=0;i<functorNames.size();i++)
add2DEntry(functorNames[i][0],functorNames[i][1],functorNames[i][2],static_pointer_cast<FunctorType>(findFunctorArguments(functorNames[i][2])));
}
}
REGISTER_ATTRIBUTES(Dispatcher,);
REGISTER_CLASS_AND_BASE(Dispatcher2D,Dispatcher DynLibDispatcher);
};
......
......@@ -16,7 +16,7 @@
class TimingDeltas;
class Scene;
class Functor : public Serializable
class Functor: public Serializable
{
public: virtual vector<std::string> getFunctorTypes(){throw;}
shared_ptr<TimingDeltas> timingDeltas;
......@@ -39,7 +39,7 @@ template
class ReturnType,
class AttributesType
>
class Functor1D : public Functor,
class Functor1D: public Functor,
public FunctorWrapper<ReturnType, AttributesType>
{
public:
......@@ -56,7 +56,7 @@ template
class ReturnType,
class AttributesType
>
class Functor2D : public Functor,
class Functor2D: public Functor,
public FunctorWrapper<ReturnType, AttributesType>
{
public:
......
......@@ -253,7 +253,7 @@ GenGeo
Dynamic
^^^^^^^
The most versatile algorithm for random dense packing is provided by :yref:`yade.pack.randomDensePack`. Initial loose packing of non-overlapping spheres is generated by randomly placing placing them in cuboid volume, with radii given by requested (currently only uniform) radius distribution. When no more spheres can be inserted, the packing is compressed, then uncompressed (see :ysrc:`py/pack.py` for exact values of these "stresses"), byt running a DEM simulation; :yref:`Omega.switchScene` is used to not affect existing simulation). Finally, resulting packing is clipped using provided predicate, as explained above.
The most versatile algorithm for random dense packing is provided by :yref:`yade.pack.randomDensePack`. Initial loose packing of non-overlapping spheres is generated by randomly placing placing them in cuboid volume, with radii given by requested (currently only uniform) radius distribution. When no more spheres can be inserted, the packing is compressed, then uncompressed (see :ysrc:`py/pack/pack.py` for exact values of these "stresses"), byt running a DEM simulation; :yref:`Omega.switchScene` is used to not affect existing simulation). Finally, resulting packing is clipped using provided predicate, as explained above.
By its nature, this method might take relatively long; and there are 2 provisions to make the computation time shorter:
......
......@@ -6,10 +6,16 @@
<rect>
<x>0</x>
<y>0</y>
<width>388</width>
<height>481</height>
<width>356</width>
<height>437</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string>Frame</string>
</property>
......@@ -19,186 +25,238 @@
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QGridLayout" name="gridLayout">
<layout class="QGridLayout" name="gridLayout_3">
<property name="margin">
<number>0</number>
</property>
<property name="spacing">
<number>0</number>
<number>1</number>
</property>
<item row="0" column="0">
<widget class="QWidget" name="buttonsWidget" native="true">
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QToolButton" name="moveUpButton">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>15</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>20</width>
<height>16777215</height>
</size>
</property>
<property name="font">
<font>
<pointsize>15</pointsize>
</font>
</property>
<property name="toolTip">
<string>Move up</string>
</property>
<property name="styleSheet">
<string notr="true"/>
</property>
<property name="text">
<string></string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QToolButton" name="moveDownButton">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>15</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>20</width>
<height>16777215</height>
</size>
</property>
<property name="font">
<font>
<pointsize>15</pointsize>
</font>
</property>
<property name="toolTip">
<string>Move down</string>
</property>
<property name="styleSheet">
<string notr="true"/>
</property>
<property name="text">
<string></string>
</property>
</widget>
</item>
</layout>
</item>
<item row="0" column="1">
<widget class="QToolBox" name="objectToolBox">
<property name="enabled">
<bool>true</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>10</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>40</width>
<height>0</height>
<width>0</width>
<height>10</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>40</width>
<height>16777215</height>
</size>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing">
<number>2</number>
</property>
<property name="margin">
<number>2</number>
</property>
<item>
<widget class="QPushButton" name="moveUpButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="MinimumExpanding">
<horstretch>0</horstretch>
<verstretch>2</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<pointsize>15</pointsize>
</font>
</property>
<property name="toolTip">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Sans'; font-size:15pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Move up&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string></string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="newButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="MinimumExpanding">
<horstretch>0</horstretch>
<verstretch>1</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<pointsize>30</pointsize>
</font>
</property>
<property name="toolTip">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Sans'; font-size:30pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Create new object&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string></string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="killButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="MinimumExpanding">
<horstretch>0</horstretch>
<verstretch>1</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<pointsize>30</pointsize>
</font>
</property>
<property name="toolTip">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Sans'; font-size:30pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Delete current object&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string></string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="moveDownButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="MinimumExpanding">
<horstretch>0</horstretch>
<verstretch>2</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<pointsize>15</pointsize>
</font>
</property>
<property name="toolTip">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;