6#ifndef DUNE_ISTL_BVECTOR_HH
7#define DUNE_ISTL_BVECTOR_HH
12#include <initializer_list>
29#include "istlexception.hh"
48 template <
class B,
bool isNumber>
52 class BlockTraitsImp<B,true>
59 class BlockTraitsImp<B,false>
62 using field_type =
typename B::field_type;
68 using BlockTraits = BlockTraitsImp<B,IsNumber<B>::value>;
83 template<
class B,
class A=std::allocator<B> >
84 class block_vector_unmanaged :
public base_array_unmanaged<B,A>
89 using field_type =
typename Imp::BlockTraits<B>::field_type;
95 typedef A allocator_type;
98 typedef typename A::size_type size_type;
101 typedef typename base_array_unmanaged<B,A>::iterator Iterator;
104 typedef typename base_array_unmanaged<B,A>::const_iterator ConstIterator;
107 typedef B value_type;
110 typedef B& reference;
113 typedef const B& const_reference;
118 block_vector_unmanaged& operator= (
const field_type& k)
120 for (size_type i=0; i<this->n; i++)
127 block_vector_unmanaged& operator+= (
const block_vector_unmanaged& y)
129#ifdef DUNE_ISTL_WITH_CHECKING
130 if (this->n!=y.N())
DUNE_THROW(ISTLError,
"vector size mismatch");
132 for (size_type i=0; i<this->n; ++i) (*
this)[i] += y[i];
137 block_vector_unmanaged& operator-= (
const block_vector_unmanaged& y)
139#ifdef DUNE_ISTL_WITH_CHECKING
140 if (this->n!=y.N())
DUNE_THROW(ISTLError,
"vector size mismatch");
142 for (size_type i=0; i<this->n; ++i) (*
this)[i] -= y[i];
147 block_vector_unmanaged& operator*= (
const field_type& k)
149 for (size_type i=0; i<this->n; ++i) (*
this)[i] *= k;
154 block_vector_unmanaged& operator/= (
const field_type& k)
156 for (size_type i=0; i<this->n; ++i) (*
this)[i] /= k;
161 block_vector_unmanaged& axpy (
const field_type& a,
const block_vector_unmanaged& y)
163#ifdef DUNE_ISTL_WITH_CHECKING
164 if (this->n!=y.N())
DUNE_THROW(ISTLError,
"vector size mismatch");
166 for (size_type i=0; i<this->n; ++i)
167 Impl::asVector((*
this)[i]).axpy(a,Impl::asVector(y[i]));
180 template<
class OtherB,
class OtherA>
181 auto operator* (
const block_vector_unmanaged<OtherB,OtherA>& y)
const
183 typedef typename PromotionTraits<field_type,typename BlockTraits<OtherB>::field_type>::PromotedType PromotedType;
185#ifdef DUNE_ISTL_WITH_CHECKING
186 if (this->n!=y.N())
DUNE_THROW(ISTLError,
"vector size mismatch");
188 for (size_type i=0; i<this->n; ++i) {
189 sum += PromotedType(((*
this)[i])*y[i]);
201 template<
class OtherB,
class OtherA>
202 auto dot(
const block_vector_unmanaged<OtherB,OtherA>& y)
const
204 typedef typename PromotionTraits<field_type,typename BlockTraits<OtherB>::field_type>::PromotedType PromotedType;
206#ifdef DUNE_ISTL_WITH_CHECKING
207 if (this->n!=y.N())
DUNE_THROW(ISTLError,
"vector size mismatch");
210 for (size_type i=0; i<this->n; ++i)
211 sum += Impl::asVector((*
this)[i]).dot(Impl::asVector(y[i]));
219 typename FieldTraits<field_type>::real_type one_norm ()
const
221 typename FieldTraits<field_type>::real_type sum=0;
222 for (size_type i=0; i<this->n; ++i)
223 sum += Impl::asVector((*
this)[i]).one_norm();
228 typename FieldTraits<field_type>::real_type one_norm_real ()
const
230 typename FieldTraits<field_type>::real_type sum=0;
231 for (size_type i=0; i<this->n; ++i)
232 sum += Impl::asVector((*
this)[i]).one_norm_real();
237 typename FieldTraits<field_type>::real_type two_norm ()
const
240 return sqrt(two_norm2());
244 typename FieldTraits<field_type>::real_type two_norm2 ()
const
246 typename FieldTraits<field_type>::real_type sum=0;
247 for (size_type i=0; i<this->n; ++i)
248 sum += Impl::asVector((*
this)[i]).two_norm2();
253 template <
typename ft = field_type,
254 typename std::enable_if<!HasNaN<ft>::value,
int>::type = 0>
255 typename FieldTraits<ft>::real_type infinity_norm()
const {
256 using real_type =
typename FieldTraits<ft>::real_type;
260 for (
auto const &xi : *
this) {
261 real_type
const a = Impl::asVector(xi).infinity_norm();
268 template <
typename ft = field_type,
269 typename std::enable_if<!HasNaN<ft>::value,
int>::type = 0>
270 typename FieldTraits<ft>::real_type infinity_norm_real()
const {
271 using real_type =
typename FieldTraits<ft>::real_type;
275 for (
auto const &xi : *
this) {
276 real_type
const a = Impl::asVector(xi).infinity_norm_real();
283 template <
typename ft = field_type,
284 typename std::enable_if<HasNaN<ft>::value,
int>::type = 0>
285 typename FieldTraits<ft>::real_type infinity_norm()
const {
286 using real_type =
typename FieldTraits<ft>::real_type;
293 for (
auto const &xi : *
this) {
294 real_type
const a = Impl::asVector(xi).infinity_norm();
298 return norm * (isNaN / isNaN);
302 template <
typename ft = field_type,
303 typename std::enable_if<HasNaN<ft>::value,
int>::type = 0>
304 typename FieldTraits<ft>::real_type infinity_norm_real()
const {
305 using real_type =
typename FieldTraits<ft>::real_type;
311 for (
auto const &xi : *
this) {
312 real_type
const a = Impl::asVector(xi).infinity_norm_real();
317 return norm * (isNaN / isNaN);
329 size_type dim ()
const
333 for (size_type i=0; i<this->n; i++)
334 d += Impl::asVector((*
this)[i]).dim();
341 block_vector_unmanaged () : base_array_unmanaged<B,A>()
355 ScopeGuard(F cleanupFunc) : cleanupFunc_(
std::move(cleanupFunc)) {}
356 ScopeGuard(
const ScopeGuard &) =
delete;
357 ScopeGuard(ScopeGuard &&) =
delete;
358 ScopeGuard &operator=(ScopeGuard) =
delete;
359 ~ScopeGuard() { cleanupFunc_(); }
373 ScopeGuard<F> makeScopeGuard(F cleanupFunc)
375 return { std::move(cleanupFunc) };
393 template<
class B,
class A=std::allocator<B> >
413 [[deprecated(
"Use free function blockLevel(). Will be removed after 2.8.")]]
414 static constexpr unsigned int blocklevel = blockLevel<B>()+1;
417 typedef typename Imp::block_vector_unmanaged<B,A>::Iterator
Iterator;
420 typedef typename Imp::block_vector_unmanaged<B,A>::ConstIterator
ConstIterator;
457 static_assert(std::numeric_limits<S>::is_integer,
458 "capacity must be an unsigned integral type (be aware, that this constructor does not set the default value!)" );
460 storage_.reserve(_capacity);
477 [[maybe_unused]]
const auto &guard =
478 Imp::makeScopeGuard([
this]{ syncBaseArray(); });
490 return storage_.capacity();
505 [[maybe_unused]]
const auto &guard =
506 Imp::makeScopeGuard([
this]{ syncBaseArray(); });
507 storage_.resize(size);
512 noexcept(
noexcept(std::declval<BlockVector>().storage_ = a.storage_))
514 storage_ = a.storage_;
520 noexcept(
noexcept(std::declval<BlockVector>().swap(a)))
527 noexcept(
noexcept(std::declval<BlockVector>().storage_ = a.storage_))
529 [[maybe_unused]]
const auto &guard =
530 Imp::makeScopeGuard([
this]{ syncBaseArray(); });
531 storage_ = a.storage_;
537 noexcept(
noexcept(std::declval<BlockVector>().swap(a)))
546 std::declval<BlockVector&>().storage_.swap(other.storage_)))
548 [[maybe_unused]]
const auto &guard = Imp::makeScopeGuard([&]{
550 other.syncBaseArray();
552 storage_.swap(other.storage_);
559 (
static_cast<Imp::block_vector_unmanaged<B,A>&
>(*this)) = k;
564 void syncBaseArray() noexcept
566 this->p = storage_.data();
567 this->n = storage_.size();
570 std::vector<B, A> storage_;
578 template<
class B,
class A>
579 struct FieldTraits< BlockVector<B, A> >
581 typedef typename FieldTraits<B>::field_type field_type;
582 typedef typename FieldTraits<B>::real_type real_type;
589 template<
class K,
class A>
594 for (size_type i=0; i<v.size(); i++)
595 s << v[i] << std::endl;
622 template<
class B,
class A>
624 template<
class B,
class A=std::allocator<B> >
626 class BlockVectorWindow :
public Imp::block_vector_unmanaged<B,A>
633 using field_type =
typename Imp::BlockTraits<B>::field_type;
636 typedef B block_type;
639 typedef A allocator_type;
642 typedef typename A::size_type size_type;
645 [[deprecated(
"Use free function blockLevel(). Will be removed after 2.8.")]]
646 static constexpr unsigned int blocklevel = blockLevel<B>()+1;
649 typedef typename Imp::block_vector_unmanaged<B,A>::Iterator Iterator;
652 typedef typename Imp::block_vector_unmanaged<B,A>::ConstIterator ConstIterator;
657 BlockVectorWindow () : Imp::block_vector_unmanaged<B,A>()
661 BlockVectorWindow (B* _p, size_type _n)
668 BlockVectorWindow (
const BlockVectorWindow& a)
675 BlockVectorWindow& operator= (
const BlockVectorWindow& a)
678#ifdef DUNE_ISTL_WITH_CHECKING
679 if (this->n!=a.N())
DUNE_THROW(ISTLError,
"vector size mismatch");
685 for (size_type i=0; i<this->n; i++) this->p[i]=a.p[i];
691 BlockVectorWindow& operator= (
const field_type& k)
693 (
static_cast<Imp::block_vector_unmanaged<B,A>&
>(*this)) = k;
698 operator BlockVector<B, A>()
const {
699 auto bv = BlockVector<B, A>(this->n);
701 std::copy(this->begin(), this->end(), bv.begin());
709 void set (size_type _n, B* _p)
716 void setsize (size_type _n)
734 size_type getsize ()
const
752 template<
class B,
class A=std::allocator<B> >
753 class compressed_block_vector_unmanaged :
public compressed_base_array_unmanaged<B,A>
760 using field_type =
typename Imp::BlockTraits<B>::field_type;
763 typedef B block_type;
766 typedef A allocator_type;
769 typedef typename compressed_base_array_unmanaged<B,A>::iterator Iterator;
772 typedef typename compressed_base_array_unmanaged<B,A>::const_iterator ConstIterator;
775 typedef typename A::size_type size_type;
779 compressed_block_vector_unmanaged& operator= (
const field_type& k)
781 for (size_type i=0; i<this->n; i++)
791 compressed_block_vector_unmanaged& operator+= (
const V& y)
793#ifdef DUNE_ISTL_WITH_CHECKING
794 if (!includesindexset(y))
DUNE_THROW(ISTLError,
"index set mismatch");
796 for (size_type i=0; i<y.n; ++i) this->
operator[](y.j[i]) += y.p[i];
802 compressed_block_vector_unmanaged& operator-= (
const V& y)
804#ifdef DUNE_ISTL_WITH_CHECKING
805 if (!includesindexset(y))
DUNE_THROW(ISTLError,
"index set mismatch");
807 for (size_type i=0; i<y.n; ++i) this->
operator[](y.j[i]) -= y.p[i];
813 compressed_block_vector_unmanaged& axpy (
const field_type& a,
const V& y)
815#ifdef DUNE_ISTL_WITH_CHECKING
816 if (!includesindexset(y))
DUNE_THROW(ISTLError,
"index set mismatch");
818 for (size_type i=0; i<y.n; ++i)
819 Impl::asVector((*
this)[y.j[i]]).axpy(a,Impl::asVector(y.p[i]));
824 compressed_block_vector_unmanaged& operator*= (
const field_type& k)
826 for (size_type i=0; i<this->n; ++i) (this->p)[i] *= k;
831 compressed_block_vector_unmanaged& operator/= (
const field_type& k)
833 for (size_type i=0; i<this->n; ++i) (this->p)[i] /= k;
841 field_type operator* (
const compressed_block_vector_unmanaged& y)
const
843#ifdef DUNE_ISTL_WITH_CHECKING
844 if (!includesindexset(y) || !y.includesindexset(*
this) )
848 for (size_type i=0; i<this->n; ++i)
849 sum += (this->p)[i] * y[(this->j)[i]];
857 typename FieldTraits<field_type>::real_type one_norm ()
const
859 typename FieldTraits<field_type>::real_type sum=0;
860 for (size_type i=0; i<this->n; ++i) sum += (this->p)[i].one_norm();
865 typename FieldTraits<field_type>::real_type one_norm_real ()
const
867 typename FieldTraits<field_type>::real_type sum=0;
868 for (size_type i=0; i<this->n; ++i) sum += (this->p)[i].one_norm_real();
873 typename FieldTraits<field_type>::real_type two_norm ()
const
876 typename FieldTraits<field_type>::real_type sum=0;
877 for (size_type i=0; i<this->n; ++i) sum += (this->p)[i].two_norm2();
882 typename FieldTraits<field_type>::real_type two_norm2 ()
const
884 typename FieldTraits<field_type>::real_type sum=0;
885 for (size_type i=0; i<this->n; ++i) sum += (this->p)[i].two_norm2();
890 template <
typename ft = field_type,
891 typename std::enable_if<!HasNaN<ft>::value,
int>::type = 0>
892 typename FieldTraits<ft>::real_type infinity_norm()
const {
893 using real_type =
typename FieldTraits<ft>::real_type;
897 for (
auto const &x : *
this) {
898 real_type
const a = x.infinity_norm();
905 template <
typename ft = field_type,
906 typename std::enable_if<!HasNaN<ft>::value,
int>::type = 0>
907 typename FieldTraits<ft>::real_type infinity_norm_real()
const {
908 using real_type =
typename FieldTraits<ft>::real_type;
912 for (
auto const &x : *
this) {
913 real_type
const a = x.infinity_norm_real();
920 template <
typename ft = field_type,
921 typename std::enable_if<HasNaN<ft>::value,
int>::type = 0>
922 typename FieldTraits<ft>::real_type infinity_norm()
const {
923 using real_type =
typename FieldTraits<ft>::real_type;
928 for (
auto const &x : *
this) {
929 real_type
const a = x.infinity_norm();
933 return norm * (isNaN / isNaN);
937 template <
typename ft = field_type,
938 typename std::enable_if<HasNaN<ft>::value,
int>::type = 0>
939 typename FieldTraits<ft>::real_type infinity_norm_real()
const {
940 using real_type =
typename FieldTraits<ft>::real_type;
945 for (
auto const &x : *
this) {
946 real_type
const a = x.infinity_norm_real();
950 return norm * (isNaN / isNaN);
962 size_type dim ()
const
965 for (size_type i=0; i<this->n; i++)
966 d += (this->p)[i].dim();
972 compressed_block_vector_unmanaged () : compressed_base_array_unmanaged<B,A>()
977 bool includesindexset (
const V& y)
979 typename V::ConstIterator e=this->end();
980 for (size_type i=0; i<y.n; i++)
981 if (this->find(y.j[i])==e)
1006 template<
class B,
class A=std::allocator<B> >
1007 class CompressedBlockVectorWindow :
public compressed_block_vector_unmanaged<B,A>
1014 using field_type =
typename Imp::BlockTraits<B>::field_type;
1017 typedef B block_type;
1020 typedef A allocator_type;
1023 typedef typename A::size_type size_type;
1026 [[deprecated(
"Use free function blockLevel(). Will be removed after 2.8.")]]
1027 static constexpr unsigned int blocklevel = blockLevel<B>()+1;
1030 typedef typename compressed_block_vector_unmanaged<B,A>::Iterator Iterator;
1033 typedef typename compressed_block_vector_unmanaged<B,A>::ConstIterator ConstIterator;
1038 CompressedBlockVectorWindow () : compressed_block_vector_unmanaged<B,A>()
1042 CompressedBlockVectorWindow (B* _p, size_type* _j, size_type _n)
1050 CompressedBlockVectorWindow (
const CompressedBlockVectorWindow& a)
1058 CompressedBlockVectorWindow& operator= (
const CompressedBlockVectorWindow& a)
1061#ifdef DUNE_ISTL_WITH_CHECKING
1062 if (this->n!=a.N())
DUNE_THROW(ISTLError,
"vector size mismatch");
1068 for (size_type i=0; i<this->n; i++) this->p[i]=a.p[i];
1069 for (size_type i=0; i<this->n; i++) this->j[i]=a.j[i];
1075 CompressedBlockVectorWindow& operator= (
const field_type& k)
1077 (
static_cast<compressed_block_vector_unmanaged<B,A>&
>(*this)) = k;
1085 void set (size_type _n, B* _p, size_type* _j)
1093 void setsize (size_type _n)
1105 void setindexptr (size_type* _j)
1117 size_type* getindexptr ()
1123 const B* getptr ()
const
1129 const size_type* getindexptr ()
const
1134 size_type getsize ()
const
1144 template<
typename B,
typename A>
1145 struct AutonomousValueType<Imp::BlockVectorWindow<B,A>>
1147 using type = BlockVector<B, A>;
Implements several basic array containers.
Helper functions for determining the vector/matrix block level.
A vector of blocks with memory management.
Definition: bvector.hh:395
BlockVector()
makes empty vector
Definition: bvector.hh:425
void reserve(size_type capacity)
Reserve space.
Definition: bvector.hh:475
BlockVector(BlockVector &&a) noexcept(noexcept(std::declval< BlockVector >().swap(a)))
move constructor
Definition: bvector.hh:519
BlockVector(size_type _n)
make vector with _n components
Definition: bvector.hh:431
void resize(size_type size)
Resize the vector.
Definition: bvector.hh:503
Imp::block_vector_unmanaged< B, A >::Iterator Iterator
make iterators available as types
Definition: bvector.hh:417
static constexpr unsigned int blocklevel
increment block level counter
Definition: bvector.hh:414
BlockVector(const BlockVector &a) noexcept(noexcept(std::declval< BlockVector >().storage_=a.storage_))
copy constructor
Definition: bvector.hh:511
A allocator_type
export the allocator type
Definition: bvector.hh:407
BlockVector & operator=(const BlockVector &a) noexcept(noexcept(std::declval< BlockVector >().storage_=a.storage_))
assignment
Definition: bvector.hh:526
typename Imp::BlockTraits< B >::field_type field_type
export the type representing the field
Definition: bvector.hh:401
A::size_type size_type
The type for the index access.
Definition: bvector.hh:410
BlockVector(std::initializer_list< B > const &l)
Construct from a std::initializer_list.
Definition: bvector.hh:437
size_type capacity() const
Get the capacity of the vector.
Definition: bvector.hh:488
BlockVector(size_type _n, S _capacity)
Make vector with _n components but preallocating capacity components.
Definition: bvector.hh:455
B block_type
export the type representing the components
Definition: bvector.hh:404
void swap(BlockVector &other) noexcept(noexcept(std::declval< BlockVector & >().storage_.swap(other.storage_)))
swap operation
Definition: bvector.hh:544
Imp::block_vector_unmanaged< B, A >::ConstIterator ConstIterator
make iterators available as types
Definition: bvector.hh:420
Provides the functions dot(a,b) := and dotT(a,b) := .
Implements a matrix constructed from a given type representing a field and compile-time given number ...
Type traits to determine the type of reals (when working with complex numbers)
Implements a vector constructed from a given type representing a field and a compile-time given size.
auto dot(const A &a, const B &b) -> typename std::enable_if< IsNumber< A >::value &&!IsVector< A >::value &&!std::is_same< typename FieldTraits< A >::field_type, typename FieldTraits< A >::real_type > ::value, decltype(conj(a) *b)>::type
computes the dot product for fundamental data types according to Petsc's VectDot function: dot(a,...
Definition: dotproduct.hh:42
#define DUNE_THROW(E, m)
Definition: exceptions.hh:218
auto max(ADLTag< 0 >, const V &v1, const V &v2)
implements binary Simd::max()
Definition: defaults.hh:81
Dune namespace.
Definition: alignedallocator.hh:13
Implements a scalar vector view wrapper around an existing scalar.
Traits for type conversions and type information.