Loading...
Searching...
No Matches
vbvector.hh
Go to the documentation of this file.
// SPDX-FileCopyrightText: Copyright © DUNE Project contributors, see file LICENSE.md in module root
// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
// vi: set et ts=4 sw=2 sts=2:
#ifndef DUNE_ISTL_VBVECTOR_HH
#define DUNE_ISTL_VBVECTOR_HH
#include <cmath>
#include <complex>
#include <iostream>
#include <iterator>
#include <memory>
#include <dune/common/ftraits.hh>
#include <dune/common/indexediterator.hh>
#include <dune/common/iteratorfacades.hh>
#include "istlexception.hh"
#include "bvector.hh"
#include <dune/istl/blocklevel.hh>
namespace Dune {
template<class B, class A=std::allocator<B> >
class VariableBlockVector : public Imp::block_vector_unmanaged<B,typename A::size_type>
// this derivation gives us all the blas level 1 and norms
// on the large array. However, access operators have to be
// overwritten.
{
using Base = Imp::block_vector_unmanaged<B,typename A::size_type>;
// just a shorthand
using window_type = Imp::BlockVectorWindow<B,A>;
// data-structure holding the windows (but not the actual data)
using VectorWindows = std::vector<window_type, typename std::allocator_traits<A>::template rebind_alloc<window_type>>;
// block type bool is not supported since std::vector<bool> is used for storage
static_assert(not std::is_same_v<B,bool>, "Block type 'bool' not supported by VariableBlockVector.");
public:
//===== type definitions and constants
using field_type = typename Imp::BlockTraits<B>::field_type;
using allocator_type = A;
using reference = window_type&;
using const_reference = const window_type&;
using size_type = typename A::size_type;
using value_type = BlockVector<B,A>;
using block_type = BlockVector<B,A>;
//===== constructors and such
VariableBlockVector () :
Base()
{}
explicit VariableBlockVector (size_type numBlocks) :
Base(),
block(numBlocks)
{}
VariableBlockVector (size_type numBlocks, size_type blockSize) :
Base(),
block(numBlocks),
storage_(numBlocks*blockSize)
{
// and we can allocate the big array in the base class
syncBaseArray();
// set the windows into the big array
for (size_type i=0; i<numBlocks; ++i)
block[i].set(blockSize,this->p+(i*blockSize));
// and the vector is usable
initialized = true;
}
VariableBlockVector (const VariableBlockVector& a) :
Base(static_cast<const Base&>(a)),
block(a.block),
storage_(a.storage_)
{
syncBaseArray();
// and we must set the windows
if (block.size()>0) {
block[0].set(block[0].getsize(),this->p); // first block
for (size_type i=1; i<block.size(); ++i) // and the rest
block[i].set(block[i].getsize(),block[i-1].getptr()+block[i-1].getsize());
}
// and we have a usable vector
initialized = a.initialized;
}
VariableBlockVector (VariableBlockVector&& tmp) :
Base()
{
tmp.swap(*this);
}
~VariableBlockVector () = default;
VariableBlockVector& operator= (VariableBlockVector tmp)
{
tmp.swap(*this);
return *this;
}
void swap (VariableBlockVector& other) noexcept
{
using std::swap;
swap(storage_, other.storage_);
swap(block, other.block);
swap(initialized, other.initialized);
other.syncBaseArray();
syncBaseArray();
}
friend void swap (VariableBlockVector& lhs, VariableBlockVector& rhs) noexcept
{
lhs.swap(rhs);
}
void resize (size_type numBlocks)
{
storage_.clear();
syncBaseArray();
// we can allocate the windows now
block.resize(numBlocks);
// and the vector not fully usable
initialized = false;
}
void resize (size_type numBlocks, size_type blockSize)
{
// and we can allocate the big array in the base class
storage_.resize(numBlocks*blockSize);
block.resize(numBlocks);
syncBaseArray();
// set the windows into the big array
for (size_type i=0; i<block.size(); ++i)
block[i].set(blockSize,this->p+(i*blockSize));
// and the vector is usable
initialized = true;
}
//===== assignment from scalar
VariableBlockVector& operator= (const field_type& k)
{
(static_cast<Imp::block_vector_unmanaged<B,size_type>&>(*this)) = k;
return *this;
}
//===== the creation interface
class CreateIterator;
#ifndef DOXYGEN
// The window_type does not hand out a reference to its size,
// so in order to provide a valid iterator, we need a workaround
// to make assignment possible. This proxy enables just that by
// implicitly converting to the stored size for read access and
// tunneling assignment to the accessor method of the window.
struct SizeProxy
{
operator size_type () const
{
return target->getsize();
}
SizeProxy& operator= (size_type size)
{
target->setsize(size);
return *this;
}
private:
friend class CreateIterator;
SizeProxy (window_type& t) :
target(&t)
{}
window_type* target;
};
#endif // DOXYGEN
class CreateIterator
{
public:
using iterator_category = std::output_iterator_tag;
using value_type = size_type;
using difference_type = void;
using pointer = size_type*;
using reference = SizeProxy;
CreateIterator (VariableBlockVector& _v, int _i, bool _isEnd) :
v(&_v),
i(_i),
isEnd(_isEnd)
{}
~CreateIterator ()
{
// When the iterator gets destructed, we allocate the memory
// for the VariableBlockVector if
// 1. the current iterator was not created as enditerator
// 2. we're at the last block
// 3. the vector hasn't been initialized earlier
if (not isEnd && i==v->block.size() && not v->initialized)
v->allocate();
}
CreateIterator& operator++()
{
// go to next block
++i;
return *this;
}
CreateIterator operator++ (int)
{
CreateIterator tmp(*this);
this->operator++();
return tmp;
}
bool operator!= (const CreateIterator& it) const
{
return not (*this == it);
}
bool operator== (const CreateIterator& it) const
{
return (i==it.i) && (v==it.v);
}
size_type index () const
{
return i;
}
void setblocksize (size_type _k)
{
v->block[i].setsize(_k);
}
#ifdef DOXYGEN
size_type&
#else
SizeProxy
#endif
operator*()
{
return {v->block[i]};
}
private:
VariableBlockVector* v; // my vector
size_type i; // current block to be defined
bool isEnd; // flag if this object was created as the end iterator.
};
// CreateIterator wants to set all the arrays ...
friend class CreateIterator;
CreateIterator createbegin ()
{
#ifdef DUNE_ISTL_WITH_CHECKING
if (initialized) DUNE_THROW(ISTLError,"no CreateIterator in initialized state");
#endif
return CreateIterator(*this, 0, false);
}
CreateIterator createend ()
{
return CreateIterator(*this, block.size(), true);
}
//===== access to components
// has to be overwritten from base class because it must
// return access to the windows
window_type& operator[] (size_type i)
{
#ifdef DUNE_ISTL_WITH_CHECKING
if (i>=block.size()) DUNE_THROW(ISTLError,"index out of range");
#endif
return block[i];
}
const window_type& operator[] (size_type i) const
{
#ifdef DUNE_ISTL_WITH_CHECKING
if (i<0 || i>=block.size()) DUNE_THROW(ISTLError,"index out of range");
#endif
return block[i];
}
using Iterator = IndexedIterator<typename VectorWindows::iterator>;
Iterator begin ()
{
return Iterator{block.begin()};
}
Iterator end ()
{
return Iterator{block.end()};
}
Iterator beforeEnd ()
{
return Iterator{--block.end()};
}
Iterator beforeBegin ()
{
return Iterator{--block.begin()};
}
using iterator = Iterator;
using ConstIterator = IndexedIterator<typename VectorWindows::const_iterator>;
using const_iterator = ConstIterator;
ConstIterator begin () const
{
return ConstIterator{block.begin()};
}
ConstIterator end () const
{
return ConstIterator{block.end()};
}
ConstIterator beforeEnd () const
{
return ConstIterator{--block.end()};
}
ConstIterator beforeBegin () const
{
return ConstIterator{--block.begin()};
}
ConstIterator rend () const
{
return ConstIterator{block.rend()};
}
Iterator find (size_type i)
{
Iterator tmp = block.begin();
tmp+=std::min(i, block.size());
return tmp;
}
ConstIterator find (size_type i) const
{
ConstIterator tmp = block.begin();
tmp+=std::min(i, block.size());
return tmp;
}
//===== sizes
size_type N () const noexcept
{
return block.size();
}
size_type size () const noexcept
{
return block.size();
}
private:
void allocate ()
{
if (this->initialized)
DUNE_THROW(ISTLError, "Attempt to re-allocate already initialized VariableBlockVector");
// calculate space needed:
size_type storageNeeded = 0;
for(size_type i = 0; i < block.size(); i++)
storageNeeded += block[i].size();
storage_.resize(storageNeeded);
syncBaseArray();
// and we set the window pointers
block[0].setptr(this->p); // pointer to first block
for (size_type j=1; j<block.size(); ++j) // and the rest
block[j].setptr(block[j-1].getptr()+block[j-1].getsize());
// and the vector is ready
this->initialized = true;
}
void syncBaseArray () noexcept
{
this->p = storage_.data();
this->n = storage_.size();
}
VectorWindows block = {}; // vector of blocks pointing to the array in the base class
std::vector<B, A> storage_ = {};
bool initialized = false; // true if vector has been initialized
};
template<class B, class A>
struct FieldTraits< VariableBlockVector<B, A> >
{
typedef typename FieldTraits<B>::field_type field_type;
typedef typename FieldTraits<B>::real_type real_type;
};
} // end namespace
#endif
blocklevel.hh
Helper functions for determining the vector/matrix block level.
istlexception.hh
bvector.hh
This file implements a vector space as a tensor product of a given vector space. The number of compon...
Dune
Definition allocator.hh:11
Dune::size_type
Dune::BlockVector
A vector of blocks with memory management.
Definition bvector.hh:392
Dune::ISTLError
derive error class from the base class in common
Definition istlexception.hh:19
Dune::VariableBlockVector
A Vector of blocks with different blocksizes.
Definition vbvector.hh:48
Dune::VariableBlockVector::VariableBlockVector
VariableBlockVector(size_type numBlocks, size_type blockSize)
Construct a vector with given number of blocks each having a constant size.
Definition vbvector.hh:125
Dune::VariableBlockVector::VariableBlockVector
VariableBlockVector()
Constructor without arguments makes an empty vector.
Definition vbvector.hh:102
Dune::VariableBlockVector::swap
friend void swap(VariableBlockVector &lhs, VariableBlockVector &rhs) noexcept
Free function to swap the storage and internal state of lhs with rhs.
Definition vbvector.hh:190
Dune::VariableBlockVector::iterator
Iterator iterator
Export the iterator type using std naming rules.
Definition vbvector.hh:443
Dune::VariableBlockVector::CreateIterator
friend class CreateIterator
Definition vbvector.hh:374
Dune::VariableBlockVector::operator=
VariableBlockVector & operator=(VariableBlockVector tmp)
Copy and move assignment.
Definition vbvector.hh:171
Dune::VariableBlockVector::VariableBlockVector
VariableBlockVector(size_type numBlocks)
Construct a vector with given number of blocks, but size of each block is not yet known.
Definition vbvector.hh:112
Dune::VariableBlockVector::field_type
typename Imp::BlockTraits< B >::field_type field_type
export the type representing the field
Definition vbvector.hh:65
Dune::VariableBlockVector::size_type
typename A::size_type size_type
The size type for the index access.
Definition vbvector.hh:83
Dune::VariableBlockVector::block_type
BlockVector< B, A > block_type
Same as value_type, here for historical reasons.
Definition vbvector.hh:94
Dune::VariableBlockVector::N
size_type N() const noexcept
number of blocks in the vector (are of variable size here)
Definition vbvector.hh:502
Dune::VariableBlockVector::VariableBlockVector
VariableBlockVector(const VariableBlockVector &a)
Copy constructor, has copy semantics.
Definition vbvector.hh:142
Dune::VariableBlockVector::operator[]
window_type & operator[](size_type i)
random access to blocks
Definition vbvector.hh:397
Dune::VariableBlockVector::allocator_type
A allocator_type
export the allocator type
Definition vbvector.hh:68
Dune::VariableBlockVector::createend
CreateIterator createend()
get create iterator pointing to one after the last block
Definition vbvector.hh:386
Dune::VariableBlockVector::VariableBlockVector
VariableBlockVector(VariableBlockVector &&tmp)
Move constructor:
Definition vbvector.hh:161
Dune::VariableBlockVector::createbegin
CreateIterator createbegin()
get initial create iterator
Definition vbvector.hh:377
Dune::VariableBlockVector::const_iterator
ConstIterator const_iterator
Export the const iterator type using std naming rules.
Definition vbvector.hh:449
Dune::VariableBlockVector::reference
window_type & reference
Export type used for references to container entries.
Definition vbvector.hh:74
Dune::VariableBlockVector::rend
ConstIterator rend() const
end ConstIterator
Definition vbvector.hh:478
Dune::VariableBlockVector::const_reference
const window_type & const_reference
Export type used for const references to container entries.
Definition vbvector.hh:80
Dune::VariableBlockVector::find
ConstIterator find(size_type i) const
random access returning iterator (end if not contained)
Definition vbvector.hh:492
Dune::VariableBlockVector::beforeEnd
ConstIterator beforeEnd() const
Definition vbvector.hh:465
Dune::VariableBlockVector::find
Iterator find(size_type i)
random access returning iterator (end if not contained)
Definition vbvector.hh:484
Dune::VariableBlockVector::ConstIterator
IndexedIterator< typename VectorWindows::const_iterator > ConstIterator
Const iterator.
Definition vbvector.hh:446
Dune::VariableBlockVector::~VariableBlockVector
~VariableBlockVector()=default
Dune::VariableBlockVector::value_type
BlockVector< B, A > value_type
Type of the elements of the outer vector, i.e., dynamic vectors of B.
Definition vbvector.hh:90
Dune::VariableBlockVector::beforeBegin
ConstIterator beforeBegin() const
Definition vbvector.hh:472
Dune::VariableBlockVector::resize
void resize(size_type numBlocks)
same effect as constructor with same argument
Definition vbvector.hh:196
Dune::VariableBlockVector::end
Iterator end()
end Iterator
Definition vbvector.hh:423
Dune::VariableBlockVector::swap
void swap(VariableBlockVector &other) noexcept
Exchange the storage and internal state with other.
Definition vbvector.hh:178
Dune::VariableBlockVector::begin
ConstIterator begin() const
begin ConstIterator
Definition vbvector.hh:452
Dune::VariableBlockVector::size
size_type size() const noexcept
Definition vbvector.hh:511
Dune::VariableBlockVector::resize
void resize(size_type numBlocks, size_type blockSize)
same effect as constructor with same argument
Definition vbvector.hh:210
Dune::VariableBlockVector::Iterator
IndexedIterator< typename VectorWindows::iterator > Iterator
Definition vbvector.hh:414
Dune::VariableBlockVector::end
ConstIterator end() const
end ConstIterator
Definition vbvector.hh:458
Dune::VariableBlockVector::beforeBegin
Iterator beforeBegin()
Definition vbvector.hh:437
Dune::VariableBlockVector::beforeEnd
Iterator beforeEnd()
Definition vbvector.hh:430
Dune::VariableBlockVector::begin
Iterator begin()
begin Iterator
Definition vbvector.hh:417
Dune::VariableBlockVector::CreateIterator
Iterator class for sequential creation of blocks.
Definition vbvector.hh:275
Dune::VariableBlockVector::CreateIterator::operator==
bool operator==(const CreateIterator &it) const
equality
Definition vbvector.hh:339
Dune::VariableBlockVector::CreateIterator::index
size_type index() const
dereferencing
Definition vbvector.hh:345
Dune::VariableBlockVector::CreateIterator::reference
SizeProxy reference
reference type
Definition vbvector.hh:295
Dune::VariableBlockVector::CreateIterator::pointer
size_type * pointer
pointer type
Definition vbvector.hh:292
Dune::VariableBlockVector::CreateIterator::operator!=
bool operator!=(const CreateIterator &it) const
inequality
Definition vbvector.hh:333
Dune::VariableBlockVector::CreateIterator::~CreateIterator
~CreateIterator()
Definition vbvector.hh:304
Dune::VariableBlockVector::CreateIterator::value_type
size_type value_type
value type
Definition vbvector.hh:281
Dune::VariableBlockVector::CreateIterator::CreateIterator
CreateIterator(VariableBlockVector &_v, int _i, bool _isEnd)
constructor
Definition vbvector.hh:298
Dune::VariableBlockVector::CreateIterator::setblocksize
void setblocksize(size_type _k)
set size of current block
Definition vbvector.hh:351
Dune::VariableBlockVector::CreateIterator::operator*
size_type & operator*()
Access size of current block.
Definition vbvector.hh:362
Dune::VariableBlockVector::CreateIterator::iterator_category
std::output_iterator_tag iterator_category
iterator category
Definition vbvector.hh:278
Dune::VariableBlockVector::CreateIterator::operator++
CreateIterator & operator++()
prefix increment
Definition vbvector.hh:316
Dune::VariableBlockVector::CreateIterator::difference_type
void difference_type
difference type (unused)
Definition vbvector.hh:289
Dune::FieldTraits< VariableBlockVector< B, A > >::real_type
FieldTraits< B >::real_type real_type
Definition vbvector.hh:559
Dune::FieldTraits< VariableBlockVector< B, A > >::field_type
FieldTraits< B >::field_type field_type
Definition vbvector.hh:558