← Back to team overview

yade-dev team mailing list archive

[Branch ~yade-dev/yade/trunk] Rev 2581: 1. Add access to clump member from python

 

------------------------------------------------------------
revno: 2581
fixes bug(s): https://launchpad.net/bugs/683501 https://launchpad.net/bugs/681018
committer: Václav Šmilauer <eu@xxxxxxxx>
branch nick: yade
timestamp: Wed 2010-12-01 12:09:53 +0100
message:
  1. Add access to clump member from python
  2. Fix Clump i/o (clumpId was not saved)
  3. Rename regular-sphere-pack to packs
  4. Fix a few bugs (thanks, Anton)
  5. Fix SubdomainOptimizer behavior in some corner cases
  6. Add some checks to qt4
renamed:
  examples/regular-sphere-pack/ => examples/packs/
  examples/regular-sphere-pack/regular-sphere-pack-FromFile => examples/packs/foo.spheres
  examples/regular-sphere-pack/regular-sphere-pack-LSMGenGeo.geo => examples/packs/LSMGenGeo.geo
  examples/regular-sphere-pack/regular-sphere-pack.geo => examples/packs/packs.geo
  examples/regular-sphere-pack/regular-sphere-pack.mesh => examples/packs/cone.mesh
  examples/regular-sphere-pack/regular-sphere-pack.py => examples/packs/packs.py
modified:
  core/Body.hpp
  core/InteractionContainer.cpp
  gui/qt4/Inspector.py
  gui/qt4/SerializableEditor.py
  pkg/common/SubdomainOptimizer.cpp
  pkg/dem/Clump.cpp
  pkg/dem/Clump.hpp
  py/log.cpp
  examples/packs/packs.py


--
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	2010-11-30 13:51:41 +0000
+++ core/Body.hpp	2010-12-01 11:09:53 +0000
@@ -84,7 +84,7 @@
 		((shared_ptr<Shape>,shape,,,"Geometrical :yref:`Shape`."))
 		((shared_ptr<Bound>,bound,,,":yref:`Bound`, approximating volume for the purposes of collision detection."))
 		((MapId2IntrT,intrs,,Attr::hidden,"Map from otherId to Interaction with otherId, managed by InteractionContainer. NOTE: (currently) does not contain all interactions with this body (only those where otherId>id), since performance issues with such data duplication have not yet been investigated."))
-		((int,clumpId,Body::ID_NONE,(Attr::readonly|Attr::noSave),"Id of clump this body makes part of; invalid number if not part of clump; see :yref:`Body::isStandalone`, :yref:`Body::isClump`, :yref:`Body::isClumpMember` properties. \n\n This property is not meant to be modified directly from Python, use :yref:`O.bodies.appendClumped<BodyContainer.appendClumped>` instead.")),
+		((int,clumpId,Body::ID_NONE,Attr::readonly,"Id of clump this body makes part of; invalid number if not part of clump; see :yref:`Body::isStandalone`, :yref:`Body::isClump`, :yref:`Body::isClumpMember` properties. \n\nNot meant to be modified directly from Python, use :yref:`O.bodies.appendClumped<BodyContainer.appendClumped>` instead.")),
 		/* ctor */,
 		/* py */
 		//

=== modified file 'core/InteractionContainer.cpp'
--- core/InteractionContainer.cpp	2010-11-30 13:51:41 +0000
+++ core/InteractionContainer.cpp	2010-12-01 11:09:53 +0000
@@ -40,8 +40,9 @@
 	assert(bodies);
 	boost::mutex::scoped_lock lock(drawloopmutex);
 	if (id1>id2) swap(id1,id2);
-	assert(id1<(Body::id_t)bodies->size() && id2<(Body::id_t)bodies->size()); // (possibly) existing ids
-	const shared_ptr<Body>& b1((*bodies)[id1]); assert(b1); // get the body; check it is not deleted
+	if(unlikely(id2>=(Body::id_t)bodies->size())) return false; // no such interaction
+	const shared_ptr<Body>& b1((*bodies)[id1]);
+	if(unlikely(!b1)) return false;  // body vanished
 	Body::MapId2IntrT::iterator I(b1->intrs.find(id2));
 	// this used to return false
 	if(I==b1->intrs.end()) throw std::logic_error(("InteractionContainer::erase: attempt to delete non-existent interaction ##"+lexical_cast<string>(id1)+"+"+lexical_cast<string>(id2)).c_str());
@@ -66,7 +67,6 @@
 	if (id1>id2) swap(id1,id2); 
 	// those checks could be perhaps asserts, but pyInteractionContainer has no access to the body container...
 	if(unlikely(id2>=(Body::id_t)bodies->size())){ empty=shared_ptr<Interaction>(); return empty; }
-	//assert(id2<(Body::id_t)bodies->size()); // id2 is bigger
 	const shared_ptr<Body>& b1((*bodies)[id1]);
 	if(unlikely(!b1)) { empty=shared_ptr<Interaction>(); return empty; }
 	Body::MapId2IntrT::iterator I(b1->intrs.find(id2));

=== renamed directory 'examples/regular-sphere-pack' => 'examples/packs'
=== renamed file 'examples/regular-sphere-pack/regular-sphere-pack-LSMGenGeo.geo' => 'examples/packs/LSMGenGeo.geo'
=== renamed file 'examples/regular-sphere-pack/regular-sphere-pack.mesh' => 'examples/packs/cone.mesh'
=== renamed file 'examples/regular-sphere-pack/regular-sphere-pack-FromFile' => 'examples/packs/foo.spheres'
=== renamed file 'examples/regular-sphere-pack/regular-sphere-pack.geo' => 'examples/packs/packs.geo'
=== renamed file 'examples/regular-sphere-pack/regular-sphere-pack.py' => 'examples/packs/packs.py'
--- examples/regular-sphere-pack/regular-sphere-pack.py	2010-11-30 15:41:55 +0000
+++ examples/packs/packs.py	2010-12-01 11:09:53 +0000
@@ -60,19 +60,17 @@
 oriBody = Quaternion(Vector3(0,0,1),(3.14159/2))
 rotateIDs=O.bodies.append(utils.facetCylinder((6.0,6.0,-4.0),2.0,4.0,oriBody,wallMask=4,segmentsNumber=10,**kwBoxes))
 
-# Import regular-sphere-pack.mesh into the YADE simulation
 oriBody = Quaternion(Vector3(0,0,1),(3.14159/2))
-O.bodies.append(ymport.gmsh('regular-sphere-pack.mesh',orientation=oriBody,**kwMeshes))#generates facets from the mesh file
+O.bodies.append(ymport.gmsh('cone.mesh',orientation=oriBody,**kwMeshes))#generates facets from the mesh file
 
-# Import regular-sphere-pack-LSMGenGeo.geo into the YADE simulation
 oriBody = Quaternion(Vector3(0,0,1),(3.14159/2))
-O.bodies.append(ymport.gengeoFile('regular-sphere-pack-LSMGenGeo.geo',shift=Vector3(-7.0,-7.0,-5.9),scale=1.0,orientation=oriBody,color=(1,0,1),**kw))
+O.bodies.append(ymport.gengeoFile('LSMGenGeo.geo',shift=Vector3(-7.0,-7.0,-5.9),scale=1.0,orientation=oriBody,color=(1,0,1),**kw))
 
 # spheresToFile saves coordinates and radii of all spheres of the simulation into the text file, works but disabled. Please, uncomment it, if you need
 #print "Saved into the OutFile " + str (export.text("OutFile")) + " spheres";
 
-# spheresFromFile function imports coordinates and radiuses of all spheres of the simulation into the text file
-O.bodies.append(ymport.text('regular-sphere-pack-FromFile',shift=Vector3(6.0,6.0,-2.9),scale=0.7,color=(1,1,1),**kw))
+# spheresFromFile function imports coordinates and radii of all spheres of the simulation into the text file
+O.bodies.append(ymport.text('foo.spheres',shift=Vector3(6.0,6.0,-2.9),scale=0.7,color=(1,1,1),**kw))
 
 #Demonstration of HarmonicMotionEngine
 O.bodies.append(pack.regularHexa(pack.inSphere((-10,5,-5),1.5),radius=rad*2.0,gap=rad/3.0,color=(0.2,0.5,0.9),material=0))
@@ -123,4 +121,3 @@
 #from yade import timing
 #timing.stats()
 #quit()
-collider.watch1=3029

=== modified file 'gui/qt4/Inspector.py'
--- gui/qt4/Inspector.py	2010-09-15 10:06:42 +0000
+++ gui/qt4/Inspector.py	2010-12-01 11:09:53 +0000
@@ -50,11 +50,11 @@
 	
 
 def makeBodyLabel(b):
-	ret=str(b.id)+' '
+	ret=unicode(b.id)+u' '
 	if not b.shape: ret+=u'⬚'
 	else:
-		typeMap={'Sphere':u'⚫','Facet':u'△','Wall':u'┃','Box':u'⎕','Cylinder':u'⌭','ChainedCylinder':u'☡'}
-		ret+=typeMap.get(b.shape.__class__.__name__,'ï¹–')
+		typeMap={'Sphere':u'⚫','Facet':u'△','Wall':u'┃','Box':u'⎕','Cylinder':u'⌭','ChainedCylinder':u'☡','Clump':u'☍'}
+		ret+=typeMap.get(b.shape.__class__.__name__,u'ï¹–')
 	if not b.dynamic: ret+=u'âš“'
 	elif b.state.blockedDOFs!=[]: ret+=u'⎈'
 	return ret

=== modified file 'gui/qt4/SerializableEditor.py'
--- gui/qt4/SerializableEditor.py	2010-11-17 11:25:26 +0000
+++ gui/qt4/SerializableEditor.py	2010-12-01 11:09:53 +0000
@@ -310,6 +310,7 @@
 		logging.error("Unable to guess python type from cxx type '%s'"%cxxT)
 		return None
 	def mkAttrEntries(self):
+		if self.ser==None: return
 		try:
 			d=self.ser.dict()
 		except TypeError:
@@ -411,7 +412,7 @@
 		import re
 		ss=unicode(ser); m=re.match(u'<(.*) instance at (0x.*)>',ss)
 		if m: ret+=m.group(2)
-		else: logging.warning(u"Serializable converted to str ('%s') does not contain 'instance at 0x…'")
+		else: logging.warning(u"Serializable converted to str ('%s') does not contain 'instance at 0x…'"%ss)
 	return ret
 
 class SeqSerializableComboBox(QFrame):

=== modified file 'pkg/common/SubdomainOptimizer.cpp'
--- pkg/common/SubdomainOptimizer.cpp	2010-11-30 13:51:41 +0000
+++ pkg/common/SubdomainOptimizer.cpp	2010-12-01 11:09:53 +0000
@@ -79,7 +79,12 @@
 		assert(sp.aboveSplit>=0);
 		int dist=sp.aboveSplit-(sp.axNth*1./sp.axCount)*nParticles; // by how many particles to shift to get in the median position
 		// concentration correction, sp.dist is the previous distance value
-		if(sp.dist>50) sp.concentration*=1.0*(sp.dist-dist)/sp.dist; // 1.0 could be replaced by some inertia parameter that would prevent adjust to fluctuations too fast
+		if(sp.dist>50){
+			// 1.0 could be replaced by some inertia parameter that would prevent adjust to fluctuations too fast
+			Real factor=1.0*(sp.dist-dist)/sp.dist;
+			// prevent concentration from droping too fast (to zero, for instance); the .3 is tunable, again
+			sp.concentration*=max(.3,factor);
+		}
 		sp.lim+=dist/sp.concentration;
 		LOG_DEBUG("SplitPlane shifted by "<<dist/sp.concentration<<" to "<<(sp.ax==0?"x":(sp.ax==1?"y":"z"))<<"="<<sp.lim<<", being "<<dist<<" off ideal (nParticles="<<nParticles<<", aboveSplit="<<sp.aboveSplit<<"), concentration "<<sp.concentration);
 		sp.dist=dist;

=== modified file 'pkg/dem/Clump.cpp'
--- pkg/dem/Clump.cpp	2010-11-07 09:52:09 +0000
+++ pkg/dem/Clump.cpp	2010-12-01 11:09:53 +0000
@@ -9,6 +9,14 @@
 YADE_PLUGIN((Clump));
 CREATE_LOGGER(Clump);
 
+python::dict Clump::members_get(){
+	python::dict ret;
+	FOREACH(MemberMap::value_type& b, members){
+		ret[b.first]=python::make_tuple(b.second.position,b.second.orientation);
+	}
+	return ret;
+}
+
 void Clump::add(const shared_ptr<Body>& clumpBody, const shared_ptr<Body>& subBody){
 	Body::id_t subId=subBody->getId();
 	if(subBody->clumpId!=Body::ID_NONE) throw std::invalid_argument(("Body #"+lexical_cast<string>(subId)+" is already in clump #"+lexical_cast<string>(subBody->clumpId)).c_str());

=== modified file 'pkg/dem/Clump.hpp'
--- pkg/dem/Clump.hpp	2010-11-07 11:46:20 +0000
+++ pkg/dem/Clump.hpp	2010-12-01 11:09:53 +0000
@@ -71,11 +71,14 @@
 		static Matrix3r inertiaTensorRotate(const Matrix3r& I, const Matrix3r& T);
 		//! Recalculate body's inertia tensor in rotated coordinates.
 		static Matrix3r inertiaTensorRotate(const Matrix3r& I, const Quaternionr& rot);
+
+		python::dict members_get();
 	
-	YADE_CLASS_BASE_DOC_ATTRS_CTOR(Clump,Shape,"Rigid aggregate of bodies",
+	YADE_CLASS_BASE_DOC_ATTRS_CTOR_PY(Clump,Shape,"Rigid aggregate of bodies",
 		((MemberMap,members,,Attr::hidden,"Ids and relative positions+orientations of members of the clump (should not be accessed directly)"))
 		// ((vector<int>,ids,,Attr::readonly,"Ids of constituent particles (only informative; direct modifications will have no effect)."))
 		,/*ctor*/ createIndex();
+		,/*py*/ .add_property("members",&Clump::members_get,"Return clump members as {'id1':(relPos,relOri),...}")
 	);
 	DECLARE_LOGGER;
 	REGISTER_CLASS_INDEX(Clump,Shape);

=== modified file 'py/log.cpp'
--- py/log.cpp	2010-11-07 11:46:20 +0000
+++ py/log.cpp	2010-12-01 11:09:53 +0000
@@ -6,11 +6,17 @@
 enum{ll_TRACE,ll_DEBUG,ll_INFO,ll_WARN,ll_ERROR,ll_FATAL};
 
 #ifdef YADE_LOG4CXX
+
+	log4cxx::LoggerPtr logger=log4cxx::Logger::getLogger("yade.log");
+
 	#include<log4cxx/logmanager.h>
 
 	void logSetLevel(std::string loggerName,int level){
 		std::string fullName(loggerName.empty()?"yade":("yade."+loggerName));
-		if(!log4cxx::LogManager::exists(fullName)) throw std::invalid_argument("No logger named `"+fullName+"'");
+		if(!log4cxx::LogManager::exists(fullName)){
+			LOG_WARN("No logger named "<<loggerName<<", ifnoring level setting.");			
+			// throw std::invalid_argument("No logger named `"+fullName+"'");
+		} 
 		log4cxx::LevelPtr l;
 		switch(level){
 			#ifdef LOG4CXX_TRACE