From 4933267f33d55c6750d9b6a3aff307d9aafe972d Mon Sep 17 00:00:00 2001
From: Sebastian Eibl <sebastian.eibl@fau.de>
Date: Fri, 8 Dec 2017 16:56:04 +0100
Subject: [PATCH] coarse collision returns colliding bodies in deterministic
 order

---
 src/pe/ccd/HashGrids.h   |  4 ++++
 src/pe/ccd/SimpleCCD.cpp | 20 ++++++++++++++++----
 tests/pe/HashGrids.cpp   |  9 ++++++++-
 3 files changed, 28 insertions(+), 5 deletions(-)

diff --git a/src/pe/ccd/HashGrids.h b/src/pe/ccd/HashGrids.h
index 060be9447..18871eff3 100644
--- a/src/pe/ccd/HashGrids.h
+++ b/src/pe/ccd/HashGrids.h
@@ -492,6 +492,10 @@ void HashGrids::HashGrid::processBodies( BodyID* bodies, size_t bodyCount, Conta
 template< typename Contacts >  // Contact container type
 void HashGrids::collide( BodyID a, BodyID b, Contacts& contacts )
 {
+   //make sure to always check in the correct order (a<b)
+   if (a->getSystemID() > b->getSystemID())
+      std::swap(a, b);
+
    if( ( !a->hasInfiniteMass() || !b->hasInfiniteMass() ) &&        // Ignoring contacts between two fixed bodies
        ( a->getAABB().intersects( b->getAABB() ) ) )  // Testing for overlapping bounding boxes
    {
diff --git a/src/pe/ccd/SimpleCCD.cpp b/src/pe/ccd/SimpleCCD.cpp
index b94a6669b..dee87d16b 100644
--- a/src/pe/ccd/SimpleCCD.cpp
+++ b/src/pe/ccd/SimpleCCD.cpp
@@ -57,14 +57,26 @@ PossibleContacts& SimpleCCD::generatePossibleContacts( WcTimingTree* tt ){
 
    if (tt != NULL) tt->start("SimpleCCD");
    for (auto it1 = bodies_.begin(); it1 != bodies_.end(); ++it1){
-      for (auto it2 = it1 + 1; it2 !=bodies_.end(); ++it2){
+      for (auto it2 = it1 + 1; it2 !=bodies_.end(); ++it2)
+      {
          if (!((*it1)->hasInfiniteMass() && (*it2)->hasInfiniteMass()))
-            contacts_.push_back(std::make_pair(*it1, *it2));
+         {
+            if ( (*it1)->getSystemID() > (*it2)->getSystemID() )
+               contacts_.push_back(std::make_pair(*it2, *it1));
+            else
+               contacts_.push_back(std::make_pair(*it1, *it2));
+         }
       }
 
-      for (auto it2 = globalStorage_.begin(); it2 != globalStorage_.end(); ++it2){
+      for (auto it2 = globalStorage_.begin(); it2 != globalStorage_.end(); ++it2)
+      {
          if (!((*it1)->hasInfiniteMass() && (*it2)->hasInfiniteMass()))
-            contacts_.push_back(std::make_pair(*it1, *it2));
+         {
+            if ( (*it1)->getSystemID() > (*it2)->getSystemID() )
+               contacts_.push_back(std::make_pair(*it2, *it1));
+            else
+               contacts_.push_back(std::make_pair(*it1, *it2));
+         }
       }
    }
    if (tt != NULL) tt->stop("SimpleCCD");
diff --git a/tests/pe/HashGrids.cpp b/tests/pe/HashGrids.cpp
index cc48c5b03..a1790653b 100644
--- a/tests/pe/HashGrids.cpp
+++ b/tests/pe/HashGrids.cpp
@@ -115,7 +115,7 @@ int main( int argc, char** argv )
                      iron, true, false, true);
 
     syncShadowOwners<BodyTuple>( forest->getBlockForest(), storageID);
-    for (int i=0; i < 100; ++i){
+    for (int step=0; step < 100; ++step){
        cr( real_c(0.1) );
        syncShadowOwners<BodyTuple>( forest->getBlockForest(), storageID);
 
@@ -132,6 +132,13 @@ int main( int argc, char** argv )
           WALBERLA_LOG_DETAIL_ON_ROOT("tracked particles: " << sccd->getObservedBodyCount() << "/" << hccd->getObservedBodyCount());
           WALBERLA_CHECK_EQUAL(tmp1, tmp2);
           WALBERLA_LOG_DETAIL_ON_ROOT("contacts on root: " << cont1.size());
+
+          // check for correct ordering of bodies within contacts
+          for (size_t i = 0; i < cont1.size(); ++i)
+          {
+             WALBERLA_CHECK_LESS(cont1[i].getBody1()->getSystemID(), cont1[i].getBody2()->getSystemID());
+             WALBERLA_CHECK_LESS(cont2[i].getBody1()->getSystemID(), cont2[i].getBody2()->getSystemID());
+          }
        }
     }
 
-- 
GitLab