DUNE-FEM (unstable)

dofvector.hh
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
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
14#include <dune/fem/common/hybrid.hh>
15#include <dune/fem/common/utility.hh>
16#include <dune/fem/function/blockvectors/defaultblockvectors.hh>
17
18namespace 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 {
40 typedef Hybrid::CompositeIndexRange< typename BlockIndicesFor< V >::Type... > Type;
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 >
59 struct HierarchicalDofBlock
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 >
122 struct SpecialArrayFeatures;
123
124
125 // HierarchicalDofVector
126 // ---------------------
127
128 template< class DC >
129 class HierarchicalDofVector
130 : public IsBlockVector
131 {
132 typedef HierarchicalDofVector< DC > ThisType;
133
134 public:
135 typedef DC DofContainerType;
136
137 typedef typename FieldTraits< DofContainerType >::field_type FieldType;
138
139 typedef std::size_t SizeType;
140
141 typedef FieldType value_type;
142 typedef SizeType size_type;
143
144 typedef typename Impl::BlockIndicesFor< DC >::Type BlockIndices;
145 static constexpr std::size_t blockSize = Hybrid::size( BlockIndices() );
146
147 typedef HierarchicalDofBlock< const DofContainerType > ConstDofBlockType;
148 typedef HierarchicalDofBlock< DofContainerType > DofBlockType;
149
150 explicit HierarchicalDofVector ( SizeType size ) { resize( size ); }
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;
178 typedef FieldType *IteratorType;
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 {
188 return SpecialArrayFeatures< ThisType >::used( *this );
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 >
260 struct SpecialArrayFeatures< HierarchicalDofVector< 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
This file implements a vector space as a tensor product of a given vector space. The number of compon...
Type traits to determine the type of reals (when working with complex numbers)
#define DUNE_THROW(E, m)
Definition: exceptions.hh:218
constexpr void forEach(Range &&range, F &&f)
Range based for loop.
Definition: hybridutilities.hh:256
Dune namespace.
Definition: alignedallocator.hh:13
constexpr std::integral_constant< std::size_t, sizeof...(II)> size(std::integer_sequence< T, II... >)
Return the size of the sequence.
Definition: integersequence.hh:75
void assign(T &dst, const T &src, bool mask)
masked Simd assignment (scalar version)
Definition: simd.hh:447
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Nov 13, 23:29, 2024)