yade-dev team mailing list archive
-
yade-dev team
-
Mailing list archive
-
Message #13122
[Branch ~yade-pkg/yade/git-trunk] Rev 4042: A simpler and faster version of spatialOverlapPeri. Only one call to floor(), ~20% speedup for IS...
------------------------------------------------------------
revno: 4042
committer: bchareyre <bruno.chareyre@xxxxxxxxxxxxxxx>
timestamp: Mon 2017-05-15 18:31:11 +0200
message:
A simpler and faster version of spatialOverlapPeri. Only one call to floor(), ~20% speedup for ISCollider::action. Tolerance introduced to fix detection failures.
modified:
pkg/common/InsertionSortCollider.cpp
pkg/common/InsertionSortCollider.hpp
--
lp:yade
https://code.launchpad.net/~yade-pkg/yade/git-trunk
Your team Yade developers is subscribed to branch lp:yade.
To unsubscribe from this branch go to https://code.launchpad.net/~yade-pkg/yade/git-trunk/+edit-subscription
=== modified file 'pkg/common/InsertionSortCollider.cpp'
--- pkg/common/InsertionSortCollider.cpp 2017-04-14 10:35:41 +0000
+++ pkg/common/InsertionSortCollider.cpp 2017-05-15 16:31:11 +0000
@@ -227,7 +227,9 @@
// update periodicity
assert(BB[0].axis==0); assert(BB[1].axis==1); assert(BB[2].axis==2);
- if(periodic) for(int i=0; i<3; i++) BB[i].updatePeriodicity(scene);
+ if(periodic) {
+ for(int i=0; i<3; i++) BB[i].updatePeriodicity(scene);
+ invSizes=Vector3r(1./scene->cell->getSize()[0],1./scene->cell->getSize()[1],1./scene->cell->getSize()[2]);}
if(verletDist<0){
Real minR=std::numeric_limits<Real>::infinity();
@@ -475,10 +477,6 @@
periodicity information; both values could be passed down as a parameters, avoiding 1 of 3 loops here.
We do some floats math here, so the speedup could noticeable; doesn't concertn the non-periodic variant,
where it is only plain comparisons taking place.
-
- In the same way, handleBoundInversion is passed only id1 and id2, but again insertionSort already knows in which sense
- the inversion happens; if the boundaries get apart (min getting up over max), it wouldn't have to check for overlap
- at all, for instance.
*/
//! return true if bodies bb overlap in all 3 dimensions
bool InsertionSortCollider::spatialOverlapPeri(Body::id_t id1, Body::id_t id2,Scene* scene, Vector3i& periods) const {
@@ -489,31 +487,24 @@
// LOG_DEBUG("dim["<<axis<<"]="<<dim);
// too big bodies
if (!allowBiggerThanPeriod){ assert(maxima[3*id1+axis]-minima[3*id1+axis]<.99*dim); assert(maxima[3*id2+axis]-minima[3*id2+axis]<.99*dim);}
- // find body of which minimum when taken as period start will make the gap smaller
- Real m1=minima[3*id1+axis],m2=minima[3*id2+axis];
- Real wMn=(cellWrapRel(m1,m2,m2+dim)<cellWrapRel(m2,m1,m1+dim)) ? m2 : m1;
- int pmn1,pmx1,pmn2,pmx2;
- Real mn1=cellWrap(m1,wMn,wMn+dim,pmn1), mx1=cellWrap(maxima[3*id1+axis],wMn,wMn+dim,pmx1);
- Real mn2=cellWrap(m2,wMn,wMn+dim,pmn2), mx2=cellWrap(maxima[3*id2+axis],wMn,wMn+dim,pmx2);
- if((pmn1!=pmx1) || (pmn2!=pmx2)){
- if (allowBiggerThanPeriod) {
- // If both bodies are bigger, we place them in the (0,0,0) period
- if((pmn1!=pmx1) && (pmn2!=pmx2)) {periods[axis]=0;}
- // else we define period with the position of the small body (we assume the big one sits in period (0,0,0), keep that in mind if velGrad(.,axis) is not a null vector)
- else {
- //FIXME: not sure what to do here...
-// periods[axis]=(pmn1==pmx1)? pmn1 : -pmn2;
- periods[axis]=0;
-// return true;
- }
- } else {
- Real span=(pmn1!=pmx1?mx1-mn1:mx2-mn2); if(span<0) span=dim-span;
- LOG_FATAL("Body #"<<(pmn1!=pmx1?id1:id2)<<" spans over half of the cell size "<<dim<<" (axis="<<axis<<", min="<<(pmn1!=pmx1?mn1:mn2)<<", max="<<(pmn1!=pmx1?mx1:mx2)<<", span="<<span<<", see flag allowBiggerThanPeriod)");
+
+ // define normalized positions relative to id1->max, and with +1 shift for id1->min so that body1's bounds cover an interval [shiftedMin; 1] at the end of a b1-centric period
+ Real lmin = (minima[3*id2+axis]-maxima[3*id1+axis])*invSizes[axis];
+ Real lmax = (maxima[3*id2+axis]-maxima[3*id1+axis])*invSizes[axis];
+ Real shiftedMin = (minima[3*id1+axis]-maxima[3*id1+axis])*invSizes[axis]+1.;
+ if((lmax-lmin)>1 || shiftedMin<0){
+ if (allowBiggerThanPeriod) {periods[axis]=0; continue;}
+ else {
+ LOG_FATAL("Body #"<<((lmax-lmin)>1?id2:id1)<<" spans over half of the cell size "<<dim<<" (axis="<<axis<<", see flag allowBiggerThanPeriod)");
throw runtime_error(__FILE__ ": Body larger than half of the cell size encountered.");}
- }
- else {
- periods[axis]=(int)(pmn1-pmn2);
- if(!(mn1<=mx2 && mx1 >= mn2)) return false;}
+ }
+ int period1 = floor(lmax);
+ //overlap around zero, on the "+" side
+ if ((lmin-period1) <= overlapTolerance) {periods[axis]=-period1; continue;}
+ //overlap around 1, on the "-" side
+ if ((lmax-period1+overlapTolerance) >= shiftedMin) {periods[axis]=-period1-1; continue;}
+ // none of the above, exit
+ return false;
}
return true;
}
=== modified file 'pkg/common/InsertionSortCollider.hpp'
--- pkg/common/InsertionSortCollider.hpp 2017-05-15 16:31:11 +0000
+++ pkg/common/InsertionSortCollider.hpp 2017-05-15 16:31:11 +0000
@@ -130,7 +130,8 @@
std::vector<Real> maxima, minima;
//! Whether the Scene was periodic (to detect the change, which shouldn't happen, but shouldn't crash us either)
bool periodic;
-
+ //! Store inverse sizes to avoid repeated divisions within loops
+ Vector3r invSizes;
// return python representation of the BB struct, as ([...],[...],[...]).
boost::python::tuple dumpBounds();