Author: eudoxos
Date: 2009-07-11 15:52:26 +0200 (Sat, 11 Jul 2009)
New Revision: 1854

Modified:
   trunk/core/Interaction.hpp
   trunk/core/InteractionContainer.cpp
   trunk/core/InteractionContainer.hpp
   trunk/pkg/common/Engine/MetaEngine/InteractionDispatchers.cpp
   trunk/pkg/common/Engine/StandAloneEngine/InsertionSortCollider.cpp
   trunk/pkg/common/Engine/StandAloneEngine/InsertionSortCollider.hpp
   trunk/pkg/dem/Engine/DeusExMachina/NewtonsDampedLaw.cpp
   trunk/pkg/dem/Engine/DeusExMachina/NewtonsDampedLaw.hpp
   trunk/py/yadeWrapper/yadeWrapper.cpp
   trunk/scripts/test/collider-stride-triax.py
   trunk/scripts/test/compare-identical.py
   trunk/scripts/test/regular-sphere-pack.py
Log:
1. Handle clumps in a better way in NewtonsDampedLaw (only if asked by the 
clump itself) -- future parallelization work. (related to bug #398086)
2. InsertionSortCollider now knows when to run based on maximum distance the 
fastest body could have travelled. (It is actually the physical meaning of 
sweepDistance). Handle varying maxVelocitySq in a constitent way.
3. Add InteractionContainer::serializeSorted to sort interactions by id1 and 
id2 before serializing (useful for comparing XML files). Added 
Interaction::operator< to compare 2 interactions in that way.
4. Fix openMP strategy in InteractionDispatchers to "guided" (as per 
https://blueprints.launchpad.net/yade/+spec/omp-schedule-strategy)



Modified: trunk/core/Interaction.hpp
===================================================================
--- trunk/core/Interaction.hpp  2009-07-10 19:16:01 UTC (rev 1853)
+++ trunk/core/Interaction.hpp  2009-07-11 13:52:26 UTC (rev 1854)
@@ -44,12 +44,14 @@
                Interaction ();
                Interaction(body_id_t newId1,body_id_t newId2);
 
-               body_id_t getId1() {return id1;};
-               body_id_t getId2() {return id2;};
+               const body_id_t& getId1() const {return id1;};
+               const body_id_t& getId2() const {return id2;};
 
                //! swaps order of bodies within the interaction
                void swapOrder();
 
+               bool operator<(const Interaction& other) const { return 
getId1()<other.getId1() || (getId1()==other.getId1() && 
getId2()<other.getId2()); }
+
                //! cache functors that are called for this interaction. 
Currently used by InteractionDispatchers.
                struct {
                        // Whether geometry dispatcher exists at all; this is 
different from !geom, since that can mean we haven't populated the cache yet.

Modified: trunk/core/InteractionContainer.cpp
===================================================================
--- trunk/core/InteractionContainer.cpp 2009-07-10 19:16:01 UTC (rev 1853)
+++ trunk/core/InteractionContainer.cpp 2009-07-11 13:52:26 UTC (rev 1854)
@@ -24,6 +24,12 @@
 }
 
 
+struct compPtrInteraction{
+       bool operator() (const shared_ptr<Interaction>& i1, const 
shared_ptr<Interaction>& i2) const {
+               return (*i1)<(*i2);
+       }
+};
+
 void InteractionContainer::preProcessAttributes(bool deserializing)
 {
        if(deserializing)
@@ -37,6 +43,7 @@
                InteractionContainer::iterator iEnd = this->end();
                for( ; i!=iEnd ; ++i )
                        interaction.push_back(*i);
+               if(serializeSorted) 
std::sort(interaction.begin(),interaction.end(),compPtrInteraction());
        }
 }
 

Modified: trunk/core/InteractionContainer.hpp
===================================================================
--- trunk/core/InteractionContainer.hpp 2009-07-10 19:16:01 UTC (rev 1853)
+++ trunk/core/InteractionContainer.hpp 2009-07-11 13:52:26 UTC (rev 1854)
@@ -86,7 +86,7 @@
        public :
                boost::mutex    drawloopmutex;
 
-               InteractionContainer() { };
+               InteractionContainer(): serializeSorted(false) { };
                virtual ~InteractionContainer() {};
 
                virtual bool insert(body_id_t /*id1*/,body_id_t /*id2*/)        
                        {throw;};
@@ -104,6 +104,9 @@
                virtual shared_ptr<Interaction>& operator[] (unsigned int) 
{throw;};
                virtual const shared_ptr<Interaction>& operator[] (unsigned 
int) const {throw;};
 
+               // sort interactions before serializations; useful if comparing 
XML files from different runs (false by default)
+               bool serializeSorted;
+
                // std::pair is not handled by yade::serialization, use 
vector<body_id_t> instead
                typedef Vector2<body_id_t> bodyIdPair;
                //! Ask for erasing the interaction given (from the 
constitutive law); this resets the interaction (to the initial=potential state)
@@ -147,7 +150,7 @@
        protected :
                virtual void preProcessAttributes(bool deserializing);
                virtual void postProcessAttributes(bool deserializing);
-       REGISTER_ATTRIBUTES(/*no base*/,(interaction)(pendingErase));
+       REGISTER_ATTRIBUTES(/*no 
base*/,(interaction)(pendingErase)(serializeSorted));
        REGISTER_CLASS_AND_BASE(InteractionContainer,Serializable);
 };
 

Modified: trunk/pkg/common/Engine/MetaEngine/InteractionDispatchers.cpp
===================================================================
--- trunk/pkg/common/Engine/MetaEngine/InteractionDispatchers.cpp       
2009-07-10 19:16:01 UTC (rev 1853)
+++ trunk/pkg/common/Engine/MetaEngine/InteractionDispatchers.cpp       
2009-07-11 13:52:26 UTC (rev 1854)
@@ -22,7 +22,7 @@
        }
        #ifdef YADE_OPENMP
                const long size=rootBody->interactions->size();
-               #pragma omp parallel for
+               #pragma omp parallel for schedule(guided)
                for(long i=0; i<size; i++){
                        const shared_ptr<Interaction>& 
I=(*rootBody->interactions)[i];
        #else

Modified: trunk/pkg/common/Engine/StandAloneEngine/InsertionSortCollider.cpp
===================================================================
--- trunk/pkg/common/Engine/StandAloneEngine/InsertionSortCollider.cpp  
2009-07-10 19:16:01 UTC (rev 1853)
+++ trunk/pkg/common/Engine/StandAloneEngine/InsertionSortCollider.cpp  
2009-07-11 13:52:26 UTC (rev 1854)
@@ -65,25 +65,16 @@
        bool InsertionSortCollider::isActivated(MetaBody* rb){
                // activated if number of bodies changes (hence need to refresh 
collision information)
                // or the time of scheduled run already came, or we were never 
scheduled yet
-               if(stride<=1) return true;
                if(sweepLength<=0) return true;
-               if(!newton) return true; // we wouldn't be able to find the max 
velocity
-               bool ret=rb->simulationTime>=scheduledRun ||
-                       // if the max velocity is bigger than the one that we 
used for bb computation last time
-                       // and the distance bodies would travel with this 
bigger velocity since last run (rb->simulationTime-lastRun)
-                       // would be the same or greater than the one that would 
be traveled with the original velocity
-                       // over the stride time (scheduledRun-lastRun)
-                       (newton->maxVelocitySq<0) || // no valid data about max 
velocity, run always
-                       (sweepVelocity==0 && newton->maxVelocitySq>0) || 
-                       (sweepVelocity<sqrt(newton->maxVelocitySq) && 
rb->simulationTime-lastRun>=(sweepVelocity/sqrt(newton->maxVelocitySq)/* we 
know maxVelocitySq>0 from the first condition */)*(scheduledRun-lastRun)) ||
-                       // number of bodies changed
-                       XX.size()!=2*rb->bodies->size() ||
-                       // we've never run yet (this should never happen as per 
if(!newton) above)
-                       scheduledRun<0;
+               if(!newton || newton->maxVelocitySq<0 || sweepVelocity<0) 
return true; // we wouldn't be able to find the max velocity, or it has not 
been computed yet, or there were no data available last time
+               if(XX.size()!=2*rb->bodies->size()) return true;
+               if(fastestBodyMaxDist<0){fastestBodyMaxDist=0; return true;}
+               fastestBodyMaxDist+=sqrt(newton->maxVelocitySq)*rb->dt;
+               if(fastestBodyMaxDist>=sweepLength) return true;
                // we wouldn't run in this step; in that case, just delete 
pending interactions
                // this is done in ::action normally, but it would make the 
call counters not reflect the stride
-               if(!ret) rb->interactions->erasePending(*this);
-               return ret;
+               rb->interactions->erasePending(*this);
+               return false;
        }
 #endif
 
@@ -146,21 +137,17 @@
                                                
stride=max(1,int((sweepLength/sweepVelocity)/rb->dt));
                                                
boundDispatcher->sweepDist=rb->dt*(stride-1)*sweepVelocity;
                                        } else { // no motion
-                                               stride=1000; // shouldn't this 
be some saner value? Infinity? How to decide?
                                                boundDispatcher->sweepDist=0; 
// nothing moves, no need to make bboxes larger
                                        }
-                                       
scheduledRun=rb->simulationTime+rb->dt*(stride-.5); // -.5 to avoid rounding 
issues
-                               } else { /* no valid data yet, run next time 
again */ boundDispatcher->sweepDist=0; stride=1; 
scheduledRun=rb->simulationTime+rb->dt; }
+                               } else { /* no valid data yet, run next time 
again */ boundDispatcher->sweepDist=0; sweepVelocity=-1; stride=1; }
                                LOG_DEBUG(rb->simulationTime<<"s: stride 
adapted to "<<stride<<"; sweepVelocity="<<sweepVelocity<<", 
maxVelocity="<<sqrt(newton->maxVelocitySq)<<", 
sweepDist="<<boundDispatcher->sweepDist);
-                               newton->maxVelocitySq=-1; // reset to invalid 
value again
-                       } else { scheduledRun=-1; 
boundDispatcher->sweepTime=-1; boundDispatcher->sweepDist=0; }
+                               fastestBodyMaxDist=0; // reset
+                       } else { boundDispatcher->sweepTime=-1; 
boundDispatcher->sweepDist=0; }
                        boundDispatcher->action(rb);
                #endif
 
        ISC_CHECKPOINT("bound");
 
-
-
        // copy bounds along given axis into our arrays
                for(size_t i=0; i<2*nBodies; i++){
                        const body_id_t& idXX=XX[i].id; const body_id_t& 
idYY=YY[i].id; const body_id_t& idZZ=ZZ[i].id;
@@ -191,10 +178,14 @@
                        if(doInitSort){
                                // the initial sort is in independent in 3 
dimensions, may be run in parallel
                                // it seems that there is no time gain running 
this in parallel, though
+                               #pragma omp parallel sections
                                {
-                                               std::sort(XX.begin(),XX.end());
-                                               std::sort(YY.begin(),YY.end());
-                                               std::sort(ZZ.begin(),ZZ.end());
+                                       #pragma omp section
+                                               { 
std::sort(XX.begin(),XX.end()); }
+                                       #pragma omp section
+                                               { 
std::sort(YY.begin(),YY.end()); }
+                                       #pragma omp section
+                                               { 
std::sort(ZZ.begin(),ZZ.end()); }
                                }
                        } else { // sortThenCollide
                                insertionSort(XX,interactions,rb,false); 
insertionSort(YY,interactions,rb,false); 
insertionSort(ZZ,interactions,rb,false);
@@ -214,7 +205,7 @@
                                        const body_id_t& jid=V[j].id;
                                        /// Not sure why this doesn't work. If 
this condition is commented out, we have exact same interactions as from 
SpatialQuickSort. Otherwise some interactions are missing!
                                        // skip bodies with smaller (arbitrary, 
could be greater as well) id, since they will detect us when their turn comes
-                                       // if(jid<iid) { /* LOG_TRACE("Skip 
#"<<V[j].id<<(V[j].flags.isMin?"(min)":"(max)")<<" with "<<iid<<" (smaller 
id)"); */ continue; }
+                                       //if(jid<iid) { /* LOG_TRACE("Skip 
#"<<V[j].id<<(V[j].flags.isMin?"(min)":"(max)")<<" with "<<iid<<" (smaller 
id)"); */ continue; }
                                        /* abuse the same function here; since 
it does spatial overlap check first, it is OK to use it */
                                        
handleBoundInversion(iid,jid,interactions,rb);
                                        // now we are at the last element, but 
we still have not met the upper bound of V[i].id

Modified: trunk/pkg/common/Engine/StandAloneEngine/InsertionSortCollider.hpp
===================================================================
--- trunk/pkg/common/Engine/StandAloneEngine/InsertionSortCollider.hpp  
2009-07-10 19:16:01 UTC (rev 1853)
+++ trunk/pkg/common/Engine/StandAloneEngine/InsertionSortCollider.hpp  
2009-07-11 13:52:26 UTC (rev 1854)
@@ -46,12 +46,8 @@
                shared_ptr<BoundingVolumeMetaEngine> boundDispatcher;
                // we need this to find out about current maxVelocitySq
                shared_ptr<NewtonsDampedLaw> newton;
-               // interval at which we will run; if 0, we run always (as 
usual).
+               // interval at which we will run (informative only, is updated 
automatically)
                int stride;
-               //! virtual time when we were run last time
-               Real lastRun;
-               //! virtual time when we have to run the next time
-               Real scheduledRun; 
                /// Absolute length that will be added to bounding boxes at 
each side; it should be something like 1/5 of typical grain radius
                /// this value is used to adapt stride; if too large, stride 
will be big, but the ratio of potential-only interactions will be very big, 
                /// thus slowing down collider & interaction loops 
significantly (remember: O(addLength^3))
@@ -63,6 +59,8 @@
                /// Has no influence on sweepLength, only on the computed 
stride.
                /// Default 1.05
                Real sweepFactor;
+               //! maximum distance that the fastest body could have travelled 
since the last run; if >= sweepLength, we could get out of bboxes and will 
trigger full run
+               Real fastestBodyMaxDist;
        #endif
        //! storage for bounds
        std::vector<Bound> XX,YY,ZZ;
@@ -92,7 +90,7 @@
 
        InsertionSortCollider():
        #ifdef COLLIDE_STRIDED
-               stride(0), lastRun(-1), scheduledRun(-1), sweepLength(-1), 
sweepVelocity(-1), sweepFactor(1.05),
+               stride(0), sweepLength(-1), sweepVelocity(-1), 
sweepFactor(1.05), fastestBodyMaxDist(-1),
        #endif
                sortAxis(0), sortThenCollide(false){
                        #ifdef ISC_TIMING
@@ -103,7 +101,7 @@
        REGISTER_CLASS_AND_BASE(InsertionSortCollider,Collider);
        REGISTER_ATTRIBUTES(Collider,(sortAxis)(sortThenCollide)
                #ifdef COLLIDE_STRIDED
-                       
(stride)(lastRun)(scheduledRun)(sweepLength)(sweepFactor)(sweepVelocity)
+                       
(stride)(sweepLength)(sweepFactor)(sweepVelocity)(fastestBodyMaxDist)
                #endif
        );
        DECLARE_LOGGER;

Modified: trunk/pkg/dem/Engine/DeusExMachina/NewtonsDampedLaw.cpp
===================================================================
--- trunk/pkg/dem/Engine/DeusExMachina/NewtonsDampedLaw.cpp     2009-07-10 
19:16:01 UTC (rev 1853)
+++ trunk/pkg/dem/Engine/DeusExMachina/NewtonsDampedLaw.cpp     2009-07-11 
13:52:26 UTC (rev 1854)
@@ -21,6 +21,22 @@
        }
 }
 
+void NewtonsDampedLaw::handleClumpMember(MetaBody* ncb, const body_id_t 
memberId, RigidBodyParameters* clumpRBP){
+       const shared_ptr<Body>& b=Body::byId(memberId,ncb);
+       assert(b->isClumpMember());
+       RigidBodyParameters* 
rb=YADE_CAST<RigidBodyParameters*>(b->physicalParameters.get());
+       const Vector3r& m=ncb->bex.getTorque(memberId); const Vector3r& 
f=ncb->bex.getForce(memberId);
+       Vector3r diffClumpAccel=f/clumpRBP->mass;
+       // angular acceleration from: normal torque + torque generated by the 
force WRT particle centroid on the clump centroid
+       Vector3r 
diffClumpAngularAccel=diagDiv(m,clumpRBP->inertia)+diagDiv((rb->se3.position-clumpRBP->se3.position).Cross(f),clumpRBP->inertia);
 
+       // damp increment of accels on the clump, using velocities of the clump 
MEMBER
+       
cundallDamp(ncb->dt,f,rb->velocity,diffClumpAccel,m,rb->angularVelocity,diffClumpAngularAccel);
+       // clumpRBP->{acceleration,angularAcceleration} are reset byt 
Clump::moveMembers, it is ok to just increment here
+       clumpRBP->acceleration+=diffClumpAccel;
+       clumpRBP->angularAcceleration+=diffClumpAngularAccel;
+       maxVelocitySq=max(maxVelocitySq,rb->velocity.SquaredLength());
+}
+
 void NewtonsDampedLaw::applyCondition ( MetaBody * ncb )
 {
        ncb->bex.sync();
@@ -29,44 +45,28 @@
 
        FOREACH(const shared_ptr<Body>& b, *ncb->bodies){
                // clump members are non-dynamic; they skip the rest of loop 
once their forces are properly taken into account, however
-               if (!b->isDynamic && !b->isClumpMember()) continue;
-               
+               if (!b->isDynamic || b->isClumpMember()) continue;
                RigidBodyParameters* rb = 
YADE_CAST<RigidBodyParameters*>(b->physicalParameters.get());
                const body_id_t& id=b->getId();
-               const Vector3r& m=ncb->bex.getTorque(id);
-               const Vector3r& f=ncb->bex.getForce(id);
+               const Vector3r& m=ncb->bex.getTorque(id); const Vector3r& 
f=ncb->bex.getForce(id);
 
-               //Newtons mometum law :
                if (b->isStandalone()){
-                       rb->angularAcceleration=diagDiv(m,rb->inertia);
                        rb->acceleration=f/rb->mass;
+                       rb->angularAcceleration=diagDiv(m,rb->inertia);
+                       
cundallDamp(dt,f,rb->velocity,rb->acceleration,m,rb->angularVelocity,rb->angularAcceleration);
                }
                else if (b->isClump()){
-                       // at this point, forces from clump members are already 
summed up, this is just for forces applied to clump proper, if there are such 
(does it have some physical meaning?)
-                       rb->angularAcceleration+=diagDiv(m,rb->inertia);
-                       rb->acceleration+=f/rb->mass; // accel for clump will 
be reset in Clump::moveMembers, called from the clump itself
+                       
rb->acceleration=rb->angularAcceleration=Vector3r::ZERO; // to make sure; 
should be reset in Clump::moveMembers
+                       FOREACH(Clump::memberMap::value_type mm, 
static_cast<Clump*>(b.get())->members){
+                               handleClumpMember(ncb,mm.first,rb);
+                       }
+                       // at this point, forces from clump members are already 
summed up, this is just for forces applied to clump proper, if there are such
+                       Vector3r dLinAccel=f/rb->mass, 
dAngAccel=diagDiv(m,rb->inertia);
+                       
cundallDamp(dt,f,rb->velocity,dLinAccel,m,rb->angularVelocity,dAngAccel);
+                       rb->acceleration+=dLinAccel;
+                       rb->angularAcceleration+=dAngAccel;
                }
-               else {
-                       assert(b->isClumpMember());
-                       assert(b->clumpId>b->id);
-                       const shared_ptr<Body>& 
clump=Body::byId(b->clumpId,ncb);
-                       RigidBodyParameters* 
clumpRBP=YADE_CAST<RigidBodyParameters*> ( clump->physicalParameters.get() );
-                       Vector3r diffClumpAccel=f/clumpRBP->mass;
-                       // angular acceleration from: normal torque + torque 
generated by the force WRT particle centroid on the clump centroid
-                       Vector3r 
diffClumpAngularAccel=diagDiv(m,clumpRBP->inertia)+diagDiv((rb->se3.position-clumpRBP->se3.position).Cross(f),clumpRBP->inertia);
 
-                       // damp increment of accels on the clump, using 
velocities of the clump MEMBER
-                       
cundallDamp(dt,f,rb->velocity,diffClumpAccel,m,rb->angularVelocity,diffClumpAngularAccel);
-                       // clumpRBP->{acceleration,angularAcceleration} are 
reset byt Clump::moveMembers, it is ok to just increment here
-                       clumpRBP->acceleration+=diffClumpAccel;
-                       clumpRBP->angularAcceleration+=diffClumpAngularAccel;
-                       
maxVelocitySq=max(maxVelocitySq,rb->velocity.SquaredLength());
-                       continue;
-               }
 
-               assert(!b->isClumpMember());
-               // damping: applied to non-clumps only, as clumps members were 
already damped above
-               if(!b->isClump()) 
cundallDamp(dt,f,rb->velocity,rb->acceleration,m,rb->angularVelocity,rb->angularAcceleration);
-
                maxVelocitySq=max(maxVelocitySq,rb->velocity.SquaredLength());
 
                // blocking DOFs
@@ -96,14 +96,3 @@
        }
 }
 
-/*
-:09:37] eudoxos2: enum {LOOP1,LOOP2,END}
-[16:09:37] eudoxos2: for(int state=LOOP1; state!=END; state++){
-[16:09:37] eudoxos2:   FOREACH(const shared_ptr<Body>& b, rootBody->bodies){
-[16:09:38] eudoxos2:           if(b->isClumpMember() && LOOP1){ [[apply that 
on b->clumpId]]  }
-[16:09:38] eudoxos2:           if((b->isStandalone && LOOP1) || (b->isClump && 
LOOP2){ [[damping, newton, integrate]]; b->moveClumpMembers(); }
-[16:09:40] eudoxos2:           }
-[16:09:42] eudoxos2:   }
-[16:09:44] eudoxos2: }*/
-
-

Modified: trunk/pkg/dem/Engine/DeusExMachina/NewtonsDampedLaw.hpp
===================================================================
--- trunk/pkg/dem/Engine/DeusExMachina/NewtonsDampedLaw.hpp     2009-07-10 
19:16:01 UTC (rev 1853)
+++ trunk/pkg/dem/Engine/DeusExMachina/NewtonsDampedLaw.hpp     2009-07-11 
13:52:26 UTC (rev 1854)
@@ -31,10 +31,12 @@
 NOTE: Cundall damping affected dynamic simulation! See 
examples/dynamic_simulation_tests
  
  */
+class RigidBodyParameters;
 
-
 class NewtonsDampedLaw : public DeusExMachina{
        inline void cundallDamp(const Real& dt, const Vector3r& f, const 
Vector3r& velocity, Vector3r& acceleration, const Vector3r& m, const Vector3r& 
angularVelocity, Vector3r& angularAcceleration);
+       void handleClumpMember(MetaBody* ncb, const body_id_t memberId, 
RigidBodyParameters* clumpRBP);
+
        public:
                ///damping coefficient for Cundall's non viscous damping
                Real damping;

Modified: trunk/py/yadeWrapper/yadeWrapper.cpp
===================================================================
--- trunk/py/yadeWrapper/yadeWrapper.cpp        2009-07-10 19:16:01 UTC (rev 
1853)
+++ trunk/py/yadeWrapper/yadeWrapper.cpp        2009-07-11 13:52:26 UTC (rev 
1854)
@@ -422,6 +422,8 @@
                python::list withBody(long id){ python::list ret; FOREACH(const 
shared_ptr<Interaction>& I, *proxee){ if(I->isReal() && (I->getId1()==id || 
I->getId2()==id)) ret.append(pyInteraction(I));} return ret;}
                python::list withBodyAll(long id){ python::list ret; 
FOREACH(const shared_ptr<Interaction>& I, *proxee){ if(I->getId1()==id || 
I->getId2()==id) ret.append(pyInteraction(I));} return ret; }
                long countReal(){ long ret=0; FOREACH(const 
shared_ptr<Interaction>& I, *proxee){ if(I->isReal()) ret++; } return ret; }
+               bool serializeSorted_get(){return proxee->serializeSorted;}
+               void serializeSorted_set(bool ss){proxee->serializeSorted=ss;}
 };
 
 Vector3r tuple2vec(const python::tuple& t){return 
Vector3r(python::extract<double>(t[0])(),python::extract<double>(t[1])(),python::extract<double>(t[2])());}
@@ -763,6 +765,7 @@
                .def("nth",&pyInteractionContainer::pyNth)
                .def("withBody",&pyInteractionContainer::withBody)
                .def("withBodyAll",&pyInteractionContainer::withBodyAll)
+               
.add_property("serializeSorted",&pyInteractionContainer::serializeSorted_get,&pyInteractionContainer::serializeSorted_set)
                .def("nth",&pyInteractionContainer::pyNth)
                .def("clear",&pyInteractionContainer::clear);
        
boost::python::class_<pyInteractionIterator>("InteractionIterator",python::init<pyInteractionIterator&>())

Modified: trunk/scripts/test/collider-stride-triax.py
===================================================================
--- trunk/scripts/test/collider-stride-triax.py 2009-07-10 19:16:01 UTC (rev 
1853)
+++ trunk/scripts/test/collider-stride-triax.py 2009-07-11 13:52:26 UTC (rev 
1854)
@@ -4,18 +4,20 @@
 import os.path
 loadFrom='/tmp/triax.xml'
 if not os.path.exists(loadFrom):
-       
TriaxialTest(numberOfGrains=8000,fast=True,noFiles=True).generate(loadFrom)
+       TriaxialTest(numberOfGrains=8000,fast=True,noFiles=True).load()
+       #O.run(500)
+       O.save(loadFrom)
 O.load(loadFrom)
 log.setLevel('TriaxialCompressionEngine',log.WARN) # shut up
-log.setLevel('InsertionSortCollider',log.DEBUG) # shut up
+log.setLevel('InsertionSortCollider',log.DEBUG)
 
 collider=utils.typedEngine('InsertionSortCollider')
 newton=utils.typedEngine('NewtonsDampedLaw')
 
 # use striding; say "if 0:" to disable striding and compare to regular runs
-if 1:
+if 0:
        # length by which bboxes will be made larger
-       collider['sweepLength']=.05*O.bodies[100].shape['radius']
+       collider['sweepLength']=0.05*O.bodies[100].shape['radius']
 
 O.step() # filter out initialization
 O.timingEnabled=True
@@ -29,6 +31,14 @@
        print 'Number of interactions: %d (real ratio: 
%g)'%(len(O.interactions),float(O.interactions.countReal())/len(O.interactions))
        print '======================================================='
        timing.reset()
+       # plot velocity histogram
+       if 0:
+               import pylab
+               pylab.hist([sqrt(sum([v**2 for v in b.phys['velocity']])) for b 
in O.bodies])
+               pylab.title('step %d; max speed 
%g'%(O.iter,sqrt(newton['maxVelocitySq'])))
+               pylab.grid()
+               pylab.savefig('%s-%05d.png'%(loadFrom,O.iter),dpi=40)
+               pylab.cla()
 
 print 'Total time: %g s'%(totalTime/1e9)
-quit()
+#quit()

Modified: trunk/scripts/test/compare-identical.py
===================================================================
--- trunk/scripts/test/compare-identical.py     2009-07-10 19:16:01 UTC (rev 
1853)
+++ trunk/scripts/test/compare-identical.py     2009-07-11 13:52:26 UTC (rev 
1854)
@@ -30,7 +30,8 @@
 if O.numThreads>1:
        print "WARNING: You should run single-threaded with OMP_NUM_THREADS=1; 
interaction order will be probably different otherwise!"
 
-O.load(initFile); O.switchWorld(); O.load(initFile); O.switchWorld()
+for world in 0,1:
+       O.load(initFile); O.interactions.serializeSorted=True; O.switchWorld();
 from hashlib import md5; import difflib,sys
 print "Identical at steps ",
 for i in xrange(0,stopIter/nSteps):

Modified: trunk/scripts/test/regular-sphere-pack.py
===================================================================
--- trunk/scripts/test/regular-sphere-pack.py   2009-07-10 19:16:01 UTC (rev 
1853)
+++ trunk/scripts/test/regular-sphere-pack.py   2009-07-11 13:52:26 UTC (rev 
1854)
@@ -16,7 +16,7 @@
 
 rad,gap=.15,.02
 rho=1e3
-kw={'density':rho}
+kw={'density':rho,'frictionAngle':.1}
 
 O.bodies.append(
        pack.regularHexa(


_______________________________________________
Mailing list: https://launchpad.net/~yade-dev
Post to     : [email protected]
Unsubscribe : https://launchpad.net/~yade-dev
More help   : https://help.launchpad.net/ListHelp

Reply via email to