dune-fem  2.8-git
hierarchical/dofvector.hh
Go to the documentation of this file.
1 #ifndef DUNE_FEM_FUNCTION_HIERARCHICAL_DOFVECTOR_HH
2 #define DUNE_FEM_FUNCTION_HIERARCHICAL_DOFVECTOR_HH
3 
4 #include <type_traits>
5 #include <utility>
6 
7 #include <dune/common/ftraits.hh>
8 
9 #if HAVE_DUNE_ISTL
10 #include <dune/istl/bvector.hh>
11 #include <dune/istl/multitypeblockvector.hh>
12 #endif // #if HAVE_DUNE_ISTL
13 
17 
18 namespace Dune
19 {
20 
21  namespace Fem
22  {
23 
24  namespace Impl
25  {
26 
27  template< class T >
28  struct BlockIndicesFor;
29 
30 #if HAVE_DUNE_ISTL
31  template< class K, int dim, class A >
32  struct BlockIndicesFor< BlockVector< FieldVector< K, dim >, A > >
33  {
34  typedef Hybrid::IndexRange< int, dim > Type;
35  };
36 
37  template< class... V >
38  struct BlockIndicesFor< MultiTypeBlockVector< V... > >
39  {
41  };
42 
43  template< class T >
44  struct BlockIndicesFor< const T >
45  {
46  typedef typename BlockIndicesFor< T >::Type Type;
47  };
48 #endif // HAVE_DUNE_ISTL
49 
50  } // namespace Impl
51 
52 
53 
54 
55  // HierarchicalDofBlock
56  // --------------------
57 
58  template< class DofContainer >
60  {
61  friend struct HierarchicalDofBlock< const DofContainer >;
62 
63  typedef typename Impl::BlockIndicesFor< DofContainer >::Type BlockIndices;
64  static constexpr std::size_t blockSize = Hybrid::size( BlockIndices() );
65 
66  HierarchicalDofBlock ( DofContainer &data, std::size_t baseIndex )
67  : data_( data ), baseIndex_( baseIndex )
68  {}
69 
70  HierarchicalDofBlock ( const HierarchicalDofBlock< std::remove_const_t< DofContainer > > &other )
71  : data_( other.data_ ), baseIndex_( other.baseIndex_ )
72  {}
73 
74  template< class Index >
75  decltype( auto ) operator[] ( const Index &index ) const
76  {
77  return access( data_, baseIndex_, index );
78  }
79 
80  template< class Index >
81  decltype( auto ) operator[] ( const Index &index )
82  {
83  return access( data_, baseIndex_, index );
84  }
85 
86  private:
87 #if HAVE_DUNE_ISTL
88  template< class... V, std::size_t component, class I, I offset, class SI >
89  static decltype( auto ) access ( const MultiTypeBlockVector< V... > &data, std::size_t baseIndex, const Hybrid::CompositeIndex< component, I, offset, SI > &index )
90  {
91  return access( data[ std::integral_constant< std::size_t, component >() ], baseIndex, index.subIndex() );
92  }
93 
94  template< class... V, std::size_t component, class I, I offset, class SI >
95  static decltype( auto ) access ( MultiTypeBlockVector< V... > &data, std::size_t baseIndex, const Hybrid::CompositeIndex< component, I, offset, SI > &index )
96  {
97  return access( data[ std::integral_constant< std::size_t, component >() ], baseIndex, index.subIndex() );
98  }
99 
100  template< class K, int n, class A >
101  static const K &access ( const BlockVector< FieldVector< K, n >, A > &data, std::size_t baseIndex, int index )
102  {
103  return data[ baseIndex ][ index ];
104  }
105 
106  template< class K, int n, class A >
107  static K &access ( BlockVector< FieldVector< K, n >, A > &data, std::size_t baseIndex, int index )
108  {
109  return data[ baseIndex ][ index ];
110  }
111 #endif // #if HAVE_DUNE_ISTL
112 
113  DofContainer &data_;
114  std::size_t baseIndex_;
115  };
116 
117 
118  // SpecialArrayFeature for HierarhicalDofVector
119  // --------------------------------------------
120 
121  template< class >
123 
124 
125  // HierarchicalDofVector
126  // ---------------------
127 
128  template< class DC >
130  : public IsBlockVector
131  {
133 
134  public:
135  typedef DC DofContainerType;
136 
137  typedef typename FieldTraits< DofContainerType >::field_type FieldType;
138 
139  typedef std::size_t SizeType;
140 
143 
144  typedef typename Impl::BlockIndicesFor< DC >::Type BlockIndices;
145  static constexpr std::size_t blockSize = Hybrid::size( BlockIndices() );
146 
149 
151 
152  ConstDofBlockType operator[] ( SizeType i ) const { return ConstDofBlockType( data_, i ); }
153  DofBlockType operator[] ( SizeType i ) { return DofBlockType( data_, i ); }
154 
155  ThisType &operator+= ( const ThisType &other ) { data_ += other.data_; return *this; }
156  ThisType &operator-= ( const ThisType &other ) { data_ -= other.data_; return *this; }
157  ThisType &operator*= ( const FieldType &scalar ) { data_ *= scalar; return *this; }
158 
159  FieldType operator* ( const ThisType &other ) const { return data_ * other.data_; }
160 
161  void axpy ( const FieldType &scalar, const ThisType &other ) { data_.axpy( scalar, other.data_ ); }
162 
163  void clear () { data_ = FieldType( 0 ); }
164 
166  const DofContainerType &array () const noexcept { return data_; }
168  DofContainerType &array () noexcept { return data_; }
169 
170  void reserve ( SizeType size ) { reserve( data_, size ); }
171  void resize ( SizeType size ) { resize( data_, size ); }
172 
173  SizeType size () const { return size( data_ ); }
174 
175  // unimplemented interface methods
176 
177  typedef const FieldType *ConstIteratorType;
179 
180  ConstIteratorType begin () const { DUNE_THROW( NotImplemented, "HierarchicalDofVector does not provide iterators" ); }
181  IteratorType begin () { DUNE_THROW( NotImplemented, "HierarchicalDofVector does not provide iterators" ); }
182 
183  ConstIteratorType end () const { DUNE_THROW( NotImplemented, "HierarchicalDofVector does not provide iterators" ); }
184  IteratorType end () { DUNE_THROW( NotImplemented, "HierarchicalDofVector does not provide iterators" ); }
185 
186  std::size_t usedMemorySize() const
187  {
189  }
190 
191  void setMemoryFactor ( double memFactor )
192  {}
193 
194  void memMoveBackward ( int length, int oldStartIdx, int newStartIdx )
195  {
196  SpecialArrayFeatures< ThisType >::memMoveBackward( *this, length, oldStartIdx, newStartIdx );
197  }
198 
199  void memMoveForward ( int length, int oldStartIdx, int newStartIdx )
200  {
201  SpecialArrayFeatures< ThisType >::memMoveForward( *this, length, oldStartIdx, newStartIdx );
202  }
203 
204  void copyContent ( int newIndex, int oldIndex )
205  {
206  SpecialArrayFeatures< ThisType >::assign( *this, newIndex, oldIndex );
207  }
208 
209  private:
210 #if HAVE_DUNE_ISTL
211  template< class... V >
212  static void reserve ( MultiTypeBlockVector< V... > &data, SizeType size )
213  {
214  Hybrid::forEach( std::index_sequence_for< V... >(), [ &data, size ] ( auto &&i ) { ThisType::reserve( data[ i ], size ); } );
215  }
216 
217  template< class B, class A >
218  static void reserve ( BlockVector< B, A > &data, SizeType size )
219  {
220  data.reserve( size );
221  }
222 
223  template< class... V >
224  static void resize ( MultiTypeBlockVector< V... > &data, SizeType size )
225  {
226  Hybrid::forEach( std::index_sequence_for< V... >(), [ &data, size ] ( auto &&i ) { ThisType::resize( data[ i ], size ); } );
227  }
228 
229  template< class B, class A >
230  static void resize ( BlockVector< B, A > &data, SizeType size )
231  {
232  data.resize( size );
233  }
234 
235  template< class... V >
236  static SizeType size ( const MultiTypeBlockVector< V... > &data )
237  {
238  return data[ std::integral_constant< std::size_t, 0 > () ].size();
239  }
240 
241  template< class B, class A >
242  static SizeType size ( const BlockVector< B, A > &data )
243  {
244  return data.size();
245  }
246 #endif // HAVE_DUNE_ISTL
247 
248  DofContainerType data_;
249  };
250 
251 
252 
253  // SpecialArrayFeature for HierarhicalDofVector
254  // --------------------------------------------
255 
256  template< class >
257  struct SpecialArrayFeatures;
258 
259  template< class DC >
261  {
262  static std::size_t used ( const HierarchicalDofVector< DC > &array )
263  {
264  return used( array.array() );
265  }
266 
267  static void setMemoryFactor ( HierarchicalDofVector< DC > &array, double memFactor )
268  {}
269 
270  static void memMoveBackward ( HierarchicalDofVector< DC > &array, int length, int oldStartIdx, int newStartIdx )
271  {
272  memMoveBackward( array.array(), length, oldStartIdx, newStartIdx );
273  }
274 
275  static void memMoveForward ( HierarchicalDofVector< DC > &array, int length, int oldStartIdx, int newStartIdx )
276  {
277  memMoveForward( array.array(), length, oldStartIdx, newStartIdx );
278  }
279 
280  static void assign ( HierarchicalDofVector< DC > &array, int newIndex, int oldIndex )
281  {
282  assign( array.array(), newIndex, oldIndex );
283  }
284 
285  private:
286 #if HAVE_DUNE_ISTL
287  template< class... V >
288  static std::size_t used ( const MultiTypeBlockVector< V... > &array )
289  {
290  std::size_t used( 0 );
291  Hybrid::forEach( std::index_sequence_for< V... >(), [ &array, &used ] ( auto &&i ) {
292  used += SpecialArrayFeatures< HierarchicalDofVector< DC > >::used( array[ i ] );
293  } );
294  return used;
295  }
296 
297  template< class B, class A >
298  static std::size_t used ( const BlockVector< B, A > &array )
299  {
300  return array.size() * sizeof( B );
301  }
302 
303  template< class... V >
304  static void memMoveBackward ( MultiTypeBlockVector< V... > &array, int length, int oldStartIdx, int newStartIdx )
305  {
306  Hybrid::forEach( std::index_sequence_for< V... >(), [ &array, length, oldStartIdx, newStartIdx ] ( auto &&i ) {
307  SpecialArrayFeatures< HierarchicalDofVector< DC > >::memMoveBackward( array[ i ], length, oldStartIdx, newStartIdx );
308  } );
309  }
310 
311  template< class B, class A >
312  static void memMoveBackward ( BlockVector< B, A > &array, int length, int oldStartIdx, int newStartIdx )
313  {
314  for( int oldIdx = oldStartIdx+length-1, newIdx = newStartIdx + length-1; oldIdx >= oldStartIdx; --oldIdx, --newIdx )
315  array[ newIdx ] = array[ oldIdx ];
316  }
317 
318  template< class... V >
319  static void memMoveForward ( MultiTypeBlockVector< V... > &array, int length, int oldStartIdx, int newStartIdx )
320  {
321  Hybrid::forEach( std::index_sequence_for< V... >(), [ &array, length, oldStartIdx, newStartIdx ] ( auto &&i ) {
322  SpecialArrayFeatures< HierarchicalDofVector< DC > >::memMoveForward( array[ i ], length, oldStartIdx, newStartIdx );
323  } );
324  }
325 
326  template< class B, class A >
327  static void memMoveForward ( BlockVector< B, A > &array, int length, int oldStartIdx, int newStartIdx )
328  {
329  for( int oldIdx = oldStartIdx, newIdx = newStartIdx; oldIdx < oldStartIdx+length; ++oldIdx, ++newIdx )
330  array[ newIdx ] = array[ oldIdx ];
331  }
332 
333  template< class... V >
334  static void assign ( MultiTypeBlockVector< V... > &array, int newIndex, int oldIndex )
335  {
336  Hybrid::forEach( std::index_sequence_for< V... >(), [ &array, newIndex, oldIndex ] ( auto &&i ) {
337  SpecialArrayFeatures< HierarchicalDofVector< DC > >::assign( array[ i ], newIndex, oldIndex );
338  } );
339  }
340 
341  template< class B, class A >
342  static void assign ( BlockVector< B, A > &array, int newIndex, int oldIndex )
343  {
344  array[ newIndex ] = array[ oldIndex ];
345  }
346 #endif // #if HAVE_DUNE_ISTL
347  };
348 
349  } // namespace Fem
350 
351 } // namespace Dune
352 
353 #endif // #ifndef DUNE_FEM_FUNCTION_HIERARCHICAL_DOFVECTOR_HH
Definition: bindguard.hh:11
static void forEach(IndexRange< T, sz > range, F &&f)
Definition: hybrid.hh:129
Definition: hybrid.hh:86
Definition: hybrid.hh:99
Definition: defaultblockvectors.hh:26
Definition: hierarchical/dofvector.hh:60
static constexpr std::size_t blockSize
Definition: hierarchical/dofvector.hh:64
Impl::BlockIndicesFor< DofContainer >::Type BlockIndices
Definition: hierarchical/dofvector.hh:63
HierarchicalDofBlock(const HierarchicalDofBlock< std::remove_const_t< DofContainer > > &other)
Definition: hierarchical/dofvector.hh:70
HierarchicalDofBlock(DofContainer &data, std::size_t baseIndex)
Definition: hierarchical/dofvector.hh:66
Definition: hierarchical/dofvector.hh:122
Definition: hierarchical/dofvector.hh:131
DofContainerType & array() noexcept
obtain underlaying DoF storage
Definition: hierarchical/dofvector.hh:168
FieldType value_type
Definition: hierarchical/dofvector.hh:141
ThisType & operator-=(const ThisType &other)
Definition: hierarchical/dofvector.hh:156
void memMoveForward(int length, int oldStartIdx, int newStartIdx)
Definition: hierarchical/dofvector.hh:199
HierarchicalDofVector(SizeType size)
Definition: hierarchical/dofvector.hh:150
const DofContainerType & array() const noexcept
obtain underlaying DoF storage
Definition: hierarchical/dofvector.hh:166
void resize(SizeType size)
Definition: hierarchical/dofvector.hh:171
void reserve(SizeType size)
Definition: hierarchical/dofvector.hh:170
IteratorType begin()
Definition: hierarchical/dofvector.hh:181
void axpy(const FieldType &scalar, const ThisType &other)
Definition: hierarchical/dofvector.hh:161
static constexpr std::size_t blockSize
Definition: hierarchical/dofvector.hh:145
ThisType & operator*=(const FieldType &scalar)
Definition: hierarchical/dofvector.hh:157
void clear()
Definition: hierarchical/dofvector.hh:163
ConstIteratorType begin() const
Definition: hierarchical/dofvector.hh:180
HierarchicalDofBlock< DofContainerType > DofBlockType
Definition: hierarchical/dofvector.hh:148
std::size_t SizeType
Definition: hierarchical/dofvector.hh:139
void setMemoryFactor(double memFactor)
Definition: hierarchical/dofvector.hh:191
void copyContent(int newIndex, int oldIndex)
Definition: hierarchical/dofvector.hh:204
ConstDofBlockType operator[](SizeType i) const
Definition: hierarchical/dofvector.hh:152
IteratorType end()
Definition: hierarchical/dofvector.hh:184
HierarchicalDofBlock< const DofContainerType > ConstDofBlockType
Definition: hierarchical/dofvector.hh:147
FieldTraits< DofContainerType >::field_type FieldType
Definition: hierarchical/dofvector.hh:137
SizeType size() const
Definition: hierarchical/dofvector.hh:173
std::size_t usedMemorySize() const
Definition: hierarchical/dofvector.hh:186
FieldType * IteratorType
Definition: hierarchical/dofvector.hh:178
Impl::BlockIndicesFor< DC >::Type BlockIndices
Definition: hierarchical/dofvector.hh:144
FieldType operator*(const ThisType &other) const
Definition: hierarchical/dofvector.hh:159
ConstIteratorType end() const
Definition: hierarchical/dofvector.hh:183
SizeType size_type
Definition: hierarchical/dofvector.hh:142
const FieldType * ConstIteratorType
Definition: hierarchical/dofvector.hh:177
DC DofContainerType
Definition: hierarchical/dofvector.hh:135
ThisType & operator+=(const ThisType &other)
Definition: hierarchical/dofvector.hh:155
void memMoveBackward(int length, int oldStartIdx, int newStartIdx)
Definition: hierarchical/dofvector.hh:194
static void memMoveForward(HierarchicalDofVector< DC > &array, int length, int oldStartIdx, int newStartIdx)
Definition: hierarchical/dofvector.hh:275
static void memMoveBackward(HierarchicalDofVector< DC > &array, int length, int oldStartIdx, int newStartIdx)
Definition: hierarchical/dofvector.hh:270
static void setMemoryFactor(HierarchicalDofVector< DC > &array, double memFactor)
Definition: hierarchical/dofvector.hh:267
static std::size_t used(const HierarchicalDofVector< DC > &array)
Definition: hierarchical/dofvector.hh:262
static void assign(HierarchicalDofVector< DC > &array, int newIndex, int oldIndex)
Definition: hierarchical/dofvector.hh:280