1 #ifndef DUNE_FEM_SUBFUNCTION_HH
2 #define DUNE_FEM_SUBFUNCTION_HH
3 
4 #include <memory>
5 #include <vector>
6 
7 #include <dune/fem/space/combinedspace/combineddofstorage.hh>
8 #include <dune/fem/storage/subvector.hh>
9 #include <dune/fem/function/vectorfunction/vectorfunction.hh>
10 
11 namespace Dune
12 {
13 
14   namespace Fem
15   {
16 
17     //! @ingroup SubDFunction
18     //! A class for extracting sub functions from a
19     //! discrete function containing pointbased combined data.
20     template <class DiscreteFunctionImp>
21     class SubFunctionStorage
22     {
23     protected:
24       typedef DiscreteFunctionImp DiscreteFunctionType;
25       typedef typename DiscreteFunctionType :: DiscreteFunctionSpaceType SpaceType;
26       enum { dimRange = SpaceType :: dimRange };
27       typedef typename DiscreteFunctionType :: DofStorageType DofStorageType;
28     public:
29       typedef typename SpaceType :: template ToNewDimRange < 1 > :: Type SubSpaceType;
30 
31       typedef CombinedSubMapper< typename SubSpaceType :: MapperType , dimRange, PointBased > SubMapperType;
32       typedef SubVector< DofStorageType, SubMapperType > SubDofVectorType;
33       typedef VectorDiscreteFunction< SubSpaceType, SubDofVectorType > SubDiscreteFunctionType;
34 
35       //! constructor storing the discrete function
SubFunctionStorage(DiscreteFunctionType & discreteFunction)36       explicit SubFunctionStorage( DiscreteFunctionType& discreteFunction ) :
37         discreteFunction_( discreteFunction ),
38         space_( discreteFunction.space() ),
39         subSpace_( space_.gridPart (), space_.communicationInterface(), space_.communicationDirection() ),
40         subVector_( dimRange, nullptr ),
41         subDiscreteFunction_( dimRange, nullptr )
42       {}
43 
44        SubFunctionStorage( const SubFunctionStorage& ) = delete;
45 
46       /** \brief return a SubDiscreteFunction repsenting only one
47           component of the original discrete function
48           \param component the component to be extracted
49 
50           \return reference to SubDiscreteFunction for given component
51       */
subFunction(std::size_t component) const52       SubDiscreteFunctionType& subFunction(std::size_t component) const
53       {
54         assert( component < dimRange );
55         if( ! subDiscreteFunction_[ component ] )
56         {
57           subVector_[ component ] =
58             std::make_unique< SubDofVectorType >( discreteFunction_.dofStorage(), SubMapperType( subSpace_.mapper(), component ) );
59           subDiscreteFunction_[ component ] =
60             std::make_unique< SubDiscreteFunctionType >( discreteFunction_.name()+ "_sub", subSpace_, *( subVector_[ component ] ));
61         }
62         return *( subDiscreteFunction_[ component ] );
63       }
64 
65     protected:
66       DiscreteFunctionType& discreteFunction_;
67       const SpaceType& space_;
68       SubSpaceType subSpace_;
69       mutable std::vector< std::unique_ptr< SubDofVectorType > > subVector_;
70       mutable std::vector< std::unique_ptr< SubDiscreteFunctionType > > subDiscreteFunction_;
71     };
72 
73   } // namespace Fem
74 
75 } // namespace Dune
76 
77 #endif // #ifndef DUNE_FEM_SUBFUNCTION_HH
78