diff --git a/src/pe/amr/weight_assignment/MetisAssignmentFunctor.h b/src/pe/amr/weight_assignment/MetisAssignmentFunctor.h new file mode 100644 index 0000000000000000000000000000000000000000..3b03af49e8dfcf5b48772351c7afac2678f7204f --- /dev/null +++ b/src/pe/amr/weight_assignment/MetisAssignmentFunctor.h @@ -0,0 +1,63 @@ +//====================================================================================================================== +// +// 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 MetisAssignmentFunctor.h +//! \author Sebastian Eibl <sebastian.eibl@fau.de> +// +//====================================================================================================================== + +#pragma once + +#include "pe/amr/InfoCollection.h" + +#include "blockforest/loadbalancing/DynamicParMetis.h" + +namespace walberla { +namespace pe { +namespace amr { + +class MetisAssignmentFunctor +{ +public: + + typedef blockforest::DynamicParMetisBlockInfo PhantomBlockWeight; + typedef blockforest::DynamicParMetisBlockInfoPackUnpack PhantomBlockWeightPackUnpackFunctor; + + MetisAssignmentFunctor( const shared_ptr<InfoCollection>& ic ) : ic_( ic ) + {} + + void operator()( std::vector< std::pair< const PhantomBlock *, boost::any > > & blockData, const PhantomBlockForest & ) + { + for( auto it = blockData.begin(); it != blockData.end(); ++it ) + { + const uint_t& weight = ic_->find( it->first->getId() )->second.numberOfLocalBodies; + blockforest::DynamicParMetisBlockInfo info( int64_c(weight) ); + info.setVertexSize(int64_c( weight )); + for( uint_t nb = uint_t(0); nb < it->first->getNeighborhoodSize(); ++nb ) + { + info.setEdgeWeight(it->first->getNeighborId(nb), int64_c(weight) ); + } + it->second = info; + } + } + +private: + shared_ptr< InfoCollection > ic_; +}; + +} +} +} + diff --git a/src/pe/amr/weight_assignment/WeightAssignmentFunctor.cpp b/src/pe/amr/weight_assignment/WeightAssignmentFunctor.cpp new file mode 100644 index 0000000000000000000000000000000000000000..806c3538ae46599c61a713eae9b60ac010035ad6 --- /dev/null +++ b/src/pe/amr/weight_assignment/WeightAssignmentFunctor.cpp @@ -0,0 +1,31 @@ +//====================================================================================================================== +// +// 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 WeightAssignmentFunctor.cpp +//! \author Sebastian Eibl <sebastian.eibl@fau.de> +// +//====================================================================================================================== + +#include "WeightAssignmentFunctor.h" + +namespace walberla { +namespace pe { +namespace amr { + +const double WeightAssignmentFunctor::baseWeight = real_t(10.0); + +} +} +} diff --git a/src/pe/amr/weight_assignment/WeightAssignmentFunctor.h b/src/pe/amr/weight_assignment/WeightAssignmentFunctor.h new file mode 100644 index 0000000000000000000000000000000000000000..4f5b897e80e0053677bfe42e880165f71635880c --- /dev/null +++ b/src/pe/amr/weight_assignment/WeightAssignmentFunctor.h @@ -0,0 +1,89 @@ +//====================================================================================================================== +//====================================================================================================================== +// +// 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 WeightAssignmentFunctor.h +//! \author Sebastian Eibl <sebastian.eibl@fau.de> +// +//====================================================================================================================== + +#pragma once + +#include "pe/amr/InfoCollection.h" + +#include "blockforest/loadbalancing/PODPhantomData.h" + +namespace walberla { +namespace pe { +namespace amr { + +class WeightAssignmentFunctor +{ +public: + typedef walberla::blockforest::PODPhantomWeight<double> PhantomBlockWeight; + typedef walberla::blockforest::PODPhantomWeightPackUnpack<double> PhantomBlockWeightPackUnpackFunctor; + + ///Base weight due to allocated data structures. A weight of zero for blocks is dangerous as empty blocks might accumulate on one process! + static const double baseWeight; + + WeightAssignmentFunctor( shared_ptr<InfoCollection>& ic ) : ic_(ic) {} + + void operator()( std::vector< std::pair< const PhantomBlock *, boost::any > > & blockData, const PhantomBlockForest & ) + { + for( auto it = blockData.begin(); it != blockData.end(); ++it ) + { + const PhantomBlock * block = it->first; + //only change of one level is supported! + WALBERLA_ASSERT_LESS( int_c(block->getLevel()) - int_c(block->getSourceLevel()), 2 ); + + if (block->sourceBlockIsLarger()) + { + auto infoIt = ic_->find( block->getId().getFatherId() ); + WALBERLA_ASSERT_UNEQUAL( infoIt, ic_->end() ); + it->second = PhantomBlockWeight( double_c(infoIt->second.numberOfLocalBodies) / double_c(8) + baseWeight ); + continue; + } + + if (block->sourceBlockHasTheSameSize()) + { + auto infoIt = ic_->find( block->getId() ); + WALBERLA_ASSERT_UNEQUAL( infoIt, ic_->end() ); + it->second = PhantomBlockWeight( double_c(infoIt->second.numberOfLocalBodies) + baseWeight ); + continue; + } + + if (block->sourceBlockIsSmaller()) + { + double weight = 0; + for (uint_t child = 0; child < 8; ++child) + { + blockforest::BlockID childId(block->getId(), child); + auto childIt = ic_->find( childId ); + WALBERLA_ASSERT_UNEQUAL( childIt, ic_->end() ); + weight += double_c(childIt->second.numberOfLocalBodies); + } + it->second = PhantomBlockWeight( weight + baseWeight ); + continue; + } + } + } + +private: + shared_ptr<InfoCollection> ic_; +}; + +} +} +}