dune-fem  2.4.1-rc
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 
7 #include <dune/common/densevector.hh>
8 #include <dune/common/dynvector.hh>
9 
10 #include <dune/fem/misc/debug.hh> // for DebugCounter
13 
14 #if HAVE_DUNE_ISTL
15 #include <dune/istl/bvector.hh>
16 #endif
17 
18 namespace Dune {
19  namespace Fem {
20  // Forward declaration
21  template< class BlockVector >
23  }
24 
25  template< class BlockVector >
26  struct DenseMatVecTraits< Fem::SimpleBlockVectorBlock< BlockVector > >
27  {
30  typedef typename BlockVector :: FieldType value_type;
31  typedef typename BlockVector :: SizeType size_type;
32  };
33 
34 namespace Fem {
35 
36  // tag for block vectors
37  struct IsBlockVector {};
38 
46  template< class Imp, class Field >
48  : public IsBlockVector
49  {
50  protected:
52 
54 
56  typedef Imp ThisType;
57  public:
59  typedef Field FieldType;
60 
61  /*
62  * ########## operators ##############################
63  */
66  const ThisType& operator= ( const ThisType &other )
67  {
68  if( &asImp() != &other )
69  {
70  assign( other );
71  sequence_ = other.sequence_;
72  }
73  return asImp();
74  }
75 
81  const ThisType &operator+= ( const ThisType &other )
82  {
83  assert( asImp().size() == other.size() );
84  const auto endit = asImp().end();
85  auto oit = other.begin();
86  for( auto it = asImp().begin(); it != endit; ++it, ++oit )
87  *it += *oit;
88 
89  ++sequence_;
90  return asImp();
91  }
92 
98  const ThisType &operator-= ( const ThisType &other )
99  {
100  assert( asImp().size() == other.size() );
101  const auto endit = asImp().end();
102  auto oit = other.begin();
103  for( auto it = asImp().begin(); it != endit; ++it, ++oit )
104  *it -= *oit;
105 
106  ++sequence_;
107  return asImp();
108  }
109 
115  FieldType operator* ( const ThisType &other ) const
116  {
117  assert( asImp().size() == other.size() );
118  FieldType sum( 0 );
119  const auto endit = asImp().end();
120  auto oit = other.asImp().begin();
121  for( auto it = asImp().begin(); it != endit; ++it, ++oit )
122  sum += (*it * *oit);
123 
124  return sum;
125  }
126 
132  const ThisType &operator*= ( const FieldType &scalar )
133  {
134  const auto endit = asImp().end();
135  for( auto it = asImp().begin(); it != endit; ++it )
136  *it *= scalar;
137 
138  ++sequence_;
139  return asImp();
140  }
141 
142  /*
143  * ########## methods ##############################
144  */
145 
153  void axpy ( const FieldType &scalar, const ThisType &other )
154  {
155  assert( asImp().size() == other.size() );
156  const auto endit = asImp().end();
157  auto oit = other.begin();
158  // TODO: revise
159  for( auto it = asImp().begin(); it != endit; ++it, ++oit )
160  {
161  *it += scalar * (*oit);
162  }
163 
164  ++sequence_;
165  }
166 
169  void clear ()
170  {
171  std::fill( asImp().begin(), asImp().end(), FieldType( 0 ) );
172  ++sequence_;
173  }
174 
175  protected:
176  // Copy block vectors.
177  // Note: No '++sequence_' here, sequence_ is only changed in public methods
178  void assign ( const ThisType &other )
179  {
180  assert( asImp().size() == other.size() );
181  std::copy( other.begin(), other.end(), asImp().begin() );
182  }
183 
184  ThisType& asImp() { return static_cast< ThisType& > (*this); }
185  const ThisType& asImp() const { return static_cast< ThisType& > (*this); }
186 
187  mutable CounterType sequence_; // for consistency checks...
188  };
189 
190 
198  template< class Container, int BlockSize >
200  : public BlockVectorInterface< SimpleBlockVector< Container, BlockSize>, typename Container::value_type >
201  {
202  typedef BlockVectorInterface< SimpleBlockVector< Container, BlockSize>, typename Container::value_type > BaseType;
204  typedef Container ArrayType;
205 
207 
208  friend class SimpleBlockVectorBlock< ThisType >;
209  friend class SimpleBlockVectorBlock< const ThisType >;
210 
211  public:
212  typedef ArrayType DofContainerType;
213 
215  typedef typename ArrayType::value_type FieldType;
217  typedef typename ArrayType::iterator IteratorType;
219  typedef typename ArrayType::const_iterator ConstIteratorType;
221  typedef typename ArrayType::size_type SizeType;
222 
224  typedef FieldType value_type;
226  typedef SizeType size_type;
227 
232 
235 
237  enum { blockSize = BlockSize };
238 
239 
246  explicit SimpleBlockVector ( ArrayType& array )
247  : array_( array )
248  {}
249 
250  /*
251  * ########## operators ##############################
252  */
255  const ThisType& operator= ( const ThisType& other )
256  {
257  BaseType::operator=( other );
258  return *this;
259  }
260 
266  ConstDofBlockType operator[] ( const unsigned int i ) const
267  {
268  assert( i < size() );
269  return ConstDofBlockType( *this, i*blockSize );
270  }
271 
277  DofBlockType operator[] ( const unsigned int i )
278  {
279  assert( i < size() );
280  return DofBlockType( *this, i*blockSize );
281  }
282 
288  ConstDofBlockPtrType blockPtr( const unsigned int i ) const
289  {
290  return ConstDofBlockPtrType( this->operator[] ( i ) );
291  }
292 
298  DofBlockPtrType blockPtr( const unsigned int i )
299  {
300  return DofBlockPtrType( this->operator[] ( i ) );
301  }
302 
307  IteratorType begin() { return array().begin(); }
308 
313  ConstIteratorType begin() const { return array().begin(); }
314 
319  IteratorType end() { return array().end(); }
320 
325  ConstIteratorType end() const { return array().end(); }
326 
331  SizeType size () const { return array().size() / blockSize; }
332 
337  SizeType numDofs() const { return array().size(); }
338 
339  FieldType* data() { return array().data(); }
340  const FieldType* data() const { return array().data(); }
341 
342  const ArrayType &array () const { return array_; }
343  ArrayType &array () { return array_; }
344 
345  protected:
346  /*
347  * data fields
348  */
349  ArrayType& array_;
350  };
351 
358  template< class BlockVector >
359  class SimpleBlockVectorBlock : public Dune::DenseVector< SimpleBlockVectorBlock< BlockVector > >
360  {
361  typedef BlockVector BlockVectorType;
362  typedef typename BlockVectorType :: FieldType FieldType;
363  typedef typename BlockVectorType::CounterType CounterType;
364 
365  typedef SimpleBlockVectorBlock< BlockVectorType > ConstBlockType;
367 
368  public:
369  typedef typename BlockVectorType :: SizeType size_type;
370 
372  static const unsigned int blockSize = BlockVector :: blockSize ;
373 
379  SimpleBlockVectorBlock ( const BlockVectorType &blockVector, unsigned int blockBegin )
380  : blockVector_( const_cast< BlockVectorType& > (blockVector) ),
381  blockBegin_( blockBegin )
382  {}
383 
387  : blockVector_( const_cast< BlockVectorType& > (other.blockVector_)),
388  blockBegin_( other.blockBegin_ )
389  {}
390 
391  size_type size () const { return blockSize; }
392  size_type vec_size () const { return blockSize; }
393 
399  ThisType &operator= ( const ConstBlockType &other )
400  {
401  copy( other );
402  return *this;
403  }
404 
410  FieldType& vec_access(unsigned int index)
411  {
412  assert(index < blockSize);
413  return blockVector_.array()[blockBegin_ + index];
414  }
415 
421  const FieldType& vec_access(unsigned int index) const
422  {
423  assert(index < blockSize);
424  return blockVector_.array()[blockBegin_ + index];
425  }
426 
429  int dim() const { return blockSize; }
430 
431  protected:
432  // An empty constructor does not make sense in this case
434 
435  template< class Block >
436  void copy ( const Block &other )
437  {
438  for( unsigned int i=0; i < blockSize; ++i )
439  (*this)[ i ] = other[ i ];
440  }
441 
442  // data fields
443  BlockVectorType &blockVector_;
444  const unsigned int blockBegin_;
445  };
446 
454  template< class Container, unsigned int BlockSize >
456  : public SimpleBlockVector< Container, BlockSize >
457  {
460  typedef Container ArrayType;
461  using BaseType :: array_;
462  using BaseType :: sequence_;
463  public:
464 
465  using BaseType :: array;
466  using BaseType :: blockSize ;
467  typedef typename BaseType :: SizeType SizeType;
468 
475  explicit MutableBlockVector ( SizeType size )
476  : BaseType( *(new Container( size*blockSize ) ) )
477  {}
478 
481  MutableBlockVector ( const ThisType &other )
482  : BaseType( *(new Container( other.array().size() ) ) )
483  {
484  assign( other );
485  }
486 
488  {
489  delete &array_;
490  }
491 
500  void reserve ( const int size )
501  {
502  array().reserve( size*blockSize );
503  }
504 
509  void resize ( SizeType size )
510  {
511  array().resize( size*blockSize );
512  ++sequence_;
513  }
514  };
515 
523  template< class F, unsigned int BlockSize >
524  class MutableBlockVector< MutableArray< F >, BlockSize >
525  : public SimpleBlockVector< StaticArray< F >, BlockSize >
526  {
531 
532  protected:
533  using BaseType :: sequence_;
534 
535  MutableContainer* container_;
536  public:
537  using BaseType :: blockSize ;
538  typedef typename BaseType :: SizeType SizeType;
539 
546  explicit MutableBlockVector ( SizeType size )
547  : BaseType( allocateContainer( size*blockSize ) )
548  {}
549 
552  MutableBlockVector ( const ThisType &other )
553  : BaseType( allocateContainer( other.array().size() ) )
554  {
555  assign( other );
556  }
557 
559  {
560  delete container_;
561  }
562 
571  void reserve ( const int size )
572  {
573  container_->reserve( size*blockSize );
574  }
575 
580  void resize ( SizeType size )
581  {
582  container_->resize( size*blockSize );
583  ++sequence_;
584  }
585 
586  protected:
587  StaticContainer& allocateContainer( const SizeType size )
588  {
589  container_ = new MutableContainer( size );
590  return *container_;
591  }
592  };
593 
601  template< class DofBlock >
603  : public BlockVectorInterface< ISTLBlockVector< DofBlock >, typename DofBlock :: value_type >
604  {
605  ISTLBlockVector ( const ISTLBlockVector& );
607 #if HAVE_DUNE_ISTL
608  typedef BlockVector< DofBlock > ArrayType;
609 #else
610  // fallback in case dune-istl is not present
611  typedef DynamicVector< DofBlock > ArrayType;
612 #endif
613  typedef BlockVectorInterface< ISTLBlockVector< DofBlock >, typename DofBlock :: value_type > BaseType;
614 
615 
616  using BaseType :: sequence_;
617  public:
618  typedef ArrayType DofContainerType;
619 
620  enum { blockSize = DofBlock :: dimension };
621 
622  typedef typename DofBlock :: value_type FieldType;
623  protected:
624  template <class EmbeddedIterator, class V>
625  class Iterator
626  : public ForwardIteratorFacade< Iterator< EmbeddedIterator,V >, V >
627  {
628  public:
629  typedef V FieldType;
630  protected:
631  mutable EmbeddedIterator it_;
632 #ifndef NDEBUG
633  const EmbeddedIterator end_;
634 #endif
635  int index_;
636  public:
638  Iterator( const EmbeddedIterator& it
639 #ifndef NDEBUG
640  , const EmbeddedIterator& end = EmbeddedIterator()
641 #endif
642  )
643  : it_( it ),
644 #ifndef NDEBUG
645  end_( end ),
646 #endif
647  index_(0)
648  {}
649 
651  FieldType& dereference () const
652  {
653  assert( it_ != end_ );
654  assert( index_ < blockSize );
655  return (*it_)[ index_ ];
656  }
657 
659  void increment ()
660  {
661  ++index_;
662  if( index_ >= blockSize )
663  {
664  index_ = 0;
665  ++it_;
666  }
667  }
668 
670  bool equals ( const Iterator &other ) const
671  {
672  return (it_ == other.it_) && (index_ == other.index_);
673  }
674 
675  }; // end DofIteratorBlockVectorDiscreteFunction
676 
677  public:
680 
681  typedef DofBlock DofBlockType;
682  typedef const DofBlock ConstDofBlockType;
683 
684  typedef DofBlockType* DofBlockPtrType;
685  typedef ConstDofBlockType* ConstDofBlockPtrType;
686 
687  typedef typename ArrayType::size_type SizeType;
690 
697  explicit ISTLBlockVector ( ArrayType& array )
698  : array_( &array )
699  {}
700 
701  ISTLBlockVector () : array_( 0 )
702  {}
703 
704  /*
705  * ########## operators ##############################
706  */
709  const ThisType& operator= ( const ThisType& other )
710  {
711  if( this != &other )
712  {
713  array() = other.array();
714  }
715  return *this;
716  }
717 
718  DofBlockPtrType blockPtr(const unsigned int i ) { return &array()[ i ]; }
719  ConstDofBlockPtrType blockPtr(const unsigned int i ) const { return &array()[ i ]; }
720 
721  DofBlockType& operator[] (const unsigned int i ) { return array()[ i ]; }
722  ConstDofBlockType& operator[] (const unsigned int i ) const { return array()[ i ]; }
723 
724  IteratorType begin() { return IteratorType( array().begin()
725 #ifndef NDEBUG
726  , array().end()
727 #endif
728  ); }
729  ConstIteratorType begin() const
730  {
731  return ConstIteratorType( array().begin()
732 #ifndef NDEBUG
733  , array().end()
734 #endif
735  ); }
736 
737  IteratorType end() { return IteratorType( array().end() ); }
738  ConstIteratorType end() const { return ConstIteratorType( array().end() ); }
739 
740  SizeType size() const { return array().size(); }
741 
750  void reserve ( const int size )
751  {
752  array().reserve( size );
753  }
754 
759  void resize ( SizeType size )
760  {
761  array().resize( size );
762  ++sequence_;
763  }
764 
765  ArrayType& array() { assert( array_ ); return *array_; }
766  const ArrayType& array() const { assert( array_ ); return *array_; }
767 
768  protected:
769  // ISTL BlockVector
770  ArrayType* array_;
771  };
772 
773 } // namespace Fem
774 } // namespace Dune
775 
776 #endif // DUNE_FEM_REFERENCEBLOCKVECTOR_HH
BlockVector::SizeType size_type
Definition: defaultblockvectors.hh:31
BaseType::SizeType SizeType
Definition: defaultblockvectors.hh:538
ArrayType::size_type SizeType
Definition: defaultblockvectors.hh:687
IteratorType end()
Iterator pointing to the last dof.
Definition: defaultblockvectors.hh:319
ConstIteratorType begin() const
Const-iterator pointing to the first dof.
Definition: defaultblockvectors.hh:313
void copy(const Block &other)
Definition: defaultblockvectors.hh:436
Definition: envelope.hh:10
ConstDofBlockPtrType blockPtr(const unsigned int i) const
Accessor for a constant block.
Definition: defaultblockvectors.hh:288
ArrayType DofContainerType
Definition: defaultblockvectors.hh:212
ArrayType::value_type value_type
Typedef to make this class STL-compatible.
Definition: defaultblockvectors.hh:689
const DofBlock ConstDofBlockType
Definition: defaultblockvectors.hh:682
size_type size() const
Definition: defaultblockvectors.hh:391
ConstIteratorType begin() const
Definition: defaultblockvectors.hh:729
Fem::SimpleBlockVectorBlock< BlockVector > container_type
Definition: defaultblockvectors.hh:29
DofBlockType * DofBlockPtrType
Definition: defaultblockvectors.hh:684
void axpy(const FieldType &scalar, const ThisType &other)
Add a scalar multiple of another block vector to this block vector.
Definition: defaultblockvectors.hh:153
void resize(size_t nsize)
Definition: arrays.hh:491
ArrayType::const_iterator ConstIteratorType
Constant iterator to iterate over the dofs.
Definition: defaultblockvectors.hh:219
const ArrayType & array() const
Definition: defaultblockvectors.hh:766
MutableBlockVector(const ThisType &other)
Copy constructor.
Definition: defaultblockvectors.hh:481
const FieldType & vec_access(unsigned int index) const
Obtain a dof inside this block.
Definition: defaultblockvectors.hh:421
SimpleBlockVectorBlock< ThisType > ConstDofBlockType
Type of one constant block.
Definition: defaultblockvectors.hh:231
Imp ThisType
Type of derived class (implementation)
Definition: defaultblockvectors.hh:56
const ArrayType & array() const
Definition: defaultblockvectors.hh:342
SimpleBlockVector(ArrayType &array)
Constructor; use this to create a block vector with &#39;size&#39; blocks.
Definition: defaultblockvectors.hh:246
ConstIteratorType end() const
Const-iterator pointing to the last dof.
Definition: defaultblockvectors.hh:325
static constexpr T sum(T a)
Definition: utility.hh:33
DebugCounter< size_t > CounterType
Definition: defaultblockvectors.hh:51
const EmbeddedIterator end_
Definition: defaultblockvectors.hh:633
Definition: arrays.hh:36
IteratorType begin()
Iterator pointing to the first dof.
Definition: defaultblockvectors.hh:307
Definition: defaultblockvectors.hh:37
SizeType size() const
Returns the number of blocks.
Definition: defaultblockvectors.hh:331
StaticContainer & allocateContainer(const SizeType size)
Definition: defaultblockvectors.hh:587
This is the implementation of a block of SimpleBlockVector.
Definition: defaultblockvectors.hh:22
SizeType numDofs() const
Returns the number of dofs in the block vector.
Definition: defaultblockvectors.hh:337
int dim() const
Returns the size of the block.
Definition: defaultblockvectors.hh:429
Definition: defaultblockvectors.hh:625
SizeType size() const
Definition: defaultblockvectors.hh:740
SimpleBlockVectorBlock(const SimpleBlockVectorBlock< BlockVectorType > &other)
Copy constructor.
Definition: defaultblockvectors.hh:386
ArrayType * array_
Definition: defaultblockvectors.hh:770
Fem::SimpleBlockVectorBlock< BlockVector > derived_type
Definition: defaultblockvectors.hh:28
Definition: defaultblockvectors.hh:455
~MutableBlockVector()
Definition: defaultblockvectors.hh:487
void clear()
Clear this block vector, i.e. set each dof to 0.
Definition: defaultblockvectors.hh:169
BlockVectorType::SizeType size_type
Definition: defaultblockvectors.hh:369
Definition: coordinate.hh:4
void reserve(const int size)
Reserve memory.
Definition: defaultblockvectors.hh:500
Fem::Envelope< DofBlockType > DofBlockPtrType
Definition: defaultblockvectors.hh:233
FieldType value_type
Typedef to make this class STL-compatible.
Definition: defaultblockvectors.hh:224
ArrayType::iterator IteratorType
Iterator to iterate over the dofs.
Definition: defaultblockvectors.hh:217
ISTLBlockVector(ArrayType &array)
Constructor; use this to create a block vector with &#39;size&#39; blocks.
Definition: defaultblockvectors.hh:697
Static Array Wrapper for simple C Vectors like double* and int*. This also works as base class for th...
Definition: arrays.hh:141
ConstIteratorType end() const
Definition: defaultblockvectors.hh:738
Field FieldType
Type of the field the dofs lie in.
Definition: defaultblockvectors.hh:59
bool equals(const Iterator &other) const
compare
Definition: defaultblockvectors.hh:670
BlockVectorType & blockVector_
Definition: defaultblockvectors.hh:443
Double operator*(const Double &a, const Double &b)
Definition: double.hh:495
IteratorType begin()
Definition: defaultblockvectors.hh:724
void reserve(size_t mSize)
Definition: arrays.hh:517
void reserve(const int size)
Reserve memory.
Definition: defaultblockvectors.hh:571
Iterator(const EmbeddedIterator &it, const EmbeddedIterator &end=EmbeddedIterator())
Default constructor.
Definition: defaultblockvectors.hh:638
int index_
Definition: defaultblockvectors.hh:635
const unsigned int blockBegin_
Definition: defaultblockvectors.hh:444
This is the reference implementation of a block vector as it is expected as the second template param...
Definition: defaultblockvectors.hh:199
Fem::Envelope< ConstDofBlockType > ConstDofBlockPtrType
Definition: defaultblockvectors.hh:234
void increment()
go to next dof
Definition: defaultblockvectors.hh:659
EmbeddedIterator it_
Definition: defaultblockvectors.hh:631
ConstDofBlockPtrType blockPtr(const unsigned int i) const
Definition: defaultblockvectors.hh:719
void assign(const ThisType &other)
Definition: defaultblockvectors.hh:178
ArrayType::value_type FieldType
Type of the field the dofs lie in.
Definition: defaultblockvectors.hh:215
FieldType * data()
Definition: defaultblockvectors.hh:339
DofBlock DofBlockType
Definition: defaultblockvectors.hh:681
ThisType & asImp()
Definition: defaultblockvectors.hh:184
BaseType::SizeType SizeType
Definition: defaultblockvectors.hh:467
ConstDofBlockType * ConstDofBlockPtrType
Definition: defaultblockvectors.hh:685
ArrayType & array()
Definition: defaultblockvectors.hh:343
MutableBlockVector(SizeType size)
Constructor; use this to create a block vector with &#39;size&#39; blocks.
Definition: defaultblockvectors.hh:546
ISTLBlockVector()
Definition: defaultblockvectors.hh:701
MutableBlockVector(const ThisType &other)
Copy constructor.
Definition: defaultblockvectors.hh:552
size_type vec_size() const
Definition: defaultblockvectors.hh:392
ArrayType & array()
Definition: defaultblockvectors.hh:765
void resize(SizeType size)
Resize the block vector.
Definition: defaultblockvectors.hh:509
const FieldType * data() const
Definition: defaultblockvectors.hh:340
SizeType size_type
Typedef to make this class STL-compatible.
Definition: defaultblockvectors.hh:226
Definition: defaultblockvectors.hh:47
V FieldType
Definition: defaultblockvectors.hh:629
void reserve(const int size)
Reserve memory.
Definition: defaultblockvectors.hh:750
const ThisType & asImp() const
Definition: defaultblockvectors.hh:185
IteratorType end()
Definition: defaultblockvectors.hh:737
Iterator< typename ArrayType::ConstIterator, const FieldType > ConstIteratorType
Definition: defaultblockvectors.hh:679
ArrayType & array_
Definition: defaultblockvectors.hh:349
SimpleBlockVectorBlock< ThisType > DofBlockType
Type of one (mutable) block.
Definition: defaultblockvectors.hh:229
CounterType sequence_
Definition: defaultblockvectors.hh:187
~MutableBlockVector()
Definition: defaultblockvectors.hh:558
void resize(SizeType size)
Resize the block vector.
Definition: defaultblockvectors.hh:580
DofBlockPtrType blockPtr(const unsigned int i)
Definition: defaultblockvectors.hh:718
MutableBlockVector(SizeType size)
Constructor; use this to create a block vector with &#39;size&#39; blocks.
Definition: defaultblockvectors.hh:475
DofBlock::value_type FieldType
Definition: defaultblockvectors.hh:622
DofBlockPtrType blockPtr(const unsigned int i)
Accessor for a block.
Definition: defaultblockvectors.hh:298
void resize(SizeType size)
Resize the block vector.
Definition: defaultblockvectors.hh:759
BlockVector::FieldType value_type
Definition: defaultblockvectors.hh:30
BlockVectorInterface()
Definition: defaultblockvectors.hh:53
Iterator< typename ArrayType::Iterator, FieldType > IteratorType
Definition: defaultblockvectors.hh:678
SimpleBlockVectorBlock(const BlockVectorType &blockVector, unsigned int blockBegin)
Standard constructor for SimpleBlockVectorBlocks.
Definition: defaultblockvectors.hh:379
ArrayType DofContainerType
Definition: defaultblockvectors.hh:618
FieldType & vec_access(unsigned int index)
Obtain a dof inside this block.
Definition: defaultblockvectors.hh:410
ArrayType::size_type SizeType
Used for indexing the blocks, for example.
Definition: defaultblockvectors.hh:221
A vector using a DynamicArray as storage.
Definition: vector.hh:542
MutableContainer * container_
Definition: defaultblockvectors.hh:535
FieldType & dereference() const
return dof
Definition: defaultblockvectors.hh:651
Definition: defaultblockvectors.hh:602