diff --git a/src/geometry/InitBoundaryHandling.h b/src/geometry/InitBoundaryHandling.h index 43d97318006e45c31a077e960b9e00f1440aaa3c..7be3b02710ad675f91a8906e67f34b28a0b3bd74 100644 --- a/src/geometry/InitBoundaryHandling.h +++ b/src/geometry/InitBoundaryHandling.h @@ -127,7 +127,19 @@ void setNonBoundaryCellsToDomain( StructuredBlockStorage & blocks, BlockDataID b } } - +template<typename FlagField_T> +void setNonBoundaryCellsToDomain( StructuredBlockStorage & blocks, BlockDataID flagFieldID, + field::FlagUID fluidFlagID) +{ + for( auto blockIt = blocks.begin(); blockIt != blocks.end(); ++blockIt ) + { + auto flagField = blockIt->template getData<FlagField_T>( flagFieldID ); + auto fluidFlag = flagField->getOrRegisterFlag(fluidFlagID); + for( auto it = flagField->beginWithGhostLayerXYZ(); it != flagField->end(); ++it ) + if ( *it == 0 ) + addFlag(it, fluidFlag); + } +} } // namespace geometry diff --git a/src/geometry/initializer/BoundaryFromImage.impl.h b/src/geometry/initializer/BoundaryFromImage.impl.h index c946839202e6868018d425809a000e9299bbd8b8..7b75bdf5c2cbfe1511cd55e6c777e175eedf88b0 100644 --- a/src/geometry/initializer/BoundaryFromImage.impl.h +++ b/src/geometry/initializer/BoundaryFromImage.impl.h @@ -102,15 +102,14 @@ namespace initializer { for( auto setterIt = boundarySetters.begin(); setterIt != boundarySetters.end(); ++setterIt ) setterIt->second.configure( *blockIt, handlingID_ ); - auto handling = blockIt->template getData<Handling>( handlingID_ ); - const auto flagField = handling->getFlagField(); + const auto flagField = BoundarySetter<Handling>::getFlagField(*blockIt, handlingID_); const cell_idx_t width = cell_idx_c( img.width() ) ; const cell_idx_t height = cell_idx_c( img.height()) ; CellInterval imgInterval( xOffset, yOffset, lowerExtrusionLimit, xOffset+ width-1, yOffset + height-1, upperExtrusionLimit-1 ); - const cell_idx_t ghostLayers = cell_idx_c( handling->getFlagField()->nrOfGhostLayers() ); + const cell_idx_t ghostLayers = cell_idx_c( flagField->nrOfGhostLayers() ); if ( lowerExtrusionLimit < -ghostLayers ) lowerExtrusionLimit = -ghostLayers; diff --git a/src/geometry/initializer/BoundaryFromVoxelFile.impl.h b/src/geometry/initializer/BoundaryFromVoxelFile.impl.h index bd526421a58432d52112e71b7ac6cbe62495a7d1..de8e99a47aeb14ff63242810653e8211a17a9079 100644 --- a/src/geometry/initializer/BoundaryFromVoxelFile.impl.h +++ b/src/geometry/initializer/BoundaryFromVoxelFile.impl.h @@ -104,7 +104,8 @@ BoundaryFromVoxelFile<BoundaryHandlerT>::getIntersectedCellIntervals( const std: CellIntervalMap cellIntervals; for( auto blockIt = structuredBlockStorage_.begin(); blockIt != structuredBlockStorage_.end(); ++blockIt ) { - auto ci = blockIt->template getData<BoundaryHandlerT>( boundaryHandlerID_ )->getFlagField()->xyzSizeWithGhostLayer(); + auto flagField = BoundarySetter<BoundaryHandlerT>::getFlagField(*blockIt, boundaryHandlerID_); + auto ci = flagField->xyzSizeWithGhostLayer(); structuredBlockStorage_.transformBlockLocalToGlobalCellInterval( ci, *blockIt ); ci.intersect(fileCellInterval); if( !ci.empty() ) diff --git a/src/geometry/initializer/BoundarySetter.h b/src/geometry/initializer/BoundarySetter.h index 0c2281dcf06b14fe7799bff60e6317872f18ecd9..256ec58444530bcce20502a4541cab8b3a1b951c 100644 --- a/src/geometry/initializer/BoundarySetter.h +++ b/src/geometry/initializer/BoundarySetter.h @@ -91,6 +91,10 @@ namespace initializer { //@} //**************************************************************************************************************** + + static const typename BoundaryHandling_T::FlagField * getFlagField(const IBlock & block, ConstBlockDataID bdId) { + return block.getData<BoundaryHandling_T >(bdId)->getFlagField(); + } private: bool flagOrBoundaryCondition_; @@ -241,3 +245,4 @@ namespace initializer { } // namespace walberla +#include "BoundarySetterFlagFieldSpecialization.h" diff --git a/src/geometry/initializer/BoundarySetterFlagFieldSpecialization.h b/src/geometry/initializer/BoundarySetterFlagFieldSpecialization.h new file mode 100644 index 0000000000000000000000000000000000000000..1ae6a04e217ea2533180775e914f38788c10b5b5 --- /dev/null +++ b/src/geometry/initializer/BoundarySetterFlagFieldSpecialization.h @@ -0,0 +1,161 @@ +//====================================================================================================================== +// +// 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 Helper.h +//! \ingroup geometry +//! \author Martin Bauer <martin.bauer@fau.de> +// +//====================================================================================================================== + +#pragma once + +#include "core/Abort.h" +#include "core/DataTypes.h" +#include "core/config/Config.h" + +#include "field/FlagFunctions.h" +#include "field/FlagField.h" +#include "domain_decomposition/IBlock.h" +#include "domain_decomposition/StructuredBlockStorage.h" + +#include "BoundarySetter.h" + +namespace walberla { +namespace geometry { +namespace initializer { + + /* + * Specialization for FlagFields to make all initializers also work with pure FlagFields instead of + * boundary handlings + */ + template< typename Flag_T > + class BoundarySetter< FlagField<Flag_T> > + { + public: + + //** Setup ************************************************************************************************ + /*! \name Setup */ + //@{ + void setConfigBlock( const Config::BlockHandle & blockHandle, + const std::set<std::string> & subblocksToIgnore = std::set<std::string> () ); + void setBoundaryConfigBlock( const BoundaryUID & boundaryUID, const Config::BlockHandle & blockHandle ); + void setBoundaryConfig( const BoundaryUID & boundaryUID, const shared_ptr<BoundaryConfiguration> & conf ); + void setFlagUID( const FlagUID & flag ); + //@} + //**************************************************************************************************************** + + + //** Setting Boundaries *********************************************************************************** + /*! \name Setting Boundaries */ + //@{ + void configure( IBlock & block, BlockDataID boundaryHandlingID ); + void set( cell_idx_t x, cell_idx_t y, cell_idx_t z ); + void set( const CellInterval & ci ); + + template<typename CellIterator> + void set( const CellIterator & begin, const CellIterator & end ); + + FlagField<Flag_T> * getFlagField() const { return flagField_; } + //@} + //**************************************************************************************************************** + + static const FlagField<Flag_T> * getFlagField(const IBlock & block, ConstBlockDataID bdId) { + return block.getData<FlagField< Flag_T > >(bdId); + } + private: + FlagUID flagUID_; + FlagField<Flag_T> * flagField_; + Flag_T flag_; + }; + + template<typename Flag_T> + void BoundarySetter<FlagField<Flag_T> >::setConfigBlock( const Config::BlockHandle & blockHandle, + const std::set<std::string> & subblocksToIgnore ) + { + // Check that either there is one sub-block with boundary information or a flag parameter + Config::Blocks boundaryConfigBlocks; + blockHandle.getBlocks ( boundaryConfigBlocks ); + + for( auto blockHandleIt = boundaryConfigBlocks.begin(); blockHandleIt != boundaryConfigBlocks.end(); ) + { + std::string key = blockHandleIt->getKey(); + if ( subblocksToIgnore.find( key ) != subblocksToIgnore.end() ) + boundaryConfigBlocks.erase( blockHandleIt ); + else + ++blockHandleIt; + } + + if (boundaryConfigBlocks.size () > 0 ) { + WALBERLA_ABORT_NO_DEBUG_INFO( "No boundary setup blocks are allowed when configuring a flag field" + << blockHandle.getKey() ); + } + const bool hasFlagParameter = blockHandle.isDefined( "flag" ); + if( !hasFlagParameter ) { + WALBERLA_ABORT_NO_DEBUG_INFO( "Geometry Block \"" << blockHandle.getKey() << ": missing flag parameter " ); + } + flagUID_ = FlagUID( blockHandle.getParameter<std::string>("flag") ); + } + + template<typename Flag_T> + void BoundarySetter<FlagField<Flag_T> >::setBoundaryConfigBlock( const BoundaryUID & boundaryUID, const Config::BlockHandle & blockHandle ) + { + WALBERLA_ABORT("Passed boundary information to an initializer that sets up a pure flag field only"); + } + + template<typename Flag_T> + void BoundarySetter<FlagField<Flag_T>>::setBoundaryConfig( const BoundaryUID & boundaryUID, const shared_ptr<BoundaryConfiguration> & conf ) + { + WALBERLA_ABORT("Passed boundary information to an initializer that sets up a pure flag field only"); + } + + template<typename Flag_T> + void BoundarySetter<FlagField<Flag_T>>::setFlagUID( const FlagUID & flag ) + { + flagUID_ = flag; + } + + template<typename Flag_T> + void BoundarySetter<FlagField<Flag_T>>::configure( IBlock & block, BlockDataID flagFieldID ) + { + flagField_ = block.getData< FlagField<Flag_T> >( flagFieldID ); + flag_ = flagField_->getOrRegisterFlag( flagUID_ ); + } + + template<typename Flag_T> + void BoundarySetter<FlagField<Flag_T>>::set( cell_idx_t x, cell_idx_t y, cell_idx_t z ) + { + flagField_->addFlag( x, y, z, flag_ ); + } + + template<typename Flag_T> + void BoundarySetter<FlagField<Flag_T>>::set( const CellInterval & ci ) + { + for( auto it = flagField_->beginSliceXYZ(ci); it != flagField_->end(); ++it ) + field::addFlag(it, flag_); + } + + template<typename Flag_T> + template< typename CellIterator > + void BoundarySetter<FlagField<Flag_T> >::set( const CellIterator & begin, const CellIterator & end ) + { + for(auto it = begin; it != end; ++it) + flagField_->addFlag(it->x(), it->y(), it->z(), flag_); + } + +} // namespace initializer +} // namespace geometry +} // namespace walberla + +