------------------------------------------------------------ revno: 2581 fixes bug(s): https://launchpad.net/bugs/683501 https://launchpad.net/bugs/681018 committer: Václav Šmilauer <e...@doxos.eu> 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
_______________________________________________ Mailing list: https://launchpad.net/~yade-dev Post to : yade-dev@lists.launchpad.net Unsubscribe : https://launchpad.net/~yade-dev More help : https://help.launchpad.net/ListHelp