Author: eudoxos
Date: 2009-07-29 10:04:35 +0200 (Wed, 29 Jul 2009)
New Revision: 1899

Modified:
   trunk/pkg/common/Engine/StandAloneEngine/InsertionSortCollider.cpp
   trunk/pkg/dem/PreProcessor/TriaxialTest.cpp
Log:
1. Hopefully fix https://bugs.launchpad.net/yade/+bug/402098
2. Fast in TriaxialTest uses nBins==5 and binCoeff==2 for VelocityBins


Modified: trunk/pkg/common/Engine/StandAloneEngine/InsertionSortCollider.cpp
===================================================================
--- trunk/pkg/common/Engine/StandAloneEngine/InsertionSortCollider.cpp  
2009-07-29 08:00:56 UTC (rev 1898)
+++ trunk/pkg/common/Engine/StandAloneEngine/InsertionSortCollider.cpp  
2009-07-29 08:04:35 UTC (rev 1899)
@@ -216,20 +216,35 @@
                                // skip bodies without bbox since we would 
possibly never meet the upper bound again (std::sort may not be stable) and we 
don't want to collide those anyway
                                if(!(V[i].flags.isMin && V[i].flags.hasBB)) 
continue;
                                const body_id_t& iid=V[i].id;
+                               /* If std::sort swaps equal min/max bounds, 
there are 2 cases distinct cases to handle:
+
+                                       1. i is inside V, j gets to the end of 
V (since it loops till the maxbound is found)
+                                               here, we swap min/max to get 
the in the right order and continue with the loop over i;
+                                               next time this j-bound is 
handled (with a different i, for sure), it will be OK.
+                                       2. i is at the end of V, therefore 
(j=i+1)==2*nBodies, therefore V[j] doesn't exist (past the end)
+                                               here, we can just check for 
that and break the loop if it happens.
+                                               It is the last i that we 
process, nothing will come after.
+
+                                       NOTE: XX,YY,ZZ containers don't 
guarantee that i_min<i_max. This is needed only here and is
+                                               handled only for the sortAxis. 
Functionality-wise, this has no impact on further collision
+                                               detection, though.
+                               */
                                // TRVAR3(i,iid,V[i].coord);
                                // go up until we meet the upper bound
-                               for(size_t j=i+1; V[j].id!=iid; j++){
+                               for(size_t j=i+1; V[j].id!=iid && /* handle 
case 2. of swapped min/max */ j<2*nBodies; j++){
                                        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; }
+                                       // take 2 of the same condition (only 
handle collision [min_i..max_i]+min_j, not [min_i..max_i]+min_i (symmetric)
+                                       if(!V[j].flags.isMin) 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
                                        // that means that the upper bound is 
before the upper one; that can only happen if they
                                        // are equal and the unstable std::sort 
has swapped them. In that case, we need to go reverse
                                        // from V[i] until we meet the upper 
bound and swap the isMin flag
-                                       if(j==2*nBodies-1){
+                                       if(j==2*nBodies-1){ /* handle case 1. 
of swapped min/max */
                                                size_t k=i-1;
                                                while(V[k].id!=iid && k>0) k--;
                                                assert(V[k].id==iid); // if 
this fails, we didn't meet the other bound in the downwards sense either; that 
should never happen

Modified: trunk/pkg/dem/PreProcessor/TriaxialTest.cpp
===================================================================
--- trunk/pkg/dem/PreProcessor/TriaxialTest.cpp 2009-07-29 08:00:56 UTC (rev 
1898)
+++ trunk/pkg/dem/PreProcessor/TriaxialTest.cpp 2009-07-29 08:04:35 UTC (rev 
1899)
@@ -573,6 +573,7 @@
        rootBody->engines.push_back(collider);
        if(fast){
                collider->sweepLength=.05*radiusMean;
+               collider->nBins=5; collider->binCoeff=2; /* gives a 2^5=32× 
difference between the lower and higher bin sweep lengths */
                shared_ptr<InteractionDispatchers> ids(new 
InteractionDispatchers);
                        ids->geomDispatcher=interactionGeometryDispatcher;
                        ids->physDispatcher=interactionPhysicsDispatcher;


_______________________________________________
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