16 #ifndef dealii_block_vector_base_h 17 #define dealii_block_vector_base_h 20 #include <deal.II/base/config.h> 22 #include <deal.II/base/exceptions.h> 23 #include <deal.II/base/memory_consumption.h> 24 #include <deal.II/base/numbers.h> 25 #include <deal.II/base/subscriptor.h> 27 #include <deal.II/lac/block_indices.h> 28 #include <deal.II/lac/exceptions.h> 29 #include <deal.II/lac/vector.h> 30 #include <deal.II/lac/vector_operation.h> 37 DEAL_II_NAMESPACE_OPEN
64 template <
typename VectorType>
104 template <
typename VectorType>
116 namespace BlockVectorIterators
122 template <
class BlockVectorType,
bool Constness>
134 template <
class BlockVectorType>
135 struct Types<BlockVectorType, false>
141 using Vector =
typename BlockVectorType::BlockType;
169 template <
class BlockVectorType>
176 using Vector =
const typename BlockVectorType::BlockType;
216 template <
class BlockVectorType,
bool Constness>
238 using difference_type = std::ptrdiff_t;
239 using reference =
typename BlockVectorType::reference;
242 using dereference_type =
307 dereference_type operator[](
const difference_type d)
const;
343 template <
bool OtherConstness>
351 template <
bool OtherConstness>
360 template <
bool OtherConstness>
362 operator<(const Iterator<BlockVectorType, OtherConstness> &i)
const;
367 template <
bool OtherConstness>
369 operator<=(const Iterator<BlockVectorType, OtherConstness> &i)
const;
374 template <
bool OtherConstness>
381 template <
bool OtherConstness>
388 template <
bool OtherConstness>
397 operator+(
const difference_type &d)
const;
404 operator-(
const difference_type &d)
const;
411 operator+=(
const difference_type &d);
418 operator-=(
const difference_type &d);
430 "Your program tried to compare iterators pointing to " 431 "different block vectors. There is no reasonable way " 480 template <
typename,
bool>
525 template <
class VectorType>
544 using value_type =
typename BlockType::value_type;
545 using pointer = value_type *;
546 using const_pointer =
const value_type *;
551 using reference =
typename BlockType::reference;
552 using const_reference =
typename BlockType::const_reference;
609 block(const
unsigned int i);
615 block(const
unsigned int i) const;
623 get_block_indices() const;
655 locally_owned_elements() const;
687 operator()(const size_type i) const;
693 operator()(const size_type i);
700 value_type operator[](const size_type i) const;
707 reference operator[](const size_type i);
724 template <typename OtherNumber>
726 extract_subvector_to(const
std::vector<size_type> &indices,
727 std::vector<OtherNumber> & values) const;
756 template <typename ForwardIterator, typename OutputIterator>
758 extract_subvector_to(ForwardIterator indices_begin,
759 const ForwardIterator indices_end,
760 OutputIterator values_begin) const;
767 operator=(const value_type s);
786 template <class VectorType2>
794 operator=(const VectorType &v);
800 template <class VectorType2>
864 add_and_dot(const value_type a,
873 in_local_range(const size_type global_index) const;
889 is_non_negative() const;
908 template <typename Number>
910 add(const
std::vector<size_type> &indices, const
std::vector<Number> &values);
916 template <typename Number>
918 add(const
std::vector<size_type> &indices, const Vector<Number> &values);
925 template <typename Number>
927 add(const size_type n_elements,
928 const size_type *indices,
929 const Number * values);
936 add(const value_type s);
948 add(const value_type a,
963 sadd(const value_type s, const value_type a, const
BlockVectorBase &V);
969 sadd(const value_type s,
979 sadd(const value_type s,
991 operator*=(const value_type factor);
997 operator/=(const value_type factor);
1003 template <class BlockVector2>
1005 scale(const BlockVector2 &v);
1010 template <class BlockVector2>
1012 equ(const value_type a, const BlockVector2 &V);
1018 equ(const value_type a,
1028 update_ghost_values() const;
1035 memory_consumption() const;
1041 std::vector<VectorType> components;
1052 template <typename N,
bool C>
1053 friend class ::
internal::BlockVectorIterators::Iterator;
1068 namespace BlockVectorIterators
1070 template <
class BlockVectorType,
bool Constness>
1071 inline Iterator<BlockVectorType, Constness>::Iterator(
1072 const Iterator<BlockVectorType, Constness> &c)
1074 , global_index(c.global_index)
1075 , current_block(c.current_block)
1076 , index_within_block(c.index_within_block)
1077 , next_break_forward(c.next_break_forward)
1078 , next_break_backward(c.next_break_backward)
1083 template <
class BlockVectorType,
bool Constness>
1084 inline Iterator<BlockVectorType, Constness>::Iterator(
1085 const Iterator<BlockVectorType, !Constness> &c)
1087 , global_index(c.global_index)
1088 , current_block(c.current_block)
1089 , index_within_block(c.index_within_block)
1090 , next_break_forward(c.next_break_forward)
1091 , next_break_backward(c.next_break_backward)
1096 static_assert(Constness ==
true,
1097 "Constructing a non-const iterator from a const iterator " 1098 "does not make sense.");
1103 template <
class BlockVectorType,
bool Constness>
1104 inline Iterator<BlockVectorType, Constness>::Iterator(
1106 const size_type global_index,
1107 const size_type current_block,
1108 const size_type index_within_block,
1109 const size_type next_break_forward,
1110 const size_type next_break_backward)
1112 , global_index(global_index)
1113 , current_block(current_block)
1114 , index_within_block(index_within_block)
1115 , next_break_forward(next_break_forward)
1116 , next_break_backward(next_break_backward)
1121 template <
class BlockVectorType,
bool Constness>
1122 inline Iterator<BlockVectorType, Constness> &
1123 Iterator<BlockVectorType, Constness>::operator=(
const Iterator &c)
1126 global_index = c.global_index;
1127 index_within_block = c.index_within_block;
1128 current_block = c.current_block;
1129 next_break_forward = c.next_break_forward;
1130 next_break_backward = c.next_break_backward;
1137 template <
class BlockVectorType,
bool Constness>
1138 inline typename Iterator<BlockVectorType, Constness>::dereference_type
1141 return parent->
block(current_block)(index_within_block);
1146 template <
class BlockVectorType,
bool Constness>
1147 inline typename Iterator<BlockVectorType, Constness>::dereference_type
1148 Iterator<BlockVectorType, Constness>::
1149 operator[](
const difference_type d)
const 1156 if ((global_index + d >= next_break_backward) &&
1157 (global_index + d <= next_break_forward))
1158 return parent->
block(current_block)(index_within_block + d);
1167 return (*parent)(global_index + d);
1172 template <
class BlockVectorType,
bool Constness>
1173 inline Iterator<BlockVectorType, Constness> &
1174 Iterator<BlockVectorType, Constness>::operator++()
1182 template <
class BlockVectorType,
bool Constness>
1183 inline Iterator<BlockVectorType, Constness>
1184 Iterator<BlockVectorType, Constness>::operator++(
int)
1186 const Iterator old_value = *
this;
1193 template <
class BlockVectorType,
bool Constness>
1194 inline Iterator<BlockVectorType, Constness> &
1195 Iterator<BlockVectorType, Constness>::operator--()
1203 template <
class BlockVectorType,
bool Constness>
1204 inline Iterator<BlockVectorType, Constness>
1205 Iterator<BlockVectorType, Constness>::operator--(
int)
1207 const Iterator old_value = *
this;
1214 template <
class BlockVectorType,
bool Constness>
1215 template <
bool OtherConstness>
1217 Iterator<BlockVectorType, Constness>::
1218 operator==(
const Iterator<BlockVectorType, OtherConstness> &i)
const 1220 Assert(parent == i.parent, ExcPointerToDifferentVectors());
1222 return (global_index == i.global_index);
1227 template <
class BlockVectorType,
bool Constness>
1228 template <
bool OtherConstness>
1230 Iterator<BlockVectorType, Constness>::
1231 operator!=(
const Iterator<BlockVectorType, OtherConstness> &i)
const 1233 Assert(parent == i.parent, ExcPointerToDifferentVectors());
1235 return (global_index != i.global_index);
1240 template <
class BlockVectorType,
bool Constness>
1241 template <
bool OtherConstness>
1243 Iterator<BlockVectorType, Constness>::
1244 operator<(
const Iterator<BlockVectorType, OtherConstness> &i)
const 1246 Assert(parent == i.parent, ExcPointerToDifferentVectors());
1248 return (global_index < i.global_index);
1253 template <
class BlockVectorType,
bool Constness>
1254 template <
bool OtherConstness>
1256 Iterator<BlockVectorType, Constness>::
1257 operator<=(
const Iterator<BlockVectorType, OtherConstness> &i)
const 1259 Assert(parent == i.parent, ExcPointerToDifferentVectors());
1261 return (global_index <= i.global_index);
1266 template <
class BlockVectorType,
bool Constness>
1267 template <
bool OtherConstness>
1269 Iterator<BlockVectorType, Constness>::
1270 operator>(
const Iterator<BlockVectorType, OtherConstness> &i)
const 1272 Assert(parent == i.parent, ExcPointerToDifferentVectors());
1274 return (global_index > i.global_index);
1279 template <
class BlockVectorType,
bool Constness>
1280 template <
bool OtherConstness>
1282 Iterator<BlockVectorType, Constness>::
1283 operator>=(
const Iterator<BlockVectorType, OtherConstness> &i)
const 1285 Assert(parent == i.parent, ExcPointerToDifferentVectors());
1287 return (global_index >= i.global_index);
1292 template <
class BlockVectorType,
bool Constness>
1293 template <
bool OtherConstness>
1294 inline typename Iterator<BlockVectorType, Constness>::difference_type
1296 operator-(
const Iterator<BlockVectorType, OtherConstness> &i)
const 1298 Assert(parent == i.parent, ExcPointerToDifferentVectors());
1300 return (static_cast<signed int>(global_index) -
1301 static_cast<signed int>(i.global_index));
1306 template <
class BlockVectorType,
bool Constness>
1307 inline 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,
1321 index_within_block + d,
1323 next_break_backward);
1328 return Iterator(*parent, global_index + d);
1333 template <
class BlockVectorType,
bool Constness>
1334 inline Iterator<BlockVectorType, Constness>
1336 operator-(
const difference_type &d)
const 1343 if ((global_index - d >= next_break_backward) &&
1344 (global_index - d <= next_break_forward))
1345 return Iterator(*parent,
1348 index_within_block - d,
1350 next_break_backward);
1355 return Iterator(*parent, global_index - d);
1360 template <
class BlockVectorType,
bool Constness>
1361 inline Iterator<BlockVectorType, Constness> &
1362 Iterator<BlockVectorType, Constness>::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);
1386 template <
class BlockVectorType,
bool Constness>
1387 inline Iterator<BlockVectorType, Constness> &
1388 Iterator<BlockVectorType, Constness>::operator-=(
const difference_type &d)
1395 if ((global_index - d >= next_break_backward) &&
1396 (global_index - d <= next_break_forward))
1399 index_within_block -= d;
1405 *
this = Iterator(*parent, global_index - d);
1411 template <
class BlockVectorType,
bool Constness>
1412 Iterator<BlockVectorType, Constness>::Iterator(
BlockVector & parent,
1413 const size_type global_index)
1415 , global_index(global_index)
1423 if (global_index < parent.
size())
1425 const std::pair<size_type, size_type> indices =
1427 current_block = indices.first;
1428 index_within_block = indices.second;
1430 next_break_backward =
1432 next_break_forward =
1440 this->global_index = parent.
size();
1442 index_within_block = 0;
1443 next_break_backward = global_index;
1450 template <
class BlockVectorType,
bool Constness>
1452 Iterator<BlockVectorType, Constness>::move_forward()
1454 if (global_index != next_break_forward)
1455 ++index_within_block;
1460 index_within_block = 0;
1465 next_break_backward = next_break_forward + 1;
1468 if (current_block < parent->block_indices.
size())
1469 next_break_forward +=
1484 template <
class BlockVectorType,
bool Constness>
1486 Iterator<BlockVectorType, Constness>::move_backward()
1488 if (global_index != next_break_backward)
1489 --index_within_block;
1490 else if (current_block != 0)
1495 index_within_block =
1500 next_break_forward = next_break_backward - 1;
1503 next_break_backward -=
1512 next_break_forward = 0;
1513 next_break_backward = 0;
1526 template <
class VectorType>
1535 template <
class VectorType>
1543 for (
unsigned int b = 0; b < n_blocks(); ++b)
1545 IndexSet x = block(b).locally_owned_elements();
1556 template <
class VectorType>
1560 return block_indices.
size();
1564 template <
class VectorType>
1570 return components[i];
1575 template <
class VectorType>
1581 return components[i];
1586 template <
class VectorType>
1590 return block_indices;
1594 template <
class VectorType>
1598 std::vector<size_type> sizes(n_blocks());
1600 for (size_type i = 0; i < n_blocks(); ++i)
1601 sizes[i] = block(i).size();
1603 block_indices.
reinit(sizes);
1608 template <
class VectorType>
1613 for (
unsigned int i = 0; i < n_blocks(); ++i)
1614 block(i).compress(operation);
1619 template <
class VectorType>
1628 template <
class VectorType>
1636 template <
class VectorType>
1645 template <
class VectorType>
1653 template <
class VectorType>
1657 const std::pair<size_type, size_type> local_index =
1660 return components[local_index.first].in_local_range(global_index);
1664 template <
class VectorType>
1668 for (size_type i = 0; i < n_blocks(); ++i)
1669 if (components[i].all_zero() ==
false)
1677 template <
class VectorType>
1681 for (size_type i = 0; i < n_blocks(); ++i)
1682 if (components[i].is_non_negative() ==
false)
1690 template <
class VectorType>
1697 value_type sum = 0.;
1698 for (size_type i = 0; i < n_blocks(); ++i)
1705 template <
class VectorType>
1710 for (size_type i = 0; i < n_blocks(); ++i)
1711 sum += components[i].norm_sqr();
1718 template <
class VectorType>
1719 typename BlockVectorBase<VectorType>::value_type
1722 value_type sum = 0.;
1725 for (size_type i = 0; i < n_blocks(); ++i)
1726 sum += components[i].mean_value() *
1728 components[i].size()));
1735 template <
class VectorType>
1740 for (size_type i = 0; i < n_blocks(); ++i)
1741 sum += components[i].l1_norm();
1748 template <
class VectorType>
1752 return std::sqrt(norm_sqr());
1757 template <
class VectorType>
1762 for (size_type i = 0; i < n_blocks(); ++i)
1764 value_type newval = components[i].linfty_norm();
1773 template <
class VectorType>
1774 typename BlockVectorBase<VectorType>::value_type
1776 const typename BlockVectorBase<VectorType>::value_type a,
1783 value_type sum = 0.;
1784 for (size_type i = 0; i < n_blocks(); ++i)
1792 template <
class VectorType>
1799 for (size_type i = 0; i < n_blocks(); ++i)
1809 template <
class VectorType>
1816 for (size_type i = 0; i < n_blocks(); ++i)
1825 template <
class VectorType>
1826 template <
typename Number>
1829 const std::vector<Number> & values)
1831 Assert(indices.size() == values.size(),
1833 add(indices.size(), indices.data(), values.data());
1838 template <
class VectorType>
1839 template <
typename Number>
1842 const Vector<Number> & values)
1844 Assert(indices.size() == values.size(),
1846 const size_type n_indices = indices.size();
1847 for (size_type i = 0; i < n_indices; ++i)
1848 (*
this)(indices[i]) += values(i);
1853 template <
class VectorType>
1854 template <
typename Number>
1857 const size_type *indices,
1858 const Number * values)
1860 for (size_type i = 0; i < n_indices; ++i)
1861 (*
this)(indices[i]) += values[i];
1866 template <
class VectorType>
1872 for (size_type i = 0; i < n_blocks(); ++i)
1874 components[i].add(a);
1880 template <
class VectorType>
1890 for (size_type i = 0; i < n_blocks(); ++i)
1898 template <
class VectorType>
1914 for (size_type i = 0; i < n_blocks(); ++i)
1922 template <
class VectorType>
1932 for (size_type i = 0; i < n_blocks(); ++i)
1940 template <
class VectorType>
1952 for (size_type i = 0; i < n_blocks(); ++i)
1960 template <
class VectorType>
1977 for (size_type i = 0; i < n_blocks(); ++i)
1985 template <
class VectorType>
2007 for (size_type i = 0; i < n_blocks(); ++i)
2016 template <
class VectorType>
2017 template <
class BlockVector2>
2021 Assert(n_blocks() == v.n_blocks(),
2023 for (size_type i = 0; i < n_blocks(); ++i)
2024 components[i].scale(v.block(i));
2029 template <
class VectorType>
2044 for (size_type i = 0; i < n_blocks(); ++i)
2052 template <
class VectorType>
2062 template <
class VectorType>
2063 template <
class BlockVector2>
2069 Assert(n_blocks() == v.n_blocks(),
2072 for (size_type i = 0; i < n_blocks(); ++i)
2073 components[i].equ(a, v.components[i]);
2078 template <
class VectorType>
2082 for (size_type i = 0; i < n_blocks(); ++i)
2083 block(i).update_ghost_values();
2088 template <
class VectorType>
2094 for (size_type i = 0; i < n_blocks(); ++i)
2101 template <
class VectorType>
2107 for (size_type i = 0; i < n_blocks(); ++i)
2114 template <
class VectorType>
2115 template <
class VectorType2>
2121 for (size_type i = 0; i < n_blocks(); ++i)
2129 template <
class VectorType>
2135 size_type index_v = 0;
2136 for (size_type b = 0; b < n_blocks(); ++b)
2137 for (size_type i = 0; i < block(b).size(); ++i, ++index_v)
2138 block(b)(i) = v(index_v);
2145 template <
class VectorType>
2146 template <
class VectorType2>
2153 for (size_type i = 0; i < n_blocks(); ++i)
2162 template <
class VectorType>
2168 for (size_type i = 0; i < n_blocks(); ++i)
2169 components[i] *= factor;
2176 template <
class VectorType>
2183 for (size_type i = 0; i < n_blocks(); ++i)
2184 components[i] /= factor;
2190 template <
class VectorType>
2191 inline typename BlockVectorBase<VectorType>::value_type
2194 const std::pair<unsigned int, size_type> local_index =
2196 return components[local_index.first](local_index.second);
2201 template <
class VectorType>
2202 inline typename BlockVectorBase<VectorType>::reference
2205 const std::pair<unsigned int, size_type> local_index =
2207 return components[local_index.first](local_index.second);
2212 template <
class VectorType>
2213 inline typename BlockVectorBase<VectorType>::value_type
2216 return operator()(i);
2221 template <
class VectorType>
2222 inline typename BlockVectorBase<VectorType>::reference
2225 return operator()(i);
2230 template <
typename VectorType>
2231 template <
typename OtherNumber>
2234 const std::vector<size_type> &indices,
2235 std::vector<OtherNumber> & values)
const 2237 for (size_type i = 0; i < indices.size(); ++i)
2238 values[i] =
operator()(indices[i]);
2243 template <
typename VectorType>
2244 template <
typename ForwardIterator,
typename OutputIterator>
2247 ForwardIterator indices_begin,
2248 const ForwardIterator indices_end,
2249 OutputIterator values_begin)
const 2251 while (indices_begin != indices_end)
2253 *values_begin = operator()(*indices_begin);
2261 DEAL_II_NAMESPACE_CLOSE
const types::global_dof_index invalid_size_type
static yes_type check_for_block_vector(const BlockVectorBase< T > *)
#define AssertDimension(dim1, dim2)
bool operator==(const BlockVectorBase< VectorType2 > &v) const
void add(const std::vector< size_type > &indices, const std::vector< Number > &values)
void compress(::VectorOperation::values operation)
real_type linfty_norm() const
typename Types< BlockVectorType, Constness >::value_type value_type
typename Vector::reference dereference_type
void add_indices(const ForwardIterator &begin, const ForwardIterator &end)
real_type norm_sqr() const
unsigned int n_blocks() const
SymmetricTensor< rank_, dim, typename ProductType< Number, OtherNumber >::type > operator+(const SymmetricTensor< rank_, dim, Number > &left, const SymmetricTensor< rank_, dim, OtherNumber > &right)
static::ExceptionBase & ExcIndexRange(int arg1, int arg2, int arg3)
SymmetricTensor< rank_, dim, Number > operator*(const SymmetricTensor< rank_, dim, Number > &t, const Number &factor)
static::ExceptionBase & ExcDivideByZero()
value_type operator[](const size_type i) const
unsigned long long int global_dof_index
BlockVectorBase & operator/=(const value_type factor)
value_type add_and_dot(const value_type a, const BlockVectorBase &V, const BlockVectorBase &W)
void scale(const BlockVector2 &v)
bool is_non_negative() const
std::random_access_iterator_tag iterator_category
value_type operator()(const size_type i) const
BlockIndices block_indices
size_type block_start(const unsigned int i) const
bool in_local_range(const size_type global_index) const
size_type next_break_forward
typename BlockVector::value_type value_type
#define Assert(cond, exc)
void update_ghost_values() const
static::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
const BlockIndices & get_block_indices() const
void reinit(const unsigned int n_blocks, const size_type n_elements_per_block)
types::global_dof_index size_type
#define DeclExceptionMsg(Exception, defaulttext)
const typename BlockVector::value_type value_type
size_type total_size() const
value_type mean_value() const
static::ExceptionBase & ExcDifferentBlockIndices()
std::pair< unsigned int, size_type > global_to_local(const size_type i) const
BlockVectorBase & operator+=(const BlockVectorBase &V)
std::vector< VectorType > components
size_type block_size(const unsigned int i) const
BlockVectorBase & operator*=(const value_type factor)
Vector< Number > BlockType
unsigned int current_block
void sadd(const value_type s, const BlockVectorBase &V)
BlockVectorBase & operator-=(const BlockVectorBase &V)
typename BlockType::real_type real_type
value_type operator*(const BlockVectorBase &V) const
real_type l2_norm() const
IndexSet locally_owned_elements() const
unsigned int size() const
BlockType & block(const unsigned int i)
size_type local_to_global(const unsigned int block, const size_type index) const
SymmetricTensor< rank_, dim, typename ProductType< Number, OtherNumber >::type > operator-(const SymmetricTensor< rank_, dim, Number > &left, const SymmetricTensor< rank_, dim, OtherNumber > &right)
value_type dereference_type
BlockVectorBase & operator=(const value_type s)
void extract_subvector_to(const std::vector< size_type > &indices, std::vector< OtherNumber > &values) const
#define AssertIsFinite(number)
real_type l1_norm() const
void equ(const value_type a, const BlockVector2 &V)
std::enable_if< std::is_fundamental< T >::value, std::size_t >::type memory_consumption(const T &t)
std::size_t memory_consumption() const
typename BaseClass::value_type value_type