dune-fem  2.8-git
tuplediscretefunction/dofvector.hh
Go to the documentation of this file.
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 
14 
15 
16 namespace Dune
17 {
18 
19  namespace Fem
20  {
21 
22 
23  // TupleDofVector
24  // --------------
25 
26  template< class ... DofVectors >
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 
49 
50  typedef std::size_t SizeType;
53 
54  static const int blockSize = 1;
55 
57  typedef const FieldType *ConstDofBlockType;
58 
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 &
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 ... >::
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
Definition: bindguard.hh:11
bool operator==(const Double &a, const Double &b)
Definition: double.hh:600
bool operator!=(const Double &a, const Double &b)
Definition: double.hh:640
static constexpr std::decay_t< T > sum(T a)
Definition: utility.hh:33
static DUNE_PRIVATE void apply(Args &&... args)
Definition: forloop.hh:23
Definition: utility.hh:147
Definition: defaultblockvectors.hh:26
Definition: tuplediscretefunction/dofvector.hh:30
constexpr std::size_t blocks() const
Definition: tuplediscretefunction/dofvector.hh:160
void reserve(SizeType size)
Definition: tuplediscretefunction/dofvector.hh:157
void clear()
Definition: tuplediscretefunction/dofvector.hh:125
TupleDofVector(BaseType data)
Definition: tuplediscretefunction/dofvector.hh:67
Iterator IteratorType
Definition: tuplediscretefunction/dofvector.hh:45
FieldType value_type
Definition: tuplediscretefunction/dofvector.hh:51
const ThisType & operator+=(const ThisType &other)
Definition: tuplediscretefunction/dofvector.hh:77
SizeType size_type
Definition: tuplediscretefunction/dofvector.hh:52
const FieldType * blockAccess(std::size_t index, std::integral_constant< std::size_t, i >) const
Definition: tuplediscretefunction/dofvector.hh:221
FieldType operator*(const ThisType &other) const
Definition: tuplediscretefunction/dofvector.hh:100
Fem::Envelope< ConstDofBlockType > ConstDofBlockPtrType
Definition: tuplediscretefunction/dofvector.hh:60
const FieldType * blockAccess(std::size_t index, std::integral_constant< std::size_t, sizeof ...(DofVectors) >) const
Definition: tuplediscretefunction/dofvector.hh:231
const ThisType & operator*=(const FieldType &scalar)
Definition: tuplediscretefunction/dofvector.hh:108
ConstIterator ConstIteratorType
Definition: tuplediscretefunction/dofvector.hh:48
DofBlockPtrType blockPtr(std::size_t index)
Definition: tuplediscretefunction/dofvector.hh:146
const std::tuple_element< i, DofVectorTuple >::type & subDofVector() const
Definition: tuplediscretefunction/dofvector.hh:164
static const int blockSize
Definition: tuplediscretefunction/dofvector.hh:54
void scale(FieldType scale, std::index_sequence< i ... >)
Definition: tuplediscretefunction/dofvector.hh:174
ConstIteratorType begin() const
Definition: tuplediscretefunction/dofvector.hh:132
IteratorType end()
Definition: tuplediscretefunction/dofvector.hh:134
void assign(const ThisType &other, std::index_sequence< i ... >)
Definition: tuplediscretefunction/dofvector.hh:186
FieldType * DofBlockType
Definition: tuplediscretefunction/dofvector.hh:56
std::tuple_element< i, DofVectorTuple >::type & subDofVector()
Definition: tuplediscretefunction/dofvector.hh:168
ConstDofBlockType blockPtr(std::size_t index) const
Definition: tuplediscretefunction/dofvector.hh:150
DofBlockType operator[](std::size_t index)
Definition: tuplediscretefunction/dofvector.hh:137
const FieldType * ConstDofBlockType
Definition: tuplediscretefunction/dofvector.hh:57
Fem::Envelope< DofBlockType > DofBlockPtrType
Definition: tuplediscretefunction/dofvector.hh:59
SizeType size(std::index_sequence< i ... >) const
Definition: tuplediscretefunction/dofvector.hh:192
const ThisType & operator-=(const ThisType &other)
Definition: tuplediscretefunction/dofvector.hh:83
const ThisType & operator/=(const FieldType &scalar)
Definition: tuplediscretefunction/dofvector.hh:114
SizeType size() const
Definition: tuplediscretefunction/dofvector.hh:127
ConstIteratorType end() const
Definition: tuplediscretefunction/dofvector.hh:135
TupleDofVector(DofVectors &... dofVectors)
Definition: tuplediscretefunction/dofvector.hh:62
std::size_t SizeType
Definition: tuplediscretefunction/dofvector.hh:50
FieldType * blockAccess(std::size_t index, std::integral_constant< std::size_t, i >)
Definition: tuplediscretefunction/dofvector.hh:205
TupleDofVector(const ThisType &)=default
void resize(SizeType size)
Definition: tuplediscretefunction/dofvector.hh:158
std::tuple_element< 0, DofVectorTuple >::type::FieldType FieldType
Definition: tuplediscretefunction/dofvector.hh:41
void axpy(const FieldType &scalar, const ThisType &other)
Definition: tuplediscretefunction/dofvector.hh:120
IteratorType begin()
Definition: tuplediscretefunction/dofvector.hh:131
TupleDofVector(ThisType &&)=default
void axpy(FieldType a, const ThisType &other, std::index_sequence< i ... >)
Definition: tuplediscretefunction/dofvector.hh:180
void clear(std::index_sequence< I ... >)
Definition: tuplediscretefunction/dofvector.hh:199
const ThisType & operator=(const ThisType &other)
Definition: tuplediscretefunction/dofvector.hh:71
FieldType * blockAccess(std::size_t index, std::integral_constant< std::size_t, sizeof ...(DofVectors) >)
Definition: tuplediscretefunction/dofvector.hh:215
Definition: tuplediscretefunction/dofvector.hh:242
std::size_t iterator_
Definition: tuplediscretefunction/dofvector.hh:265
TupleDofVector< DofVectors ... > & container_
Definition: tuplediscretefunction/dofvector.hh:264
Iterator(const Iterator &)=default
Iterator(TupleDofVector< DofVectors ... > &container, std::size_t it=0)
Definition: tuplediscretefunction/dofvector.hh:243
Definition: tuplediscretefunction/dofvector.hh:271
ConstIterator(const ConstIterator &)=default
std::size_t iterator_
Definition: tuplediscretefunction/dofvector.hh:293
const TupleDofVector< DofVectors ... > & container_
Definition: tuplediscretefunction/dofvector.hh:292
ConstIterator(const TupleDofVector< DofVectors ... > &container, std::size_t it=0)
Definition: tuplediscretefunction/dofvector.hh:272
Definition: envelope.hh:11