dune-fem  2.6-git
defaultblockvectors.hh
Go to the documentation of this file.
1 #ifndef DUNE_FEM_SIMPLEBLOCKVECTOR_HH
2 #define DUNE_FEM_SIMPLEBLOCKVECTOR_HH
3 
4 #include <algorithm>
5 #include <cassert>
6 #include <memory>
7 
8 #include <dune/common/densevector.hh>
9 #include <dune/common/dynvector.hh>
10 
12 #include <dune/fem/misc/debug.hh>
16 
17 #if HAVE_DUNE_ISTL
18 #include <dune/istl/bvector.hh>
19 #endif
20 
21 namespace Dune {
22 
23  namespace Fem {
24 
25  // tag for block vectors
26  struct IsBlockVector {};
27 
28 
29 
37  template< class Imp, class Field >
39  : public IsBlockVector
40  {
41  protected:
43 
45 
47  typedef Imp ThisType;
48  public:
50  typedef Field FieldType;
51 
53  const ThisType& operator= ( const ThisType &other )
54  {
55  if( &asImp() != &other )
56  {
57  assign( other );
58  sequence_ = other.sequence_;
59  }
60  return asImp();
61  }
62 
64  const ThisType &operator+= ( const ThisType &other )
65  {
66  assert( asImp().size() == other.size() );
67  const auto endit = asImp().end();
68  auto oit = other.begin();
69  for( auto it = asImp().begin(); it != endit; ++it, ++oit )
70  *it += *oit;
71 
72  ++sequence_;
73  return asImp();
74  }
75 
77  const ThisType &operator-= ( const ThisType &other )
78  {
79  assert( asImp().size() == other.size() );
80  const auto endit = asImp().end();
81  auto oit = other.begin();
82  for( auto it = asImp().begin(); it != endit; ++it, ++oit )
83  *it -= *oit;
84 
85  ++sequence_;
86  return asImp();
87  }
88 
90  FieldType operator* ( const ThisType &other ) const
91  {
92  assert( asImp().size() == other.size() );
93  FieldType sum( 0 );
94  const auto endit = asImp().end();
95  auto oit = other.asImp().begin();
96  for( auto it = asImp().begin(); it != endit; ++it, ++oit )
97  sum += (*it * *oit);
98 
99  return sum;
100  }
101 
107  const ThisType &operator*= ( const FieldType &scalar )
108  {
109  const auto endit = asImp().end();
110  for( auto it = asImp().begin(); it != endit; ++it )
111  *it *= scalar;
112 
113  ++sequence_;
114  return asImp();
115  }
116 
124  void axpy ( const FieldType &scalar, const ThisType &other )
125  {
126  assert( asImp().size() == other.size() );
127  const auto endit = asImp().end();
128  auto oit = other.begin();
129  for( auto it = asImp().begin(); it != endit; ++it, ++oit )
130  *it += scalar * (*oit);
131 
132  ++sequence_;
133  }
134 
136  void clear ()
137  {
138  std::fill( asImp().begin(), asImp().end(), FieldType( 0 ) );
139  ++sequence_;
140  }
141 
142  protected:
143  // Copy block vectors.
144  // Note: No '++sequence_' here, sequence_ is only changed in public methods
145  void assign ( const ThisType &other )
146  {
147  assert( asImp().size() == other.size() );
148  std::copy( other.begin(), other.end(), asImp().begin() );
149  }
150 
151  ThisType& asImp() { return static_cast< ThisType& > (*this); }
152  const ThisType& asImp() const { return static_cast< const ThisType& > (*this); }
153 
154  mutable CounterType sequence_; // for consistency checks...
155  };
156 
157 
158 
166  template< class Container, int BlockSize >
168  : public BlockVectorInterface< SimpleBlockVector< Container, BlockSize>, typename Container::value_type >
169  {
170  typedef BlockVectorInterface< SimpleBlockVector< Container, BlockSize>, typename Container::value_type > BaseType;
172  typedef Container ArrayType;
173 
175 
176  public:
178 
182  typedef typename ArrayType::iterator IteratorType;
184  typedef typename ArrayType::const_iterator ConstIteratorType;
186  typedef typename ArrayType::size_type SizeType;
187 
192 
197 
200 
202  enum { blockSize = BlockSize };
203 
205 
208  : array_( array )
209  {}
210 
212  const ThisType& operator= ( const ThisType& other )
213  {
214  BaseType::operator=( other );
215  return *this;
216  }
217 
219  ConstDofBlockType operator[] ( const unsigned int i ) const
220  {
221  assert( i < size() );
223  }
224 
226  DofBlockType operator[] ( const unsigned int i )
227  {
228  assert( i < size() );
230  }
231 
233  ConstDofBlockPtrType blockPtr( const unsigned int i ) const
234  {
235  return ConstDofBlockPtrType( this->operator[] ( i ) );
236  }
237 
239  DofBlockPtrType blockPtr( const unsigned int i )
240  {
241  return DofBlockPtrType( this->operator[] ( i ) );
242  }
243 
245  IteratorType begin() { return array().begin(); }
246 
248  ConstIteratorType begin() const { return array().begin(); }
249 
251  IteratorType end() { return array().end(); }
252 
254  ConstIteratorType end() const { return array().end(); }
255 
257  SizeType size () const { return array().size() / blockSize; }
258 
260  SizeType numDofs() const { return array().size(); }
261 
262  FieldType* data() { return array().data(); }
263  const FieldType* data() const { return array().data(); }
264 
265  const ArrayType &array () const { return array_; }
266  ArrayType &array () { return array_; }
267 
268  protected:
270  };
271 
272 
273 
281  template< class Container, unsigned int BlockSize >
283  : public SimpleBlockVector< Container, BlockSize >
284  {
287 
288  typedef Container ArrayType;
289  using BaseType :: array_;
290  using BaseType :: sequence_;
291  public:
292 
293  using BaseType :: array;
294  using BaseType :: blockSize ;
295  typedef typename BaseType :: SizeType SizeType;
296 
299  : BaseType( *(new Container( size*blockSize ) ) )
300  {}
301 
303  MutableBlockVector ( const ThisType &other )
304  : BaseType( *(new Container( other.array().size() ) ) )
305  {
306  assign( other );
307  }
308 
310  {
311  delete &array_;
312  }
313 
322  void reserve ( const int size )
323  {
324  array().reserve( size*blockSize );
325  }
326 
329  {
330  array().resize( size*blockSize );
331  ++sequence_;
332  }
333  };
334 
335 
336 
344  template< class Field, unsigned int BlockSize >
345  class MutableBlockVector< DynamicArray< Field >, BlockSize >
346  : public SimpleBlockVector< StaticArray< Field >, BlockSize >
347  {
352 
353  protected:
354  using BaseType :: array_;
355  using BaseType :: sequence_;
356 
357  std::unique_ptr< MutableContainer > container_;
358  public:
359  using BaseType :: blockSize ;
360  typedef typename BaseType :: SizeType SizeType;
361 
364  : BaseType( allocateContainer( size*blockSize ) ),
365  container_( static_cast< MutableContainer* > (&array_) )
366  {}
367 
369  MutableBlockVector ( const ThisType &other )
370  : BaseType( allocateContainer( other.array().size() ) ),
371  container_( static_cast< MutableContainer* > (&array_) )
372  {
373  assign( other );
374  }
375 
384  void reserve ( const int size )
385  {
386  assert( container_ );
387  container_->reserve( size*blockSize );
388  }
389 
392  {
393  assert( container_ );
394  container_->resize( size*blockSize );
395  ++sequence_;
396  }
397 
398  protected:
400  {
401  MutableContainer* container = new MutableContainer( size );
402  return *container;
403  }
404  };
405 
406 
407 
412  template< class DofBlock >
414  : public BlockVectorInterface< ISTLBlockVector< DofBlock >, typename DofBlock :: value_type >
415  {
417 #if HAVE_DUNE_ISTL
418  typedef BlockVector< DofBlock > ArrayType;
419 #else
420  // fallback in case dune-istl is not present
421  typedef Dune::DynamicVector< DofBlock > ArrayType;
422 #endif
423  typedef BlockVectorInterface< ISTLBlockVector< DofBlock >, typename DofBlock :: value_type > BaseType;
424 
425 
426  using BaseType :: sequence_;
427 
428  public:
429  ISTLBlockVector ( const ThisType& ) = default;
430 
431  typedef ArrayType DofContainerType;
432 
433  enum { blockSize = DofBlock :: dimension };
435 
436  typedef typename DofBlock :: value_type FieldType;
437 
438  protected:
439  template <class EmbeddedIterator, class V>
440  class Iterator
441  : public ForwardIteratorFacade< Iterator< EmbeddedIterator,V >, V >
442  {
443  public:
444  typedef V FieldType;
445  protected:
446  mutable EmbeddedIterator it_;
447 #ifndef NDEBUG
448  EmbeddedIterator end_;
449 #endif
450  int index_;
451  public:
453  Iterator( const EmbeddedIterator& it
454 #ifndef NDEBUG
455  , const EmbeddedIterator& end = EmbeddedIterator()
456 #endif
457  )
458  : it_( it ),
459 #ifndef NDEBUG
460  end_( end ),
461 #endif
462  index_(0)
463  {}
464 
467  {
468  assert( it_ != end_ );
469  assert( index_ < blockSize );
470  return (*it_)[ index_ ];
471  }
472 
474  void increment ()
475  {
476  ++index_;
477  if( index_ >= blockSize )
478  {
479  index_ = 0;
480  ++it_;
481  }
482  }
483 
485  bool equals ( const Iterator &other ) const
486  {
487  return (it_ == other.it_) && (index_ == other.index_);
488  }
489 
490  }; // end DofIteratorBlockVectorDiscreteFunction
491 
492  public:
495 
496  typedef DofBlock DofBlockType;
497  typedef const DofBlock ConstDofBlockType;
498 
501 
502  typedef typename ArrayType::size_type SizeType;
504  typedef typename ArrayType::value_type value_type;
505 
507  explicit ISTLBlockVector ( ArrayType& array )
508  : array_( &array )
509  {}
510 
511  ISTLBlockVector () = default;
512 
514  const ThisType& operator= ( const ThisType& other )
515  {
516  if( this != &other )
517  {
518  array() = other.array();
519  }
520  return *this;
521  }
522 
523  DofBlockPtrType blockPtr(const unsigned int i ) { return &array()[ i ]; }
524  ConstDofBlockPtrType blockPtr(const unsigned int i ) const { return &array()[ i ]; }
525 
526  DofBlockType& operator[] (const unsigned int i ) { return array()[ i ]; }
527  ConstDofBlockType& operator[] (const unsigned int i ) const { return array()[ i ]; }
528 
530 #ifndef NDEBUG
531  , array().end()
532 #endif
533  ); }
535  {
536  return ConstIteratorType( array().begin()
537 #ifndef NDEBUG
538  , array().end()
539 #endif
540  ); }
541 
542  IteratorType end() { return IteratorType( array().end() ); }
543  ConstIteratorType end() const { return ConstIteratorType( array().end() ); }
544 
545  SizeType size() const { return array().size(); }
546 
555  void reserve ( const int size )
556  {
557  array().reserve( size );
558  }
559 
562  {
563  array().resize( size );
564  ++sequence_;
565  }
566 
567  ArrayType& array() { assert( array_ ); return *array_; }
568  const ArrayType& array() const { assert( array_ ); return *array_; }
569 
570  protected:
571  // ISTL BlockVector
572  ArrayType* array_;
573  };
574 
575 } // namespace Fem
576 } // namespace Dune
577 
578 #endif // DUNE_FEM_REFERENCEBLOCKVECTOR_HH
Definition: bindguard.hh:11
static constexpr std::decay_t< T > sum(T a)
Definition: utility.hh:33
Definition: hybrid.hh:86
Definition: defaultblockvectors.hh:26
Definition: defaultblockvectors.hh:40
CounterType sequence_
Definition: defaultblockvectors.hh:154
Field FieldType
Type of the field the dofs lie in.
Definition: defaultblockvectors.hh:50
Imp ThisType
Type of derived class (implementation)
Definition: defaultblockvectors.hh:47
const ThisType & operator*=(const FieldType &scalar)
Scale this block vector.
Definition: defaultblockvectors.hh:107
DebugCounter< size_t > CounterType
Definition: defaultblockvectors.hh:42
void axpy(const FieldType &scalar, const ThisType &other)
Add a scalar multiple of another block vector to this block vector.
Definition: defaultblockvectors.hh:124
ThisType & asImp()
Definition: defaultblockvectors.hh:151
BlockVectorInterface()
Definition: defaultblockvectors.hh:44
const ThisType & operator=(const ThisType &other)
Copy assignment operator.
Definition: defaultblockvectors.hh:53
FieldType operator*(const ThisType &other) const
Scalar product between *this and another block vector.
Definition: defaultblockvectors.hh:90
void assign(const ThisType &other)
Definition: defaultblockvectors.hh:145
const ThisType & asImp() const
Definition: defaultblockvectors.hh:152
const ThisType & operator-=(const ThisType &other)
Subtract another block vector from *this.
Definition: defaultblockvectors.hh:77
void clear()
Clear this block vector, i.e. set each dof to 0.
Definition: defaultblockvectors.hh:136
const ThisType & operator+=(const ThisType &other)
Add another block vector to *this.
Definition: defaultblockvectors.hh:64
This is the reference implementation of a block vector as it is expected as the second template param...
Definition: defaultblockvectors.hh:169
ArrayType::size_type SizeType
Used for indexing the blocks, for example.
Definition: defaultblockvectors.hh:186
SubVector< DofContainerType, StaticOffsetSubMapper< BlockSize > > DofBlockType
Type of one (mutable) block.
Definition: defaultblockvectors.hh:194
Fem::Envelope< DofBlockType > DofBlockPtrType
Definition: defaultblockvectors.hh:198
SizeType numDofs() const
Number of dofs in the block vector.
Definition: defaultblockvectors.hh:260
SizeType size() const
Number of blocks.
Definition: defaultblockvectors.hh:257
ArrayType DofContainerType
Definition: defaultblockvectors.hh:177
ArrayType::const_iterator ConstIteratorType
Constant iterator to iterate over the dofs.
Definition: defaultblockvectors.hh:184
ConstIteratorType end() const
Const-iterator pointing to the last dof.
Definition: defaultblockvectors.hh:254
ArrayType::value_type FieldType
Type of the field the dofs lie in.
Definition: defaultblockvectors.hh:180
Hybrid::IndexRange< int, blockSize > BlockIndices
Definition: defaultblockvectors.hh:204
ConstDofBlockPtrType blockPtr(const unsigned int i) const
Constant access for the i-th block.
Definition: defaultblockvectors.hh:233
ConstIteratorType begin() const
Const-iterator pointing to the first dof.
Definition: defaultblockvectors.hh:248
FieldType * data()
Definition: defaultblockvectors.hh:262
ArrayType & array_
Definition: defaultblockvectors.hh:269
ArrayType::iterator IteratorType
Iterator to iterate over the dofs.
Definition: defaultblockvectors.hh:182
IteratorType end()
Iterator pointing to the last dof.
Definition: defaultblockvectors.hh:251
const ArrayType & array() const
Definition: defaultblockvectors.hh:265
const FieldType * data() const
Definition: defaultblockvectors.hh:263
SimpleBlockVector(ArrayType &array)
Constructor.
Definition: defaultblockvectors.hh:207
DofBlockPtrType blockPtr(const unsigned int i)
Access the i-th block.
Definition: defaultblockvectors.hh:239
SizeType size_type
Typedef to make this class STL-compatible.
Definition: defaultblockvectors.hh:191
ArrayType & array()
Definition: defaultblockvectors.hh:266
@ blockSize
Definition: defaultblockvectors.hh:202
FieldType value_type
Typedef to make this class STL-compatible.
Definition: defaultblockvectors.hh:189
DofBlockType ConstDofBlockType
Type of one constant block.
Definition: defaultblockvectors.hh:196
IteratorType begin()
Iterator pointing to the first dof.
Definition: defaultblockvectors.hh:245
ConstDofBlockType operator[](const unsigned int i) const
Constant access the i-th block.
Definition: defaultblockvectors.hh:219
const ThisType & operator=(const ThisType &other)
Copy assignment operator.
Definition: defaultblockvectors.hh:212
Fem::Envelope< ConstDofBlockType > ConstDofBlockPtrType
Definition: defaultblockvectors.hh:199
Definition: defaultblockvectors.hh:284
MutableBlockVector(const ThisType &other)
Copy constructor.
Definition: defaultblockvectors.hh:303
void reserve(const int size)
Reserve memory.
Definition: defaultblockvectors.hh:322
BaseType ::SizeType SizeType
Definition: defaultblockvectors.hh:295
~MutableBlockVector()
Definition: defaultblockvectors.hh:309
MutableBlockVector(SizeType size)
Construct a block vector with 'size' blocks (not initialized)
Definition: defaultblockvectors.hh:298
void resize(SizeType size)
Resize the block vector.
Definition: defaultblockvectors.hh:328
MutableBlockVector(const ThisType &other)
Copy constructor.
Definition: defaultblockvectors.hh:369
void resize(SizeType size)
Resize the block vector.
Definition: defaultblockvectors.hh:391
std::unique_ptr< MutableContainer > container_
Definition: defaultblockvectors.hh:357
BaseType ::SizeType SizeType
Definition: defaultblockvectors.hh:360
MutableBlockVector(SizeType size)
Construct a block vector with 'size' blocks (not initialized)
Definition: defaultblockvectors.hh:363
StaticContainer & allocateContainer(const SizeType size)
Definition: defaultblockvectors.hh:399
void reserve(const int size)
Reserve memory.
Definition: defaultblockvectors.hh:384
Definition: defaultblockvectors.hh:415
ISTLBlockVector(ArrayType &array)
Constructor.
Definition: defaultblockvectors.hh:507
DofBlock ::value_type FieldType
Definition: defaultblockvectors.hh:436
ConstIteratorType begin() const
Definition: defaultblockvectors.hh:534
void reserve(const int size)
Reserve memory.
Definition: defaultblockvectors.hh:555
DofBlock DofBlockType
Definition: defaultblockvectors.hh:496
IteratorType end()
Definition: defaultblockvectors.hh:542
ArrayType & array()
Definition: defaultblockvectors.hh:567
DofBlockType & operator[](const unsigned int i)
Definition: defaultblockvectors.hh:526
const ThisType & operator=(const ThisType &other)
Copy assignment operator.
Definition: defaultblockvectors.hh:514
ConstDofBlockType * ConstDofBlockPtrType
Definition: defaultblockvectors.hh:500
ConstIteratorType end() const
Definition: defaultblockvectors.hh:543
ArrayType DofContainerType
Definition: defaultblockvectors.hh:431
DofBlockType * DofBlockPtrType
Definition: defaultblockvectors.hh:499
SizeType size() const
Definition: defaultblockvectors.hh:545
ISTLBlockVector(const ThisType &)=default
const ArrayType & array() const
Definition: defaultblockvectors.hh:568
ArrayType::value_type value_type
Typedef to make this class STL-compatible.
Definition: defaultblockvectors.hh:504
ArrayType::size_type SizeType
Definition: defaultblockvectors.hh:502
Iterator< typename ArrayType::ConstIterator, const FieldType > ConstIteratorType
Definition: defaultblockvectors.hh:494
Hybrid::IndexRange< int, blockSize > BlockIndices
Definition: defaultblockvectors.hh:434
IteratorType begin()
Definition: defaultblockvectors.hh:529
DofBlockPtrType blockPtr(const unsigned int i)
Definition: defaultblockvectors.hh:523
Iterator< typename ArrayType::Iterator, FieldType > IteratorType
Definition: defaultblockvectors.hh:493
@ blockSize
Definition: defaultblockvectors.hh:433
const DofBlock ConstDofBlockType
Definition: defaultblockvectors.hh:497
ArrayType * array_
Definition: defaultblockvectors.hh:572
ConstDofBlockPtrType blockPtr(const unsigned int i) const
Definition: defaultblockvectors.hh:524
void resize(SizeType size)
Resize the block vector.
Definition: defaultblockvectors.hh:561
Definition: defaultblockvectors.hh:442
void increment()
go to next dof
Definition: defaultblockvectors.hh:474
EmbeddedIterator end_
Definition: defaultblockvectors.hh:448
EmbeddedIterator it_
Definition: defaultblockvectors.hh:446
FieldType & dereference() const
return dof
Definition: defaultblockvectors.hh:466
int index_
Definition: defaultblockvectors.hh:450
V FieldType
Definition: defaultblockvectors.hh:444
bool equals(const Iterator &other) const
compare
Definition: defaultblockvectors.hh:485
Iterator(const EmbeddedIterator &it, const EmbeddedIterator &end=EmbeddedIterator())
Default constructor.
Definition: defaultblockvectors.hh:453
An implementation of DenseVector which uses a C-array of fixed size as storage.
Definition: dynamicarray.hh:142
BaseType::size_type size_type
Definition: dynamicarray.hh:147
BaseType::value_type value_type
Definition: dynamicarray.hh:149
An implementation of DenseVector which uses a C-array of dynamic size as storage.
Definition: dynamicarray.hh:238
Definition: envelope.hh:11
An implementation of DenseVector to extract a portion, not necessarly contiguos, of a vector.
Definition: subvector.hh:165
Index mapper with static size which simply adds an offset to the index.
Definition: subvector.hh:123