1 #ifndef DUNE_FEM_SPACE_COMBINEDSPACE_INTERPOLATION_HH 2 #define DUNE_FEM_SPACE_COMBINEDSPACE_INTERPOLATION_HH 3 4 #include <tuple> 5 #include <utility> 6 7 #include <dune/fem/common/forloop.hh> 8 #include <dune/fem/function/localfunction/converter.hh> 9 #include <dune/fem/space/basisfunctionset/tuple.hh> 10 #include <dune/fem/space/basisfunctionset/vectorial.hh> 11 #include <dune/fem/storage/subvector.hh> 12 13 14 namespace Dune 15 { 16 17 namespace Fem 18 { 19 20 // PowerSpaceInterpolation 21 // ------------------ 22 23 template< class Space, int N > 24 class PowerSpaceInterpolation 25 { 26 typedef PowerSpaceInterpolation< Space, N > ThisType; 27 28 struct RangeConverter 29 { RangeConverterDune::Fem::PowerSpaceInterpolation::RangeConverter30 RangeConverter ( std::size_t range ) : range_( range ) {} 31 32 template< class T > operator ()Dune::Fem::PowerSpaceInterpolation::RangeConverter33 FieldVector< T, 1 > operator() ( const FieldVector< T, N > &in ) const 34 { 35 return in[ range_ ]; 36 } 37 38 template< class T, int j > operator ()Dune::Fem::PowerSpaceInterpolation::RangeConverter39 FieldMatrix< T, 1, j > operator() ( const FieldMatrix< T, N, j > &in ) const 40 { 41 return in[ range_ ]; 42 } 43 44 protected: 45 std::size_t range_; 46 }; 47 48 template <class DofVector, class DofAlignment> 49 struct SubDofVectorWrapper 50 : public SubDofVector< DofVector, DofAlignment > 51 { 52 typedef SubDofVector< DofVector, DofAlignment > BaseType; 53 SubDofVectorWrapperDune::Fem::PowerSpaceInterpolation::SubDofVectorWrapper54 SubDofVectorWrapper( DofVector& dofs, int coordinate, const DofAlignment &dofAlignment ) 55 : BaseType( dofs, coordinate, dofAlignment ) 56 {} 57 58 //! do nothing on clear since it's done in apply of this class clearDune::Fem::PowerSpaceInterpolation::SubDofVectorWrapper59 void clear() {} 60 }; 61 62 // Note: BasisFunctionSetType is VectorialBasisFunctionSet 63 typedef typename Space::BasisFunctionSetType::DofAlignmentType DofAlignmentType; 64 65 public: 66 typedef typename Space::EntityType EntityType; 67 PowerSpaceInterpolation(const Space & space,const EntityType & entity)68 PowerSpaceInterpolation ( const Space &space, const EntityType &entity ) 69 : interpolation_( space.containedSpace().localInterpolation( entity ) ), 70 dofAlignment_( space.basisFunctionSet( entity ).dofAlignment() ) 71 {} 72 73 template< class LocalFunction, class LocalDofVector > operator ()(const LocalFunction & lv,LocalDofVector & ldv) const74 void operator () ( const LocalFunction &lv, LocalDofVector &ldv ) const 75 { 76 apply( lv, ldv ); 77 } 78 79 template< class LocalFunction, class LocalDofVector > apply(const LocalFunction & lv,LocalDofVector & ldv) const80 void apply ( const LocalFunction &lv, LocalDofVector &ldv ) const 81 { 82 // clear dofs before something is adedd 83 ldv.clear(); 84 85 for( std::size_t i = 0; i < N; ++i ) 86 { 87 SubDofVectorWrapper< LocalDofVector, DofAlignmentType > subLdv( ldv, i, dofAlignment_ ); 88 interpolation_( localFunctionConverter( lv, RangeConverter( i ) ), subLdv ); 89 } 90 } 91 92 protected: 93 typename Space::ContainedDiscreteFunctionSpaceType::InterpolationImplType interpolation_; 94 DofAlignmentType dofAlignment_; 95 }; 96 97 98 // TupleSpaceInterpolation 99 // ----------------------- 100 // CombineOp describes the way in which the spaces have been combined, i.e. 101 // Product: V = V_1 x V_2 x ... 102 // Summation: V = V_1 + V_2 + ... 103 104 template< class CombineOp , class ... Spaces > 105 class TupleSpaceInterpolation 106 { 107 typedef TupleSpaceInterpolation< CombineOp, Spaces ... > ThisType; 108 typedef std::tuple< typename Spaces::InterpolationImplType ... > InterpolationTupleType; 109 110 static const int setSize = sizeof ... ( Spaces ) -1; 111 112 template< int > 113 struct ProductApply; 114 115 template< int > 116 struct SummationApply; 117 118 template< int, class CombOp > 119 struct ApplyBase; 120 121 template< int counter > 122 struct ApplyBase< counter, TupleSpaceProduct > : public ProductApply< counter >{}; 123 124 template< int counter > 125 struct ApplyBase< counter, TupleSpaceSummation > : public SummationApply< counter >{}; 126 127 template < int counter > 128 struct Apply : public ApplyBase< counter, CombineOp > {}; 129 130 typedef TupleBasisFunctionSet< CombineOp, typename Spaces::BasisFunctionSetType ... > BasisFunctionSetType; 131 132 public: 133 134 static_assert( Std::are_all_same< typename Spaces::EntityType ... >::value, 135 "TupleSpaceInterpolation requires Spaces defined over the same grid" ); 136 137 typedef typename std::tuple_element< 0, std::tuple< Spaces ... > >::type::EntityType EntityType; 138 TupleSpaceInterpolation(std::tuple<const Spaces &...> tuple,const EntityType & entity)139 TupleSpaceInterpolation ( std::tuple< const Spaces & ... > tuple, const EntityType &entity ) 140 : interpolation_( interpolationTuple( tuple, entity ) ), 141 basisFunctionSet_( basisFunctionSetTuple( tuple, entity ) ) 142 {} 143 TupleSpaceInterpolation(const Spaces &...spaces,const EntityType & entity)144 TupleSpaceInterpolation ( const Spaces & ... spaces, const EntityType &entity ) 145 : interpolation_( std::make_tuple( spaces.localInterpolation( entity ) ... ) ), 146 basisFunctionSet_( std::make_tuple( spaces.basisFunctionSet( entity ) ... ) ) 147 {} 148 149 template< class LocalFunction, class LocalDofVector > operator ()(const LocalFunction & lf,LocalDofVector & ldv) const150 void operator() ( const LocalFunction &lf, LocalDofVector &ldv ) const 151 { 152 Fem::ForLoop< Apply, 0, setSize >::apply( interpolation_, basisFunctionSet_, lf, ldv ); 153 } 154 unbind()155 void unbind() {} 156 157 protected: 158 InterpolationTupleType interpolation_; 159 BasisFunctionSetType basisFunctionSet_; 160 }; 161 162 163 // specialization of TupleSpaceInterpolation::Apply for SpaceProduct 164 template< class CombineOp, class ... Spaces > 165 template< int i > 166 struct TupleSpaceInterpolation< CombineOp, Spaces ... >::ProductApply 167 { 168 static const int rangeOffset = BasisFunctionSetType::RangeIndices::template offset< i >(); 169 static const int thisDimRange = BasisFunctionSetType::template SubBasisFunctionSet< i >::type::FunctionSpaceType::dimRange; 170 static const int dimRange = BasisFunctionSetType::FunctionSpaceType::dimRange; 171 172 struct RangeConverter 173 { 174 template< class T > operator ()Dune::Fem::TupleSpaceInterpolation::ProductApply::RangeConverter175 FieldVector< T, thisDimRange > operator() ( const FieldVector< T, dimRange > &in ) const 176 { 177 FieldVector< T, thisDimRange > ret; 178 apply( in, ret ); 179 return ret; 180 } 181 182 template< class T, int j > operator ()Dune::Fem::TupleSpaceInterpolation::ProductApply::RangeConverter183 FieldMatrix< T, thisDimRange, j > operator() ( const FieldMatrix< T, dimRange, j > &in ) const 184 { 185 FieldMatrix< T, thisDimRange, j > ret; 186 apply( in, ret ); 187 return ret; 188 } 189 190 protected: 191 template< class In, class Out > applyDune::Fem::TupleSpaceInterpolation::ProductApply::RangeConverter192 void apply ( const In &in, Out &out ) const 193 { 194 for( std::size_t j = 0; j < thisDimRange; ++j ) 195 out[ j ] = in[ j + rangeOffset ]; 196 } 197 }; 198 199 template< class Tuple, class LocalFunction, class LocalDofVector > applyDune::Fem::TupleSpaceInterpolation::ProductApply200 static void apply ( const Tuple &tuple, const BasisFunctionSetType &basisSet, const LocalFunction &lv, LocalDofVector &ldv ) 201 { 202 SubVector< LocalDofVector, OffsetSubMapper > 203 subLdv( ldv, OffsetSubMapper( basisSet.template subBasisFunctionSet< i >().size(), basisSet.offset( i ) ) ); 204 std::get< i >( tuple ) ( localFunctionConverter( lv, RangeConverter() ), subLdv ); 205 } 206 }; 207 208 209 template< class CombineOp, class ... Spaces > 210 template< int i > 211 struct TupleSpaceInterpolation< CombineOp, Spaces ... >::SummationApply 212 { 213 template< class Tuple, class LocalFunction, class LocalDofVector > applyDune::Fem::TupleSpaceInterpolation::SummationApply214 static void apply ( const Tuple &tuple, const BasisFunctionSetType &basisSet, const LocalFunction &lv, LocalDofVector &ldv ) 215 { 216 SubVector< LocalDofVector, OffsetSubMapper > 217 subLdv( ldv, OffsetSubMapper( basisSet.template subBasisFunctionSet< i >().size(), basisSet.offset( i ) ) ); 218 std::get< i >( tuple ) ( lv, subLdv ); 219 } 220 }; 221 222 } // namespace Fem 223 224 } // namespace Dune 225 226 #endif // #ifndef DUNE_FEM_SPACE_COMBINEDSPACE_INTERPOLATION_HH 227