yade-dev team mailing list archive
-
yade-dev team
-
Mailing list archive
-
Message #01566
[svn] r1899 - in trunk/pkg: common/Engine/StandAloneEngine dem/PreProcessor
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;