diff --git a/src/pe/amr/regrid/RegridMinMax.cpp b/src/pe/amr/regrid/RegridMinMax.cpp new file mode 100644 index 0000000000000000000000000000000000000000..62e9d06f410276eec3194f76de63d862cf3a06d4 --- /dev/null +++ b/src/pe/amr/regrid/RegridMinMax.cpp @@ -0,0 +1,85 @@ +//====================================================================================================================== +// +// 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 RegridMinMax.cpp +//! \author Sebastian Eibl <sebastian.eibl@fau.de> +// +//====================================================================================================================== + +#include "RegridMinMax.h" + +namespace walberla { +namespace pe { +namespace amr { + +void ReGridMinMax::operator()( std::vector< std::pair< const Block *, uint_t > > & minTargetLevels, + std::vector< const Block * > &, const BlockForest & /*forest*/ ) +{ + for( auto it = minTargetLevels.begin(); it != minTargetLevels.end(); ++it ) + { + const auto infoIt = ic_->find(it->first->getId()); + WALBERLA_ASSERT_UNEQUAL( infoIt, ic_->end() ); + + it->second = it->first->getLevel(); //keep everything as it is + + //check for refinement + if (infoIt->second.numberOfLocalBodies > maxBodies_) + { + it->second = it->first->getLevel() + uint_t(1); + continue; + } + + //check for coarsening + if ((it->first->getLevel() > 0) && (infoIt->second.numberOfLocalBodies < minBodies_)) + { + if (getOrCreateCoarseInfo(it->first->getId())->second.numberOfLocalBodies < maxBodies_) + { + it->second = it->first->getLevel() - uint_t(1); + } + continue; + } + } +} + +InfoCollection::const_iterator ReGridMinMax::getOrCreateCoarseInfo( const blockforest::BlockID& id ) +{ + auto fatherId = id.getFatherId(); + auto infoIt = ic_->find( fatherId ); + if (infoIt != ic_->end()) return infoIt; + + BlockInfo newWeight( 0, 0); + for (uint_t child = 0; child < 8; ++child) + { + blockforest::BlockID childId(fatherId, child); + auto childIt = ic_->find( childId ); + //meight be not available if not all blocks are on the same level + //return giant number to prevent coarsening + if (childIt == ic_->end()) + { + newWeight = BlockInfo( std::numeric_limits<uint_t>::max(), + std::numeric_limits<uint_t>::max()); + break; + } else + { + newWeight += childIt->second; + } + } + WALBERLA_LOG_DETAIL("creating coarse weights (" << newWeight << ")"); + return ic_->insert( std::make_pair(fatherId, newWeight) ).first; +} + +} // namespace amr +} // namespace pe +} // namespace walberla diff --git a/src/pe/amr/regrid/RegridMinMax.h b/src/pe/amr/regrid/RegridMinMax.h new file mode 100644 index 0000000000000000000000000000000000000000..47d24349ea07922a90c88e7e2ae5febfb1e4fb22 --- /dev/null +++ b/src/pe/amr/regrid/RegridMinMax.h @@ -0,0 +1,56 @@ +//====================================================================================================================== +// +// 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 RegridMinMax.h +//! \author Sebastian Eibl <sebastian.eibl@fau.de> +// +//====================================================================================================================== + +#pragma once + +#include <pe/Types.h> +#include <pe/amr/InfoCollection.h> + +#include <blockforest/Block.h> +#include <blockforest/BlockForest.h> +#include <core/logging/Logging.h> +#include <domain_decomposition/BlockDataID.h> + +namespace walberla { +namespace pe { +namespace amr { + +class ReGridMinMax +{ +public: + + ReGridMinMax( const shared_ptr<InfoCollection>& ic, const size_t minBodies, const size_t maxBodies) : + ic_( ic ), minBodies_(minBodies), maxBodies_(maxBodies) + {} + + void operator()( std::vector< std::pair< const Block *, uint_t > > & minTargetLevels, + std::vector< const Block * > &, const BlockForest & forest ); + +public: + const shared_ptr<InfoCollection> ic_; + size_t minBodies_; + size_t maxBodies_; + + InfoCollection::const_iterator getOrCreateCoarseInfo( const blockforest::BlockID& id ); +}; + +} // namespace amr +} // namespace pe +} // namespace walberla