yade-dev team mailing list archive
-
yade-dev team
-
Mailing list archive
-
Message #03114
[Branch ~yade-dev/yade/trunk] Rev 1978: 1. Fix numpy_boost and TesselationWrapper
------------------------------------------------------------
revno: 1978
committer: Václav Šmilauer <eudoxos@xxxxxxxx>
branch nick: trunk
timestamp: Thu 2010-01-21 08:53:17 +0100
message:
1. Fix numpy_boost and TesselationWrapper
2. Start moving python registration code inside classes themselves. That should allow proper class hierarchy in python as well as (faster) object.attribute access instead of hacky object['attribute']. Please report errors you might encounter.
3. Resurrect Dem6DofGeom, doesn't work for now.
added:
lib/pyutil/raw_constructor.hpp
modified:
core/Body.hpp
core/Cell.hpp
core/Material.hpp
core/Omega.cpp
core/main/main.py.in
lib/pyutil/numpy.hpp
lib/pyutil/numpy_boost.hpp
lib/serialization/Serializable.cpp
lib/serialization/Serializable.hpp
pkg/common/DataClass/Material/ElastMat.cpp
pkg/common/DataClass/Material/ElastMat.hpp
pkg/common/Engine/PartialEngine/GravityEngines.hpp
pkg/dem/DataClass/InteractionGeometry/Dem3DofGeom_SphereSphere.cpp
pkg/dem/DataClass/InteractionGeometry/Dem3DofGeom_SphereSphere.hpp
pkg/dem/DataClass/InteractionGeometry/DemXDofGeom.cpp
pkg/dem/DataClass/InteractionGeometry/DemXDofGeom.hpp
pkg/dem/Engine/GlobalEngine/ElasticContactLaw.cpp
pkg/dem/Engine/GlobalEngine/ElasticContactLaw.hpp
pkg/dem/Engine/GlobalEngine/MicroMacroAnalyser.cpp
pkg/dem/Engine/GlobalEngine/TesselationWrapper.cpp
pkg/dem/Engine/GlobalEngine/TesselationWrapper.hpp
pkg/dem/meta/ConcretePM.hpp
py/SConscript
py/system.py
py/yadeWrapper/yadeWrapper.cpp
--
lp:yade
https://code.launchpad.net/~yade-dev/yade/trunk
Your team Yade developers is subscribed to branch lp:yade.
To unsubscribe from this branch go to https://code.launchpad.net/~yade-dev/yade/trunk/+edit-subscription.
=== modified file 'core/Body.hpp'
--- core/Body.hpp 2009-12-18 09:48:16 +0000
+++ core/Body.hpp 2010-01-21 07:53:17 +0000
@@ -100,26 +100,18 @@
Body ();
Body (body_id_t newId, int newGroup);
- // Serialization
- protected:
- REGISTER_ATTRIBUTES(Serializable,
- (id)
- (groupMask)
- (isDynamic)
- #ifdef YADE_PHYSPAR
- (physicalParameters)
- #else
- (material)
- (state)
- #endif
- #ifdef YADE_GEOMETRICALMODEL
- (geometricalModel)
- #endif
- (shape)
- (bound)
- (clumpId)
- );
-
- REGISTER_CLASS_AND_BASE(Body,Serializable);
+ // Serialization
+ //protected:
+ // REGISTER_ATTRIBUTES(Serializable,(id)(groupMask)(isDynamic)(material)(state)(shape)(bound)(clumpId));
+ //REGISTER_CLASS_AND_BASE(Body,Serializable);
+ YADE_CLASS_BASE_ATTRS_PY(Body,Serializable,(id)(groupMask)(isDynamic)(material)(state)(shape)(bound)(clumpId),
+ .def_readwrite("mat",&Body::material)
+ .def_readwrite("dynamic",&Body::isDynamic)
+ .def_readonly("id",&Body::id) // should overwrite def_readwrite("id",...) earlier
+ .def_readwrite("mask",&Body::groupMask)
+ .add_property("isStandalone",&Body::isStandalone)
+ .add_property("isClumpMember",&Body::isClumpMember)
+ .add_property("isClump",&Body::isClump);
+ );
};
REGISTER_SERIALIZABLE(Body);
=== modified file 'core/Cell.hpp'
--- core/Cell.hpp 2009-12-30 17:38:37 +0000
+++ core/Cell.hpp 2010-01-21 07:53:17 +0000
@@ -94,7 +94,7 @@
Real norm=x/sz; period=(int)floor(norm); return (norm-period)*sz;
}
void postProcessAttributes(bool deserializing){ if(deserializing) integrateAndUpdate(0); }
- REGISTER_ATTRIBUTES(Serializable,(refSize)(trsf)(velGrad));
- REGISTER_CLASS_AND_BASE(Cell,Serializable);
+ YADE_CLASS_BASE_ATTRS_PY(Cell,Serializable,(refSize)(trsf)(velGrad),.def_readonly("size",&Cell::getSize_copy));
+ //void pyRegisterClass() const { boost::python::class_<Cell,shared_ptr<Cell>,boost::python::bases<Serializable>,boost::noncopyable>("Cell").def_readwrite("refSize",&Cell::refSize) ; }
};
REGISTER_SERIALIZABLE(Cell);
=== modified file 'core/Material.hpp'
--- core/Material.hpp 2009-12-11 12:37:44 +0000
+++ core/Material.hpp 2010-01-21 07:53:17 +0000
@@ -15,7 +15,7 @@
class Material: public Serializable, public Indexable{
public:
Material(): id(-1), density(1000){ }
- ~Material();
+ virtual ~Material();
//! global id of the material; if >= 0, the material is shared and can be found under this index in Scene::materials
//! (necessary since yade::serialization doesn't track shared pointers)
int id;
@@ -41,8 +41,11 @@
static const shared_ptr<Material> byLabel(const std::string& label, Scene* scene=NULL);
static const shared_ptr<Material> byLabel(const std::string& label, shared_ptr<Scene> scene) {return byLabel(label,scene.get());}
- REGISTER_CLASS_AND_BASE(Material,Serializable);
- REGISTER_ATTRIBUTES(Serializable,(id)(label)(density));
+ //REGISTER_CLASS_AND_BASE(Material,Serializable);
+ //REGISTER_ATTRIBUTES(Serializable,(id)(label)(density));
+ YADE_CLASS_BASE_ATTRS_PY(Material,Serializable,(id)(label)(density),
+ .def("newAssocState",&Material::newAssocState)
+ );
REGISTER_INDEX_COUNTER(Material);
};
REGISTER_SERIALIZABLE(Material);
=== modified file 'core/Omega.cpp'
--- core/Omega.cpp 2009-12-13 19:27:57 +0000
+++ core/Omega.cpp 2010-01-21 07:53:17 +0000
@@ -25,6 +25,7 @@
#include<boost/algorithm/string.hpp>
#include<boost/thread/mutex.hpp>
#include<boost/version.hpp>
+#include<boost/python.hpp>
#include<cxxabi.h>
@@ -139,6 +140,8 @@
void Omega::buildDynlibDatabase(const vector<string>& dynlibsList){
LOG_DEBUG("called with "<<dynlibsList.size()<<" plugins.");
+ boost::python::object wrapperScope=boost::python::import("yade.wrapper");
+ std::list<string> pythonables;
FOREACH(string name, dynlibsList){
shared_ptr<Factorable> f;
try {
@@ -150,12 +153,34 @@
for(int i=0;i<f->getBaseClassNumber();i++){
dynlibs[name].baseClasses.insert(f->getBaseClassName(i));
}
+ if(dynlibs[name].isSerializable) pythonables.push_back(name);
}
catch (FactoryError& e){
/* FIXME: this catches all errors! Some of them are not harmful, however:
* when a class is not factorable, it is OK to skip it; */
}
}
+ // handle Serializable specially
+ Serializable().pyRegisterClass(wrapperScope);
+ /* python classes must be registered such that base classes come before derived ones;
+ for now, just loop until we succeed; proper solution will be to build graphs of classes
+ and traverse it from the top. It will be done once all classes are pythonable. */
+ for(int i=0; i<100; i++){
+ std::list<string> done;
+ for(std::list<string>::iterator I=pythonables.begin(); I!=pythonables.end(); ){
+ shared_ptr<Serializable> s=static_pointer_cast<Serializable>(ClassFactory::instance().createShared(*I));
+ try{
+ s->pyRegisterClass(wrapperScope);
+ //cerr<<"{"<<*I<<"}"<<endl;
+ std::list<string>::iterator prev=I++;
+ pythonables.erase(prev);
+ } catch (boost::python::error_already_set& w){
+ if(getenv("YADE_DEBUG")) cerr<<"["<<*I<<"]";
+ boost::python::handle_exception();
+ I++;
+ }
+ }
+ }
map<string,DynlibDescriptor>::iterator dli = dynlibs.begin();
map<string,DynlibDescriptor>::iterator dliEnd = dynlibs.end();
=== modified file 'core/main/main.py.in'
--- core/main/main.py.in 2010-01-15 09:21:57 +0000
+++ core/main/main.py.in 2010-01-21 07:53:17 +0000
@@ -37,6 +37,7 @@
# other parts we will need soon
import yade.config
import yade.wrapper
+import yade.ww
import yade.log
import yade.system
#import yade.plot
=== modified file 'lib/pyutil/numpy.hpp'
--- lib/pyutil/numpy.hpp 2010-01-01 15:21:30 +0000
+++ lib/pyutil/numpy.hpp 2010-01-21 07:53:17 +0000
@@ -1,5 +1,5 @@
// 2009 © Václav Šmilauer <eudoxos@xxxxxxxx
-
+#pragma once
#include"numpy_boost.hpp"
// helper macro do assign Vector3r values to a subarray
=== modified file 'lib/pyutil/numpy_boost.hpp'
--- lib/pyutil/numpy_boost.hpp 2010-01-01 15:21:30 +0000
+++ lib/pyutil/numpy_boost.hpp 2010-01-21 07:53:17 +0000
@@ -47,7 +47,7 @@
#include <complex>
#include <algorithm>
-namespace detail {
+namespace numpy_boost_detail {
template<class T>
class numpy_type_map {
public:
@@ -143,7 +143,7 @@
{
PyArrayObject* a;
- a = (PyArrayObject*)PyArray_FromObject(obj, detail::numpy_type_map<T>::typenum, NDims, NDims);
+ a = (PyArrayObject*)PyArray_FromObject(obj, numpy_boost_detail::numpy_type_map<T>::typenum, NDims, NDims);
if (a == NULL) {
// TODO: Extract Python exception
throw numpy_boost_exception();
@@ -170,7 +170,7 @@
boost::detail::multi_array::copy_n(extents, NDims, shape);
- a = (PyArrayObject*)PyArray_SimpleNew(NDims, shape, detail::numpy_type_map<T>::typenum);
+ a = (PyArrayObject*)PyArray_SimpleNew(NDims, shape, numpy_boost_detail::numpy_type_map<T>::typenum);
if (a == NULL) {
// TODO: Extract Python exception
throw numpy_boost_exception();
=== added file 'lib/pyutil/raw_constructor.hpp'
--- lib/pyutil/raw_constructor.hpp 1970-01-01 00:00:00 +0000
+++ lib/pyutil/raw_constructor.hpp 2010-01-21 07:53:17 +0000
@@ -0,0 +1,21 @@
+#pragma once
+#include<boost/python.hpp>
+#include<boost/python/raw_function.hpp>
+// many thanks to http://markmail.org/message/s4ksg6nfspw2wxwd
+namespace boost { namespace python { namespace detail {
+ template <class F> struct raw_constructor_dispatcher{
+ raw_constructor_dispatcher(F f): f(make_constructor(f)) {}
+ PyObject* operator()(PyObject* args, PyObject* keywords)
+ {
+ borrowed_reference_t* ra = borrowed_reference(args); object a(ra);
+ return incref(object(f(object(a[0]),object(a.slice(1,len(a))),keywords ? dict(borrowed_reference(keywords)) : dict())).ptr() );
+ }
+ private: object f;
+ };
+ }
+ template <class F> object raw_constructor(F f, std::size_t min_args = 0){
+ return detail::make_raw_function(objects::py_function(detail::raw_constructor_dispatcher<F>(f),mpl::vector2<void, object>(),min_args+1,(std::numeric_limits<unsigned>::max)()));
+ }
+}} // namespace boost::python
+
+
=== modified file 'lib/serialization/Serializable.cpp'
--- lib/serialization/Serializable.cpp 2009-12-25 14:46:48 +0000
+++ lib/serialization/Serializable.cpp 2010-01-21 07:53:17 +0000
@@ -10,6 +10,7 @@
#include "Serializable.hpp"
+
void Serializable::pyUpdateAttrs(const python::dict& d){
python::list l=d.items(); size_t ll=python::len(l);
for(size_t i=0; i<ll; i++){
=== modified file 'lib/serialization/Serializable.hpp'
--- lib/serialization/Serializable.hpp 2009-12-25 14:46:48 +0000
+++ lib/serialization/Serializable.hpp 2010-01-21 07:53:17 +0000
@@ -29,6 +29,7 @@
#include<vector>
#include<iostream>
#include<yade/lib-factory/Factorable.hpp>
+#include<yade/lib-pyutil/raw_constructor.hpp>
#include"SerializationExceptions.hpp"
#include"Archive.hpp"
@@ -84,6 +85,7 @@
#define _PYKEYS_ATTR(x,y,z) ret.append(BOOST_PP_STRINGIZE(z));
#define _PYHASKEY_ATTR(x,y,z) if(key==BOOST_PP_STRINGIZE(z)) return true;
#define _PYDICT_ATTR(x,y,z) ret[BOOST_PP_STRINGIZE(z)]=boost::python::object(z);
+#define _PYCLASS_DEF(x,thisClass,z) .def_readwrite(BOOST_PP_STRINGIZE(z),&thisClass::z)
#define REGISTER_ATTRIBUTES(baseClass,attrs) protected: void registerAttributes(){ baseClass::registerAttributes(); BOOST_PP_SEQ_FOR_EACH(_REGISTER_ATTRIBUTES_REPEAT,~,attrs) } _REGISTER_BOOST_ATTRIBUTES(baseClass,attrs) \
public: boost::python::object pyGetAttr(const std::string& key) const{ BOOST_PP_SEQ_FOR_EACH(_PYGET_ATTR,~,attrs); return baseClass::pyGetAttr(key); } \
@@ -92,6 +94,14 @@
bool pyHasKey(const std::string& key) const { BOOST_PP_SEQ_FOR_EACH(_PYHASKEY_ATTR,~,attrs); return baseClass::pyHasKey(key); } \
boost::python::dict pyDict() const { boost::python::dict ret; BOOST_PP_SEQ_FOR_EACH(_PYDICT_ATTR,~,attrs); ret.update(baseClass::pyDict()); return ret; }
+#define YADE_CLASS_BASE_ATTRS_PY(thisClass,baseClass,attrs,extras) \
+ REGISTER_ATTRIBUTES(baseClass,attrs) \
+ REGISTER_CLASS_AND_BASE(thisClass,baseClass) \
+ virtual void pyRegisterClass(python::object _scope) const { if(getClassName()!=#thisClass) return; boost::python::scope thisScope(_scope); boost::python::class_<thisClass,shared_ptr<thisClass>,boost::python::bases<baseClass>,boost::noncopyable>(#thisClass).def("__init__",python::raw_constructor(Serializable_ctor_kwAttrs<thisClass>)).def("clone",&Serializable_clone<thisClass>,python::arg("attrs")=python::dict()) BOOST_PP_SEQ_FOR_EACH(_PYCLASS_DEF,thisClass,attrs) extras ; }
+
+#define YADE_CLASS_BASE_ATTRS(thisClass,baseClass,attrs) \
+ YADE_CLASS_BASE_ATTRS_PY(thisClass,baseClass,attrs,)
+
// for both fundamental and non-fundamental cases
#define REGISTER_SERIALIZABLE_GENERIC(name,isFundamental) \
@@ -107,6 +117,41 @@
REGISTER_FACTORABLE(sname); \
REGISTER_SERIALIZABLE_DESCRIPTOR(name,sname,SerializableTypes::CUSTOM_CLASS,isFundamental);
+// helper functions
+template <typename T>
+shared_ptr<T> Serializable_ctor_kwAttrs(const python::tuple& t, const python::dict& d){
+ if(python::len(t)>1) throw runtime_error("Zero or one (and not more) non-keyword string argument required");
+ string clss;
+ if(python::len(t)==1){
+ python::extract<string> clss_(t[0]); if(!clss_.check()) throw runtime_error("First argument (if given) must be a string.");
+ clss=clss_();
+ }
+ shared_ptr<T> instance;
+ if(clss.empty()){ instance=shared_ptr<T>(new T); }
+ else{
+ shared_ptr<Factorable> instance0=ClassFactory::instance().createShared(clss);
+ if(!instance0) throw runtime_error("Invalid class `"+clss+"' (not created by ClassFactory).");
+ instance=dynamic_pointer_cast<T>(instance0);
+ if(!instance) throw runtime_error("Invalid class `"+clss+"' (unable to cast to typeid `"+typeid(T).name()+"')");
+ }
+ instance->pyUpdateAttrs(d);
+ return instance;
+}
+
+template <typename T>
+shared_ptr<T> Serializable_clone(const shared_ptr<T>& self, const python::dict& d){
+ shared_ptr<Factorable> inst0=ClassFactory::instance().createShared(self->getClassName());
+ if(!inst0) throw runtime_error("Invalid class `"+self->getClassName()+"' (not created by ClassFactory).");
+ shared_ptr<T> inst=dynamic_pointer_cast<T>(inst0);
+ if(!inst) throw runtime_error("Invalid class `"+self->getClassName()+"' (unable to cast to typeid `"+typeid(T).name()+"')");
+ inst->pyUpdateAttrs(self->pyDict());
+ // if d not empty (how to test that?)
+ inst->pyUpdateAttrs(d);
+ inst->postProcessAttributes(/*deserializing*/true);
+ return inst;
+}
+
+
class Serializable : public Factorable
{
@@ -134,6 +179,19 @@
virtual boost::python::list pyKeys() const {return ::pyKeys(); };
virtual bool pyHasKey(const std::string& key) const {return ::pyHasKey(key);}
virtual boost::python::dict pyDict() const { return ::pyDict(); }
+ virtual void pyRegisterClass(boost::python::object _scope) const {
+ // hack (string comparison), to catch method that is not overridden
+ if(getClassName()!="Serializable"){ if(getenv("YADE_DEBUG")){std::cerr<<"WARN: class "+getClassName()+" did not register with YADE_CLASS_BASE_ATTRS"<<std::endl;} /* throw logic_error("Class "+getClassName()+" did not register with YADE_CLASS_BASE_ATTRS."); */ return; }
+ // called properly
+ boost::python::scope thisScope(_scope);
+ python::class_<Serializable, shared_ptr<Serializable>, noncopyable >("Serializable")
+ .add_property("name",&Serializable::getClassName).def("__str__",&Serializable::pyStr).def("__repr__",&Serializable::pyStr).def("postProcessAttributes",&Serializable::postProcessAttributes,(python::arg("deserializing")=true))
+ .def("dict",&Serializable::pyDict).def("__getitem__",&Serializable::pyGetAttr).def("__setitem__",&Serializable::pySetAttr).def("has_key",&Serializable::pyHasKey).def("keys",&Serializable::pyKeys)
+ .def("updateAttrs",&Serializable::pyUpdateAttrs).def("updateExistingAttrs",&Serializable::pyUpdateExistingAttrs)
+ .def("clone",&Serializable_clone<Serializable>,python::arg("attrs")=python::dict())
+ .def("__init__",python::raw_constructor(Serializable_ctor_kwAttrs<Serializable>))
+ ;
+ }
//! update attributes from dictionary
void pyUpdateAttrs(const boost::python::dict& d);
=== modified file 'pkg/common/DataClass/Material/ElastMat.cpp'
--- pkg/common/DataClass/Material/ElastMat.cpp 2010-01-10 09:09:32 +0000
+++ pkg/common/DataClass/Material/ElastMat.cpp 2010-01-21 07:53:17 +0000
@@ -1,4 +1,5 @@
// 2009 © Václav Šmilauer <eudoxos@xxxxxxxx>
#include<yade/pkg-common/ElastMat.hpp>
+YADE_PLUGIN((ElastMat)(FrictMat));
ElastMat::~ElastMat(){}
FrictMat::~FrictMat(){}
=== modified file 'pkg/common/DataClass/Material/ElastMat.hpp'
--- pkg/common/DataClass/Material/ElastMat.hpp 2010-01-10 09:09:32 +0000
+++ pkg/common/DataClass/Material/ElastMat.hpp 2010-01-21 07:53:17 +0000
@@ -9,8 +9,9 @@
Real poisson;
ElastMat(): young(1e9),poisson(.25) { createIndex(); }
virtual ~ElastMat();
- REGISTER_ATTRIBUTES(Material,(young)(poisson));
- REGISTER_CLASS_AND_BASE(ElastMat,Material);
+ //REGISTER_ATTRIBUTES(Material,(young)(poisson));
+ //REGISTER_CLASS_AND_BASE(ElastMat,Material);
+ YADE_CLASS_BASE_ATTRS(ElastMat,Material,(young)(poisson));
REGISTER_CLASS_INDEX(ElastMat,Material);
};
REGISTER_SERIALIZABLE(ElastMat);
@@ -21,8 +22,9 @@
Real frictionAngle;
FrictMat(): frictionAngle(.5){ createIndex(); }
virtual ~FrictMat();
- REGISTER_ATTRIBUTES(ElastMat,(frictionAngle));
- REGISTER_CLASS_AND_BASE(FrictMat,ElastMat);
+ //REGISTER_ATTRIBUTES(ElastMat,(frictionAngle));
+ //REGISTER_CLASS_AND_BASE(FrictMat,ElastMat);
+ YADE_CLASS_BASE_ATTRS(FrictMat,ElastMat,(frictionAngle));
REGISTER_CLASS_INDEX(FrictMat,ElastMat);
};
REGISTER_SERIALIZABLE(FrictMat);
=== modified file 'pkg/common/Engine/PartialEngine/GravityEngines.hpp'
--- pkg/common/Engine/PartialEngine/GravityEngines.hpp 2009-12-11 18:10:19 +0000
+++ pkg/common/Engine/PartialEngine/GravityEngines.hpp 2010-01-21 07:53:17 +0000
@@ -11,8 +11,7 @@
GravityEngine(): gravity(Vector3r::ZERO){};
virtual ~GravityEngine(){};
virtual void action(Scene*);
- REGISTER_ATTRIBUTES(GlobalEngine,(gravity));
- REGISTER_CLASS_AND_BASE(GravityEngine,GlobalEngine);
+ YADE_CLASS_BASE_ATTRS(GravityEngine,GlobalEngine,(gravity));
};
REGISTER_SERIALIZABLE(GravityEngine);
@@ -32,10 +31,7 @@
CentralGravityEngine(){ reciprocal=false; }
virtual ~CentralGravityEngine(){};
virtual void action(Scene*);
- protected:
- REGISTER_ATTRIBUTES(GlobalEngine,(centralBody)(accel)(reciprocal));
- REGISTER_CLASS_NAME(CentralGravityEngine);
- REGISTER_BASE_CLASS_NAME(GlobalEngine);
+ YADE_CLASS_BASE_ATTRS(CentralGravityEngine,GlobalEngine,(centralBody)(accel)(reciprocal));
};
REGISTER_SERIALIZABLE(CentralGravityEngine);
@@ -53,10 +49,7 @@
AxialGravityEngine(){ }
virtual ~AxialGravityEngine(){};
virtual void action(Scene*);
- protected:
- REGISTER_ATTRIBUTES(GlobalEngine,(axisPoint)(axisDirection)(acceleration));
- REGISTER_CLASS_NAME(AxialGravityEngine);
- REGISTER_BASE_CLASS_NAME(GlobalEngine);
+ YADE_CLASS_BASE_ATTRS(AxialGravityEngine,GlobalEngine,(axisPoint)(axisDirection)(acceleration));
};
REGISTER_SERIALIZABLE(AxialGravityEngine);
=== modified file 'pkg/dem/DataClass/InteractionGeometry/Dem3DofGeom_SphereSphere.cpp'
--- pkg/dem/DataClass/InteractionGeometry/Dem3DofGeom_SphereSphere.cpp 2009-12-19 07:16:06 +0000
+++ pkg/dem/DataClass/InteractionGeometry/Dem3DofGeom_SphereSphere.cpp 2010-01-21 07:53:17 +0000
@@ -2,11 +2,11 @@
#include<yade/pkg-common/Sphere.hpp>
#include<yade/core/Omega.hpp>
-YADE_PLUGIN((Dem3DofGeom_SphereSphere)
+YADE_PLUGIN((Dem3DofGeom_SphereSphere)(Dem6DofGeom_SphereSphere)
#ifdef YADE_OPENGL
(Gl1_Dem3DofGeom_SphereSphere)
#endif
- (Ig2_Sphere_Sphere_Dem3DofGeom));
+ (Ig2_Sphere_Sphere_Dem3DofGeom)(Ig2_Sphere_Sphere_Dem6DofGeom));
Dem3DofGeom_SphereSphere::~Dem3DofGeom_SphereSphere(){}
@@ -92,6 +92,27 @@
}
}
+
+Dem6DofGeom_SphereSphere::~Dem6DofGeom_SphereSphere(){}
+
+Vector3r Dem6DofGeom_SphereSphere::relRotVector() const{
+ // FIXME: this is not correct, as it assumes normal will not change (?)
+ Quaternionr relOri12=ori1.Conjugate()*ori2;
+ Quaternionr oriDiff=initRelOri12.Conjugate()*relOri12;
+ Vector3r axis; Real angle;
+ oriDiff.ToAxisAngle(axis,angle);
+ if(angle>Mathr::PI)angle-=Mathr::TWO_PI;
+ // cerr<<axis<<";"<<angle<<";"<<ori1<<";"<<ori2<<";"<<oriDiff<<endl;
+ return angle*axis;
+}
+
+void Dem6DofGeom_SphereSphere::bendTwistAbs(Vector3r& bend, Real& twist){
+ const Vector3r& relRot=relRotVector();
+ twist=relRot.Dot(normal);
+ bend=relRot-twist*normal;
+}
+
+
#ifdef YADE_OPENGL
#include<yade/lib-opengl/OpenGLWrapper.hpp>
#include<yade/lib-opengl/GLUtils.hpp>
@@ -146,9 +167,10 @@
}
}
}
- CREATE_LOGGER(Ig2_Sphere_Sphere_Dem3DofGeom);
#endif
+CREATE_LOGGER(Ig2_Sphere_Sphere_Dem3DofGeom);
+
bool Ig2_Sphere_Sphere_Dem3DofGeom::go(const shared_ptr<Shape>& cm1, const shared_ptr<Shape>& cm2, const State& state1, const State& state2, const Vector3r& shift2, const bool& force, const shared_ptr<Interaction>& c){
Sphere *s1=static_cast<Sphere*>(cm1.get()), *s2=static_cast<Sphere*>(cm2.get());
Vector3r normal=(state2.pos+shift2)-state1.pos;
@@ -183,3 +205,19 @@
return true;
}
+CREATE_LOGGER(Ig2_Sphere_Sphere_Dem6DofGeom);
+bool Ig2_Sphere_Sphere_Dem6DofGeom::go(const shared_ptr<Shape>& cm1, const shared_ptr<Shape>& cm2, const State& state1, const State& state2, const Vector3r& shift2, const bool& force, const shared_ptr<Interaction>& c){
+ bool hadIntrGeom=c->interactionGeometry;
+ if(!Ig2_Sphere_Sphere_Dem3DofGeom::go(cm1,cm2,state1,state2,shift2,force,c)) return false;
+ // HACK: dem3dof functor creates a dem3dof instance; we need to copy-construct dem6dof from it instead
+ // proper solution would be to factor out the computation part from the dem3dof to separate functions and call those from here, or make the dem3dof functor templated on the dem3dof/dem6dof
+ if(!hadIntrGeom){
+ assert(c->interactionGeometry);
+ assert(c->interactionGeometry->getClassName()=="Dem3DofGeom_SphereSphere");
+ const shared_ptr<Dem6DofGeom_SphereSphere> geom(new Dem6DofGeom_SphereSphere(*YADE_CAST<Dem3DofGeom_SphereSphere*>(c->interactionGeometry.get())));
+ geom->initRelOri12=state1.ori.Conjugate()*state2.ori;
+ c->interactionGeometry=geom;
+ //TRVAR3(geom->refLength,geom->contactPoint,geom->initRelOri12)
+ }
+ return true;
+}
=== modified file 'pkg/dem/DataClass/InteractionGeometry/Dem3DofGeom_SphereSphere.hpp'
--- pkg/dem/DataClass/InteractionGeometry/Dem3DofGeom_SphereSphere.hpp 2009-12-19 07:16:06 +0000
+++ pkg/dem/DataClass/InteractionGeometry/Dem3DofGeom_SphereSphere.hpp 2010-01-21 07:53:17 +0000
@@ -43,6 +43,22 @@
};
REGISTER_SERIALIZABLE(Dem3DofGeom_SphereSphere);
+class Dem6DofGeom_SphereSphere: public Dem3DofGeom_SphereSphere{
+ public:
+ // initial relative orientation, used for bending and twist computation
+ Quaternionr initRelOri12;
+ // return relative rotation, composed of both bend and twist
+ Vector3r relRotVector() const;
+ virtual void bendTwistAbs(Vector3r& bend, Real& twist);
+ virtual ~Dem6DofGeom_SphereSphere();
+ Dem6DofGeom_SphereSphere(const Dem3DofGeom_SphereSphere& ss): Dem3DofGeom_SphereSphere(ss){ createIndex(); }
+ Dem6DofGeom_SphereSphere(){ createIndex(); }
+ REGISTER_ATTRIBUTES(Dem3DofGeom_SphereSphere,(initRelOri12));
+ REGISTER_CLASS_AND_BASE(Dem6DofGeom_SphereSphere,Dem3DofGeom_SphereSphere);
+ REGISTER_CLASS_INDEX(Dem6DofGeom_SphereSphere,Dem3DofGeom_SphereSphere);
+};
+REGISTER_SERIALIZABLE(Dem6DofGeom_SphereSphere);
+
#ifdef YADE_OPENGL
#include<yade/pkg-common/GLDrawFunctors.hpp>
class Gl1_Dem3DofGeom_SphereSphere:public GlInteractionGeometryFunctor{
@@ -73,3 +89,14 @@
};
REGISTER_SERIALIZABLE(Ig2_Sphere_Sphere_Dem3DofGeom);
+class Ig2_Sphere_Sphere_Dem6DofGeom: public Ig2_Sphere_Sphere_Dem3DofGeom{
+ public:
+ virtual bool go(const shared_ptr<Shape>& cm1, const shared_ptr<Shape>& cm2, const State& state1, const State& state2, const Vector3r& shift2, const bool& force, const shared_ptr<Interaction>& c);
+ virtual bool goReverse( const shared_ptr<Shape>&, const shared_ptr<Shape>&, const State&, const State&, const Vector3r& shift2, const bool& force, const shared_ptr<Interaction>&){throw runtime_error("goReverse on symmetric functor should never be called!");}
+ FUNCTOR2D(Sphere,Sphere);
+ DEFINE_FUNCTOR_ORDER_2D(Sphere,Sphere);
+ REGISTER_CLASS_AND_BASE(Ig2_Sphere_Sphere_Dem6DofGeom,Ig2_Sphere_Sphere_Dem3DofGeom);
+ REGISTER_ATTRIBUTES(Ig2_Sphere_Sphere_Dem3DofGeom,/* no attrs */);
+ DECLARE_LOGGER;
+};
+REGISTER_SERIALIZABLE(Ig2_Sphere_Sphere_Dem6DofGeom);
=== modified file 'pkg/dem/DataClass/InteractionGeometry/DemXDofGeom.cpp'
--- pkg/dem/DataClass/InteractionGeometry/DemXDofGeom.cpp 2009-11-21 12:46:54 +0000
+++ pkg/dem/DataClass/InteractionGeometry/DemXDofGeom.cpp 2010-01-21 07:53:17 +0000
@@ -1,5 +1,6 @@
#include"DemXDofGeom.hpp"
-YADE_PLUGIN((Dem3DofGeom));
+YADE_PLUGIN((Dem3DofGeom)(Dem6DofGeom));
Real Dem3DofGeom::displacementN(){throw;}
Dem3DofGeom::~Dem3DofGeom(){}
+Dem6DofGeom::~Dem6DofGeom(){}
GenericSpheresContact::~GenericSpheresContact(){}
=== modified file 'pkg/dem/DataClass/InteractionGeometry/DemXDofGeom.hpp'
--- pkg/dem/DataClass/InteractionGeometry/DemXDofGeom.hpp 2009-12-13 20:11:31 +0000
+++ pkg/dem/DataClass/InteractionGeometry/DemXDofGeom.hpp 2010-01-21 07:53:17 +0000
@@ -56,13 +56,14 @@
};
REGISTER_SERIALIZABLE(Dem3DofGeom);
-#if 0
+#if 1
/*! Abstract class for providing torsion and bending, in addition to inherited normal and shear strains. */
class Dem6DofGeom: public Dem3DofGeom {
public:
//! rotations perpendicular to the normal (bending; in global coords) and parallel with the normal (torsion)
- void bendingTorsionAbs(Vector3r& bend, Real& tors)=0;
- void bendingTorsionRel(Vector3r& bend, Real& tors){ bendingTorsionAbs(bend,tors); bend/=refLength; tors/=refLength;}
+ virtual void bendTwistAbs(Vector3r& bend, Real& twist) {throw std::logic_error("bendTwistAbs not overridden in derived class.");};
+ void bendTwistRel(Vector3r& bend, Real& twist){ bendTwistAbs(bend,twist); bend/=refLength; twist/=refLength;}
+ virtual ~Dem6DofGeom();
REGISTER_CLASS_AND_BASE(Dem6DofGeom,Dem3DofGeom);
REGISTER_ATTRIBUTES(Dem3DofGeom, /*nothing*/);
};
=== modified file 'pkg/dem/Engine/GlobalEngine/ElasticContactLaw.cpp'
--- pkg/dem/Engine/GlobalEngine/ElasticContactLaw.cpp 2010-01-10 09:09:32 +0000
+++ pkg/dem/Engine/GlobalEngine/ElasticContactLaw.cpp 2010-01-21 07:53:17 +0000
@@ -14,7 +14,7 @@
#include<yade/core/Scene.hpp>
#include<yade/core/Scene.hpp>
-YADE_PLUGIN((Law2_ScGeom_FrictPhys_Basic)(Law2_Dem3DofGeom_FrictPhys_Basic)(ElasticContactLaw));
+YADE_PLUGIN((Law2_ScGeom_FrictPhys_Basic)(Law2_Dem3DofGeom_FrictPhys_Basic)(ElasticContactLaw)(Law2_Dem6DofGeom_FrictPhys_Beam));
ElasticContactLaw::ElasticContactLaw() : InteractionSolver()
{
@@ -109,15 +109,33 @@
}
// same as elasticContactLaw, but using Dem3DofGeom
-void Law2_Dem3DofGeom_FrictPhys_Basic::go(shared_ptr<InteractionGeometry>& ig, shared_ptr<InteractionPhysics>& ip, Interaction* contact, Scene* rootBody){
+void Law2_Dem3DofGeom_FrictPhys_Basic::go(shared_ptr<InteractionGeometry>& ig, shared_ptr<InteractionPhysics>& ip, Interaction* contact, Scene*){
Dem3DofGeom* geom=static_cast<Dem3DofGeom*>(ig.get());
FrictPhys* phys=static_cast<FrictPhys*>(ip.get());
Real displN=geom->displacementN();
- if(displN>0){ rootBody->interactions->requestErase(contact->getId1(),contact->getId2()); return; }
+ if(displN>0){ scene->interactions->requestErase(contact->getId1(),contact->getId2()); return; }
phys->normalForce=phys->kn*displN*geom->normal;
Real maxFsSq=phys->normalForce.SquaredLength()*pow(phys->tangensOfFrictionAngle,2);
Vector3r trialFs=phys->ks*geom->displacementT();
if(trialFs.SquaredLength()>maxFsSq){ geom->slipToDisplacementTMax(sqrt(maxFsSq)); trialFs*=sqrt(maxFsSq/(trialFs.SquaredLength()));}
phys->shearForce=trialFs;
- applyForceAtContactPoint(phys->normalForce+trialFs,geom->contactPoint,contact->getId1(),geom->se31.position,contact->getId2(),geom->se32.position,rootBody);
+ applyForceAtContactPoint(phys->normalForce+trialFs,geom->contactPoint,contact->getId1(),geom->se31.position,contact->getId2(),geom->se32.position,scene);
+}
+
+// same as elasticContactLaw, but using Dem3DofGeom
+void Law2_Dem6DofGeom_FrictPhys_Beam::go(shared_ptr<InteractionGeometry>& ig, shared_ptr<InteractionPhysics>& ip, Interaction* contact, Scene* scene){
+ // normal & shear forces
+ Dem6DofGeom* geom=static_cast<Dem6DofGeom*>(ig.get());
+ FrictPhys* phys=static_cast<FrictPhys*>(ip.get());
+ Real displN=geom->displacementN();
+ phys->normalForce=phys->kn*displN*geom->normal;
+ phys->shearForce=phys->ks*geom->displacementT();
+ applyForceAtContactPoint(phys->normalForce+phys->shearForce,geom->contactPoint,contact->getId1(),geom->se31.position,contact->getId2(),geom->se32.position,scene);
+ // bend&twist:
+ Vector3r bend; Real twist;
+ geom->bendTwistAbs(bend,twist);
+ Vector3r tt=bend*phys->kn+geom->normal*twist*phys->kn;
+ cerr<<twist<<";"<<bend<<endl;
+ scene->forces.addTorque(contact->getId1(),tt);
+ scene->forces.addTorque(contact->getId2(),-tt);
}
=== modified file 'pkg/dem/Engine/GlobalEngine/ElasticContactLaw.hpp'
--- pkg/dem/Engine/GlobalEngine/ElasticContactLaw.hpp 2010-01-10 09:09:32 +0000
+++ pkg/dem/Engine/GlobalEngine/ElasticContactLaw.hpp 2010-01-21 07:53:17 +0000
@@ -53,13 +53,23 @@
*/
class Law2_Dem3DofGeom_FrictPhys_Basic: public LawFunctor{
public:
- virtual void go(shared_ptr<InteractionGeometry>& _geom, shared_ptr<InteractionPhysics>& _phys, Interaction* I, Scene* rootBody);
+ virtual void go(shared_ptr<InteractionGeometry>& _geom, shared_ptr<InteractionPhysics>& _phys, Interaction* I, Scene*);
FUNCTOR2D(Dem3DofGeom,FrictPhys);
REGISTER_CLASS_AND_BASE(Law2_Dem3DofGeom_FrictPhys_Basic,LawFunctor);
REGISTER_ATTRIBUTES(LawFunctor,/*nothing here*/);
};
REGISTER_SERIALIZABLE(Law2_Dem3DofGeom_FrictPhys_Basic);
+/* Class for demonstrating beam-like behavior of the contact (normal, shear, bend and twist) */
+class Law2_Dem6DofGeom_FrictPhys_Beam: public LawFunctor{
+ public:
+ virtual void go(shared_ptr<InteractionGeometry>& _geom, shared_ptr<InteractionPhysics>& _phys, Interaction* I, Scene*);
+ FUNCTOR2D(Dem6DofGeom,FrictPhys);
+ REGISTER_CLASS_AND_BASE(Law2_Dem6DofGeom_FrictPhys_Beam,LawFunctor);
+ REGISTER_ATTRIBUTES(LawFunctor,/*nothing here*/);
+};
+REGISTER_SERIALIZABLE(Law2_Dem6DofGeom_FrictPhys_Beam);
+
class ElasticContactLaw : public InteractionSolver
{
/// Attributes
=== modified file 'pkg/dem/Engine/GlobalEngine/MicroMacroAnalyser.cpp'
--- pkg/dem/Engine/GlobalEngine/MicroMacroAnalyser.cpp 2010-01-16 14:54:28 +0000
+++ pkg/dem/Engine/GlobalEngine/MicroMacroAnalyser.cpp 2010-01-21 07:53:17 +0000
@@ -14,7 +14,6 @@
#include<yade/core/Scene.hpp>
#include <yade/pkg-common/Sphere.hpp>
#include "MicroMacroAnalyser.hpp"
-#include<yade/pkg-dem/TesselationWrapper.hpp>
#include<yade/lib-triangulation/KinematicLocalisationAnalyser.hpp>
#include<yade/lib-triangulation/TriaxialState.h>
#include <yade/lib-triangulation/Tenseur3.h>
=== modified file 'pkg/dem/Engine/GlobalEngine/TesselationWrapper.cpp'
--- pkg/dem/Engine/GlobalEngine/TesselationWrapper.cpp 2010-01-16 14:54:28 +0000
+++ pkg/dem/Engine/GlobalEngine/TesselationWrapper.cpp 2010-01-21 07:53:17 +0000
@@ -7,7 +7,7 @@
*************************************************************************/
///FIXME : this include breaks compilation, see commented "numpy" code at the end of the file
-//#include<yade/lib-pyutil/numpy.hpp>
+#include<yade/lib-pyutil/numpy.hpp>
//#include "CGAL/constructions/constructions_on_weighted_points_cartesian_3.h"
//#include<yade/lib-triangulation/KinematicLocalisationAnalyser.hpp>
@@ -392,26 +392,26 @@
int dim1[]={bodiesDim};
int dim2[]={bodiesDim,9};
/// This is the code that needs numpy include
- //numpy_boost<body_id_t,1> id(dim1);
-// boost::python::numpy_boost<double,1> vol(dim1);
-// boost::python::numpy_boost<double,1> poro(dim1);
-// boost::python::numpy_boost<double,2> def(dim2);
-// //FOREACH(const shared_ptr<Body>& b, *scene->bodies){
-// for (CGT::RTriangulation::Finite_vertices_iterator V_it = Tri.finite_vertices_begin(); V_it != Tri.finite_vertices_end(); V_it++) {
-// id[]=V_it->info().id()
-// //if(!b) continue;
-// const body_id_t id = V_it->info().id();
-// Real sphereVol = 4.188790 * std::pow ( ( V_it->point().weight() ),1.5 );// 4/3*PI*R³ = 4.188...*R³
-// vol[id]=V_it->info().v();
-// poro[id]=(V_it->info().v() - sphereVol)/V_it->info().v();
-// //if (deformation) MATRIX3R_TO_NUMPY(def[id],ParticleDeformation[id]);
-// cerr << V_it->info().v()<<" "<<ParticleDeformation[id]<<endl;
-// }
-// python::dict ret;
-// ret["vol"]=vol;
-// ret["poro"]=poro;
-// if (deformation) ret["def"]=def;
-// return ret;
+ numpy_boost<body_id_t,1> id(dim1);
+ numpy_boost<double,1> vol(dim1);
+ numpy_boost<double,1> poro(dim1);
+ numpy_boost<double,2> def(dim2);
+ //FOREACH(const shared_ptr<Body>& b, *scene->bodies){
+ for (CGT::RTriangulation::Finite_vertices_iterator V_it = Tri.finite_vertices_begin(); V_it != Tri.finite_vertices_end(); V_it++) {
+ //id[]=V_it->info().id()
+ //if(!b) continue;
+ const body_id_t id = V_it->info().id();
+ Real sphereVol = 4.188790 * std::pow ( ( V_it->point().weight() ),1.5 );// 4/3*PI*R³ = 4.188...*R³
+ vol[id]=V_it->info().v();
+ poro[id]=(V_it->info().v() - sphereVol)/V_it->info().v();
+ //if (deformation) MATRIX3R_TO_NUMPY(def[id],ParticleDeformation[id]);
+ //cerr << V_it->info().v()<<" "<<ParticleDeformation[id]<<endl;
+ }
+ python::dict ret;
+ ret["vol"]=vol;
+ ret["poro"]=poro;
+ if (deformation) ret["def"]=def;
+ return ret;
}
/// Needed somewhere?
=== modified file 'pkg/dem/Engine/GlobalEngine/TesselationWrapper.hpp'
--- pkg/dem/Engine/GlobalEngine/TesselationWrapper.hpp 2010-01-16 14:54:28 +0000
+++ pkg/dem/Engine/GlobalEngine/TesselationWrapper.hpp 2010-01-21 07:53:17 +0000
@@ -14,7 +14,7 @@
#include<yade/lib-triangulation/Tesselation.h>
//#include<yade/lib-pyutil/numpy.hpp>
#include<boost/python.hpp>
-#include"MicroMacroAnalyser.hpp"
+#include<yade/pkg-dem/MicroMacroAnalyser.hpp>
#include<yade/extra/boost_python_len.hpp>
/*! \class TesselationWrapper
=== modified file 'pkg/dem/meta/ConcretePM.hpp'
--- pkg/dem/meta/ConcretePM.hpp 2010-01-10 09:09:32 +0000
+++ pkg/dem/meta/ConcretePM.hpp 2010-01-21 07:53:17 +0000
@@ -98,8 +98,9 @@
};
virtual shared_ptr<State> newAssocState() const { return shared_ptr<State>(new CpmState); }
virtual bool stateTypeOk(State* s) const { return (bool)dynamic_cast<CpmState*>(s); }
- REGISTER_ATTRIBUTES(FrictMat,(G_over_E)(sigmaT)(neverDamage)(epsCrackOnset)(relDuctility)(dmgTau)(dmgRateExp)(plTau)(plRateExp)(isoPrestress));
- REGISTER_CLASS_AND_BASE(CpmMat,FrictMat);
+ //REGISTER_ATTRIBUTES(FrictMat,(G_over_E)(sigmaT)(neverDamage)(epsCrackOnset)(relDuctility)(dmgTau)(dmgRateExp)(plTau)(plRateExp)(isoPrestress));
+ //REGISTER_CLASS_AND_BASE(CpmMat,FrictMat);
+ YADE_CLASS_BASE_ATTRS(CpmMat,FrictMat,(G_over_E)(sigmaT)(neverDamage)(epsCrackOnset)(relDuctility)(dmgTau)(dmgRateExp)(plTau)(plRateExp)(isoPrestress));
REGISTER_CLASS_INDEX(CpmMat,FrictMat);
};
REGISTER_SERIALIZABLE(CpmMat);
=== modified file 'py/SConscript'
--- py/SConscript 2009-12-13 20:30:13 +0000
+++ py/SConscript 2010-01-21 07:53:17 +0000
@@ -33,8 +33,9 @@
env.File('system.py'),
env.File('export.py'),
env.File('post2d.py'),
+ env.File('ww.py'),
env.SharedLibrary('wrapper',['yadeWrapper/yadeWrapper.cpp'],SHLIBPREFIX='',LIBS=['PythonUI']+linkPlugins(['Shop','BoundDispatcher','InteractionGeometryDispatcher','InteractionPhysicsDispatcher','LawDispatcher','InteractionDispatchers','ParallelEngine','Clump','STLImporter',]+(['GeometricalModelMetaEngine','InteractingGeometryMetaEngine',] if 'geometricalmodel' in env['features'] else [])+(['StateMetaEngine',] if 'physpar' in env['features'] else []))),
- env.SharedLibrary('_customConverters',['yadeWrapper/customConverters.cpp'],SHLIBPREFIX='',LIBS=env['LIBS']+linkPlugins(Split("BoundFunctor InteractionGeometryFunctor InteractionPhysicsFunctor LawFunctor")+(['GeometricalModelEngineUnit','InteractingGeometryEngineUnit'] if 'geometricalmodel' in env['features'] else [])+(['PhysicalActionDamperUnit','PhysicalActionApplierUnit','StateEngineUnit'] if 'physpar' in env['features'] else [])))
+ env.SharedLibrary('_customConverters',['yadeWrapper/customConverters.cpp'],SHLIBPREFIX='',LIBS=env['LIBS']+linkPlugins(Split("BoundFunctor InteractionGeometryFunctor InteractionPhysicsFunctor LawFunctor")))
])
env.Install('$PREFIX/lib/yade$SUFFIX/py/yade/tests',[
env.File('__init__.py','tests'),
=== modified file 'py/system.py'
--- py/system.py 2010-01-10 09:09:32 +0000
+++ py/system.py 2010-01-21 07:53:17 +0000
@@ -126,12 +126,14 @@
except KeyError:
print 'WARNING: class %s not defined'%root
for p in childClasses(root):
+ if proxyNamespace.has_key(p): continue
proxyNamespace[p]=type(p,(rootType,),{'__init__': lambda self,__subType_=p,*args,**kw: super(type(self),self).__init__(__subType_,*args,**kw)})
_proxiedClasses.add(p)
# inject wrapped class itself into proxyNamespace
proxyNamespace[root]=rootType
# classes that derive just from Serializable: the remaining ones
for p in _allSerializables-_proxiedClasses-_pyRootClasses:
+ if proxyNamespace.has_key(p): continue
proxyNamespace[p]=type(p,(wrapper.Serializable,),{'__init__': lambda self,__subType_=p,*args,**kw: super(type(self),self).__init__(__subType_,*args,**kw)})
# deprecated names
for oldName in _deprecated.keys():
=== modified file 'py/yadeWrapper/yadeWrapper.cpp'
--- py/yadeWrapper/yadeWrapper.cpp 2010-01-15 09:21:57 +0000
+++ py/yadeWrapper/yadeWrapper.cpp 2010-01-21 07:53:17 +0000
@@ -26,6 +26,7 @@
#include<yade/lib-base/Logging.hpp>
#include<yade/lib-serialization-xml/XMLFormatManager.hpp>
#include<yade/lib-pyutil/gil.hpp>
+#include<yade/lib-pyutil/raw_constructor.hpp>
#include<yade/core/Omega.hpp>
#include<yade/core/ThreadRunner.hpp>
#include<yade/core/FileGenerator.hpp>
@@ -54,6 +55,7 @@
#include<yade/pkg-dem/Shop.hpp>
#include<yade/pkg-dem/Clump.hpp>
+
using namespace boost;
using namespace std;
@@ -281,7 +283,7 @@
try { return Material::byLabel(label,scene); }
catch (std::runtime_error& e){ PyErr_SetString(PyExc_KeyError,e.what()); python::throw_error_already_set(); /* never reached; avoids warning */ throw; }
}
- int append(shared_ptr<Material>& m){ scene->materials.push_back(m); m->id=scene->materials.size()-1; return m->id; }
+ int append(shared_ptr<Material> m){ scene->materials.push_back(m); m->id=scene->materials.size()-1; return m->id; }
vector<int> appendList(vector<shared_ptr<Material> > mm){ vector<int> ret; FOREACH(shared_ptr<Material>& m, mm) ret.push_back(append(m)); return ret; }
int len(){ return (int)scene->materials.size(); }
};
@@ -556,39 +558,6 @@
return instance;
}
-template <typename T>
-shared_ptr<T> Serializable_ctor_kwAttrs(const python::tuple& t, const python::dict& d){
- if(python::len(t)>1) throw runtime_error("Zero or one (and not more) non-keyword string argument required");
- string clss;
- if(python::len(t)==1){
- python::extract<string> clss_(t[0]); if(!clss_.check()) throw runtime_error("First argument (if given) must be a string.");
- clss=clss_();
- }
- shared_ptr<T> instance;
- if(clss.empty()){ instance=shared_ptr<T>(new T); }
- else{
- shared_ptr<Factorable> instance0=ClassFactory::instance().createShared(clss);
- if(!instance0) throw runtime_error("Invalid class `"+clss+"' (not created by ClassFactory).");
- instance=dynamic_pointer_cast<T>(instance0);
- if(!instance) throw runtime_error("Invalid class `"+clss+"' (unable to cast to typeid `"+typeid(T).name()+"')");
- }
- instance->pyUpdateAttrs(d);
- return instance;
-}
-
-template <typename T>
-shared_ptr<T> Serializable_clone(const shared_ptr<T>& self, const python::dict& d){
- shared_ptr<Factorable> inst0=ClassFactory::instance().createShared(self->getClassName());
- if(!inst0) throw runtime_error("Invalid class `"+self->getClassName()+"' (not created by ClassFactory).");
- shared_ptr<T> inst=dynamic_pointer_cast<T>(inst0);
- if(!inst) throw runtime_error("Invalid class `"+self->getClassName()+"' (unable to cast to typeid `"+typeid(T).name()+"')");
- inst->pyUpdateAttrs(self->pyDict());
- // if d not empty (how to test that?)
- inst->pyUpdateAttrs(d);
- inst->postProcessAttributes(/*deserializing*/true);
- return inst;
-}
-
// stupid; Dispatcher is not a template, hence converting this into a real constructor would be complicated; keep it here.
template<typename DispatcherT>
shared_ptr<DispatcherT> Dispatcher_ctor_list(const std::vector<shared_ptr<typename DispatcherT::functorType> >& functors){
@@ -632,23 +601,6 @@
void FileGenerator_generate(const shared_ptr<FileGenerator>& fg, string outFile){ fg->setFileName(outFile); fg->setSerializationLibrary("XMLFormatManager"); bool ret=fg->generateAndSave(); LOG_INFO((ret?"SUCCESS:\n":"FAILURE:\n")<<fg->message); if(ret==false) throw runtime_error("Generator reported error: "+fg->message); };
void FileGenerator_load(const shared_ptr<FileGenerator>& fg){ string xml(Omega::instance().tmpFilename()+".xml.bz2"); LOG_DEBUG("Using temp file "<<xml); FileGenerator_generate(fg,xml); pyOmega().load(xml); }
-// many thanks to http://markmail.org/message/s4ksg6nfspw2wxwd
-namespace boost { namespace python { namespace detail {
- template <class F> struct raw_constructor_dispatcher{
- raw_constructor_dispatcher(F f): f(make_constructor(f)) {}
- PyObject* operator()(PyObject* args, PyObject* keywords)
- {
- borrowed_reference_t* ra = borrowed_reference(args); object a(ra);
- return incref(object(f(object(a[0]),object(a.slice(1,len(a))),keywords ? dict(borrowed_reference(keywords)) : dict())).ptr() );
- }
- private: object f;
- };
- }
- template <class F> object raw_constructor(F f, std::size_t min_args = 0){
- return detail::make_raw_function(objects::py_function(detail::raw_constructor_dispatcher<F>(f),mpl::vector2<void, object>(),min_args+1,(std::numeric_limits<unsigned>::max)()));
- }
-}} // namespace boost::python
-
BOOST_PYTHON_MODULE(wrapper)
{
python::scope().attr("__doc__")="Wrapper for c++ internals of yade.";
@@ -760,7 +712,8 @@
//////////////////////////////////////////////////////////////
///////////// proxyless wrappers
-
+ Serializable().pyRegisterClass(python::scope());
+#if 0
python::class_<Serializable, shared_ptr<Serializable>, noncopyable >("Serializable")
.add_property("name",&Serializable::getClassName).def("__str__",&Serializable::pyStr).def("__repr__",&Serializable::pyStr).def("postProcessAttributes",&Serializable::postProcessAttributes,(python::arg("deserializing")=true))
.def("dict",&Serializable::pyDict).def("__getitem__",&Serializable::pyGetAttr).def("__setitem__",&Serializable::pySetAttr).def("has_key",&Serializable::pyHasKey).def("keys",&Serializable::pyKeys)
@@ -770,6 +723,7 @@
// aliases for __getitem__ and __setitem__, but they are used by the property generator code and can be useful if we deprecate the object['attr'] type of access
.def("_prop_get",&Serializable::pyGetAttr).def("_prop_set",&Serializable::pySetAttr)
;
+#endif
python::class_<Engine, shared_ptr<Engine>, python::bases<Serializable>, noncopyable >("Engine",python::no_init)
.add_property("execTime",&Engine_timingInfo_nsec_get,&Engine_timingInfo_nsec_set)
.add_property("execCount",&Engine_timingInfo_nExec_get,&Engine_timingInfo_nExec_set)
@@ -782,7 +736,7 @@
.add_property("bases",&Functor::getFunctorTypes);
python::class_<Dispatcher, shared_ptr<Dispatcher>, python::bases<Engine>, noncopyable>("Dispatcher",python::no_init);
python::class_<TimingDeltas, shared_ptr<TimingDeltas>, noncopyable >("TimingDeltas").add_property("data",&TimingDeltas::pyData).def("reset",&TimingDeltas::reset);
-
+#if 0
python::class_<Cell,shared_ptr<Cell>, python::bases<Serializable>, noncopyable>("Cell",python::no_init)
.def_readwrite("refSize",&Cell::refSize)
.def_readwrite("trsf",&Cell::trsf)
@@ -791,7 +745,7 @@
//.def_readwrite("Hsize",&Cell::Hsize)
//.add_property("size",&Cell::getSize,python::return_value_policy<python::return_internal_referece>()
;
-
+#endif
python::class_<InteractionDispatchers,shared_ptr<InteractionDispatchers>, python::bases<Engine>, noncopyable >("InteractionDispatchers")
.def("__init__",python::make_constructor(InteractionDispatchers_ctor_lists))
.def_readonly("geomDispatcher",&InteractionDispatchers::geomDispatcher)
@@ -820,6 +774,7 @@
// expose indexable class, with access to the index
#define EXPOSE_CXX_CLASS_IX(className) EXPOSE_CXX_CLASS(className).add_property("dispIndex",&Indexable_getClassIndex<className>,"Return class index of this instance.").def("dispHierarchy",&Indexable_getClassIndices<className>,(python::arg("names")=true),"Return list of dispatch classes (from down upwards), starting with the class instance itself, top-level indexable at last. If names is true (default), return class names rather than numerical indices.")
+#if 0
EXPOSE_CXX_CLASS(Body)
// mold and geom are deprecated:
.add_property("mold",&Body_shape_deprec_get,&Body_shape_deprec_set)
@@ -834,14 +789,17 @@
.add_property("isStandalone",&Body::isStandalone)
.add_property("isClumpMember",&Body::isClumpMember)
.add_property("isClump",&Body::isClump);
+#endif
EXPOSE_CXX_CLASS_IX(Shape);
EXPOSE_CXX_CLASS_IX(Bound)
.def_readonly("min",&Bound::min)
.def_readonly("max",&Bound::max);
+#if 0
EXPOSE_CXX_CLASS_IX(Material)
.def_readwrite("label",&Material::label)
.def("newAssocState",&Material::newAssocState)
;
+#endif
EXPOSE_CXX_CLASS(State)
.add_property("blockedDOFs",&State::blockedDOFs_vec_get,&State::blockedDOFs_vec_set)
.add_property("pos",&State::pos_get,&State::pos_set)