1 #ifndef DUNE_FEM_SPACE_MAPPER_PETSC_HH 2 #define DUNE_FEM_SPACE_MAPPER_PETSC_HH 3 4 #include <cassert> 5 6 #include <memory> 7 #include <tuple> 8 #include <utility> 9 10 #include <dune/fem/space/mapper/ghost.hh> 11 #include <dune/fem/space/mapper/parallel.hh> 12 #include <dune/fem/storage/singletonlist.hh> 13 14 namespace Dune 15 { 16 17 namespace Fem 18 { 19 20 // PetscMappers 21 // ------------ 22 23 #if HAVE_PETSC 24 template< class DiscreteFunctionSpace > 25 class PetscMappers 26 { 27 typedef PetscMappers< DiscreteFunctionSpace > PetscMappersType; 28 29 public: 30 typedef DiscreteFunctionSpace DiscreteFunctionSpaceType; 31 32 typedef typename DiscreteFunctionSpaceType::BlockMapperType BlockMapperType; 33 typedef typename DiscreteFunctionSpaceType::GridPartType GridPartType; 34 35 typedef GhostDofMapper< GridPartType, BlockMapperType, PetscInt > GhostMapperType; 36 typedef ParallelDofMapper< GridPartType, GhostMapperType, PetscInt > ParallelMapperType; 37 38 private: 39 template< class Mapper > 40 struct MapperFactory 41 { createObjectDune::Fem::PetscMappers::MapperFactory42 static std::pair< Mapper, int > *createObject ( std::pair< GridPartType *, typename Mapper::BaseMapperType * > key, int sequence ) 43 { 44 return new std::pair< Mapper, int >( std::piecewise_construct, std::tie( *key.first, *key.second ), std::make_tuple( sequence ) ); 45 } 46 deleteObjectDune::Fem::PetscMappers::MapperFactory47 static void deleteObject ( std::pair< Mapper, int > *object ) { delete object; } 48 }; 49 50 template< class Mapper > 51 using MapperProvider = SingletonList< std::pair< GridPartType *, typename Mapper::BaseMapperType * >, std::pair< Mapper, int >, MapperFactory< Mapper > >; 52 53 typedef MapperProvider< GhostMapperType > GhostMapperProviderType; 54 typedef MapperProvider< ParallelMapperType > ParallelMapperProviderType; 55 56 public: 57 //! constructor creating petsc mapper PetscMappers(const DiscreteFunctionSpaceType & space)58 PetscMappers ( const DiscreteFunctionSpaceType &space ) 59 : space_( space ) 60 { 61 const int sequence = space_.sequence(); 62 63 ghostMapper_.reset( &GhostMapperProviderType::getObject( std::make_pair( &space_.gridPart(), &space_.blockMapper() ), sequence ) ); 64 update( *ghostMapper_, sequence ); 65 66 parallelMapper_.reset( &ParallelMapperProviderType::getObject( std::make_pair( &space_.gridPart(), &ghostMapper_->first ), sequence ) ); 67 update( *parallelMapper_, sequence ); 68 } 69 70 //! copy constructor obtaining pointers for mapper objects PetscMappers(const PetscMappers & other)71 PetscMappers ( const PetscMappers &other ) 72 : space_( other.space_ ) 73 { 74 const int sequence = space_.sequence(); 75 76 ghostMapper_.reset( &GhostMapperProviderType::getObject( std::make_pair( &space_.gridPart(), &space_.blockMapper() ), sequence ) ); 77 parallelMapper_.reset( &ParallelMapperProviderType::getObject( std::make_pair( &space_.gridPart(), &ghostMapper_->first ), sequence ) ); 78 } 79 space() const80 const DiscreteFunctionSpaceType &space () const { return space_; } 81 ghostMapper() const82 const GhostMapperType &ghostMapper () const { assert( ghostMapper_ ); return ghostMapper_->first; } parallelMapper() const83 const ParallelMapperType ¶llelMapper () const { assert( parallelMapper_ ); return parallelMapper_->first; } 84 ghostIndex(const typename BlockMapperType::GlobalKeyType & index) const85 PetscInt ghostIndex ( const typename BlockMapperType::GlobalKeyType &index ) const 86 { 87 assert( static_cast< std::size_t >( index ) < size() ); 88 return ghostMapper().mapping()[ index ]; 89 } 90 parallelIndex(const typename BlockMapperType::GlobalKeyType & index) const91 PetscInt parallelIndex ( const typename BlockMapperType::GlobalKeyType &index ) const 92 { 93 return parallelMapper().mapping()[ ghostIndex( index ) ]; 94 } 95 size() const96 std::size_t size () const { return ghostMapper().mapping().size(); } 97 update()98 void update () 99 { 100 const int sequence = space().sequence(); 101 102 assert( ghostMapper_ ); 103 update( *ghostMapper_, sequence ); 104 105 assert( parallelMapper_ ); 106 update( *parallelMapper_, sequence ); 107 } 108 109 private: 110 template< class Mapper > update(std::pair<Mapper,int> & mapper,int sequence)111 static void update ( std::pair< Mapper, int > &mapper, int sequence ) 112 { 113 if( mapper.second != sequence ) 114 { 115 mapper.first.update(); 116 mapper.second = sequence; 117 } 118 } 119 120 const DiscreteFunctionSpaceType &space_; 121 std::unique_ptr< std::pair< GhostMapperType, int >, typename GhostMapperProviderType::Deleter > ghostMapper_; 122 std::unique_ptr< std::pair< ParallelMapperType, int >, typename ParallelMapperProviderType::Deleter > parallelMapper_; 123 }; 124 #endif // #if HAVE_PETSC 125 126 } // namespace Fem 127 128 } // namespace Dune 129 130 #endif // #ifndef DUNE_FEM_SPACE_MAPPER_PETSC_HH 131