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 &parallelMapper () 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