16 #ifndef dealii__block_vector_base_h 17 #define dealii__block_vector_base_h 20 #include <deal.II/base/config.h> 21 #include <deal.II/base/exceptions.h> 22 #include <deal.II/base/subscriptor.h> 23 #include <deal.II/base/memory_consumption.h> 24 #include <deal.II/lac/exceptions.h> 25 #include <deal.II/lac/block_indices.h> 26 #include <deal.II/lac/vector.h> 32 DEAL_II_NAMESPACE_OPEN
58 template <
typename VectorType>
98 template <
typename VectorType>
112 namespace BlockVectorIterators
118 template <
class BlockVectorType,
bool Constness>
131 template <
class BlockVectorType>
138 typedef typename BlockVectorType::BlockType
Vector;
166 template <
class BlockVectorType>
173 typedef const typename BlockVectorType::BlockType
Vector;
213 template <
class BlockVectorType,
bool Constness>
215 public std::iterator<std::random_access_iterator_tag,
216 typename Types<BlockVectorType,Constness>::value_type>
239 typedef std::ptrdiff_t difference_type;
240 typedef typename BlockVectorType::reference reference;
314 dereference_type
operator [] (
const difference_type d)
const;
346 template <
bool OtherConstness>
353 template <
bool OtherConstness>
361 template <
bool OtherConstness>
362 bool operator < (const Iterator<BlockVectorType, OtherConstness> &i)
const;
367 template <
bool OtherConstness>
368 bool operator <= (const Iterator<BlockVectorType, OtherConstness> &i)
const;
373 template <
bool OtherConstness>
379 template <
bool OtherConstness>
385 template <
bool OtherConstness>
422 "Your program tried to compare iterators pointing to " 423 "different block vectors. There is no reasonable way " 434 "Constructing a non-const iterator from a const " 435 "iterator does not make sense.");
480 template <
typename,
bool>
525 template <
class VectorType>
544 typedef typename BlockType::value_type value_type;
545 typedef value_type *pointer;
546 typedef const value_type *const_pointer;
547 typedef ::internal::BlockVectorIterators::Iterator<BlockVectorBase,false>
iterator;
548 typedef ::internal::BlockVectorIterators::Iterator<BlockVectorBase,true>
const_iterator;
549 typedef typename BlockType::reference reference;
550 typedef typename BlockType::const_reference const_reference;
583 #ifdef DEAL_II_WITH_CXX11 624 block (
const unsigned int i);
630 block (
const unsigned int i)
const;
649 std::size_t
size ()
const;
694 value_type
operator() (
const size_type i)
const;
706 value_type
operator[] (
const size_type i)
const;
721 template <
typename OtherNumber>
723 std::vector<OtherNumber> &values)
const;
729 template <
typename ForwardIterator,
typename OutputIterator>
731 const ForwardIterator indices_end,
732 OutputIterator values_begin)
const;
746 #ifdef DEAL_II_WITH_CXX11 758 template <
class VectorType2>
772 template <
class VectorType2>
867 template <
typename Number>
868 void add (
const std::vector<size_type> &indices,
869 const std::vector<Number> &values);
875 template <
typename Number>
876 void add (
const std::vector<size_type> &indices,
884 template <
typename Number>
885 void add (
const size_type n_elements,
886 const size_type *indices,
887 const Number *values);
893 void add (
const value_type s);
926 void sadd (
const value_type s,
const value_type a,
933 void sadd (
const value_type s,
const value_type a,
952 template <
class BlockVector2>
953 void scale (
const BlockVector2 &v);
958 template <
class BlockVector2>
959 void equ (
const value_type a,
const BlockVector2 &V);
1001 template <
typename N,
bool C>
1002 friend class ::internal::BlockVectorIterators::Iterator;
1016 namespace BlockVectorIterators
1018 template <
class BlockVectorType,
bool Constness>
1021 Iterator (
const Iterator<BlockVectorType,Constness> &c)
1024 global_index (c.global_index),
1025 current_block (c.current_block),
1026 index_within_block (c.index_within_block),
1027 next_break_forward (c.next_break_forward),
1028 next_break_backward (c.next_break_backward)
1033 template <
class BlockVectorType,
bool Constness>
1035 Iterator<BlockVectorType,Constness>::
1036 Iterator (
const Iterator<BlockVectorType,!Constness> &c)
1039 global_index (c.global_index),
1040 current_block (c.current_block),
1041 index_within_block (c.index_within_block),
1042 next_break_forward (c.next_break_forward),
1043 next_break_backward (c.next_break_backward)
1049 #ifdef DEAL_II_WITH_CXX11 1050 static_assert(Constness ==
true,
1051 "Constructing a non-const iterator from a const iterator " 1052 "does not make sense.");
1054 Assert(Constness ==
true, ExcCastingAwayConstness());
1060 template <
class BlockVectorType,
bool Constness>
1062 Iterator<BlockVectorType,Constness>::
1064 const size_type global_index,
1065 const size_type current_block,
1066 const size_type index_within_block,
1067 const size_type next_break_forward,
1068 const size_type next_break_backward)
1071 global_index (global_index),
1072 current_block (current_block),
1073 index_within_block (index_within_block),
1074 next_break_forward (next_break_forward),
1075 next_break_backward (next_break_backward)
1081 template <
class BlockVectorType,
bool Constness>
1083 Iterator<BlockVectorType,Constness> &
1084 Iterator<BlockVectorType,Constness>::
1085 operator = (
const Iterator &c)
1088 global_index = c.global_index;
1089 index_within_block = c.index_within_block;
1090 current_block = c.current_block;
1091 next_break_forward = c.next_break_forward;
1092 next_break_backward = c.next_break_backward;
1099 template <
class BlockVectorType,
bool Constness>
1101 typename Iterator<BlockVectorType,Constness>::dereference_type
1102 Iterator<BlockVectorType,Constness>::operator * ()
const 1104 return parent->
block(current_block)(index_within_block);
1109 template <
class BlockVectorType,
bool Constness>
1111 typename Iterator<BlockVectorType,Constness>::dereference_type
1112 Iterator<BlockVectorType,Constness>::operator [] (
const difference_type d)
const 1119 if ((global_index+d >= next_break_backward) &&
1120 (global_index+d <= next_break_forward))
1121 return parent->block(current_block)(index_within_block +
d);
1130 return (*parent)(global_index+
d);
1135 template <
class BlockVectorType,
bool Constness>
1137 Iterator<BlockVectorType,Constness> &
1138 Iterator<BlockVectorType,Constness>::operator ++ ()
1146 template <
class BlockVectorType,
bool Constness>
1148 Iterator<BlockVectorType,Constness>
1149 Iterator<BlockVectorType,Constness>::operator ++ (
int)
1151 const Iterator old_value = *
this;
1158 template <
class BlockVectorType,
bool Constness>
1160 Iterator<BlockVectorType,Constness> &
1161 Iterator<BlockVectorType,Constness>::operator -- ()
1169 template <
class BlockVectorType,
bool Constness>
1171 Iterator<BlockVectorType,Constness>
1172 Iterator<BlockVectorType,Constness>::operator -- (
int)
1174 const Iterator old_value = *
this;
1181 template <
class BlockVectorType,
bool Constness>
1182 template <
bool OtherConstness>
1185 Iterator<BlockVectorType,Constness>::
1186 operator == (
const Iterator<BlockVectorType, OtherConstness> &i)
const 1188 Assert (parent == i.parent, ExcPointerToDifferentVectors());
1190 return (global_index == i.global_index);
1195 template <
class BlockVectorType,
bool Constness>
1196 template <
bool OtherConstness>
1199 Iterator<BlockVectorType,Constness>::
1200 operator != (
const Iterator<BlockVectorType, OtherConstness> &i)
const 1202 Assert (parent == i.parent, ExcPointerToDifferentVectors());
1204 return (global_index != i.global_index);
1209 template <
class BlockVectorType,
bool Constness>
1210 template <
bool OtherConstness>
1213 Iterator<BlockVectorType,Constness>::
1214 operator < (
const Iterator<BlockVectorType, OtherConstness> &i)
const 1216 Assert (parent == i.parent, ExcPointerToDifferentVectors());
1218 return (global_index < i.global_index);
1223 template <
class BlockVectorType,
bool Constness>
1224 template <
bool OtherConstness>
1227 Iterator<BlockVectorType,Constness>::
1228 operator <= (
const Iterator<BlockVectorType, OtherConstness> &i)
const 1230 Assert (parent == i.parent, ExcPointerToDifferentVectors());
1232 return (global_index <= i.global_index);
1237 template <
class BlockVectorType,
bool Constness>
1238 template <
bool OtherConstness>
1241 Iterator<BlockVectorType,Constness>::
1242 operator > (
const Iterator<BlockVectorType, OtherConstness> &i)
const 1244 Assert (parent == i.parent, ExcPointerToDifferentVectors());
1246 return (global_index > i.global_index);
1251 template <
class BlockVectorType,
bool Constness>
1252 template <
bool OtherConstness>
1255 Iterator<BlockVectorType,Constness>::
1256 operator >= (
const Iterator<BlockVectorType, OtherConstness> &i)
const 1258 Assert (parent == i.parent, ExcPointerToDifferentVectors());
1260 return (global_index >= i.global_index);
1265 template <
class BlockVectorType,
bool Constness>
1266 template <
bool OtherConstness>
1268 typename Iterator<BlockVectorType,Constness>::difference_type
1269 Iterator<BlockVectorType,Constness>::
1270 operator - (
const Iterator<BlockVectorType, OtherConstness> &i)
const 1272 Assert (parent == i.parent, ExcPointerToDifferentVectors());
1274 return (static_cast<signed int>(global_index) -
1275 static_cast<signed int>(i.global_index));
1280 template <
class BlockVectorType,
bool Constness>
1282 Iterator<BlockVectorType,Constness>
1283 Iterator<BlockVectorType,Constness>::
1284 operator + (
const difference_type &d)
const 1291 if ((global_index+d >= next_break_backward) &&
1292 (global_index+d <= next_break_forward))
1293 return Iterator (*parent, global_index+d, current_block,
1294 index_within_block+d,
1295 next_break_forward, next_break_backward);
1300 return Iterator (*parent, global_index+d);
1305 template <
class BlockVectorType,
bool Constness>
1307 Iterator<BlockVectorType,Constness>
1308 Iterator<BlockVectorType,Constness>::
1309 operator - (
const difference_type &d)
const 1316 if ((global_index-d >= next_break_backward) &&
1317 (global_index-d <= next_break_forward))
1318 return Iterator (*parent, global_index-d, current_block,
1319 index_within_block-d,
1320 next_break_forward, next_break_backward);
1325 return Iterator (*parent, global_index-d);
1330 template <
class BlockVectorType,
bool Constness>
1332 Iterator<BlockVectorType,Constness> &
1333 Iterator<BlockVectorType,Constness>::
1334 operator += (
const difference_type &d)
1341 if ((global_index+d >= next_break_backward) &&
1342 (global_index+d <= next_break_forward))
1345 index_within_block +=
d;
1351 *
this = Iterator (*parent, global_index+d);
1358 template <
class BlockVectorType,
bool Constness>
1360 Iterator<BlockVectorType,Constness> &
1361 Iterator<BlockVectorType,Constness>::
1362 operator -= (
const difference_type &d)
1369 if ((global_index-d >= next_break_backward) &&
1370 (global_index-d <= next_break_forward))
1373 index_within_block -=
d;
1379 *
this = Iterator (*parent, global_index-d);
1385 template <
class BlockVectorType,
bool Constness>
1386 Iterator<BlockVectorType,Constness>::
1388 const size_type global_index)
1391 global_index (global_index)
1399 if (global_index < parent.
size())
1401 const std::pair<size_type, size_type>
1403 current_block = indices.first;
1404 index_within_block = indices.second;
1416 this->global_index = parent.
size ();
1418 index_within_block = 0;
1419 next_break_backward = global_index;
1426 template <
class BlockVectorType,
bool Constness>
1428 Iterator<BlockVectorType,Constness>::move_forward ()
1430 if (global_index != next_break_forward)
1431 ++index_within_block;
1436 index_within_block = 0;
1441 next_break_backward = next_break_forward+1;
1444 if (current_block < parent->block_indices.size())
1460 template <
class BlockVectorType,
bool Constness>
1462 Iterator<BlockVectorType,Constness>::move_backward ()
1464 if (global_index != next_break_backward)
1465 --index_within_block;
1466 else if (current_block != 0)
1475 next_break_forward = next_break_backward-1;
1487 next_break_forward = 0;
1488 next_break_backward = 0;
1501 template <
class VectorType>
1508 template <
class VectorType>
1513 return block_indices.total_size();
1518 template <
class VectorType>
1527 for (
unsigned int b=0;
b<n_blocks(); ++
b)
1529 IndexSet x = block(b).locally_owned_elements();
1540 template <
class VectorType>
1545 return block_indices.size();
1549 template <
class VectorType>
1556 return components[i];
1561 template <
class VectorType>
1568 return components[i];
1573 template <
class VectorType>
1578 return block_indices;
1582 template <
class VectorType>
1587 std::vector<size_type> sizes (n_blocks());
1589 for (size_type i=0; i<n_blocks(); ++i)
1590 sizes[i] = block(i).size();
1592 block_indices.reinit(sizes);
1597 template <
class VectorType>
1602 for (
unsigned int i=0; i<n_blocks(); ++i)
1603 block(i).compress (operation);
1608 template <
class VectorType>
1613 return iterator(*
this, 0U);
1618 template <
class VectorType>
1623 return const_iterator(*
this, 0U);
1627 template <
class VectorType>
1632 return iterator(*
this, size());
1637 template <
class VectorType>
1642 return const_iterator(*
this, size());
1646 template <
class VectorType>
1650 (
const size_type global_index)
const 1652 const std::pair<size_type,size_type> local_index
1653 = block_indices.global_to_local (global_index);
1655 return components[local_index.first].in_local_range (global_index);
1659 template <
class VectorType>
1663 for (size_type i=0; i<n_blocks(); ++i)
1664 if (components[i].all_zero() ==
false)
1672 template <
class VectorType>
1676 for (size_type i=0; i<n_blocks(); ++i)
1677 if (components[i].is_non_negative() ==
false)
1685 template <
class VectorType>
1686 typename BlockVectorBase<VectorType>::value_type
1693 value_type
sum = 0.;
1694 for (size_type i=0; i<n_blocks(); ++i)
1701 template <
class VectorType>
1706 for (size_type i=0; i<n_blocks(); ++i)
1707 sum += components[i].norm_sqr();
1714 template <
class VectorType>
1715 typename BlockVectorBase<VectorType>::value_type
1718 value_type
sum = 0.;
1720 for (size_type i=0; i<n_blocks(); ++i)
1721 sum += components[i].mean_value() *
static_cast<double>(components[i].size());
1723 return sum/
static_cast<double>(size());
1728 template <
class VectorType>
1733 for (size_type i=0; i<n_blocks(); ++i)
1741 template <
class VectorType>
1745 return std::sqrt(norm_sqr());
1750 template <
class VectorType>
1755 for (size_type i=0; i<n_blocks(); ++i)
1757 value_type newval = components[i].linfty_norm();
1766 template <
class VectorType>
1767 typename BlockVectorBase<VectorType>::value_type
1769 add_and_dot (
const typename BlockVectorBase<VectorType>::value_type a,
1776 value_type
sum = 0.;
1777 for (size_type i=0; i<n_blocks(); ++i)
1785 template <
class VectorType>
1792 for (size_type i=0; i<n_blocks(); ++i)
1802 template <
class VectorType>
1809 for (size_type i=0; i<n_blocks(); ++i)
1818 template <
class VectorType>
1819 template <
typename Number>
1823 const std::vector<Number> &values)
1825 Assert (indices.size() == values.size(),
1827 add (indices.size(), &indices[0], &values[0]);
1832 template <
class VectorType>
1833 template <
typename Number>
1841 const size_type n_indices = indices.size();
1842 for (size_type i=0; i<n_indices; ++i)
1843 (*
this)(indices[i]) += values(i);
1848 template <
class VectorType>
1849 template <
typename Number>
1853 const size_type *indices,
1854 const Number *values)
1856 for (size_type i=0; i<n_indices; ++i)
1857 (*
this)(indices[i]) += values[i];
1862 template <
class VectorType>
1867 for (size_type i=0; i<n_blocks(); ++i)
1869 components[i].add(a);
1875 template <
class VectorType>
1883 template <
class VectorType>
1893 for (size_type i=0; i<n_blocks(); ++i)
1901 template <
class VectorType>
1913 Assert (n_blocks() ==
w.n_blocks(),
1917 for (size_type i=0; i<n_blocks(); ++i)
1919 components[i].add(a, v.
components[i], b,
w.components[i]);
1925 template <
class VectorType>
1935 for (size_type i=0; i<n_blocks(); ++i)
1943 template <
class VectorType>
1954 for (size_type i=0; i<n_blocks(); ++i)
1962 template <
class VectorType>
1975 Assert (n_blocks() ==
w.n_blocks(),
1978 for (size_type i=0; i<n_blocks(); ++i)
1980 components[i].sadd(x, a, v.
components[i], b,
w.components[i]);
1986 template <
class VectorType>
2002 Assert (n_blocks() ==
w.n_blocks(),
2007 for (size_type i=0; i<n_blocks(); ++i)
2016 template <
class VectorType>
2017 template <
class BlockVector2>
2020 Assert (n_blocks() == v.n_blocks(),
2022 for (size_type i=0; i<n_blocks(); ++i)
2023 components[i].
scale(v.block(i));
2028 template <
class VectorType>
2040 Assert (n_blocks() ==
w.n_blocks(),
2043 for (size_type i=0; i<n_blocks(); ++i)
2045 components[i].equ( a, v.
components[i], b,
w.components[i]);
2051 template <
class VectorType>
2062 template <
class VectorType>
2063 template <
class BlockVector2>
2065 const BlockVector2 &v)
2070 Assert (n_blocks() == v.n_blocks(),
2073 for (size_type i=0; i<n_blocks(); ++i)
2074 components[i].equ( a, v.components[i]);
2079 template <
class VectorType>
2082 for (size_type i=0; i<n_blocks(); ++i)
2083 block(i).update_ghost_values ();
2088 template <
class VectorType>
2095 for (size_type i=0; i<n_blocks(); ++i)
2102 template <
class VectorType>
2108 for (size_type i=0; i<n_blocks(); ++i)
2115 template <
class VectorType>
2116 template <
class VectorType2>
2122 for (size_type i=0; i<n_blocks(); ++i)
2130 template <
class VectorType>
2134 Assert (size() == v.size(),
2138 for (size_type b=0;
b<n_blocks(); ++
b)
2139 for (size_type i=0; i<block(b).size(); ++i, ++index_v)
2140 block(b)(i) = v(index_v);
2147 template <
class VectorType>
2148 template <
class VectorType2>
2156 for (size_type i=0; i<n_blocks(); ++i)
2165 template <
class VectorType>
2173 for (size_type i=0; i<n_blocks(); ++i)
2174 components[i] *= factor;
2181 template <
class VectorType>
2190 for (size_type i=0; i<n_blocks(); ++i)
2191 components[i] /= factor;
2197 template <
class VectorType>
2199 typename BlockVectorBase<VectorType>::value_type
2202 const std::pair<unsigned int,size_type> local_index
2203 = block_indices.global_to_local (i);
2204 return components[local_index.first](local_index.second);
2209 template <
class VectorType>
2211 typename BlockVectorBase<VectorType>::reference
2214 const std::pair<unsigned int,size_type> local_index
2215 = block_indices.global_to_local (i);
2216 return components[local_index.first](local_index.second);
2221 template <
class VectorType>
2223 typename BlockVectorBase<VectorType>::value_type
2226 return operator()(i);
2231 template <
class VectorType>
2233 typename BlockVectorBase<VectorType>::reference
2236 return operator()(i);
2241 template <
typename VectorType>
2242 template <
typename OtherNumber>
2245 std::vector<OtherNumber> &values)
const 2247 for (size_type i = 0; i < indices.size(); ++i)
2248 values[i] =
operator()(indices[i]);
2253 template <
typename VectorType>
2254 template <
typename ForwardIterator,
typename OutputIterator>
2257 const ForwardIterator indices_end,
2258 OutputIterator values_begin)
const 2260 while (indices_begin != indices_end)
2262 *values_begin = operator()(*indices_begin);
2270 DEAL_II_NAMESPACE_CLOSE
types::global_dof_index size_type
const types::global_dof_index invalid_size_type
static yes_type check_for_block_vector(const BlockVectorBase< T > *)
BaseClass::value_type value_type
bool operator>(const Iterator< BlockVectorType, OtherConstness > &i) const
value_type dereference_type
std::random_access_iterator_tag iterator_type
#define AssertDimension(dim1, dim2)
value_type operator[](const size_type i) const
void add(const std::vector< size_type > &indices, const std::vector< Number > &values)
real_type l2_norm() const
value_type operator*(const BlockVectorBase &V) const
dereference_type operator[](const difference_type d) const
bool operator==(const BlockVectorBase< VectorType2 > &v) const
void compress(::VectorOperation::values operation)
BlockVector::value_type value_type
bool in_local_range(const size_type global_index) const
void add_indices(const ForwardIterator &begin, const ForwardIterator &end)
static ::ExceptionBase & ExcCastingAwayConstness()
size_type block_size(const unsigned int i) const
static ::ExceptionBase & ExcIndexRange(int arg1, int arg2, int arg3)
static ::ExceptionBase & ExcDivideByZero()
Iterator operator+(const difference_type &d) const
BlockVectorBase & operator/=(const value_type factor)
value_type add_and_dot(const value_type a, const BlockVectorBase &V, const BlockVectorBase &W)
bool is_non_negative() const
void scale(const BlockVector2 &v)
Vector::reference dereference_type
BlockIndices block_indices
IndexSet locally_owned_elements() const
real_type norm_sqr() const
size_type next_break_forward
unsigned int global_dof_index
const BlockIndices & get_block_indices() const
#define Assert(cond, exc)
BlockType::real_type real_type
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
#define DeclExceptionMsg(Exception, defaulttext)
real_type l1_norm() const
void update_ghost_values() const
size_type local_to_global(const unsigned int block, const size_type index) const
bool operator==(const Iterator< BlockVectorType, OtherConstness > &i) const
double l1_norm(const Tensor< 2, dim, Number > &t)
static ::ExceptionBase & ExcDifferentBlockIndices()
const BlockVectorType BlockVector
SymmetricTensor< 2, dim, Number > d(const Tensor< 2, dim, Number > &F, const Tensor< 2, dim, Number > &dF_dt)
BlockVectorBase & operator+=(const BlockVectorBase &V)
std::vector< VectorType > components
SymmetricTensor< rank, dim, Number > sum(const SymmetricTensor< rank, dim, Number > &local, const MPI_Comm &mpi_communicator)
BlockVectorBase & operator*=(const value_type factor)
SymmetricTensor< 2, dim, Number > b(const Tensor< 2, dim, Number > &F)
Types< BlockVectorType, Constness >::value_type value_type
Tensor< 2, dim, Number > w(const Tensor< 2, dim, Number > &F, const Tensor< 2, dim, Number > &dF_dt)
Iterator & operator+=(const difference_type &d)
unsigned int current_block
const BlockVector::value_type value_type
std_cxx11::enable_if< std_cxx11::is_fundamental< T >::value, std::size_t >::type memory_consumption(const T &t)
BlockVectorType BlockVector
void extract_subvector_to(const std::vector< size_type > &indices, std::vector< OtherNumber > &values) const
void sadd(const value_type s, const BlockVectorBase &V)
std::size_t memory_consumption() const
BlockVectorType::BlockType Vector
unsigned int n_blocks() const
types::global_dof_index size_type
BlockVectorBase & operator-=(const BlockVectorBase &V)
bool operator!=(const Iterator< BlockVectorType, OtherConstness > &i) const
value_type operator()(const size_type i) const
const BlockVectorType::BlockType Vector
difference_type operator-(const Iterator< BlockVectorType, OtherConstness > &i) const
real_type linfty_norm() const
bool operator>=(const Iterator< BlockVectorType, OtherConstness > &i) const
BlockType & block(const unsigned int i)
BlockVectorBase & operator=(const value_type s)
static ::ExceptionBase & ExcPointerToDifferentVectors()
std::pair< unsigned int, size_type > global_to_local(const size_type i) const
#define AssertIsFinite(number)
void equ(const value_type a, const BlockVector2 &V)
Iterator & operator=(const Iterator &c)
Iterator & operator-=(const difference_type &d)
dereference_type operator*() const
static const bool supports_distributed_data
value_type mean_value() const
Types< BlockVectorType, Constness >::BlockVector BlockVector