yade-dev team mailing list archive
-
yade-dev team
-
Mailing list archive
-
Message #12098
[Branch ~yade-pkg/yade/git-trunk] Rev 3684: Revert previous commit.
------------------------------------------------------------
revno: 3684
committer: Anton Gladky <gladky.anton@xxxxxxxxx>
timestamp: Mon 2015-06-15 08:33:01 +0200
message:
Revert previous commit.
Sometimes the following error occurs:
FATAL /home/gladk/dem/yade/trunk/core/ThreadRunner.cpp:30 run: Exception
occured:
boost: mutex lock failed in pthread_mutex_lock: Invalid argument
modified:
pkg/common/InsertionSortCollider.cpp
pkg/common/InsertionSortCollider.hpp
pkg/dem/GeneralIntegratorInsertionSortCollider.cpp
--
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 2015-06-13 07:40:38 +0000
+++ pkg/common/InsertionSortCollider.cpp 2015-06-15 06:33:01 +0000
@@ -30,28 +30,22 @@
assert(!periodic);
assert(v.size==(long)v.vec.size());
for(long i=1; i<v.size; i++){
- const Bounds viInit=v[i];
- long j=i-1;
- /* cache hasBB; otherwise 1% overall performance hit */ const bool viInitBB=viInit.hasBB;
- const bool isMin=viInit.isMin;
+ const Bounds viInit=v[i]; long j=i-1; /* cache hasBB; otherwise 1% overall performance hit */ const bool viInitBB=viInit.flags.hasBB;
+ const bool isMin=viInit.flags.isMin;
while(j>=0 && v[j]>viInit){
v[j+1]=v[j];
#ifdef PISC_DEBUG
if(watchIds(v[j].id,viInit.id)) cerr<<"Swapping #"<<v[j].id<<" with #"<<viInit.id<<" ("<<setprecision(80)<<v[j].coord<<">"<<setprecision(80)<<viInit.coord<<" along axis "<<v.axis<<")"<<endl;
- if(v[j].id==viInit.id){
- cerr<<"Inversion of body #"<<v[j].id<<" with itself, "<<v[j].isMin<<" & "<<
- viInit.isMin<<", isGreater "<<(v[j]>viInit)<<", "<<(v[j].coord>viInit.coord)<<endl;
- j--;
- continue;
- }
+ if(v[j].id==viInit.id){ cerr<<"Inversion of body #"<<v[j].id<<" with itself, "<<v[j].flags.isMin<<" & "<<viInit.flags.isMin<<", isGreater "<<(v[j]>viInit)<<", "<<(v[j].coord>viInit.coord)<<endl; j--; continue; }
#endif
// no collisions without bounding boxes
// also, do not collide body with itself; it sometimes happens for facets aligned perpendicular to an axis, for reasons that are not very clear
// see https://bugs.launchpad.net/yade/+bug/669095
// skip bounds with same isMin flags, since inversion doesn't imply anything in that case
- if(isMin && !v[j].isMin && doCollide && viInitBB && v[j].hasBB && (viInit.id!=v[j].id)) {
- handleBoundInversion(viInit.id,v[j].id,interactions,scene);
+ if(isMin && !v[j].flags.isMin && doCollide && viInitBB && v[j].flags.hasBB && (viInit.id!=v[j].id)) {
+ /*if (isMin)*/ handleBoundInversion(viInit.id,v[j].id,interactions,scene);
+// else handleBoundSplit(viInit.id,v[j].id,interactions,scene);
}
j--;
}
@@ -95,13 +89,11 @@
for (unsigned k=0; k<nChunks;k++) {
int threadNum = omp_get_thread_num();
for(long i=chunks[k]+1; i<chunks[k+1]; i++){
- const Bounds viInit=v[i];
- long j=i-1;
- const bool viInitBB=viInit.hasBB;
- const bool isMin=viInit.isMin;
+ const Bounds viInit=v[i]; long j=i-1; const bool viInitBB=viInit.flags.hasBB;
+ const bool isMin=viInit.flags.isMin;
while(j>=chunks[k] && v[j]>viInit){
v[j+1]=v[j];
- if(isMin && !v[j].isMin && doCollide && viInitBB && v[j].hasBB && (viInit.id!=v[j].id)) {
+ if(isMin && !v[j].flags.isMin && doCollide && viInitBB && v[j].flags.hasBB && (viInit.id!=v[j].id)) {
const Body::id_t& id1 = v[j].id; const Body::id_t& id2 = viInit.id;
if (spatialOverlap(id1,id2) && Collider::mayCollide(Body::byId(id1,scene).get(),Body::byId(id2,scene).get()) && !interactions->found(id1,id2))
newInteractions[threadNum].push_back(std::pair<Body::id_t,Body::id_t>(v[j].id,viInit.id));
@@ -123,14 +115,12 @@
long halfChunkEnd = long(i+chunkSize*0.5);
for(; i<halfChunkEnd; i++){
if (!(v[i]<v[i-1])) break; //contiguous chunks now connected consistently
- const Bounds viInit=v[i];
- long j=i-1;
- /* cache hasBB; otherwise 1% overall performance hit */ const bool viInitBB=viInit.hasBB;
- const bool isMin=viInit.isMin;
+ const Bounds viInit=v[i]; long j=i-1; /* cache hasBB; otherwise 1% overall performance hit */ const bool viInitBB=viInit.flags.hasBB;
+ const bool isMin=viInit.flags.isMin;
while(j>=halfChunkStart && viInit<v[j]){
v[j+1]=v[j];
- if(isMin && !v[j].isMin && doCollide && viInitBB && v[j].hasBB && (viInit.id!=v[j].id)) {
+ if(isMin && !v[j].flags.isMin && doCollide && viInitBB && v[j].flags.hasBB && (viInit.id!=v[j].id)) {
const Body::id_t& id1 = v[j].id; const Body::id_t& id2 = viInit.id;
//FIXME: do we need the check with found(id1,id2) here? It is checked again below...
if (spatialOverlap(id1,id2) && Collider::mayCollide(Body::byId(id1,scene).get(),Body::byId(id2,scene).get()) && !interactions->found(id1,id2))
@@ -160,7 +150,7 @@
it=BB[0].vec.begin(),et=BB[0].vec.end(); it < et; ++it)
{
if (it->coord > bv.max[0]) break;
- if (!it->isMin || !it->hasBB) continue;
+ if (!it->flags.isMin || !it->flags.hasBB) continue;
int offset = 3*it->id;
const shared_ptr<Body>& b=Body::byId(it->id,scene);
if(!b || !b->bound) continue;
@@ -303,16 +293,15 @@
const shared_ptr<Bound>& bv=b->bound;
// coordinate is min/max if has bounding volume, otherwise both are the position. Add periodic shift so that we are inside the cell
// watch out for the parentheses around ?: within ?: (there was unwanted conversion of the Reals to bools!)
- BBji.coord=((BBji.hasBB=((bool)bv)) ? (BBji.isMin ? bv->min[j] : bv->max[j]) : (b->state->pos[j])) - (periodic ? BBj.cellDim*BBji.period : 0.);
+ BBji.coord=((BBji.flags.hasBB=((bool)bv)) ? (BBji.flags.isMin ? bv->min[j] : bv->max[j]) : (b->state->pos[j])) - (periodic ? BBj.cellDim*BBji.period : 0.);
// if initializing periodic, shift coords & record the period into BBj[i].period
if(doInitSort && periodic) BBji.coord=cellWrap(BBji.coord,0,BBj.cellDim,BBji.period);
// for each body, copy its minima and maxima, for quick checks of overlaps later
//bounds have been all updated when j==0, we can safely copy them here when j==1
- if (BBji.isMin && j==1 &&bv) {
- memcpy(&minima[3*id],&bv->min,3*sizeof(Real));
- memcpy(&maxima[3*id],&bv->max,3*sizeof(Real));
- }
- } else { BBj[i].hasBB=false; /* for vanished body, keep the coordinate as-is, to minimize inversions. */ }
+ if (BBji.flags.isMin && j==1 &&bv) {
+ memcpy(&minima[3*id],&bv->min,3*sizeof(Real)); memcpy(&maxima[3*id],&bv->max,3*sizeof(Real));
+ }
+ } else { BBj[i].flags.hasBB=false; /* for vanished body, keep the coordinate as-is, to minimize inversions. */ }
}
}
@@ -363,13 +352,13 @@
for(long i=0; i<2*nBodies; i++){
// start from the lower bound (i.e. skipping upper bounds)
// skip bodies without bbox, because they don't collide
- if(!(V[i].isMin && V[i].hasBB)) continue;
+ if(!(V[i].flags.isMin && V[i].flags.hasBB)) continue;
const Body::id_t& iid=V[i].id;
// go up until we meet the upper bound
for(long j=i+1; /* handle case 2. of swapped min/max */ j<2*nBodies && V[j].id!=iid; j++){
const Body::id_t& jid=V[j].id;
// 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].isMin && V[j].hasBB)) continue;
+ if(!(V[j].flags.isMin && V[j].flags.hasBB)) continue;
if (spatialOverlap(iid,jid) && Collider::mayCollide(Body::byId(iid,scene).get(),Body::byId(jid,scene).get()) ){
#ifdef YADE_OPENMP
unsigned int threadNum = omp_get_thread_num();
@@ -389,13 +378,13 @@
#endif
} else { // periodic case: see comments above
for(long i=0; i<2*nBodies; i++){
- if(!(V[i].isMin && V[i].hasBB)) continue;
+ if(!(V[i].flags.isMin && V[i].flags.hasBB)) continue;
const Body::id_t& iid=V[i].id;
long cnt=0;
// we might wrap over the periodic boundary here; that's why the condition is different from the aperiodic case
for(long j=V.norm(i+1); V[j].id!=iid; j=V.norm(j+1)){
const Body::id_t& jid=V[j].id;
- if(!(V[j].isMin && V[j].hasBB)) continue;
+ if(!(V[j].flags.isMin && V[j].flags.hasBB)) continue;
handleBoundInversionPeri(iid,jid,interactions,scene);
if(cnt++>2*(long)nBodies){ LOG_FATAL("Uninterrupted loop in the initial sort?"); throw std::logic_error("loop??"); }
}
@@ -435,11 +424,8 @@
if(v[i_1].coord<=iCmpCoord) continue;
// vi is the copy that will travel down the list, while other elts go up
// if will be placed in the list only at the end, to avoid extra copying
- int j=i_1;
- Bounds vi=v[i];
- const bool viHasBB=vi.hasBB;
- const bool isMin=v[i].isMin;
-
+ int j=i_1; Bounds vi=v[i]; const bool viHasBB=vi.flags.hasBB;
+ const bool isMin=v[i].flags.isMin;
while(v[j].coord>vi.coord + /* wrap for elt just below split */ (v.norm(j+1)==loIdx ? v.cellDim : 0)){
long j1=v.norm(j+1);
// OK, now if many bodies move at the same pace through the cell and at one point, there is inversion,
@@ -455,8 +441,14 @@
// inversions close the the split need special care
if(j==loIdx && vi.coord<0) { vi.period-=1; vi.coord+=v.cellDim; loIdx=v.norm(loIdx+1); }
else if(j1==loIdx) { vNew.period+=1; vNew.coord-=v.cellDim; loIdx=v.norm(loIdx-1); }
- if(isMin && !v[j].isMin && (doCollide && viHasBB && v[j].hasBB)){
+ if(isMin && !v[j].flags.isMin && (doCollide && viHasBB && v[j].flags.hasBB)){
// see https://bugs.launchpad.net/yade/+bug/669095 and similar problem in aperiodic insertionSort
+ #if 0
+ if(vi.id==vNew.id){
+ LOG_FATAL("Inversion of body's #"<<vi.id<<" boundary with its other boundary, "<<v[j].coord<<" meets "<<vi.coord);
+ throw runtime_error(__FILE__ ": Body's boundary metting its opposite boundary.");
+ }
+ #endif
if((vi.id!=vNew.id)) handleBoundInversionPeri(vi.id,vNew.id,interactions,scene);
}
j=v.norm(j-1);
@@ -545,81 +537,6 @@
return true;
}
-inline bool InsertionSortCollider::spatialOverlap(const Body::id_t& id1, const Body::id_t& id2) const {
- assert(!periodic);
- return (minima[3*id1+0]<=maxima[3*id2+0]) && (maxima[3*id1+0]>=minima[3*id2+0]) &&
- (minima[3*id1+1]<=maxima[3*id2+1]) && (maxima[3*id1+1]>=minima[3*id2+1]) &&
- (minima[3*id1+2]<=maxima[3*id2+2]) && (maxima[3*id1+2]>=minima[3*id2+2]);
-}
-
-bool InsertionSortCollider::shouldBeErased(Body::id_t id1, Body::id_t id2, Scene* rb) const {
- if(!periodic) {
- return !spatialOverlap(id1,id2);
- } else {
- Vector3i periods;
- return !spatialOverlapPeri(id1,id2,rb,periods);
- }
-}
-
-void InsertionSortCollider::invalidatePersistentData() {
- for(int i=0; i<3; i++) {
- BB[i].vec.clear();
- BB[i].size=0;
- }
-}
-
-bool InsertionSortCollider::Bounds::operator<(const Bounds& b) const {
- /* handle special case of zero-width bodies, which could otherwise get min/max swapped in the unstable std::sort */
- if(id==b.id && coord==b.coord) return isMin;
- return coord<b.coord;
-}
-
-bool InsertionSortCollider::Bounds::operator>(const Bounds& b) const {
- if(id==b.id && coord==b.coord) return !isMin;
- return coord>b.coord;
-}
-
-#ifdef PISC_DEBUG
-bool InsertionSortCollider::Bounds::watchIds(Body::id_t id1,Body::id_t id2) const {
- return (watch1<0 &&(watch2==id1||watch2==id2))||
- (watch2<0 && (watch1==id1||watch1==id2))||
- (watch1==id1 && watch2==id2)||
- (watch1==id2 && watch2==id1);
-}
-#endif
-
-void InsertionSortCollider::VecBounds::updatePeriodicity(Scene* scene){
- assert(scene->isPeriodic);
- assert(axis>=0 && axis <=2);
- cellDim=scene->cell->getSize()[axis];
-}
-
-long InsertionSortCollider::VecBounds::norm(long i) const {
- if(i<0) i+=size;
- long ret=i%size;
- assert(ret>=0 && ret<size);
- return ret;
-}
-
-void InsertionSortCollider::VecBounds::dump(ostream& os) {
- string ret;
- for(size_t i=0; i<vec.size(); i++) {
- os<<((long)i==loIdx?"@@ ":"")<<vec[i].coord<<"(id="<<vec[i].id
- <<","<<(vec[i].isMin?"min":"max")<<",p"<<vec[i].period<<") ";
- }
- os<<endl;
-}
-
-InsertionSortCollider::Bounds& InsertionSortCollider::VecBounds::operator[](long idx) {
- assert(idx<size && idx>=0);
- return vec[idx];
-}
-
-const InsertionSortCollider::Bounds& InsertionSortCollider::VecBounds::operator[](long idx) const {
- assert(idx<size && idx>=0);
- return vec[idx];
-}
-
boost::python::tuple InsertionSortCollider::dumpBounds(){
boost::python::list bl[3]; // 3 bound lists, inserted into the tuple at the end
for(int axis=0; axis<3; axis++){
@@ -627,11 +544,11 @@
if(periodic){
for(long i=0; i<V.size; i++){
long ii=V.norm(i); // start from the period boundary
- bl[axis].append(boost::python::make_tuple(V[ii].coord,(V[ii].isMin?-1:1)*V[ii].id,V[ii].period));
+ bl[axis].append(boost::python::make_tuple(V[ii].coord,(V[ii].flags.isMin?-1:1)*V[ii].id,V[ii].period));
}
} else {
for(long i=0; i<V.size; i++){
- bl[axis].append(boost::python::make_tuple(V[i].coord,(V[i].isMin?-1:1)*V[i].id));
+ bl[axis].append(boost::python::make_tuple(V[i].coord,(V[i].flags.isMin?-1:1)*V[i].id));
}
}
}
=== modified file 'pkg/common/InsertionSortCollider.hpp'
--- pkg/common/InsertionSortCollider.hpp 2015-06-13 07:40:38 +0000
+++ pkg/common/InsertionSortCollider.hpp 2015-06-15 06:33:01 +0000
@@ -86,24 +86,30 @@
friend class GeneralIntegratorInsertionSortCollider;
- // struct for storing bounds of bodies
+ //! struct for storing bounds of bodies
struct Bounds{
- // coordinate along the given sortAxis
+ //! coordinate along the given sortAxis
Real coord;
//! id of the body this bound belongs to
Body::id_t id;
- // periodic cell coordinate
+ //! periodic cell coordinate
int period;
- // is it the minimum (true) or maximum (false) bound?
- bool hasBB=true;
- bool isMin=true;
- Bounds(Real coord_, Body::id_t id_, bool _isMin): coord(coord_), id(id_), period(0), isMin(_isMin){};
- bool operator<(const Bounds& b) const;
- bool operator>(const Bounds& b) const;
+ //! is it the minimum (true) or maximum (false) bound?
+ struct{ unsigned hasBB:1; unsigned isMin:1; } flags;
+ Bounds(Real coord_, Body::id_t id_, bool isMin): coord(coord_), id(id_), period(0){ flags.isMin=isMin; }
+ bool operator<(const Bounds& b) const {
+ /* handle special case of zero-width bodies, which could otherwise get min/max swapped in the unstable std::sort */
+ if(id==b.id && coord==b.coord) return flags.isMin;
+ return coord<b.coord;
+ }
+ bool operator>(const Bounds& b) const {
+ if(id==b.id && coord==b.coord) return !flags.isMin;
+ return coord>b.coord;
+ }
};
#ifdef PISC_DEBUG
int watch1, watch2;
- bool watchIds(Body::id_t,Body::id_t) const;
+ bool watchIds(Body::id_t id1,Body::id_t id2) const { return (watch1<0 &&(watch2==id1||watch2==id2))||(watch2<0 && (watch1==id1||watch1==id2))||(watch1==id1 && watch2==id2)||(watch1==id2 && watch2==id1); }
#endif
// we need this to find out about current maxVelocitySq
shared_ptr<NewtonIntegrator> newton;
@@ -119,32 +125,37 @@
long size;
// index of the lowest coordinate element, before which the container wraps
long loIdx;
- Bounds& operator[](long);
- const Bounds& operator[](long idx) const;
+ Bounds& operator[](long idx){ assert(idx<size && idx>=0); return vec[idx]; }
+ const Bounds& operator[](long idx) const { assert(idx<size && idx>=0); return vec[idx]; }
// update number of bodies, periodic properties and size from Scene
- void updatePeriodicity(Scene*);
+ void updatePeriodicity(Scene* scene){
+ assert(scene->isPeriodic);
+ assert(axis>=0 && axis <=2);
+ cellDim=scene->cell->getSize()[axis];
+ }
// normalize given index to the right range (wraps around)
- long norm(long) const;
+ long norm(long i) const { if(i<0) i+=size; long ret=i%size; assert(ret>=0 && ret<size); return ret;}
VecBounds(): axis(-1), size(0), loIdx(0){}
- void dump(ostream&);
+ void dump(ostream& os){ string ret; for(size_t i=0; i<vec.size(); i++) os<<((long)i==loIdx?"@@ ":"")<<vec[i].coord<<"(id="<<vec[i].id<<","<<(vec[i].flags.isMin?"min":"max")<<",p"<<vec[i].period<<") "; os<<endl;}
};
private:
- // storage for bounds
+ //! storage for bounds
VecBounds BB[3];
- // storage for bb maxima and minima
+ //! storage for bb maxima and minima
std::vector<Real> maxima, minima;
- // Whether the Scene was periodic (to detect the change, which shouldn't happen, but shouldn't crash us either)
+ //! Whether the Scene was periodic (to detect the change, which shouldn't happen, but shouldn't crash us either)
bool periodic;
// return python representation of the BB struct, as ([...],[...],[...]).
boost::python::tuple dumpBounds();
- /* sorting routine; insertion sort is very fast for strongly pre-sorted lists, which is our case
- http://en.wikipedia.org/wiki/Insertion_sort has the algorithm and other details
+ /*! sorting routine; insertion sort is very fast for strongly pre-sorted lists, which is our case
+ http://en.wikipedia.org/wiki/Insertion_sort has the algorithm and other details
*/
void insertionSort(VecBounds& v,InteractionContainer*,Scene*,bool doCollide=true);
void insertionSortParallel(VecBounds& v,InteractionContainer*,Scene*,bool doCollide=true);
void handleBoundInversion(Body::id_t,Body::id_t,InteractionContainer*,Scene*);
+// bool spatialOverlap(Body::id_t,Body::id_t) const;
// periodic variants
void insertionSortPeri(VecBounds& v,InteractionContainer*,Scene*,bool doCollide=true);
@@ -152,18 +163,27 @@
void handleBoundSplit(Body::id_t,Body::id_t,InteractionContainer*,Scene*);
bool spatialOverlapPeri(Body::id_t,Body::id_t,Scene*,Vector3i&) const;
- bool spatialOverlap(const Body::id_t& id1, const Body::id_t& id2) const;
+ inline bool spatialOverlap(const Body::id_t& id1, const Body::id_t& id2) const {
+ assert(!periodic);
+ return (minima[3*id1+0]<=maxima[3*id2+0]) && (maxima[3*id1+0]>=minima[3*id2+0]) &&
+ (minima[3*id1+1]<=maxima[3*id2+1]) && (maxima[3*id1+1]>=minima[3*id2+1]) &&
+ (minima[3*id1+2]<=maxima[3*id2+2]) && (maxima[3*id1+2]>=minima[3*id2+2]);
+ }
static Real cellWrap(const Real, const Real, const Real, int&);
static Real cellWrapRel(const Real, const Real, const Real);
+
public:
- // Predicate called from loop within InteractionContainer::erasePending
- bool shouldBeErased(Body::id_t, Body::id_t, Scene*) const;
+ //! Predicate called from loop within InteractionContainer::erasePending
+ bool shouldBeErased(Body::id_t id1, Body::id_t id2, Scene* rb) const {
+ if(!periodic) return !spatialOverlap(id1,id2);
+ else { Vector3i periods; return !spatialOverlapPeri(id1,id2,rb,periods); }
+ }
virtual bool isActivated();
// force reinitialization at next run
- virtual void invalidatePersistentData();
+ virtual void invalidatePersistentData(){ for(int i=0; i<3; i++){ BB[i].vec.clear(); BB[i].size=0; }}
vector<Body::id_t> probeBoundingVolume(const Bound&);
=== modified file 'pkg/dem/GeneralIntegratorInsertionSortCollider.cpp'
--- pkg/dem/GeneralIntegratorInsertionSortCollider.cpp 2015-06-13 07:40:38 +0000
+++ pkg/dem/GeneralIntegratorInsertionSortCollider.cpp 2015-06-15 06:33:01 +0000
@@ -141,9 +141,9 @@
// coordinate is min/max if has bounding volume, otherwise both are the position. Add periodic shift so that we are inside the cell
// watch out for the parentheses around ?: within ?: (there was unwanted conversion of the Reals to bools!)
- BBj[i].coord=((BBj[i].hasBB=((bool)bv)) ? (BBj[i].isMin ? bv->min[j] : bv->max[j]) : (b->state->pos[j])) - (periodic ? BBj.cellDim*BBj[i].period : 0.);
+ BBj[i].coord=((BBj[i].flags.hasBB=((bool)bv)) ? (BBj[i].flags.isMin ? bv->min[j] : bv->max[j]) : (b->state->pos[j])) - (periodic ? BBj.cellDim*BBj[i].period : 0.);
- } else { BBj[i].hasBB=false; /* for vanished body, keep the coordinate as-is, to minimize inversions. */ }
+ } else { BBj[i].flags.hasBB=false; /* for vanished body, keep the coordinate as-is, to minimize inversions. */ }
// if initializing periodic, shift coords & record the period into BBj[i].period
if(doInitSort && periodic) {
BBj[i].coord=cellWrap(BBj[i].coord,0,BBj.cellDim,BBj[i].period);
@@ -195,13 +195,13 @@
for(long i=0; i<2*nBodies; i++){
// start from the lower bound (i.e. skipping upper bounds)
// skip bodies without bbox, because they don't collide
- if(!(V[i].isMin && V[i].hasBB)) continue;
+ if(!(V[i].flags.isMin && V[i].flags.hasBB)) continue;
const Body::id_t& iid=V[i].id;
// go up until we meet the upper bound
for(long j=i+1; /* handle case 2. of swapped min/max */ j<2*nBodies && V[j].id!=iid; j++){
const Body::id_t& jid=V[j].id;
// 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].isMin) continue;
+ 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,scene);
assert(j<2*nBodies-1);
@@ -209,13 +209,13 @@
}
} else { // periodic case: see comments above
for(long i=0; i<2*nBodies; i++){
- if(!(V[i].isMin && V[i].hasBB)) continue;
+ if(!(V[i].flags.isMin && V[i].flags.hasBB)) continue;
const Body::id_t& iid=V[i].id;
long cnt=0;
// we might wrap over the periodic boundary here; that's why the condition is different from the aperiodic case
for(long j=V.norm(i+1); V[j].id!=iid; j=V.norm(j+1)){
const Body::id_t& jid=V[j].id;
- if(!V[j].isMin) continue;
+ if(!V[j].flags.isMin) continue;
handleBoundInversionPeri(iid,jid,interactions,scene);
if(cnt++>2*(long)nBodies){ LOG_FATAL("Uninterrupted loop in the initial sort?"); throw std::logic_error("loop??"); }
}