Skip to content
Snippets Groups Projects
Forked from waLBerla / waLBerla
1073 commits behind the upstream repository.
SimpleCCD.cpp 3.59 KiB
//======================================================================================================================
//
//  This file is part of waLBerla. waLBerla is free software: you can
//  redistribute it and/or modify it under the terms of the GNU General Public
//  License as published by the Free Software Foundation, either version 3 of
//  the License, or (at your option) any later version.
//
//  waLBerla is distributed in the hope that it will be useful, but WITHOUT
//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
//  for more details.
//
//  You should have received a copy of the GNU General Public License along
//  with waLBerla (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
//
//! \file ICCD.h
//! \author Sebastian Eibl <sebastian.eibl@fau.de>
//
//======================================================================================================================

#include <cstdlib>

#include "SimpleCCD.h"

#include "pe/rigidbody/BodyStorage.h"

#include "core/logging/Logging.h"

#include <vector>
#include <utility>

namespace walberla {
namespace pe {
namespace ccd {

SimpleCCD::SimpleCCD(BodyStorage& globalStorage, Storage& storage) : globalStorage_(globalStorage), storage_(storage)
{
   storage_[0].registerAddCallback( "SimpleCCD", std::bind(&SimpleCCD::add, this, std::placeholders::_1) );
   storage_[0].registerRemoveCallback( "SimpleCCD", std::bind(&SimpleCCD::remove, this, std::placeholders::_1) );

   storage_[1].registerAddCallback( "SimpleCCD", std::bind(&SimpleCCD::add, this, std::placeholders::_1) );
   storage_[1].registerRemoveCallback( "SimpleCCD", std::bind(&SimpleCCD::remove, this, std::placeholders::_1) );
}

SimpleCCD::~SimpleCCD()
{
   storage_[0].deregisterAddCallback( "SimpleCCD" );
   storage_[0].deregisterRemoveCallback( "SimpleCCD" );

   storage_[1].deregisterAddCallback( "SimpleCCD" );
   storage_[1].deregisterRemoveCallback( "SimpleCCD" );
}


PossibleContacts& SimpleCCD::generatePossibleContacts( WcTimingTree* tt ){
   contacts_.clear();

   if (tt != nullptr) tt->start("SimpleCCD");
   for (auto it1 = bodies_.begin(); it1 != bodies_.end(); ++it1){
      for (auto it2 = it1 + 1; it2 !=bodies_.end(); ++it2)
      {
         if (!((*it1)->hasInfiniteMass() && (*it2)->hasInfiniteMass()))
         {
            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)
      {
         if (!((*it1)->hasInfiniteMass() && it2->hasInfiniteMass()))
         {
            if ( (*it1)->getSystemID() > it2->getSystemID() )
               contacts_.push_back(std::make_pair(it2.getBodyID(), *it1));
            else
               contacts_.push_back(std::make_pair(*it1, it2.getBodyID()));
         }
      }
   }
   if (tt != nullptr) tt->stop("SimpleCCD");

   return contacts_;
}

int SimpleCCD::getObservedBodyCount() const
{
   return static_cast<int> (globalStorage_.size() + bodies_.size());
}

void SimpleCCD::add   ( BodyID body )
{
   bodies_.push_back( body );
}

void SimpleCCD::remove( BodyID body )
{
   WALBERLA_LOG_DETAIL( "Removing body " << body->getSystemID() << " from CCD." );
   auto bodyIt = std::find(bodies_.begin(), bodies_.end(), body);
   if (bodyIt != bodies_.end())
   {
      std::swap(*bodyIt, bodies_.back());
      bodies_.pop_back();
   }
}

}  // namespace ccd
}  // namespace pe
}  // namespace walberla