DUNE-FEM (unstable)

defaultblockvectors.hh
1#ifndef DUNE_FEM_SIMPLEBLOCKVECTOR_HH
2#define DUNE_FEM_SIMPLEBLOCKVECTOR_HH
3
4#include <algorithm>
5#include <cassert>
6#include <memory>
7
11
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>
17
18#if HAVE_DUNE_ISTL
19#include <dune/istl/bvector.hh>
20#endif
21
22namespace Dune {
23
24 namespace Fem {
25
26 // tag for block vectors
27 class IsBlockVector {};
28
29
30
38 template< class Imp, class Field >
39 class BlockVectorInterface
40 : public IsBlockVector
41 {
42 protected:
43 typedef DebugCounter<size_t> CounterType;
44
45 BlockVectorInterface () {}
46
48 typedef Imp ThisType;
49 public:
51 typedef Field FieldType;
53 typedef Field DofType;
54
56 const ThisType& operator= ( const ThisType &other )
57 {
58 if( &asImp() != &other )
59 {
60 assign( other );
61 sequence_ = other.sequence_;
62 }
63 return asImp();
64 }
65
67 const ThisType &operator+= ( const ThisType &other )
68 {
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 )
73 *it += *oit;
74
75 ++sequence_;
76 return asImp();
77 }
78
80 const ThisType &operator-= ( const ThisType &other )
81 {
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 )
86 *it -= *oit;
87
88 ++sequence_;
89 return asImp();
90 }
91
93 FieldType operator* ( const ThisType &other ) const
94 {
95 assert( asImp().size() == other.size() );
96 FieldType sum( 0 );
97 const auto endit = asImp().end();
98 auto oit = other.asImp().begin();
99 for( auto it = asImp().begin(); it != endit; ++it, ++oit )
100 sum += (*it * *oit);
101
102 return sum;
103 }
104
110 const ThisType &operator*= ( const FieldType &scalar )
111 {
112 const auto endit = asImp().end();
113 for( auto it = asImp().begin(); it != endit; ++it )
114 *it *= scalar;
115
116 ++sequence_;
117 return asImp();
118 }
119
127 void axpy ( const FieldType &scalar, const ThisType &other )
128 {
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);
134
135 ++sequence_;
136 }
137
139 void clear ()
140 {
141 std::fill( asImp().begin(), asImp().end(), FieldType( 0 ) );
142 ++sequence_;
143 }
144
146 std::size_t usedMemorySize() const
147 {
148 return asImp().numDofs() * sizeof( FieldType ) ;
149 }
150
152 void copyContent( const size_t newIndex, const size_t oldIndex )
153 {
154 asImp()[ newIndex ] = asImp()[ oldIndex ];
155 }
156
158 void memMoveBackward(const size_t length, const size_t oldStartIdx, const size_t newStartIdx)
159 {
160 assert( newStartIdx >= oldStartIdx );
161 // get new end of block which is offSet + (length of block - 1)
162 size_t newIdx = newStartIdx + length - 1;
163 assert( newIdx < asImp().size() );
164 // copy all entries backwards
165 for(size_t oldIdx = oldStartIdx + length-1; oldIdx >= oldStartIdx; --oldIdx, --newIdx )
166 {
167 assert( oldIdx < asImp().size() );
168 // copy to new location
169 copyContent( newIdx, oldIdx );
170 }
171 }
172
174 void memMoveForward(const size_t length, const size_t oldStartIdx, const size_t newStartIdx)
175 {
176 assert( newStartIdx <= oldStartIdx );
177 const size_t upperBound = oldStartIdx + length;
178 // get new off set that should be smaller then old one
179 size_t newIdx = newStartIdx;
180 for(size_t oldIdx = oldStartIdx; oldIdx<upperBound; ++oldIdx, ++newIdx )
181 {
182 // copy to new location
183 copyContent( newIdx, oldIdx );
184 }
185 }
186
188 void setMemoryFactor( const double memFactor ) {}
189
190 protected:
191 // Copy block vectors.
192 // Note: No '++sequence_' here, sequence_ is only changed in public methods
193 void assign ( const ThisType &other )
194 {
195 assert( asImp().size() == other.size() );
196 std::copy( other.begin(), other.end(), asImp().begin() );
197 }
198
199 ThisType& asImp() { return static_cast< ThisType& > (*this); }
200 const ThisType& asImp() const { return static_cast< const ThisType& > (*this); }
201
202 mutable CounterType sequence_; // for consistency checks...
203 };
204
205
206
214 template< class Container, int BlockSize >
216 : public BlockVectorInterface< SimpleBlockVector< Container, BlockSize>, typename Container::value_type >
217 {
218 typedef BlockVectorInterface< SimpleBlockVector< Container, BlockSize>, typename Container::value_type > BaseType;
220 typedef Container ArrayType;
221
223
224 public:
225 typedef ArrayType DofContainerType;
226
228 typedef typename ArrayType::value_type FieldType;
230 typedef typename ArrayType::iterator IteratorType;
232 typedef typename ArrayType::const_iterator ConstIteratorType;
234 typedef typename ArrayType::size_type SizeType;
235
237 typedef FieldType value_type;
240
245
246 typedef Fem::Envelope< DofBlockType > DofBlockPtrType;
247 typedef Fem::Envelope< ConstDofBlockType > ConstDofBlockPtrType;
248
250 enum { blockSize = BlockSize };
251
252 typedef Hybrid::IndexRange< int, blockSize > BlockIndices;
253
254 protected:
255 template <class Array>
256 struct ContainerAccess
257 {
258 static FieldType* data( Array& array ) { return array.data(); }
259 static const FieldType* data( const Array& array ) { return array.data(); }
260 };
261
262 template <class K>
263 struct ContainerAccess< Dune::DynamicVector< K > >
264 {
265 typedef Dune::DynamicVector< K > Array;
266 static FieldType* data( Array& array ) { return array.container().data(); }
267 static const FieldType* data( const Array& array ) { return array.container().data(); }
268 };
269
270 public:
272 explicit SimpleBlockVector ( ArrayType& array )
273 : array_( array )
274 {}
275
277 const ThisType& operator= ( const ThisType& other )
278 {
279 BaseType::operator=( other );
280 return *this;
281 }
282
284 ConstDofBlockType operator[] ( const unsigned int i ) const
285 {
286 assert( i < size() );
287 return ConstDofBlockType( array_, StaticOffsetSubMapper< blockSize >( i*blockSize ) );
288 }
289
291 DofBlockType operator[] ( const unsigned int i )
292 {
293 assert( i < size() );
294 return DofBlockType( array_, StaticOffsetSubMapper< blockSize >( i*blockSize ) );
295 }
296
298 ConstDofBlockPtrType blockPtr( const unsigned int i ) const
299 {
300 return ConstDofBlockPtrType( this->operator[] ( i ) );
301 }
302
304 DofBlockPtrType blockPtr( const unsigned int i )
305 {
306 return DofBlockPtrType( this->operator[] ( i ) );
307 }
308
310 IteratorType begin() { return array().begin(); }
311
313 ConstIteratorType begin() const { return array().begin(); }
314
316 IteratorType end() { return array().end(); }
317
319 ConstIteratorType end() const { return array().end(); }
320
322 IteratorType beforeEnd() { return array().beforeEnd(); }
323
325 ConstIteratorType beforeEnd() const { return array().beforeEnd(); }
326
328 IteratorType beforeBegin() { return array().beforeBegin(); }
329
331 ConstIteratorType beforeBegin() const { return array().beforeBegin(); }
332
334 IteratorType find( const SizeType dof ) { return array().find( dof ); }
335
337 ConstIteratorType find( const SizeType dof ) const { return array().find( dof ); }
338
340 SizeType size () const { return array().size() / blockSize; }
341
343 SizeType numDofs() const { return array().size(); }
344
345 FieldType* data() { return ContainerAccess< ArrayType >::data( array() ); }
346 const FieldType* data() const { return ContainerAccess< ArrayType >::data( array() ); }
347
348 const ArrayType &array () const { return array_; }
349 ArrayType &array () { return array_; }
350
351 protected:
352 ArrayType& array_;
353 };
354
355
356
364 template< class Container, unsigned int BlockSize >
365 class MutableBlockVector
366 : public SimpleBlockVector< Container, BlockSize >
367 {
368 typedef MutableBlockVector< Container, BlockSize > ThisType;
369 typedef SimpleBlockVector < Container, BlockSize > BaseType;
370
371 typedef Container ArrayType;
372 using BaseType :: array_;
373 using BaseType :: sequence_;
374 public:
375
376 using BaseType :: array;
377 using BaseType :: blockSize ;
378 typedef typename BaseType :: SizeType SizeType;
379
381 explicit MutableBlockVector ( SizeType size )
382 : BaseType( *(new Container( size*blockSize ) ) )
383 {}
384
386 MutableBlockVector ( const ThisType &other )
387 : BaseType( *(new Container( other.array().size() ) ) )
388 {
389 assign( other );
390 }
391
392 ~MutableBlockVector()
393 {
394 delete &array_;
395 }
396
398 void setMemoryFactor( const double memFactor )
399 {
400 doSetMemoryFactor( array_, memFactor );
401 }
402
411 void reserve ( const int size )
412 {
413 array().reserve( size*blockSize );
414 }
415
417 void resize ( SizeType size )
418 {
419 array().resize( size*blockSize );
420 ++sequence_;
421 }
422
423 private:
424 template <class T, class Allocator>
425 void doSetMemoryFactor( Dune::Fem::DynamicArray< T, Allocator >& array, const double memFactor )
426 {
427 array_.setMemoryFactor( memFactor );
428 }
429
430 template <class Array>
431 void doSetMemoryFactor( Array& , const double memFactor ) {}
432
433 };
434
435
436
444 template< class Field, unsigned int BlockSize >
445 class MutableBlockVector< DynamicArray< Field >, BlockSize >
446 : public SimpleBlockVector< StaticArray< Field >, BlockSize >
447 {
448 typedef StaticArray< Field > StaticContainer ;
449 typedef DynamicArray< Field > MutableContainer ;
450 typedef SimpleBlockVector< StaticContainer, BlockSize > BaseType;
451 typedef MutableBlockVector< MutableContainer, BlockSize > ThisType;
452
453 protected:
454 using BaseType :: array_;
455 using BaseType :: sequence_;
456
457 std::unique_ptr< MutableContainer > container_;
458 public:
459 using BaseType :: blockSize ;
460 typedef typename BaseType :: SizeType SizeType;
461
463 explicit MutableBlockVector ( SizeType size )
464 : BaseType( allocateContainer( size*blockSize ) ),
465 container_( static_cast< MutableContainer* > (&array_) )
466 {}
467
469 MutableBlockVector ( const ThisType &other )
470 : BaseType( allocateContainer( other.array().size() ) ),
471 container_( static_cast< MutableContainer* > (&array_) )
472 {
473 assign( other );
474 }
475
484 void reserve ( const int size )
485 {
486 assert( container_ );
487 container_->reserve( size*blockSize );
488 }
489
491 void resize ( SizeType size )
492 {
493 assert( container_ );
494 container_->resize( size*blockSize );
495 ++sequence_;
496 }
497
498 protected:
499 StaticContainer& allocateContainer( const SizeType size )
500 {
501 MutableContainer* container = new MutableContainer( size );
502 return *container;
503 }
504 };
505
506
507
512 template< class DofBlock >
513 class ISTLBlockVector
514 : public BlockVectorInterface< ISTLBlockVector< DofBlock >, typename DofBlock :: value_type >
515 {
516 typedef ISTLBlockVector< DofBlock> ThisType;
517#if HAVE_DUNE_ISTL
518 typedef BlockVector< DofBlock > ArrayType;
519#else
520 // fallback in case dune-istl is not present
521 typedef Dune::DynamicVector< DofBlock > ArrayType;
522#endif
523 typedef BlockVectorInterface< ISTLBlockVector< DofBlock >, typename DofBlock :: value_type > BaseType;
524
525
526 using BaseType :: sequence_;
527
528 public:
529 ISTLBlockVector ( const ThisType& ) = default;
530
531 typedef ArrayType DofContainerType;
532
533 enum { blockSize = DofBlock :: dimension };
534 typedef Hybrid::IndexRange< int, blockSize > BlockIndices;
535
536 typedef typename DofBlock :: value_type FieldType;
537
538 protected:
539 template <class EmbeddedIterator, class V>
540 class Iterator
541 : public ForwardIteratorFacade< Iterator< EmbeddedIterator,V >, V >
542 {
543 public:
544 typedef V FieldType;
545 protected:
546 mutable EmbeddedIterator it_;
547#ifndef NDEBUG
548 EmbeddedIterator end_;
549#endif
550 int index_;
551 public:
553 Iterator( const EmbeddedIterator& it
554#ifndef NDEBUG
555 , const EmbeddedIterator& end = EmbeddedIterator()
556#endif
557 )
558 : Iterator( it, 0
559#ifndef NDEBUG
560 , end
561#endif
562 )
563 {}
564
566 Iterator( const EmbeddedIterator& it, const int index
567#ifndef NDEBUG
568 , const EmbeddedIterator& end = EmbeddedIterator()
569#endif
570 )
571 : it_( it ),
572#ifndef NDEBUG
573 end_( end ),
574#endif
575 index_( index )
576 {}
577
579 FieldType& dereference () const
580 {
581 assert( it_ != end_ );
582 assert( index_ < blockSize );
583 return (*it_)[ index_ ];
584 }
585
587 void increment ()
588 {
589 ++index_;
590 if( index_ >= blockSize )
591 {
592 index_ = 0;
593 ++it_;
594 }
595 }
596
598 bool equals ( const Iterator &other ) const
599 {
600 return (it_ == other.it_) && (index_ == other.index_);
601 }
602
603 }; // end DofIteratorBlockVectorDiscreteFunction
604
605 public:
606 typedef Iterator< typename ArrayType::Iterator, FieldType > IteratorType;
607 typedef Iterator< typename ArrayType::ConstIterator, const FieldType > ConstIteratorType;
608
609 typedef DofBlock DofBlockType;
610 typedef const DofBlock ConstDofBlockType;
611
612 typedef DofBlockType* DofBlockPtrType;
613 typedef ConstDofBlockType* ConstDofBlockPtrType;
614
615 typedef typename ArrayType::size_type SizeType;
617 typedef typename ArrayType::value_type value_type;
618
620 explicit ISTLBlockVector ( ArrayType* array )
621 : array_( array )
622 {}
623
624 ISTLBlockVector () = default;
625
627 const ThisType& operator= ( const ThisType& other )
628 {
629 if( this != &other )
630 {
631 array() = other.array();
632 }
633 return *this;
634 }
635
636 DofBlockPtrType blockPtr(const unsigned int i ) { return &array()[ i ]; }
637 ConstDofBlockPtrType blockPtr(const unsigned int i ) const { return &array()[ i ]; }
638
639 DofBlockType& operator[] (const unsigned int i ) { return array()[ i ]; }
640 ConstDofBlockType& operator[] (const unsigned int i ) const { return array()[ i ]; }
641
642 IteratorType begin() { return IteratorType( array().begin()
643#ifndef NDEBUG
644 , array().end()
645#endif
646 ); }
647 ConstIteratorType begin() const
648 {
649 return ConstIteratorType( array().begin()
650#ifndef NDEBUG
651 , array().end()
652#endif
653 ); }
654
655 IteratorType end() { return IteratorType( array().end() ); }
656 ConstIteratorType end() const { return ConstIteratorType( array().end() ); }
657
658 IteratorType beforeEnd()
659 {
660 DUNE_THROW(NotImplemented,"ISTLBlockVector::beforeEnd not implemented yet");
661 return array().end();
662 }
663
664 ConstIteratorType beforeEnd() const
665 {
666 DUNE_THROW(NotImplemented,"ISTLBlockVector::beforeEnd not implemented yet");
667 return array().end();
668 }
669
670 IteratorType beforeBegin()
671 {
672 DUNE_THROW(NotImplemented,"ISTLBlockVector::beforeBegin not implemented yet");
673 return array().end();
674 }
675
676 ConstIteratorType beforeBegin() const
677 {
678 DUNE_THROW(NotImplemented,"ISTLBlockVector::beforeBegin not implemented yet");
679 return array().end();
680 }
681
683 IteratorType find( const SizeType dof )
684 {
685 const SizeType block = dof / blockSize;
686 const SizeType index = dof % blockSize;
687 return IteratorType( array().find( block ), index
688#ifndef NDEBUG
689 , array().end()
690#endif
691 );
692 }
693
695 ConstIteratorType find( const SizeType dof ) const
696 {
697 const SizeType block = dof / blockSize;
698 const SizeType index = dof % blockSize;
699 return ConstIteratorType( array().find( block ), index
700#ifndef NDEBUG
701 , array().end()
702#endif
703 );
704 }
705
706 SizeType size() const { return array().size(); }
707
709 SizeType numDofs() const { return array().size() * DofBlock::dimension; }
710
719 void reserve ( const int size )
720 {
721 array().reserve( size );
722 }
723
725 void resize ( SizeType size )
726 {
727 array().resize( size );
728 ++sequence_;
729 }
730
731 ArrayType& array() { assert( array_ ); return *array_; }
732 const ArrayType& array() const { assert( array_ ); return *array_; }
733
734 protected:
735 // ISTL BlockVector
736 ArrayType* array_;
737 };
738
739} // namespace Fem
740} // namespace Dune
741
742#endif // DUNE_FEM_REFERENCEBLOCKVECTOR_HH
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
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Nov 21, 23:30, 2024)