← Back to team overview

yade-dev team mailing list archive

[Branch ~yade-pkg/yade/git-trunk] Rev 4028: added mask_t type for bitmask variables to be int or optionally std::bitset of fixed (yet arbitra...

 

------------------------------------------------------------
revno: 4028
committer: Jan Stransky <jan.stransky@xxxxxxxxxxx>
timestamp: Tue 2014-06-17 12:18:00 +0200
message:
  added mask_t type for bitmask variables to be int or optionally std::bitset of fixed (yet arbitrary) size. Added bitset to/from python long conversion. Added MASK_ARBITRARY cmake option. Subsequent changes in other files
modified:
  CMakeLists.txt
  core/Body.cpp
  core/Body.hpp
  lib/base/Math.cpp
  lib/base/Math.hpp
  pkg/dem/CapillaryTriaxialTest.cpp
  pkg/dem/CohesiveTriaxialTest.cpp
  pkg/dem/SimpleShear.cpp
  pkg/dem/SpheresFactory.cpp
  pkg/dem/TesselationWrapper.cpp
  pkg/dem/TriaxialTest.cpp
  pkg/dem/VTKRecorder.cpp
  py/wrapper/customConverters.cpp


--
lp:yade
https://code.launchpad.net/~yade-pkg/yade/git-trunk

Your team Yade developers is subscribed to branch lp:yade.
To unsubscribe from this branch go to https://code.launchpad.net/~yade-pkg/yade/git-trunk/+edit-subscription
=== modified file 'CMakeLists.txt'
--- CMakeLists.txt	2014-06-11 12:20:23 +0000
+++ CMakeLists.txt	2014-06-17 10:18:00 +0000
@@ -17,6 +17,7 @@
 #  ENABLE_SPH: enable SPH-option, Smoothed Particle Hydrodynamics (OFF by default, experimental)
 #  ENABLE_LBMFLOW: enable LBMFLOW-option, LBM_ENGINE (OFF by default)
 #  ENABLE_LIQMIGRATION: enable LIQMIGRATION-option, see [Mani2013] for details (OFF by default)
+#  ENABLE_MASK_ARBITRARY: enable MASK_ARBITRARY option (OFF by default)
 #  runtimePREFIX: used for packaging, when install directory is not the same is runtime directory (/usr/local by default)
 #  CHUNKSIZE: set >1, if you want several sources to be compiled at once. Increases compilation speed and RAM-consumption during it (1 by default).
 #  VECTORIZE: enables vectorization and alignment in Eigen3 library, experimental (OFF by default)
@@ -125,6 +126,7 @@
 OPTION(ENABLE_SPH "Enable SPH" OFF)
 OPTION(ENABLE_LBMFLOW "Enable LBM engine (very experimental)" OFF)
 OPTION(ENABLE_LIQMIGRATION "Enable liquid control (very experimental), see [Mani2013] for details" OFF)
+OPTION(ENABLE_MASK_ARBITRARY "Enable arbitrary precision of bitmask variables (only Body::groupMask yet implemented) (experimental). Use -DMASK_ARBITRARY_SIZE=int to set number of used bits (256 by default)" OFF)
 
 #===========================================================
 # Use Eigen3 by default
@@ -356,6 +358,18 @@
 ELSE(ENABLE_LBMFLOW)
   SET(DISABLED_FEATS "${DISABLED_FEATS} LBMFLOW")
 ENDIF(ENABLE_LBMFLOW)
+#===============================================
+IF(ENABLE_MASK_ARBITRARY)
+  ADD_DEFINITIONS("-DYADE_MASK_ARBITRARY")
+  SET(CONFIGURED_FEATS "${CONFIGURED_FEATS} MASK_ARBITRARY")
+  IF(NOT MASK_ARBITRARY_SIZE)
+  	 SET(MASK_ARBITRARY_SIZE "256")
+  ENDIF(NOT MASK_ARBITRARY_SIZE)
+  ADD_DEFINITIONS(-DYADE_MASK_ARBITRARY_SIZE=${MASK_ARBITRARY_SIZE})
+  MESSAGE("MASK_ARBITRARY_SIZE = ${MASK_ARBITRARY_SIZE}")
+ELSE(ENABLE_MASK_ARBITRARY)
+  SET(DISABLED_FEATS "${DISABLED_FEATS} MASK_ARBITRARY")
+ENDIF(ENABLE_MASK_ARBITRARY)
 
 #===========================================================
 

=== modified file 'core/Body.cpp'
--- core/Body.cpp	2014-05-23 13:05:19 +0000
+++ core/Body.cpp	2014-06-17 10:18:00 +0000
@@ -31,3 +31,13 @@
 	return intrSize;
 }
 
+
+bool Body::maskOk(int mask) const { return (mask==0 || ((groupMask & mask) != 0)); }
+bool Body::maskCompatible(int mask) const { return (groupMask & mask) != 0; }
+#ifdef YADE_MASK_ARBITRARY
+bool Body::maskOk(const mask_t& mask) const { return (mask==0 || ((groupMask & mask) != 0)); }
+bool Body::maskCompatible(const mask_t& mask) const { return (groupMask & mask) != 0; }
+#endif
+
+
+

=== modified file 'core/Body.hpp'
--- core/Body.hpp	2014-06-05 13:19:44 +0000
+++ core/Body.hpp	2014-06-17 10:18:00 +0000
@@ -21,6 +21,8 @@
 #include<yade/lib/multimethods/Indexable.hpp>
 
 
+
+
 class Scene;
 class Interaction;
 
@@ -31,12 +33,6 @@
 		// internal structure to hold some interaction of a body; used by InteractionContainer;
 		typedef std::map<Body::id_t, shared_ptr<Interaction> > MapId2IntrT;
 		// groupMask type
-#ifdef BODY_GROUP_MASK_ARBITRARY_PRECISION
-		typedef boost::python::long_ groupMask_t;
-#else
-		typedef int groupMask_t;
-#endif
-
 
 		// bits for Body::flags
 		enum { FLAG_BOUNDED=1, FLAG_ASPHERICAL=2 }; /* add powers of 2 as needed */
@@ -75,12 +71,12 @@
 		Body::id_t getId() const {return id;};
 		unsigned int coordNumber();  // Number of neighboring particles
 
-		Body::groupMask_t getGroupMask() const {return groupMask; };
-		bool maskOk(int mask) const {return (mask==0 || (bool)(groupMask & mask));}
-		bool maskCompatible(int mask) const { return (bool)(groupMask & mask); }
-#ifdef BODY_GROUP_MASK_ARBITRARY_PRECISION
-		bool maskOk(const boost::python::long_& mask) const {return (mask==0 || (bool)(groupMask & mask));}
-		bool maskCompatible(const boost::python::long_& mask) const { return (bool)(groupMask & mask); }
+		mask_t getGroupMask() const {return groupMask; };
+		bool maskOk(int mask) const;
+		bool maskCompatible(int mask) const;
+#ifdef YADE_MASK_ARBITRARY
+		bool maskOk(const mask_t& mask) const;
+		bool maskCompatible(const mask_t& mask) const;
 #endif
 
 		// only BodyContainer can set the id of a body
@@ -89,7 +85,7 @@
 	YADE_CLASS_BASE_DOC_ATTRS_CTOR_PY(Body,Serializable,"A particle, basic element of simulation; interacts with other bodies.",
 		((Body::id_t,id,Body::ID_NONE,Attr::readonly,"Unique id of this body."))
 
-		((Body::groupMask_t,groupMask,1,,"Bitmask for determining interactions."))
+		((mask_t,groupMask,1,,"Bitmask for determining interactions."))
 		((int,flags,FLAG_BOUNDED,Attr::readonly,"Bits of various body-related flags. *Do not access directly*. In c++, use isDynamic/setDynamic, isBounded/setBounded, isAspherical/setAspherical. In python, use :yref:`Body.dynamic`, :yref:`Body.bounded`, :yref:`Body.aspherical`."))
 
 		((shared_ptr<Material>,material,,,":yref:`Material` instance associated with this body."))
@@ -119,7 +115,7 @@
 		.add_property("dynamic",&Body::isDynamic,&Body::setDynamic,"Whether this body will be moved by forces. (In c++, use ``Body::isDynamic``/``Body::setDynamic``) :ydefault:`true`")
 		.add_property("bounded",&Body::isBounded,&Body::setBounded,"Whether this body should have :yref:`Body.bound` created. Note that bodies without a :yref:`bound <Body.bound>` do not participate in collision detection. (In c++, use ``Body::isBounded``/``Body::setBounded``) :ydefault:`true`")
 		.add_property("aspherical",&Body::isAspherical,&Body::setAspherical,"Whether this body has different inertia along principal axes; :yref:`NewtonIntegrator` makes use of this flag to call rotation integration routine for aspherical bodies, which is more expensive. :ydefault:`false`")
-		.def_readwrite("mask",&Body::groupMask,"Shorthand for :yref:`Body::groupMask`")
+		.add_property("mask",boost::python::make_getter(&Body::groupMask,boost::python::return_value_policy<boost::python::return_by_value>()),boost::python::make_setter(&Body::groupMask,boost::python::return_value_policy<boost::python::return_by_value>()),"Shorthand for :yref:`Body::groupMask`")
 		.add_property("isStandalone",&Body::isStandalone,"True if this body is neither clump, nor clump member; false otherwise.")
 		.add_property("isClumpMember",&Body::isClumpMember,"True if this body is clump member, false otherwise.")
 		.add_property("isClump",&Body::isClump,"True if this body is clump itself, false otherwise.")
@@ -135,16 +131,3 @@
 	);
 };
 REGISTER_SERIALIZABLE(Body);
-
-
-#ifdef BODY_GROUP_MASK_ARBITRARY_PRECISION
-namespace boost { namespace serialization {
-template<class Archive>
-void serialize(Archive & ar, boost::python::long_ & l, const unsigned int version){
-	namespace bp = boost::python;
-	std::string value = bp::extract<std::string>(bp::str(l));
-	ar & BOOST_SERIALIZATION_NVP(value);
-	l = bp::long_(value);
-}
-}} // namespace boost::serialization
-#endif

=== modified file 'lib/base/Math.cpp'
--- lib/base/Math.cpp	2010-11-07 11:46:20 +0000
+++ lib/base/Math.cpp	2014-06-17 10:18:00 +0000
@@ -10,3 +10,18 @@
 
 template<> int ZeroInitializer<int>(){ return (int)0; }
 template<> Real ZeroInitializer<Real>(){ return (Real)0; }
+
+#ifdef YADE_MASK_ARBITRARY
+bool operator==(const mask_t& g, int i) { return g == mask_t(i); }
+bool operator==(int i, const mask_t& g) { return g == i; }
+bool operator!=(const mask_t& g, int i) { return !(g == i); }
+bool operator!=(int i, const mask_t& g) { return g != i; }
+mask_t operator&(const mask_t& g, int i) { return g & mask_t(i); }
+mask_t operator&(int i, const mask_t& g) { return g & i; }
+mask_t operator|(const mask_t& g, int i) { return g | mask_t(i); }
+mask_t operator|(int i, const mask_t& g) { return g | i; }
+bool operator||(const mask_t& g, bool b) { return (g == 0) || b; }
+bool operator||(bool b, const mask_t& g) { return g || b; }
+bool operator&&(const mask_t& g, bool b) { return (g == 0) && b; }
+bool operator&&(bool b, const mask_t& g) { return g && b; }
+#endif

=== modified file 'lib/base/Math.hpp'
--- lib/base/Math.hpp	2014-06-09 12:14:44 +0000
+++ lib/base/Math.hpp	2014-06-17 10:18:00 +0000
@@ -12,6 +12,9 @@
 
 #include<limits>
 #include<cstdlib>
+#ifdef YADE_MASK_ARBITRARY
+#include<bitset>
+#endif
 
 #include<Eigen/Core>
 #include<Eigen/Geometry>
@@ -203,12 +206,36 @@
 template<typename Scalar> Scalar unitVectorsAngle(const VECTOR3_TEMPLATE(Scalar)& a, const VECTOR3_TEMPLATE(Scalar)& b){ return acos(a.dot(b)); }
 // operators
 
+
+/*
+ * Mask
+ */
+#ifdef YADE_MASK_ARBITRARY
+typedef std::bitset<YADE_MASK_ARBITRARY_SIZE> mask_t;
+bool operator==(const mask_t& g, int i);
+bool operator==(int i, const mask_t& g);
+bool operator!=(const mask_t& g, int i);
+bool operator!=(int i, const mask_t& g);
+mask_t operator&(const mask_t& g, int i);
+mask_t operator&(int i, const mask_t& g);
+mask_t operator|(const mask_t& g, int i);
+mask_t operator|(int i, const mask_t& g);
+bool operator||(const mask_t& g, bool b);
+bool operator||(bool b, const mask_t& g);
+bool operator&&(const mask_t& g, bool b);
+bool operator&&(bool b, const mask_t& g);
+#else
+typedef int mask_t;
+#endif
+
+
 /*
  * typedefs
  */
 typedef Se3<Real> Se3r;
 
 
+
 /*
  * Serialization of math classes
  */
@@ -307,6 +334,15 @@
 	   BOOST_SERIALIZATION_NVP(m50) & BOOST_SERIALIZATION_NVP(m51) & BOOST_SERIALIZATION_NVP(m52) & BOOST_SERIALIZATION_NVP(m53) & BOOST_SERIALIZATION_NVP(m54) & BOOST_SERIALIZATION_NVP(m55);
 }
 
+#ifdef YADE_MASK_ARBITRARY
+template<class Archive>
+void serialize(Archive & ar, mask_t& v, const unsigned int version){
+	std::string str = v.to_string();
+	ar & BOOST_SERIALIZATION_NVP(str);
+	v = mask_t(str);
+}
+#endif
+
 } // namespace serialization
 } // namespace boost
 

=== modified file 'pkg/dem/CapillaryTriaxialTest.cpp'
--- pkg/dem/CapillaryTriaxialTest.cpp	2014-06-05 13:19:44 +0000
+++ pkg/dem/CapillaryTriaxialTest.cpp	2014-06-17 10:18:00 +0000
@@ -209,7 +209,7 @@
 
 void CapillaryTriaxialTest::createSphere(shared_ptr<Body>& body, Vector3r position, Real radius, bool big, bool dynamic )
 {
-	body = shared_ptr<Body>(new Body); body->groupMask=Body::groupMask_t(2);
+	body = shared_ptr<Body>(new Body); body->groupMask=2;
 	shared_ptr<FrictMat> physics(new FrictMat);
 	shared_ptr<Aabb> aabb(new Aabb);
 
@@ -254,7 +254,7 @@
 
 void CapillaryTriaxialTest::createBox(shared_ptr<Body>& body, Vector3r position, Vector3r extents, bool wire)
 {
-	body = shared_ptr<Body>(new Body); body->groupMask=Body::groupMask_t(2);
+	body = shared_ptr<Body>(new Body); body->groupMask=2;
 	shared_ptr<FrictMat> physics(new FrictMat);
 	shared_ptr<Aabb> aabb(new Aabb);
 	shared_ptr<Box> iBox(new Box);

=== modified file 'pkg/dem/CohesiveTriaxialTest.cpp'
--- pkg/dem/CohesiveTriaxialTest.cpp	2014-06-05 13:19:44 +0000
+++ pkg/dem/CohesiveTriaxialTest.cpp	2014-06-17 10:18:00 +0000
@@ -200,7 +200,7 @@
 
 void CohesiveTriaxialTest::createSphere(shared_ptr<Body>& body, Vector3r position, Real radius, bool dynamic )
 {
-	body = shared_ptr<Body>(new Body); body->groupMask=Body::groupMask_t(2);
+	body = shared_ptr<Body>(new Body); body->groupMask=2;
 	shared_ptr<CohFrictMat> physics(new CohFrictMat);
 	shared_ptr<Aabb> aabb(new Aabb);
 	shared_ptr<Sphere> iSphere(new Sphere);
@@ -243,7 +243,7 @@
 
 void CohesiveTriaxialTest::createBox(shared_ptr<Body>& body, Vector3r position, Vector3r extents, bool wire)
 {
-	body = shared_ptr<Body>(new Body); body->groupMask=Body::groupMask_t(2);
+	body = shared_ptr<Body>(new Body); body->groupMask=2;
 	shared_ptr<CohFrictMat> physics(new CohFrictMat);
 	shared_ptr<Aabb> aabb(new Aabb);
 

=== modified file 'pkg/dem/SimpleShear.cpp'
--- pkg/dem/SimpleShear.cpp	2014-06-05 13:19:44 +0000
+++ pkg/dem/SimpleShear.cpp	2014-06-17 10:18:00 +0000
@@ -116,7 +116,7 @@
 
 void SimpleShear::createSphere(shared_ptr<Body>& body, Vector3r position, Real radius)
 {
-	body = shared_ptr<Body>(new Body); body->groupMask=Body::groupMask_t(1);
+	body = shared_ptr<Body>(new Body); body->groupMask=1;
 	shared_ptr<NormalInelasticMat> mat(new NormalInelasticMat);
 	shared_ptr<Aabb> aabb(new Aabb);
 	shared_ptr<Sphere> iSphere(new Sphere);
@@ -147,7 +147,7 @@
 
 void SimpleShear::createBox(shared_ptr<Body>& body, Vector3r position, Vector3r extents)
 {
-	body = shared_ptr<Body>(new Body); body->groupMask=Body::groupMask_t(1);
+	body = shared_ptr<Body>(new Body); body->groupMask=1;
 	shared_ptr<NormalInelasticMat> mat(new NormalInelasticMat);
 	shared_ptr<Aabb> aabb(new Aabb);
 // 	shared_ptr<BoxModel> gBox(new BoxModel);

=== modified file 'pkg/dem/SpheresFactory.cpp'
--- pkg/dem/SpheresFactory.cpp	2014-06-05 13:19:44 +0000
+++ pkg/dem/SpheresFactory.cpp	2014-06-17 10:18:00 +0000
@@ -182,7 +182,7 @@
 		b->shape=sphere; 
 		b->state=state; 
 		b->material=material;
-		if (mask>0) {b->groupMask=Body::groupMask_t(mask);}
+		if (mask>0) {b->groupMask=mask;}
 		// insert particle in the simulation
 		scene->bodies->insert(b);
 		ids.push_back(b->getId());

=== modified file 'pkg/dem/TesselationWrapper.cpp'
--- pkg/dem/TesselationWrapper.cpp	2014-06-05 13:19:44 +0000
+++ pkg/dem/TesselationWrapper.cpp	2014-06-17 10:18:00 +0000
@@ -306,7 +306,7 @@
 
 void createSphere(shared_ptr<Body>& body, Vector3r position, Real radius, bool big, bool dynamic )
 {
-	body = shared_ptr<Body>(new Body); body->groupMask=Body::groupMask_t(2);
+	body = shared_ptr<Body>(new Body); body->groupMask=2;
 	shared_ptr<Sphere> iSphere(new Sphere);
 	body->state->blockedDOFs=State::DOF_NONE;
 	body->state->pos=position;

=== modified file 'pkg/dem/TriaxialTest.cpp'
--- pkg/dem/TriaxialTest.cpp	2014-06-05 13:19:44 +0000
+++ pkg/dem/TriaxialTest.cpp	2014-06-17 10:18:00 +0000
@@ -187,7 +187,7 @@
 
 void TriaxialTest::createSphere(shared_ptr<Body>& body, Vector3r position, Real radius, bool big, bool dynamic )
 {
-	body = shared_ptr<Body>(new Body); body->groupMask=Body::groupMask_t(2);
+	body = shared_ptr<Body>(new Body); body->groupMask=2;
 	shared_ptr<Aabb> aabb(new Aabb);
 	shared_ptr<Sphere> iSphere(new Sphere);
 	body->state->blockedDOFs=State::DOF_NONE;
@@ -213,7 +213,7 @@
 
 void TriaxialTest::createBox(shared_ptr<Body>& body, Vector3r position, Vector3r extents, bool wire)
 {
-	body = shared_ptr<Body>(new Body); body->groupMask=Body::groupMask_t(2);
+	body = shared_ptr<Body>(new Body); body->groupMask=2;
 	body->state->blockedDOFs=State::DOF_ALL;
 	shared_ptr<Aabb> aabb(new Aabb);
 	aabb->color		= Vector3r(1,0,0);

=== modified file 'pkg/dem/VTKRecorder.cpp'
--- pkg/dem/VTKRecorder.cpp	2014-06-11 12:05:52 +0000
+++ pkg/dem/VTKRecorder.cpp	2014-06-17 10:18:00 +0000
@@ -37,8 +37,8 @@
 YADE_PLUGIN((VTKRecorder));
 CREATE_LOGGER(VTKRecorder);
 
-#ifdef BODY_GROUP_MASK_ARBITRARY_PRECISION
-#define GET_MASK(b) boost::python::extract<int>(b->groupMask)
+#ifdef YADE_MASK_ARBITRARY
+#define GET_MASK(b) b->groupMask.to_ulong()
 #else
 #define GET_MASK(b) b->groupMask
 #endif

=== modified file 'py/wrapper/customConverters.cpp'
--- py/wrapper/customConverters.cpp	2014-05-23 13:05:19 +0000
+++ py/wrapper/customConverters.cpp	2014-06-17 10:18:00 +0000
@@ -149,6 +149,38 @@
 	}
 };
 
+
+
+#ifdef YADE_MASK_ARBITRARY
+struct custom_mask_to_long{
+	static PyObject* convert(const mask_t& mask){
+		return PyLong_FromString(const_cast<char*>(mask.to_string().c_str()),NULL,2);
+	}
+};
+struct custom_mask_from_long{
+	custom_mask_from_long(){
+		 boost::python::converter::registry::push_back(&convertible,&construct,boost::python::type_id<mask_t>());
+	}
+	static void* convertible(PyObject* obj_ptr){
+		return (PyLong_Check(obj_ptr) || PyInt_Check(obj_ptr))? obj_ptr : 0;
+	}
+	static void construct(PyObject* obj_ptr, boost::python::converter::rvalue_from_python_stage1_data* data){
+		void* storage=((boost::python::converter::rvalue_from_python_storage<mask_t>*)(data))->storage.bytes;
+		new (storage) mask_t; mask_t* mask=(mask_t*)storage;
+		if (PyInt_Check(obj_ptr)) obj_ptr = PyLong_FromLong(PyInt_AsLong(obj_ptr));
+		obj_ptr = _PyLong_Format(obj_ptr,2,0,0);
+		std::string s(PyString_AsString(obj_ptr));
+		//
+		if (s.substr(0,2).compare("0b")==0) s = s.substr(2);
+		if (s[s.length()-1]=='L') s = s.substr(0,s.length()-1);
+		// TODO?
+		*mask = mask_t(s);
+		data->convertible=storage;
+	}
+};
+#endif
+
+
 BOOST_PYTHON_MODULE(_customConverters){
 
 	custom_Se3r_from_seq(); boost::python::to_python_converter<Se3r,custom_se3_to_tuple>();
@@ -167,6 +199,11 @@
 	//boost::python::to_python_converter<std::list<shared_ptr<Functor> >, custom_list_to_list<shared_ptr<Functor> > >();
 	//boost::python::to_python_converter<std::list<shared_ptr<Functor> >, custom_list_to_list<shared_ptr<Functor> > >();
 
+#ifdef YADE_MASK_ARBITRARY
+	custom_mask_from_long();
+	boost::python::to_python_converter<mask_t,custom_mask_to_long>();
+#endif
+
 	// register 2-way conversion between c++ vector and python homogeneous sequence (list/tuple) of corresponding type
 	#define VECTOR_SEQ_CONV(Type) custom_vector_from_seq<Type>();  boost::python::to_python_converter<std::vector<Type>, custom_vector_to_list<Type> >();
 		VECTOR_SEQ_CONV(int);