Author: eudoxos
Date: 2009-06-25 22:54:20 +0200 (Thu, 25 Jun 2009)
New Revision: 1815
Modified:
trunk/pkg/common/Engine/StandAloneEngine/InsertionSortCollider.cpp
Log:
1. Fix corner case in InsertionSortCollider related to instability of std::sort
(quicksort) and bodies having the same upper and lower bounds (facet in the xy
plane, for example). Thanks to Anton for providing the crasher.
Modified: trunk/pkg/common/Engine/StandAloneEngine/InsertionSortCollider.cpp
===================================================================
--- trunk/pkg/common/Engine/StandAloneEngine/InsertionSortCollider.cpp
2009-06-24 22:06:24 UTC (rev 1814)
+++ trunk/pkg/common/Engine/StandAloneEngine/InsertionSortCollider.cpp
2009-06-25 20:54:20 UTC (rev 1815)
@@ -130,7 +130,7 @@
#pragma omp section
std::sort(ZZ.begin(),ZZ.end());
}
- } else {
+ } else { // sortThenCollide
insertionSort(XX,interactions,rb,false);
insertionSort(YY,interactions,rb,false);
insertionSort(ZZ,interactions,rb,false);
}
// traverse the container along requested axis
@@ -151,6 +151,19 @@
// 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
+ // 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){
+ 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
+ assert(!V[k].flags.isMin); //
the lower bound should be maximum in this (exceptional) case; we will fix that
now
+ V[k].flags.isMin=true;
V[i].flags.isMin=false;
+ LOG_DEBUG("Swapping coincident
min/max of #"<<iid<<" at positions "<<k<<" and "<<i<<"(coords: "<<V[k].coord<<"
and "<<V[i].coord);
+ break; // would happen anyways
+ }
}
}
}
_______________________________________________
Mailing list: https://launchpad.net/~yade-dev
Post to : [email protected]
Unsubscribe : https://launchpad.net/~yade-dev
More help : https://help.launchpad.net/ListHelp