diff --git a/dune/alugrid/3d/Makefile.am b/dune/alugrid/3d/Makefile.am index b186974cad4178b968eadeb9ab4875907ac2a256..d9dcf7b29e94175e2cf27cf0e43f7361169f371b 100644 --- a/dune/alugrid/3d/Makefile.am +++ b/dune/alugrid/3d/Makefile.am @@ -6,7 +6,7 @@ alu3dgrid_HEADERS = alu3dinclude.hh communication.hh \ faceutility.hh faceutility_imp.cc geometry.hh geometry_imp.cc \ gridfactory.hh gridfactory.cc gridview.hh \ indexsets.hh iterator.hh iterator.cc iterator_imp.cc alu3diterators.hh \ - lbdatahandle.hh alugrid.hh + alugrid.hh headercheck_IGNORE = $(alu3dgrid_HEADERS) diff --git a/dune/alugrid/3d/datahandle.hh b/dune/alugrid/3d/datahandle.hh index 28eb72c180af506ffc03a06b8a17ea832c01fa51..c8c58346867aa51b41ad71053fe6d1369cd89729 100644 --- a/dune/alugrid/3d/datahandle.hh +++ b/dune/alugrid/3d/datahandle.hh @@ -10,6 +10,7 @@ #include <dune/grid/common/adaptcallback.hh> #include <dune/alugrid/3d/datacollectorcaps.hh> +#include <dune/alugrid/common/ldbhandleif.hh> //- local includes #include "alu3dinclude.hh" @@ -487,154 +488,355 @@ namespace ALUGrid } }; - //! the corresponding interface class is defined in bsinclude.hh - template <class GridType, class DataCollectorType> + + //////////////////////////////////////////////////////////////////////////////////////////// + // + // --GatherScatterLoadBalance: ALU data handle implementation for user defined load balance + // + //////////////////////////////////////////////////////////////////////////////////////////// + template <class GridType, class LoadBalanceHandleType> class GatherScatterLoadBalance : public GatherScatter { protected: - enum { codim = 0 }; typedef typename GridType::MPICommunicatorType Comm; typedef Dune::ALU3dImplTraits< GridType::elementType, Comm > ImplTraits; - typedef typename ImplTraits::template Codim< codim >::ImplementationType IMPLElementType; - typedef typename ImplTraits::template Codim< codim >::InterfaceType HElementType; + typedef typename ImplTraits::template Codim< 0 >::InterfaceType HElementType; - typedef typename GridType::template Codim<0>::Entity EntityType; - typedef Dune :: MakeableInterfaceObject<EntityType> MakeableEntityType; - typedef typename MakeableEntityType :: ImplementationType RealEntityType; - - typedef typename ImplTraits::template Codim< 1 >::InterfaceType HFaceType; - - typedef typename ImplTraits::template Codim< 0 >::GhostInterfaceType HGhostType; - typedef typename ImplTraits::template Codim< 0 >::GhostImplementationType ImplGhostType; - - typedef typename ImplTraits::PllElementType PllElementType; + typedef typename GridType :: template Codim<0>::Entity EntityType; + typedef Dune :: MakeableInterfaceObject<EntityType> MakeableEntityType; GridType & grid_; MakeableEntityType entityObj_; EntityType& entity_; - RealEntityType& realEntity_; - // data handle - DataCollectorType & dc_; + // pointer to load balancing user interface (if NULL internal load balancing is used) + LoadBalanceHandleType* ldbHandle_; - // used MessageBuffer - typedef typename GatherScatter :: ObjectStreamType ObjectStreamType; - - using GatherScatter :: inlineData ; - using GatherScatter :: xtractData ; + // true if userDefinedPartitioning is used, false if loadWeights is used + // both are disabled if ldbHandle_ is NULL + const bool useExternal_ ; public: //! Constructor - GatherScatterLoadBalance(GridType & grid, DataCollectorType & dc ) + GatherScatterLoadBalance( GridType & grid, + LoadBalanceHandleType& ldb, + const bool useExternal ) : grid_(grid), entityObj_( RealEntityType( grid.factory(), grid.maxLevel() ) ), - entity_( entityObj_ ), realEntity_( GridType::getRealImplementation( entity_ ) ), - dc_(dc) + entity_( entityObj_ ), + ldbHandle_( &ldb ), + useExternal_( useExternal ) + {} + + //! Constructor + GatherScatterLoadBalance( GridType & grid ) + : grid_(grid), + entityObj_( RealEntityType( grid.factory(), grid.maxLevel() ) ), + entity_( entityObj_ ), + ldbHandle_( 0 ), + useExternal_( false ) + {} + + // return true if user defined partitioning methods should be used + bool userDefinedPartitioning () const + { + return useExternal_ && ldbHandle_ ; + } + + // return true if user defined load balancing weights are provided + bool userDefinedLoadWeights () const + { + return ! useExternal_ && ldbHandle_ ; + } + + // returns true if user defined partitioning needs to be readjusted + bool repartition () + { + return userDefinedPartitioning() && ldbHandle().repartition(); + } + + // return set of ranks data is imported from during load balance + // this method is only used for user defined repartitioning + bool importRanks( std::set<int>& ranks ) const + { + alugrid_assert( userDefinedPartitioning() ); + return ldbHandle().importRanks( ranks ); + } + + // return set of ranks data is exported to during load balance + // this method is only used for user defined repartitioning + bool exportRanks( std::set<int>& ranks ) const + { + alugrid_assert( userDefinedPartitioning() ); + return ldbHandle().exportRanks( ranks ); + } + + // return destination (i.e. rank) where the given element should be moved to + // this needs the methods userDefinedPartitioning to return true + int destination ( HElementType &elem ) const + { + // make sure userDefinedPartitioning is enabled + alugrid_assert ( elem.level () == 0 ); + alugrid_assert ( userDefinedPartitioning() ); + return ldbHandle()( setEntity( elem ) ); + } + + // return load weight of given element + int loadWeight ( HElementType &elem ) const + { + // make sure userDefinedLoadWeights is enabled + alugrid_assert( userDefinedLoadWeights() ); + alugrid_assert ( elem.level() == 0 ); + return ldbHandle()( setEntity( elem ) ); + } + + protected: + EntityType& setEntity( HElementType& elem ) + { + GridType::getRealImplementation( entity_ ).setElement( elem ); + return entity_ ; + } + + LoadBalanceHandleType& ldbHandle() + { + alugrid_assert( ldbHandle_ ); + return *ldbHandle_; + } + + }; + + //////////////////////////////////////////////////////////////////////////////////////// + // + // --GatherScatterLoadBalance: ALU data handle implementation for CommDataHandleIF + // + //////////////////////////////////////////////////////////////////////////////////////// + template <class GridType, class LoadBalanceHandleType, class DataHandleImpl, class Data> + class GatherScatterLoadBalanceDataHandle + : public GatherScatterLoadBalance< GridType, LoadBalanceHandleType > + { + typedef GatherScatterLoadBalance< GridType, LoadBalanceHandleType > BaseType ; + protected: + static const int dimension = GridType :: dimension ; + + template< int codim > + struct Codim + { + typedef typename GridType :: Traits :: template Codim< codim > :: Entity Entity; + typedef typename GridType :: Traits :: template Codim< codim > :: EntityPointer + EntityPointer; + }; + + typedef Dune::ALU3dImplTraits< GridType::elementType, Comm > ImplTraits; + typedef typename ImplTraits::template Codim< 0 >::InterfaceType HElementType; + + typedef typename BaseType :: EntityType EntityType ; + + typedef Dune::CommDataHandleIF< DataHandleImpl, Data > DataHandleType; + + template <class DH, bool> + struct CompressAndReserve + { + static DataHandleImpl& asImp( DH& dh ) { return static_cast<DataHandleImpl &> (dh); } + + static void reserveMemory( DH& dataHandle, const size_t newElements ) + { + asImp( dataHandle ).reserveMemory( newElements ); + } + static void compress( DH& dataHandle ) + { + asImp( dataHandle ).compress(); + } + }; + + template <class DH> + struct CompressAndReserve< DH, false > + { + static void reserveMemory( DH& dataHandle, const size_t newElements ) {} + static void compress( DH& dataHandle ) {} + }; + + // check whether DataHandleImpl is derived from LoadBalanceHandleWithReserveAndCompress + static const bool hasCompressAndReserve = Dune::Conversion< DataHandleImpl, + LoadBalanceHandleWithReserveAndCompress >::exists ; + // don't transmit size in case we have special DataHandleImpl + static const bool transmitSize = ! hasCompressAndReserve ; + + typedef CompressAndReserve< DataHandleType, hasCompressAndReserve > CompressAndReserveType; + + // data handle (CommDataHandleIF) + DataHandleType& dataHandle_; + + // used MessageBuffer + typedef typename GatherScatter :: ObjectStreamType ObjectStreamType; + + using BaseType :: grid_ ; + using BaseType :: setEntity ; + + public: + //! Constructor taking load balance handle and data handle + GatherScatterLoadBalanceDataHandle( GridType & grid, + DataHandleType& dh, + LoadBalanceHandleType& ldb, + const bool useExternal = false ) + : BaseType( grid, ldb, useExternal ), + dataHandle_( dh ) + {} + + //! Constructor for DataHandle only + GatherScatterLoadBalanceDataHandle( GridType& grid, DataHandleType& dh ) + : BaseType( grid ), + dataHandle_( dh ) {} // return true if dim,codim combination is contained in data set bool contains(int dim, int codim) const { - return true; + return dataHandle_.contains( dim, codim ); } + // return true if user dataHandle is present which is the case here + bool hasUserData() const { return true ; } + //! this method is called from the dunePackAll method of the corresponding - //! Macro element class of the BSGrid, see gitter_dune_pll*.* //! here the data is written to the ObjectStream void inlineData ( ObjectStreamType & str , HElementType & elem, const int estimatedElements ) { + // store maxLevel of grid tree int mxl = grid_.maxLevel(); str.write(mxl); // store number of elements to be written (for restore) str.write(estimatedElements); // set element and then start alugrid_assert ( elem.level () == 0 ); - realEntity_.setElement(elem); - dc_.inlineData(str,entity_); + + // pack data for this element + inlineElementData( str, setEntity( elem ) ); + + // pack data for all children + for( HElementType *son = elem.down(); son ; son = son->next() ) + inlineElementData( str, setEntity( *son ) ); } //! this method is called from the duneUnpackSelf method of the corresponding - //! Macro element class of the BSGrid, see gitter_dune_pll*.* //! here the data is read from the ObjectStream void xtractData ( ObjectStreamType & str , HElementType & elem ) { alugrid_assert ( elem.level () == 0 ); + // read maxLevel int mxl = 0; str.read(mxl); - int newElements = 0 ; - str.read( newElements ); // set element and then start grid_.setMaxLevel(mxl); - realEntity_.setElement(elem); - dc_.xtractData(str, entity_, newElements); + // read number of elements to be restored + int newElements = 0 ; + str.read( newElements ); + + // if data handle provides reserve feature, reserve memory + // the data handle has to be derived from LoadBalanceHandleWithReserveAndCompress + CompressAndReserveType :: reserveMemory( dataHandle_, newElements ); + + // unpack data for this element + xtractElementData( str, setEntity( elem ) ); + + // unpack data for all children + for( HElementType *son = elem.down(); son ; son = son->next() ) + xtractElementData( str, setEntity( *son ) ); } //! call compress on data void compress () { - dc_.compress(); + // if data handle provides compress, do compress here + // the data handle has to be derived from LoadBalanceHandleWithReserveAndCompress + CompressAndReserveType :: compress( dataHandle_ ); } - // return true if user defined partitioning methods should be used - bool userDefinedPartitioning () const + protected: + void inlineElementData ( ObjectStreamType &stream, const EntityType &element ) { - return dc_.userDefinedPartitioning(); + // call element data direct without creating entity pointer + if( dataHandle_.contains( dimension, 0 ) ) + { + inlineEntityData<0>( stream, element ); + } + + // now call all higher codims + inlineCodimData< 1 >( stream, element ); + inlineCodimData< 2 >( stream, element ); + inlineCodimData< 3 >( stream, element ); } - // return true if user defined load balancing weights are provided - bool userDefinedLoadWeights () const + void xtractElementData ( ObjectStreamType &stream, const EntityType &element ) { - return dc_.userDefinedLoadWeights(); - } + // call element data direct without creating entity pointer + if( dataHandle_.contains( dimension, 0 ) ) + { + xtractEntityData<0>( stream, element ); + } - // returns true if user defined partitioning needs to be readjusted - bool repartition () - { - return (dc_.userDefinedPartitioning() && dc_.repartition()); + // now call all higher codims + xtractCodimData< 1 >( stream, element ); + xtractCodimData< 2 >( stream, element ); + xtractCodimData< 3 >( stream, element ); } - // return set of ranks data is imported from during load balance - // this method is only used for user defined repartitioning - bool importRanks( std::set<int>& ranks ) const + template< int codim > + void inlineCodimData ( ObjectStream &stream, const EntityType &element ) const { - return dc_.importRanks( ranks ); + typedef typename Codim< codim > :: EntityPointer EntityPointer; + + if( dataHandle_.contains( dimension, codim ) ) + { + const int numSubEntities = element.template count< codim >(); + for( int i = 0; i < numSubEntities; ++i ) + { + const EntityPointer pEntity = element.template subEntity< codim >( i ); + inlineEntityData< codim >( stream, *pEntity ); + } + } } - // return set of ranks data is exported to during load balance - // this method is only used for user defined repartitioning - bool exportRanks( std::set<int>& ranks ) const + template< int codim > + void xtractCodimData ( ObjectStream &stream, const EntityType &element ) { - return dc_.exportRanks( ranks ); + typedef typename Codim< codim > :: EntityPointer EntityPointer; + + if( dataHandle_.contains( dimension, codim ) ) + { + const int numSubEntities = element.template count< codim >(); + for( int i = 0; i < numSubEntities; ++i ) + { + const EntityPointer pEntity = element.template subEntity< codim >( i ); + xtractEntityData< codim >( stream, *pEntity ); + } + } } - // return load weight of given element - int loadWeight ( const HElementType &elem ) const + template< int codim > + void inlineEntityData ( ObjectStreamType &stream, + const typename Codim< codim > :: Entity &entity ) const { - alugrid_assert ( elem.level() == 0 ); - if( dc_.userDefinedLoadWeights() ) + if( transmitSize ) { - realEntity_.setElement( elem ); - return dc_.loadWeight( entity_ ); + const size_t size = dataHandle_.size( entity ); + stream.write( size ); } - else - return 1; + dataHandle_.gather( stream, entity ); } - // return destination (i.e. rank) where the given element should be moved to - // this needs the methods userDefinedPartitioning to return true - int destination ( const HElementType &elem ) const - { - alugrid_assert ( elem.level () == 0 ); - if( dc_.userDefinedPartitioning() ) + template< int codim > + void xtractEntityData ( ObjectStreamType &stream, + const typename Codim< codim > :: Entity &entity ) + { + size_t size = 0; + if( transmitSize ) { - realEntity_.setElement( elem ); - return dc_.destination( entity_ ); + stream.read( size ); } - else - return -1; + dataHandle_.scatter( stream, entity, size ); } }; diff --git a/dune/alugrid/3d/grid.hh b/dune/alugrid/3d/grid.hh index 727303b61d70efab1d386fa9c361b567d1c29dc7..09493b5d674e60e2deb041cec7615b0ad16a89dd 100644 --- a/dune/alugrid/3d/grid.hh +++ b/dune/alugrid/3d/grid.hh @@ -9,7 +9,6 @@ #include <dune/grid/common/capabilities.hh> #include <dune/alugrid/common/interfaces.hh> #include <dune/common/bigunsignedint.hh> -#include <dune/common/exceptions.hh> #include <dune/geometry/referenceelements.hh> @@ -34,7 +33,6 @@ #include <dune/alugrid/3d/communication.hh> #include <dune/alugrid/3d/gridview.hh> -#include <dune/alugrid/3d/lbdatahandle.hh> #include <dune/common/parallel/mpihelper.hh> @@ -44,29 +42,6 @@ #include <dune/common/parallel/collectivecommunication.hh> #endif -namespace Dune -{ - struct EmptyALUDataHandle - : public Dune::CommDataHandleIF< EmptyALUDataHandle, int > - { - EmptyALUDataHandle() {} - bool contains ( int dim, int codim ) const { return false; } - bool fixedsize ( int dim, int codim ) const { return true; } - template <class E> - size_t size ( const E &entity ) const { return 0; } - template< class Buffer, class E > - void gather ( Buffer &buffer, const E &entity ) const - { - DUNE_THROW(InvalidStateException,"EmptyALUDataHandle::gather should never be called!"); - } - template< class Buffer, class E > - void scatter ( Buffer &buffer, E &entity, size_t n ) - { - DUNE_THROW(InvalidStateException,"EmptyALUDataHandle::scatter should never be called!"); - } - }; -} - namespace Dune { // Forward declarations @@ -761,6 +736,8 @@ namespace Dune } protected: + typedef ALU3DSPACE GatherScatter GatherScatterType; + /** \brief Calculates load of each process and repartition the grid if neccessary. For parameters of the load balancing process see the README file of the ALUGrid package. @@ -789,19 +766,18 @@ namespace Dune \return true if the grid has changed */ - template <class DataHandle> - bool loadBalanceImpl (DataHandle & data); + bool loadBalance ( GatherScatterType* lbData ); public: /** \brief Calculates load of each process and repartition by using ALUGrid's default partitioning method. The specific load balancing algorithm is selected from a file alugrid.cfg. \return true if grid has changed */ - bool loadBalance ( ) + bool loadBalance () { - EmptyALUDataHandle dh; - return loadBalance( dh ); + return loadBalance( (GatherScatterType* ) 0 ); } + /** \brief Calculates load of each process and repartition by using ALUGrid's default partitioning method. The specific load balancing algorithm is selected from a file alugrid.cfg. \param optional dataHandleIF data handle that implements the Dune::CommDataHandleIF interface to include @@ -811,10 +787,12 @@ namespace Dune template< class DataHandleImpl, class Data > bool loadBalance ( CommDataHandleIF< DataHandleImpl, Data > &dataHandleIF ) { - typedef ALUGridDataHandleWrapper< ThisType, DataHandleImpl, Data > DataHandle; - DataHandle dataHandle( *this, dataHandleIF ); - // call the above loadBalance method with general DataHandle - return loadBalanceImpl( dataHandle ); + typedef ALU3DSPACE GatherScatterLoadBalanceDataHandle + < ThisType, GatherScatterType, DataHandleImpl, Data > DataHandleType; + DataHandleType dataHandle( *this, &dataHandleIF ); + + // call the above loadBalance method with general GatherScatterType + return loadBalance( &dataHandle ); } /** \brief Calculates load of each process and repartition by using ALUGrid's default partitioning method, the partitioning can be optimized by providing weights for each element on the macro grid. @@ -827,12 +805,14 @@ namespace Dune */ template< class LBWeights, class DataHandleImpl, class Data > bool loadBalance ( LBWeights &weights, - CommDataHandleIF< DataHandleImpl, Data > &dataHandle ) + CommDataHandleIF< DataHandleImpl, Data > &dataHandleIF ) { - typedef ALUGridLoadBalanceDataHandleWrapper< ThisType, - LBWeights, DataHandleImpl, Data, true > LBDataHandle; - LBDataHandle lbDataHandle( *this, weights, dataHandle ); - return loadBalanceImpl( lbDataHandle ); + typedef ALU3DSPACE GatherScatterLoadBalanceDataHandle + < ThisType, LBWeights, DataHandleImpl, Data > DataHandleType; + DataHandleType dataHandle( *this, dataHandleIF, weights ); + + // call the above loadBalance method with general GatherScatterType + return loadBalance( &dataHandle ); } /** \brief Distribute the grid based on a user defined partitioning. \param destinations class with int operator()(const Entity<0>&) returning the new owner process @@ -845,8 +825,9 @@ namespace Dune template< class LBDestinations > bool repartition ( LBDestinations &destinations ) { - EmptyALUDataHandle dh; - return repartition(destinations,dh); + typedef ALU3DSPACE GatherScatterLoadBalance< ThisType, LBDestinations > LoadBalanceHandleType ; + LoadBalanceHandleType loadBalanceHandle( *this, destinations, true ); + return loadBalance( &loadBalanceHandle ); } /** \brief Distribute the grid based on a user defined partitioning. \param destinations class with int operator()(const Entity<0>&) returning the new owner process @@ -860,14 +841,14 @@ namespace Dune */ template< class LBDestinations, class DataHandleImpl, class Data > bool repartition ( LBDestinations &destinations, - CommDataHandleIF< DataHandleImpl, Data > &dataHandle) + CommDataHandleIF< DataHandleImpl, Data > &dataHandleIF ) { - typedef ALUGridLoadBalanceDataHandleWrapper< ThisType, - LBDestinations, DataHandleImpl, Data,false > LBDataHandle; - LBDataHandle lbDataHandle( *this, destinations, dataHandle ); - return loadBalanceImpl( lbDataHandle ); - } + typedef ALU3DSPACE GatherScatterLoadBalanceDataHandle< ThisType, LBDestinations, DataHandleImpl, Data > DataHandleType; + DataHandleType dataHandle( *this, dataHandleIF, destinations, true ); + // call the above loadBalance method with general GatherScatterType + return loadBalance( &dataHandle ); + } /** \brief ghostSize is one for codim 0 and zero otherwise for this grid */ @@ -910,9 +891,6 @@ namespace Dune //! clear all entity new markers void clearIsNewMarkers( ); - private: - typedef ALU3DSPACE GatherScatter GatherScatterType; - public: /** \brief @copydoc Dune::Grid::comm() */ const CollectiveCommunication &comm () const { return communications().ccobj_; } diff --git a/dune/alugrid/3d/grid_inline.hh b/dune/alugrid/3d/grid_inline.hh index d6d954c72bb445e0fe631fe414343d4a0955af23..efc8bfa36155b0a45f5775d202263e8e5e67cf0d 100644 --- a/dune/alugrid/3d/grid_inline.hh +++ b/dune/alugrid/3d/grid_inline.hh @@ -403,68 +403,34 @@ namespace Dune return refined; } - - - //***************************************************************** - + // load balance grid ( lbData might be a pointer to NULL ) template< ALU3dGridElementType elType, class Comm > - struct ALU3dGridCommHelper; - - template< ALU3dGridElementType elType > - struct ALU3dGridCommHelper< elType, ALUGridNoComm > + inline bool ALU3dGrid< elType, Comm >::loadBalance( GatherScatterType* lbData ) { - typedef ALU3dGrid< elType, ALUGridNoComm > Grid; - - template< class DataHandle > - static bool loadBalance ( Grid &grid, DataHandle &data ) { return false; } - }; // ALU3dGridCommHelper + if( comm().size() <= 1 ) + return false; - template< ALU3dGridElementType elType > - struct ALU3dGridCommHelper< elType, ALUGridMPIComm > - { - typedef ALU3dGrid< elType, ALUGridMPIComm > Grid; - typedef ALU3DSPACE GatherScatter GatherScatterType; + // call load Balance + const bool changed = myGrid().loadBalance( lbData ); - template< class DataHandle > - static bool loadBalance ( Grid &grid, DataHandle &data ) + if( changed ) { + // calculate new maxlevel + // reset size and things + updateStatus(); - if( grid.comm().size() <= 1 ) - return false; - - ALU3DSPACE GatherScatterLoadBalance< Grid, DataHandle > - gs( grid, data ); - - // call load Balance - const bool changed = grid.myGrid().loadBalance( &gs ); + // build new Id Set. Only do that after updateStatus, because here + // the item lists are needed + if( globalIdSet_ ) + globalIdSet_->updateIdSet(); + + // compress data if lbData is valid + if( lbData ) + lbData->compress() ; - if( changed ) - { - // calculate new maxlevel - // reset size and things - grid.updateStatus(); - - // build new Id Set. Only do that after updateStatus, because here - // the item lists are needed - if( grid.globalIdSet_ ) - grid.globalIdSet_->updateIdSet(); - - // compress data, wrapper for dof manager - gs.compress(); - - grid.clearIsNewMarkers(); - } - return changed; + clearIsNewMarkers(); } - }; // ALU3dGridCommHelper - - - // load balance grid - template< ALU3dGridElementType elType, class Comm > - template< class DataHandle > - inline bool ALU3dGrid< elType, Comm >::loadBalanceImpl ( DataHandle &data ) - { - return ALU3dGridCommHelper< elType, Comm >::loadBalance( *this, data ); + return changed; } template< ALU3dGridElementType elType, class Comm > diff --git a/dune/alugrid/3d/lbdatahandle.hh b/dune/alugrid/3d/lbdatahandle.hh deleted file mode 100644 index 48b39c201a497a1b3caa5d69df50cc006c8192e9..0000000000000000000000000000000000000000 --- a/dune/alugrid/3d/lbdatahandle.hh +++ /dev/null @@ -1,320 +0,0 @@ -#ifndef DUNE_ALUGRID_LBDATAHANDLE_HH -#define DUNE_ALUGRID_LBDATAHANDLE_HH - -#include <dune/alugrid/3d/datahandle.hh> - -#include <dune/common/bartonnackmanifcheck.hh> -#include <dune/grid/common/datahandleif.hh> -#include <dune/alugrid/common/ldbhandleif.hh> - -namespace Dune -{ - template< class Grid, class DataHandleImpl, class Data > - class ALUGridDataHandleWrapper - { - typedef typename Grid :: Traits :: HierarchicIterator HierarchicIterator; - - public: - typedef typename Grid :: ObjectStreamType ObjectStream; - - typedef CommDataHandleIF< DataHandleImpl, Data > DataHandle; - - static const int dimension = Grid :: dimension; - - template< int codim > - struct Codim - { - typedef typename Grid :: Traits :: template Codim< codim > :: Entity Entity; - typedef typename Grid :: Traits :: template Codim< codim > :: EntityPointer - EntityPointer; - }; - - typedef typename Codim< 0 > :: Entity Element; - protected: - template <class DH, bool> - struct CompressAndReserve - { - static DataHandleImpl& asImp( DH& dh ) { return static_cast<DataHandleImpl &> (dh); } - - static void reserveMemory( DH& dataHandle, const size_t newElements ) - { - asImp( dataHandle ).reserveMemory( newElements ); - } - static void compress( DH& dataHandle ) - { - asImp( dataHandle ).compress(); - } - }; - - template <class DH> - struct CompressAndReserve< DH, false > - { - static void reserveMemory( DH& dataHandle, const size_t newElements ) {} - static void compress( DH& dataHandle ) {} - }; - - // check whether DataHandleImpl is derived from LoadBalanceHandleWithReserveAndCompress - static const bool hasCompressAndReserve = Conversion< DataHandleImpl, - LoadBalanceHandleWithReserveAndCompress >::exists ; - // don't transmit size in case we have special DataHandleImpl - static const bool transmitSize = ! hasCompressAndReserve ; - - typedef CompressAndReserve< DataHandle, hasCompressAndReserve > CompressAndReserveType; - - protected: - const Grid &grid_; - DataHandle &dataHandle_; - - public: - ALUGridDataHandleWrapper( const Grid &grid, DataHandle &dataHandle ) - : grid_( grid ), - dataHandle_( dataHandle ) - { - } - - //! write data to object stream - void inlineData ( ObjectStream &stream, const Element &element ) const - { - inlineElementData( stream, element ); - - const int maxLevel = grid_.maxLevel(); - const HierarchicIterator end = element.hend( maxLevel ); - for( HierarchicIterator it = element.hbegin( maxLevel ); it != end; ++it ) - inlineElementData( stream, *it ); - } - - //! read data from object stream - void xtractData ( ObjectStream &stream, const Element &element, size_t newElements ) - { - // if data handle provides reserve feature, reserve memory - // the data handle has to be derived from LoadBalanceHandleWithReserveAndCompress - CompressAndReserveType :: reserveMemory( dataHandle_, newElements ); - - xtractElementData( stream, element ); - - const int maxLevel = grid_.maxLevel(); - const HierarchicIterator end = element.hend( maxLevel ); - for( HierarchicIterator it = element.hbegin( maxLevel ); it != end; ++it ) - xtractElementData( stream, *it ); - } - - //! \brief data compress - //! \note nothing is done since the DataHandleIF does not provide this feature - void compress () - { - // if data handle provides compress, do compress here - // the data handle has to be derived from LoadBalanceHandleWithReserveAndCompress - CompressAndReserveType :: compress( dataHandle_ ); - } - - private: - void inlineElementData ( ObjectStream &stream, const Element &element ) const - { - // call element data direct without creating entity pointer - if( dataHandle_.contains( dimension, 0 ) ) - { - inlineEntityData<0>( stream, element ); - } - - // now call all higher codims - inlineCodimData< 1 >( stream, element ); - inlineCodimData< 2 >( stream, element ); - inlineCodimData< 3 >( stream, element ); - } - - void xtractElementData ( ObjectStream &stream, const Element &element ) - { - // call element data direct without creating entity pointer - if( dataHandle_.contains( dimension, 0 ) ) - { - xtractEntityData<0>( stream, element ); - } - - // now call all higher codims - xtractCodimData< 1 >( stream, element ); - xtractCodimData< 2 >( stream, element ); - xtractCodimData< 3 >( stream, element ); - } - - template< int codim > - void inlineCodimData ( ObjectStream &stream, const Element &element ) const - { - typedef typename Codim< codim > :: EntityPointer EntityPointer; - - if( dataHandle_.contains( dimension, codim ) ) - { - const int numSubEntities = element.template count< codim >(); - for( int i = 0; i < numSubEntities; ++i ) - { - const EntityPointer pEntity = element.template subEntity< codim >( i ); - inlineEntityData< codim >( stream, *pEntity ); - } - } - } - - template< int codim > - void xtractCodimData ( ObjectStream &stream, const Element &element ) - { - typedef typename Codim< codim > :: EntityPointer EntityPointer; - - if( dataHandle_.contains( dimension, codim ) ) - { - const int numSubEntities = element.template count< codim >(); - for( int i = 0; i < numSubEntities; ++i ) - { - const EntityPointer pEntity = element.template subEntity< codim >( i ); - xtractEntityData< codim >( stream, *pEntity ); - } - } - } - - template< int codim > - void inlineEntityData ( ObjectStream &stream, - const typename Codim< codim > :: Entity &entity ) const - { - if( transmitSize ) - { - const size_t size = dataHandle_.size( entity ); - stream.write( size ); - } - dataHandle_.gather( stream, entity ); - } - - template< int codim > - void xtractEntityData ( ObjectStream &stream, - const typename Codim< codim > :: Entity &entity ) - { - size_t size = 0; - if( transmitSize ) - { - stream.read( size ); - } - dataHandle_.scatter( stream, entity, size ); - } - - public: - bool userDefinedPartitioning () const { return false; } - bool repartition () const { return false; } - bool userDefinedLoadWeights () const { return false; } - bool importRanks( std::set<int>& ) const { return false ; } - bool exportRanks( std::set<int>& ) const { return false ; } - double loadWeight( const Element &element ) const - { - return -1; - } - int destination( const Element &element ) const - { - return -1; - } - }; - - - template< class Grid, class LoadBalanceHandle, bool internal > - class ALUGridLoadBalanceHandleWrapper - { - public: - template< int codim > - struct Codim - { - typedef typename Grid :: Traits :: template Codim< codim > :: Entity Entity; - typedef typename Grid :: Traits :: template Codim< codim > :: EntityPointer - EntityPointer; - }; - - typedef typename Codim< 0 > :: Entity Element; - protected: - const Grid &grid_; - LoadBalanceHandle &ldbHandle_; - - public: - ALUGridLoadBalanceHandleWrapper ( const Grid &grid, LoadBalanceHandle &loadBalanceHandle ) - : grid_( grid ), - ldbHandle_( loadBalanceHandle ) - {} - - // return true if user defined partitioning methods should be used - bool userDefinedPartitioning () const - { - return !internal; - } - // returns true if user defined partitioning needs to be readjusted - bool repartition () const - { - return true; - } - - // return list of ranks data is imported from - bool importRanks( std::set<int>& ranks ) const - { - return ldbHandle_.importRanks( ranks ); - } - - // return list of ranks data is imported from - bool exportRanks( std::set<int>& ranks ) const - { - // this feature is not yet enabled (although implemented in ALU) - return false ; - // return ldbHandle_.exportRanks( ranks ); - } - - // return true if user defined weights have been provided - bool userDefinedLoadWeights () const - { - return internal; - } - // return load weight of given element - double loadWeight( const Element &element ) const - { - assert( internal ); - return ldbHandle_(element); - } - // return destination (i.e. rank) where the given element should be moved to - // this needs the methods userDefinedPartitioning to return true - int destination( const Element &element ) const - { - assert( !internal ); - return ldbHandle_(element); - } - }; - - template< class Grid, class LoadBalanceHandle, class DataHandleImpl, class Data, bool internal > - class ALUGridLoadBalanceDataHandleWrapper - : public ALUGridLoadBalanceHandleWrapper< Grid, LoadBalanceHandle, internal >, - public ALUGridDataHandleWrapper< Grid, DataHandleImpl, Data > - { - typedef ALUGridLoadBalanceHandleWrapper< Grid, LoadBalanceHandle, internal > LDBHandleBase ; - typedef ALUGridDataHandleWrapper< Grid, DataHandleImpl, Data > DataHandleBase ; - - public: - typedef typename DataHandleBase :: DataHandle DataHandle ; - typedef typename LDBHandleBase::Element Element; - - ALUGridLoadBalanceDataHandleWrapper( const Grid &grid, - LoadBalanceHandle &ldbHandle, - DataHandle &dataHandle ) - : LDBHandleBase( grid, ldbHandle ), - DataHandleBase( grid, dataHandle ) - {} - - bool userDefinedPartitioning () const - { return LDBHandleBase::userDefinedPartitioning(); } - bool userDefinedLoadWeights () const - { return LDBHandleBase::userDefinedLoadWeights(); } - bool repartition () const - { return LDBHandleBase::repartition(); } - bool importRanks( std::set<int>& ranks ) const { return LDBHandleBase::importRanks( ranks ); } - bool exportRanks( std::set<int>& ranks ) const { return LDBHandleBase::exportRanks( ranks ); } - int loadWeight( const Element &element ) const - { return LDBHandleBase::loadWeight(element); } - int destination( const Element &element ) const - { return LDBHandleBase::destination(element); } - - // methods inherited from ALUGridDataHandleWrapper - using DataHandleBase :: inlineData ; - using DataHandleBase :: xtractData ; - using DataHandleBase :: compress ; - }; - -} // namespace Dune - -#endif // #ifndef DUNE_ALUGRID_LBDATAHANDLE_HH