1#ifndef DUNE_FEM_SIMPLEBLOCKVECTOR_HH
2#define DUNE_FEM_SIMPLEBLOCKVECTOR_HH
12#include <dune/fem/common/hybrid.hh>
13#include <dune/fem/misc/debug.hh>
14#include <dune/fem/storage/dynamicarray.hh>
15#include <dune/fem/storage/envelope.hh>
16#include <dune/fem/storage/subvector.hh>
27 class IsBlockVector {};
38 template<
class Imp,
class Field >
39 class BlockVectorInterface
40 :
public IsBlockVector
43 typedef DebugCounter<size_t> CounterType;
45 BlockVectorInterface () {}
51 typedef Field FieldType;
53 typedef Field DofType;
56 const ThisType& operator= (
const ThisType &other )
58 if( &asImp() != &other )
61 sequence_ = other.sequence_;
67 const ThisType &operator+= (
const ThisType &other )
69 assert( asImp().
size() == other.size() );
70 const auto endit = asImp().end();
71 auto oit = other.begin();
72 for(
auto it = asImp().begin(); it != endit; ++it, ++oit )
80 const ThisType &operator-= (
const ThisType &other )
82 assert( asImp().
size() == other.size() );
83 const auto endit = asImp().end();
84 auto oit = other.begin();
85 for(
auto it = asImp().begin(); it != endit; ++it, ++oit )
93 FieldType operator* (
const ThisType &other )
const
95 assert( asImp().
size() == other.size() );
97 const auto endit = asImp().end();
98 auto oit = other.asImp().begin();
99 for(
auto it = asImp().begin(); it != endit; ++it, ++oit )
110 const ThisType &operator*= (
const FieldType &scalar )
112 const auto endit = asImp().end();
113 for(
auto it = asImp().begin(); it != endit; ++it )
127 void axpy (
const FieldType &scalar,
const ThisType &other )
129 assert( asImp().
size() == other.size() );
130 const auto endit = asImp().end();
131 auto oit = other.begin();
132 for(
auto it = asImp().begin(); it != endit; ++it, ++oit )
133 *it += scalar * (*oit);
141 std::fill( asImp().begin(), asImp().end(), FieldType( 0 ) );
146 std::size_t usedMemorySize()
const
148 return asImp().numDofs() *
sizeof( FieldType ) ;
152 void copyContent(
const size_t newIndex,
const size_t oldIndex )
154 asImp()[ newIndex ] = asImp()[ oldIndex ];
158 void memMoveBackward(
const size_t length,
const size_t oldStartIdx,
const size_t newStartIdx)
160 assert( newStartIdx >= oldStartIdx );
162 size_t newIdx = newStartIdx + length - 1;
163 assert( newIdx < asImp().
size() );
165 for(
size_t oldIdx = oldStartIdx + length-1; oldIdx >= oldStartIdx; --oldIdx, --newIdx )
167 assert( oldIdx < asImp().
size() );
169 copyContent( newIdx, oldIdx );
174 void memMoveForward(
const size_t length,
const size_t oldStartIdx,
const size_t newStartIdx)
176 assert( newStartIdx <= oldStartIdx );
177 const size_t upperBound = oldStartIdx + length;
179 size_t newIdx = newStartIdx;
180 for(
size_t oldIdx = oldStartIdx; oldIdx<upperBound; ++oldIdx, ++newIdx )
183 copyContent( newIdx, oldIdx );
188 void setMemoryFactor(
const double memFactor ) {}
193 void assign (
const ThisType &other )
195 assert( asImp().
size() == other.size() );
196 std::copy( other.begin(), other.end(), asImp().begin() );
199 ThisType& asImp() {
return static_cast< ThisType&
> (*this); }
200 const ThisType& asImp()
const {
return static_cast< const ThisType&
> (*this); }
202 mutable CounterType sequence_;
214 template<
class Container,
int BlockSize >
216 :
public BlockVectorInterface< SimpleBlockVector< Container, BlockSize>, typename Container::value_type >
218 typedef BlockVectorInterface< SimpleBlockVector< Container, BlockSize>,
typename Container::value_type > BaseType;
220 typedef Container ArrayType;
225 typedef ArrayType DofContainerType;
246 typedef Fem::Envelope< DofBlockType > DofBlockPtrType;
247 typedef Fem::Envelope< ConstDofBlockType > ConstDofBlockPtrType;
250 enum { blockSize = BlockSize };
252 typedef Hybrid::IndexRange< int, blockSize > BlockIndices;
255 template <
class Array>
256 struct ContainerAccess
258 static FieldType* data( Array& array ) {
return array.data(); }
259 static const FieldType* data(
const Array& array ) {
return array.data(); }
263 struct ContainerAccess<
Dune::DynamicVector< K > >
266 static FieldType* data( Array& array ) {
return array.container().data(); }
267 static const FieldType* data(
const Array& array ) {
return array.container().data(); }
279 BaseType::operator=( other );
286 assert( i <
size() );
293 assert( i <
size() );
298 ConstDofBlockPtrType
blockPtr(
const unsigned int i )
const
300 return ConstDofBlockPtrType( this->
operator[] ( i ) );
306 return DofBlockPtrType( this->
operator[] ( i ) );
345 FieldType* data() {
return ContainerAccess< ArrayType >::data( array() ); }
346 const FieldType* data()
const {
return ContainerAccess< ArrayType >::data( array() ); }
348 const ArrayType &array ()
const {
return array_; }
349 ArrayType &array () {
return array_; }
364 template<
class Container,
unsigned int BlockSize >
365 class MutableBlockVector
366 :
public SimpleBlockVector< Container, BlockSize >
368 typedef MutableBlockVector< Container, BlockSize > ThisType;
369 typedef SimpleBlockVector < Container, BlockSize > BaseType;
371 typedef Container ArrayType;
372 using BaseType :: array_;
373 using BaseType :: sequence_;
376 using BaseType :: array;
377 using BaseType :: blockSize ;
381 explicit MutableBlockVector ( SizeType
size )
382 : BaseType( *(new Container(
size*blockSize ) ) )
386 MutableBlockVector (
const ThisType &other )
387 : BaseType( *(new Container( other.array().
size() ) ) )
392 ~MutableBlockVector()
398 void setMemoryFactor(
const double memFactor )
400 doSetMemoryFactor( array_, memFactor );
411 void reserve (
const int size )
413 array().reserve(
size*blockSize );
417 void resize ( SizeType
size )
419 array().resize(
size*blockSize );
424 template <
class T,
class Allocator>
427 array_.setMemoryFactor( memFactor );
430 template <
class Array>
431 void doSetMemoryFactor( Array& ,
const double memFactor ) {}
444 template<
class Field,
unsigned int BlockSize >
445 class MutableBlockVector< DynamicArray< Field >, BlockSize >
446 :
public SimpleBlockVector< StaticArray< Field >, BlockSize >
448 typedef StaticArray< Field > StaticContainer ;
449 typedef DynamicArray< Field > MutableContainer ;
450 typedef SimpleBlockVector< StaticContainer, BlockSize > BaseType;
451 typedef MutableBlockVector< MutableContainer, BlockSize > ThisType;
454 using BaseType :: array_;
455 using BaseType :: sequence_;
457 std::unique_ptr< MutableContainer > container_;
459 using BaseType :: blockSize ;
463 explicit MutableBlockVector ( SizeType
size )
464 : BaseType( allocateContainer(
size*blockSize ) ),
465 container_( static_cast< MutableContainer* > (&array_) )
469 MutableBlockVector (
const ThisType &other )
470 : BaseType( allocateContainer( other.array().
size() ) ),
471 container_( static_cast< MutableContainer* > (&array_) )
484 void reserve (
const int size )
486 assert( container_ );
487 container_->reserve(
size*blockSize );
491 void resize ( SizeType
size )
493 assert( container_ );
494 container_->resize(
size*blockSize );
499 StaticContainer& allocateContainer(
const SizeType
size )
501 MutableContainer* container =
new MutableContainer(
size );
512 template<
class DofBlock >
513 class ISTLBlockVector
514 :
public BlockVectorInterface< ISTLBlockVector< DofBlock >, typename DofBlock :: value_type >
516 typedef ISTLBlockVector< DofBlock> ThisType;
518 typedef BlockVector< DofBlock > ArrayType;
523 typedef BlockVectorInterface< ISTLBlockVector< DofBlock >,
typename DofBlock :: value_type > BaseType;
526 using BaseType :: sequence_;
529 ISTLBlockVector (
const ThisType& ) =
default;
531 typedef ArrayType DofContainerType;
533 enum { blockSize = DofBlock :: dimension };
534 typedef Hybrid::IndexRange< int, blockSize > BlockIndices;
536 typedef typename DofBlock :: value_type FieldType;
539 template <
class EmbeddedIterator,
class V>
541 :
public ForwardIteratorFacade< Iterator< EmbeddedIterator,V >, V >
546 mutable EmbeddedIterator it_;
548 EmbeddedIterator end_;
553 Iterator(
const EmbeddedIterator& it
555 ,
const EmbeddedIterator& end = EmbeddedIterator()
566 Iterator(
const EmbeddedIterator& it,
const int index
568 ,
const EmbeddedIterator& end = EmbeddedIterator()
579 FieldType& dereference ()
const
581 assert( it_ != end_ );
582 assert( index_ < blockSize );
583 return (*it_)[ index_ ];
590 if( index_ >= blockSize )
598 bool equals (
const Iterator &other )
const
600 return (it_ == other.it_) && (index_ == other.index_);
606 typedef Iterator< typename ArrayType::Iterator, FieldType > IteratorType;
607 typedef Iterator< typename ArrayType::ConstIterator, const FieldType > ConstIteratorType;
609 typedef DofBlock DofBlockType;
610 typedef const DofBlock ConstDofBlockType;
612 typedef DofBlockType* DofBlockPtrType;
613 typedef ConstDofBlockType* ConstDofBlockPtrType;
615 typedef typename ArrayType::size_type SizeType;
617 typedef typename ArrayType::value_type value_type;
620 explicit ISTLBlockVector ( ArrayType* array )
624 ISTLBlockVector () =
default;
627 const ThisType& operator= (
const ThisType& other )
631 array() = other.array();
636 DofBlockPtrType blockPtr(
const unsigned int i ) {
return &array()[ i ]; }
637 ConstDofBlockPtrType blockPtr(
const unsigned int i )
const {
return &array()[ i ]; }
639 DofBlockType& operator[] (
const unsigned int i ) {
return array()[ i ]; }
640 ConstDofBlockType& operator[] (
const unsigned int i )
const {
return array()[ i ]; }
642 IteratorType begin() {
return IteratorType( array().begin()
647 ConstIteratorType begin()
const
649 return ConstIteratorType( array().begin()
655 IteratorType end() {
return IteratorType( array().end() ); }
656 ConstIteratorType end()
const {
return ConstIteratorType( array().end() ); }
658 IteratorType beforeEnd()
660 DUNE_THROW(NotImplemented,
"ISTLBlockVector::beforeEnd not implemented yet");
661 return array().end();
664 ConstIteratorType beforeEnd()
const
666 DUNE_THROW(NotImplemented,
"ISTLBlockVector::beforeEnd not implemented yet");
667 return array().end();
670 IteratorType beforeBegin()
672 DUNE_THROW(NotImplemented,
"ISTLBlockVector::beforeBegin not implemented yet");
673 return array().end();
676 ConstIteratorType beforeBegin()
const
678 DUNE_THROW(NotImplemented,
"ISTLBlockVector::beforeBegin not implemented yet");
679 return array().end();
683 IteratorType find(
const SizeType dof )
685 const SizeType block = dof / blockSize;
686 const SizeType index = dof % blockSize;
687 return IteratorType( array().find( block ), index
695 ConstIteratorType find(
const SizeType dof )
const
697 const SizeType block = dof / blockSize;
698 const SizeType index = dof % blockSize;
699 return ConstIteratorType( array().find( block ), index
706 SizeType
size()
const {
return array().size(); }
709 SizeType numDofs()
const {
return array().size() * DofBlock::dimension; }
719 void reserve (
const int size )
721 array().reserve(
size );
725 void resize ( SizeType
size )
727 array().resize(
size );
731 ArrayType& array() { assert( array_ );
return *array_; }
732 const ArrayType& array()
const { assert( array_ );
return *array_; }
This file implements a vector space as a tensor product of a given vector space. The number of compon...
Construct a vector with a dynamic size.
Definition: dynvector.hh:59
An implementation of DenseVector which uses a C-array of dynamic size as storage.
Definition: dynamicarray.hh:244
This is the reference implementation of a block vector as it is expected as the second template param...
Definition: defaultblockvectors.hh:217
ArrayType::size_type SizeType
Used for indexing the blocks, for example.
Definition: defaultblockvectors.hh:234
ConstIteratorType find(const SizeType dof) const
Iterator pointing to a given dof (non blocked numbering)
Definition: defaultblockvectors.hh:337
SubVector< DofContainerType, StaticOffsetSubMapper< BlockSize > > DofBlockType
Type of one (mutable) block.
Definition: defaultblockvectors.hh:242
SizeType numDofs() const
Number of dofs in the block vector.
Definition: defaultblockvectors.hh:343
SizeType size() const
Number of blocks.
Definition: defaultblockvectors.hh:340
ConstIteratorType beforeBegin() const
Iterator pointing to before the first dof.
Definition: defaultblockvectors.hh:331
ArrayType::const_iterator ConstIteratorType
Constant iterator to iterate over the dofs.
Definition: defaultblockvectors.hh:232
ConstIteratorType end() const
Const-iterator pointing to the last dof.
Definition: defaultblockvectors.hh:319
ArrayType::value_type FieldType
Type of the field the dofs lie in.
Definition: defaultblockvectors.hh:228
ConstDofBlockPtrType blockPtr(const unsigned int i) const
Constant access for the i-th block.
Definition: defaultblockvectors.hh:298
ConstIteratorType begin() const
Const-iterator pointing to the first dof.
Definition: defaultblockvectors.hh:313
const ThisType & operator=(const ThisType &other)
Copy assignment operator.
Definition: defaultblockvectors.hh:277
ArrayType::iterator IteratorType
Iterator to iterate over the dofs.
Definition: defaultblockvectors.hh:230
IteratorType end()
Iterator pointing to the last dof.
Definition: defaultblockvectors.hh:316
IteratorType beforeBegin()
Iterator pointing to before the first dof.
Definition: defaultblockvectors.hh:328
SimpleBlockVector(ArrayType &array)
Constructor.
Definition: defaultblockvectors.hh:272
DofBlockPtrType blockPtr(const unsigned int i)
Access the i-th block.
Definition: defaultblockvectors.hh:304
SizeType size_type
Typedef to make this class STL-compatible.
Definition: defaultblockvectors.hh:239
IteratorType beforeEnd()
Iterator pointing to last dof.
Definition: defaultblockvectors.hh:322
FieldType value_type
Typedef to make this class STL-compatible.
Definition: defaultblockvectors.hh:237
DofBlockType ConstDofBlockType
Type of one constant block.
Definition: defaultblockvectors.hh:244
IteratorType find(const SizeType dof)
Iterator pointing to a given dof (non blocked numbering)
Definition: defaultblockvectors.hh:334
IteratorType begin()
Iterator pointing to the first dof.
Definition: defaultblockvectors.hh:310
ConstDofBlockType operator[](const unsigned int i) const
Constant access the i-th block.
Definition: defaultblockvectors.hh:284
ConstIteratorType beforeEnd() const
Iterator pointing to last dof.
Definition: defaultblockvectors.hh:325
Index mapper with static size which simply adds an offset to the index.
Definition: subvector.hh:121
An implementation of DenseVector to extract a portion, not necessarly contiguos, of a vector.
Definition: subvector.hh:161
Implements the dense vector interface, with an exchangeable storage class.
A few common exception classes.
This file implements a dense vector with a dynamic size.
#define DUNE_THROW(E, m)
Definition: exceptions.hh:218
constexpr auto equals(T1 &&t1, T2 &&t2)
Equality comparison.
Definition: hybridutilities.hh:587
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