DUNE-FEM (unstable)

dofvector.hh
1#ifndef DUNE_FEM_FUNCTION_BLOCKVECTORS_TUPLE_HH
2#define DUNE_FEM_FUNCTION_BLOCKVECTORS_TUPLE_HH
3
4#include <limits>
5#include <utility>
6#include <tuple>
7
8#include <dune/common/hybridutilities.hh>
9
10#include <dune/fem/common/forloop.hh>
11#include <dune/fem/common/utility.hh>
12#include <dune/fem/function/blockvectors/defaultblockvectors.hh>
13#include <dune/fem/function/common/functor.hh>
14
15
16namespace Dune
17{
18
19 namespace Fem
20 {
21
22
23 // TupleDofVector
24 // --------------
25
26 template< class ... DofVectors >
27 class TupleDofVector
28 : public IsBlockVector,
29 public std::tuple< DofVectors& ... >
30 {
31 typedef TupleDofVector< DofVectors ... > ThisType;
32 typedef std::tuple< DofVectors & ... > BaseType;
33
34 static_assert( sizeof ... ( DofVectors ) > 0, "TupleDofVector needs at least one DofVector." );
35
36 typedef std::tuple< DofVectors ... > DofVectorTuple;
37
38 typedef decltype ( std::index_sequence_for< DofVectors ... >() ) Sequence;
39
40 public:
41 static_assert( Std::are_all_same< typename DofVectors::FieldType ... >::value, "All blocks need to have the same FieldType." );
42 typedef typename std::tuple_element< 0, DofVectorTuple >::type::FieldType FieldType;
43
44 struct Iterator;
45 struct ConstIterator;
46
47 typedef Iterator IteratorType;
48 typedef ConstIterator ConstIteratorType;
49
50 typedef std::size_t SizeType;
51 typedef FieldType value_type;
52 typedef SizeType size_type;
53
54 static const int blockSize = 1;
55
56 typedef FieldType *DofBlockType;
57 typedef const FieldType *ConstDofBlockType;
58
59 typedef Fem::Envelope< DofBlockType > DofBlockPtrType;
60 typedef Fem::Envelope< ConstDofBlockType > ConstDofBlockPtrType;
61
62 TupleDofVector ( DofVectors & ... dofVectors )
63 : BaseType( std::forward_as_tuple( dofVectors ... ) )
64 {}
65
66 // constructor
67 TupleDofVector ( BaseType data ) : BaseType( data ) {}
68 TupleDofVector ( const ThisType & ) = default;
69 TupleDofVector ( ThisType && ) = default;
70
71 const ThisType &operator= ( const ThisType &other )
72 {
73 assign( other, Sequence() );
74 return *this;
75 }
76
77 const ThisType &operator+= ( const ThisType &other )
78 {
79 axpy( 1.0, other, Sequence() );
80 return *this;
81 }
82
83 const ThisType &operator-= ( const ThisType &other )
84 {
85 axpy( -1.0, other, Sequence() );
86 return *this;
87 }
88
89 private:
90 template <int i>
91 struct Acc
92 {
93 static void apply(const ThisType &a, const ThisType& b, FieldType& result )
94 {
95 result += (a.template subDofVector< i >() * b.template subDofVector<i>());
96 }
97 };
98
99 public:
100 FieldType operator* ( const ThisType &other ) const
101 {
102 FieldType result( 0 );
103 static const int length = std::tuple_size< BaseType >::value;
104 Dune::Fem::ForLoop<Acc, 0, length-1>::apply(*this, other, result);
105 return result;
106 }
107
108 const ThisType &operator*= ( const FieldType &scalar )
109 {
110 scale( scalar, Sequence() );
111 return *this;
112 }
113
114 const ThisType &operator/= ( const FieldType &scalar )
115 {
116 scale( 1.0 / scalar, Sequence() );
117 return *this;
118 }
119
120 void axpy ( const FieldType &scalar, const ThisType &other )
121 {
122 axpy( scalar, other, Sequence() );
123 }
124
125 void clear () { clear( Sequence() ); }
126
127 SizeType size () const { return size( Sequence() ); }
128
129 // ----------------------------------------------------------------------------
130
131 IteratorType begin () { return IteratorType( *this, 0 ); }
132 ConstIteratorType begin () const { return ConstIteratorType( *this, 0 ); }
133
134 IteratorType end () { return IteratorType( *this, size() ); }
135 ConstIteratorType end () const { return ConstIteratorType( *this, size() ); }
136
137 DofBlockType operator[] ( std::size_t index )
138 {
139 return blockAccess( index, std::integral_constant< std::size_t, 0 >() );
140 }
141 ConstDofBlockType operator[] ( std::size_t index ) const
142 {
143 return blockAccess( index, std::integral_constant< std::size_t, 0 >() );
144 }
145
146 DofBlockPtrType blockPtr ( std::size_t index )
147 {
148 return DofBlockPtrType( this->operator[]( index ) );
149 }
150 ConstDofBlockType blockPtr ( std::size_t index ) const
151 {
152 return ConstDofBlockPtrType( this->operator[]( index ) );
153 }
154
155 // ----------------------------------------------------------------------------
156
157 void reserve ( SizeType size ) {}
158 void resize ( SizeType size ) {}
159
160 constexpr std::size_t blocks () const { return sizeof ... ( DofVectors ); }
161
162 template< int i >
163 const typename std::tuple_element< i, DofVectorTuple >::type &
164 subDofVector() const { return std::get< i >( *this ); }
165
166 template< int i >
167 typename std::tuple_element< i, DofVectorTuple >::type &
168 subDofVector() {
169 return std::get< i >( *this );
170 }
171
172 protected:
173 template< std::size_t ... i >
174 void scale ( FieldType scale, std::index_sequence< i ... > )
175 {
176 std::ignore = std::make_tuple( (std::get< i >( *this ) *= scale, i ) ... );
177 }
178
179 template< std::size_t ... i >
180 void axpy ( FieldType a, const ThisType &other, std::index_sequence< i ... > )
181 {
182 std::ignore = std::make_tuple( ( std::get< i >( *this ).axpy( a, std::get< i >( other ) ), i ) ... );
183 }
184
185 template< std::size_t ... i >
186 void assign ( const ThisType &other, std::index_sequence< i ... > )
187 {
188 std::ignore = std::make_tuple( ( std::get< i >( *this ) = std::get< i >( other ), i ) ... );
189 }
190
191 template< std::size_t ... i >
192 SizeType size ( std::index_sequence< i ... > ) const
193 {
194 return Std::sum( std::get< i >( *this ).size() *
195 std::tuple_element< i, DofVectorTuple >::type::blockSize ... );
196 }
197
198 template< std::size_t ... I >
199 void clear ( std::index_sequence< I ... > )
200 {
201 std::ignore = std::make_tuple( ( std::get< I >( *this ).clear(), I ) ... );
202 }
203
204 template< std::size_t i >
205 FieldType *blockAccess ( std::size_t index, std::integral_constant< std::size_t, i > )
206 {
207 const std::size_t thisBlockSize = std::tuple_element< i, DofVectorTuple >::type::blockSize;
208 std::size_t offset = std::get< i >( *this ).size() * thisBlockSize;
209 if( index < offset )
210 return &std::get< i >( *this )[ index / thisBlockSize ][ index % thisBlockSize ];
211 else
212 return blockAccess( index - offset, std::integral_constant< std::size_t, i +1 >() );
213 }
214
215 FieldType *blockAccess ( std::size_t index, std::integral_constant< std::size_t, sizeof ... ( DofVectors ) > )
216 {
217 DUNE_THROW( RangeError, "Index out of range" );
218 }
219
220 template< std::size_t i >
221 const FieldType *blockAccess ( std::size_t index, std::integral_constant< std::size_t, i > ) const
222 {
223 const std::size_t thisBlockSize = std::tuple_element< i, DofVectorTuple >::type::blockSize;
224 std::size_t offset = std::get< i >( *this ).size() * thisBlockSize;
225 if( index < offset )
226 return &std::get< i >( *this )[ index / thisBlockSize ][ index % thisBlockSize ];
227 else
228 return blockAccess( index - offset, std::integral_constant< std::size_t, i +1 >() );
229 }
230
231 const FieldType *blockAccess ( std::size_t index, std::integral_constant< std::size_t, sizeof ... ( DofVectors ) > ) const
232 {
233 DUNE_THROW( RangeError, "Index out of range" );
234 }
235
236 };
237
238
239 template< class ... DofVectors >
240 struct TupleDofVector< DofVectors ... >::
241 Iterator
242 {
243 Iterator( TupleDofVector< DofVectors ... > &container, std::size_t it = 0 )
244 : container_( container ), iterator_( it ) {}
245
246 Iterator( const Iterator & ) = default;
247 Iterator &operator= ( const Iterator & ) = default;
248
249 FieldType &operator* () { return *container_[ iterator_ ]; }
250 FieldType *operator-> () { return container_[ iterator_ ]; }
251
252 Iterator &operator++ () { iterator_++; return *this; }
253 Iterator operator++ ( int )
254 {
255 ThisType copy( *this );
256 iterator_++;
257 return copy;
258 }
259
260 bool operator== ( const Iterator &other ) const { return iterator_ == other.iterator_; }
261 bool operator!= ( const Iterator &other ) const { return iterator_ != other.iterator_; }
262
263 protected:
264 TupleDofVector< DofVectors ... > &container_;
265 std::size_t iterator_;
266 };
267
268 template< class ... DofVectors >
269 struct TupleDofVector< DofVectors ... >::
270 ConstIterator
271 {
272 ConstIterator( const TupleDofVector< DofVectors ... > &container, std::size_t it = 0 )
273 : container_( container ), iterator_( it ) {}
274
275 ConstIterator( const ConstIterator & ) = default;
276
277 const FieldType &operator* () const { return *container_[ iterator_ ]; }
278 FieldType *operator-> () const { return container_[ iterator_ ]; }
279
280 ConstIterator &operator++ () { iterator_++; return *this; }
281 ConstIterator operator++ ( int )
282 {
283 ThisType copy( *this );
284 iterator_++;
285 return copy;
286 }
287
288 bool operator== ( const ConstIterator &other ) const { return iterator_ == other.iterator_; }
289 bool operator!= ( const ConstIterator &other ) const { return iterator_ != other.iterator_; }
290
291 protected:
292 const TupleDofVector< DofVectors ... > &container_;
293 std::size_t iterator_;
294 };
295
296 } // namespace Fem
297
298} // namespace Dune
299
300#endif // #ifndef DUNE_FEM_FUNCTION_BLOCKVECTORS_TUPLE_HH
#define DUNE_THROW(E, m)
Definition: exceptions.hh:218
EnableIfInterOperable< T1, T2, bool >::type operator==(const ForwardIteratorFacade< T1, V1, R1, D > &lhs, const ForwardIteratorFacade< T2, V2, R2, D > &rhs)
Checks for equality.
Definition: iteratorfacades.hh:238
EnableIfInterOperable< T1, T2, bool >::type operator!=(const ForwardIteratorFacade< T1, V1, R1, D > &lhs, const ForwardIteratorFacade< T2, V2, R2, D > &rhs)
Checks for inequality.
Definition: iteratorfacades.hh:260
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
STL namespace.
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Nov 13, 23:29, 2024)