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>
105 template <
typename VectorType>
117 namespace BlockVectorIterators
136 template <
class BlockVectorType,
bool Constness>
151 typename std::conditional<Constness,
152 const typename BlockVectorType::value_type,
153 typename BlockVectorType::value_type>::type;
161 using difference_type = std::ptrdiff_t;
162 using reference =
typename BlockVectorType::reference;
165 using dereference_type =
typename std::conditional<
168 typename BlockVectorType::BlockType::reference>::type;
175 conditional<Constness, const BlockVectorType, BlockVectorType>::type;
232 dereference_type
operator[](
const difference_type d)
const;
268 template <
bool OtherConstness>
276 template <
bool OtherConstness>
285 template <
bool OtherConstness>
287 operator<(const Iterator<BlockVectorType, OtherConstness> &i)
const;
292 template <
bool OtherConstness>
294 operator<=(const Iterator<BlockVectorType, OtherConstness> &i)
const;
299 template <
bool OtherConstness>
306 template <
bool OtherConstness>
313 template <
bool OtherConstness>
322 operator+(
const difference_type &d)
const;
329 operator-(
const difference_type &d)
const;
355 "Your program tried to compare iterators pointing to " 356 "different block vectors. There is no reasonable way " 405 template <
typename,
bool>
450 template <
class VectorType>
469 using value_type =
typename BlockType::value_type;
470 using pointer = value_type *;
471 using const_pointer =
const value_type *;
476 using reference =
typename BlockType::reference;
477 using const_reference =
typename BlockType::const_reference;
534 block(const
unsigned int i);
540 block(const
unsigned int i) const;
612 operator()(const size_type i) const;
618 operator()(const size_type i);
625 value_type operator[](const size_type i) const;
632 reference operator[](const size_type i);
649 template <typename OtherNumber>
652 std::vector<OtherNumber> & values) const;
681 template <typename ForwardIterator, typename OutputIterator>
684 const ForwardIterator indices_end,
685 OutputIterator values_begin) const;
692 operator=(const value_type s);
711 template <class VectorType2>
719 operator=(const VectorType &v);
725 template <class VectorType2>
833 template <typename Number>
835 add(const
std::vector<size_type> &indices, const
std::vector<Number> &values);
841 template <typename Number>
843 add(const
std::vector<size_type> &indices, const
Vector<Number> &values);
850 template <typename Number>
852 add(const size_type n_elements,
853 const size_type *indices,
854 const Number * values);
861 add(const value_type s);
873 add(const value_type a,
894 sadd(const value_type s,
904 sadd(const value_type s,
916 operator*=(const value_type factor);
922 operator/=(const value_type factor);
928 template <class BlockVector2>
930 scale(const BlockVector2 &v);
935 template <class BlockVector2>
937 equ(const value_type a, const BlockVector2 &V);
943 equ(const value_type a,
977 template <typename N,
bool C>
978 friend class ::
internal::BlockVectorIterators::Iterator;
993 namespace BlockVectorIterators
995 template <
class BlockVectorType,
bool Constness>
996 inline Iterator<BlockVectorType, Constness>::Iterator(
997 const Iterator<BlockVectorType, Constness> &c)
999 , global_index(c.global_index)
1000 , current_block(c.current_block)
1001 , index_within_block(c.index_within_block)
1002 , next_break_forward(c.next_break_forward)
1003 , next_break_backward(c.next_break_backward)
1008 template <
class BlockVectorType,
bool Constness>
1009 inline Iterator<BlockVectorType, Constness>::Iterator(
1010 const Iterator<BlockVectorType, !Constness> &c)
1012 , global_index(c.global_index)
1013 , current_block(c.current_block)
1014 , index_within_block(c.index_within_block)
1015 , next_break_forward(c.next_break_forward)
1016 , next_break_backward(c.next_break_backward)
1021 static_assert(Constness ==
true,
1022 "Constructing a non-const iterator from a const iterator " 1023 "does not make sense.");
1028 template <
class BlockVectorType,
bool Constness>
1029 inline Iterator<BlockVectorType, Constness>::Iterator(
1031 const size_type global_index,
1032 const size_type current_block,
1033 const size_type index_within_block,
1034 const size_type next_break_forward,
1035 const size_type next_break_backward)
1037 , global_index(global_index)
1038 , current_block(current_block)
1039 , index_within_block(index_within_block)
1040 , next_break_forward(next_break_forward)
1041 , next_break_backward(next_break_backward)
1046 template <
class BlockVectorType,
bool Constness>
1047 inline Iterator<BlockVectorType, Constness> &
1048 Iterator<BlockVectorType, Constness>::operator=(
const Iterator &c)
1051 global_index = c.global_index;
1052 index_within_block = c.index_within_block;
1053 current_block = c.current_block;
1054 next_break_forward = c.next_break_forward;
1055 next_break_backward = c.next_break_backward;
1062 template <
class BlockVectorType,
bool Constness>
1063 inline typename Iterator<BlockVectorType, Constness>::dereference_type
1066 return parent->
block(current_block)(index_within_block);
1071 template <
class BlockVectorType,
bool Constness>
1072 inline typename Iterator<BlockVectorType, Constness>::dereference_type
1073 Iterator<BlockVectorType, Constness>::
1074 operator[](
const difference_type d)
const 1081 if ((global_index + d >= next_break_backward) &&
1082 (global_index + d <= next_break_forward))
1083 return parent->
block(current_block)(index_within_block + d);
1092 return (*parent)(global_index + d);
1097 template <
class BlockVectorType,
bool Constness>
1098 inline Iterator<BlockVectorType, Constness> &
1099 Iterator<BlockVectorType, Constness>::operator++()
1107 template <
class BlockVectorType,
bool Constness>
1108 inline Iterator<BlockVectorType, Constness>
1109 Iterator<BlockVectorType, Constness>::operator++(
int)
1111 const Iterator old_value = *
this;
1118 template <
class BlockVectorType,
bool Constness>
1119 inline Iterator<BlockVectorType, Constness> &
1120 Iterator<BlockVectorType, Constness>::operator--()
1128 template <
class BlockVectorType,
bool Constness>
1129 inline Iterator<BlockVectorType, Constness>
1130 Iterator<BlockVectorType, Constness>::operator--(
int)
1132 const Iterator old_value = *
this;
1139 template <
class BlockVectorType,
bool Constness>
1140 template <
bool OtherConstness>
1142 Iterator<BlockVectorType, Constness>::
1143 operator==(
const Iterator<BlockVectorType, OtherConstness> &i)
const 1145 Assert(parent == i.parent, ExcPointerToDifferentVectors());
1147 return (global_index == i.global_index);
1152 template <
class BlockVectorType,
bool Constness>
1153 template <
bool OtherConstness>
1155 Iterator<BlockVectorType, Constness>::
1156 operator!=(
const Iterator<BlockVectorType, OtherConstness> &i)
const 1158 Assert(parent == i.parent, ExcPointerToDifferentVectors());
1160 return (global_index != i.global_index);
1165 template <
class BlockVectorType,
bool Constness>
1166 template <
bool OtherConstness>
1168 Iterator<BlockVectorType, Constness>::
1169 operator<(
const Iterator<BlockVectorType, OtherConstness> &i)
const 1171 Assert(parent == i.parent, ExcPointerToDifferentVectors());
1173 return (global_index < i.global_index);
1178 template <
class BlockVectorType,
bool Constness>
1179 template <
bool OtherConstness>
1181 Iterator<BlockVectorType, Constness>::
1182 operator<=(
const Iterator<BlockVectorType, OtherConstness> &i)
const 1184 Assert(parent == i.parent, ExcPointerToDifferentVectors());
1186 return (global_index <= i.global_index);
1191 template <
class BlockVectorType,
bool Constness>
1192 template <
bool OtherConstness>
1194 Iterator<BlockVectorType, Constness>::
1195 operator>(
const Iterator<BlockVectorType, OtherConstness> &i)
const 1197 Assert(parent == i.parent, ExcPointerToDifferentVectors());
1199 return (global_index > i.global_index);
1204 template <
class BlockVectorType,
bool Constness>
1205 template <
bool OtherConstness>
1207 Iterator<BlockVectorType, Constness>::
1208 operator>=(
const Iterator<BlockVectorType, OtherConstness> &i)
const 1210 Assert(parent == i.parent, ExcPointerToDifferentVectors());
1212 return (global_index >= i.global_index);
1217 template <
class BlockVectorType,
bool Constness>
1218 template <
bool OtherConstness>
1219 inline typename Iterator<BlockVectorType, Constness>::difference_type
1221 operator-(
const Iterator<BlockVectorType, OtherConstness> &i)
const 1223 Assert(parent == i.parent, ExcPointerToDifferentVectors());
1225 return (static_cast<signed int>(global_index) -
1226 static_cast<signed int>(i.global_index));
1231 template <
class BlockVectorType,
bool Constness>
1232 inline Iterator<BlockVectorType, Constness>
1234 operator+(
const difference_type &d)
const 1241 if ((global_index + d >= next_break_backward) &&
1242 (global_index + d <= next_break_forward))
1243 return Iterator(*parent,
1246 index_within_block + d,
1248 next_break_backward);
1253 return Iterator(*parent, global_index + d);
1258 template <
class BlockVectorType,
bool Constness>
1259 inline Iterator<BlockVectorType, Constness>
1261 operator-(
const difference_type &d)
const 1268 if ((global_index - d >= next_break_backward) &&
1269 (global_index - d <= next_break_forward))
1270 return Iterator(*parent,
1273 index_within_block - d,
1275 next_break_backward);
1280 return Iterator(*parent, global_index - d);
1285 template <
class BlockVectorType,
bool Constness>
1286 inline Iterator<BlockVectorType, Constness> &
1287 Iterator<BlockVectorType, Constness>::operator+=(
const difference_type &d)
1294 if ((global_index + d >= next_break_backward) &&
1295 (global_index + d <= next_break_forward))
1298 index_within_block += d;
1304 *
this = Iterator(*parent, global_index + d);
1311 template <
class BlockVectorType,
bool Constness>
1312 inline Iterator<BlockVectorType, Constness> &
1313 Iterator<BlockVectorType, Constness>::operator-=(
const difference_type &d)
1320 if ((global_index - d >= next_break_backward) &&
1321 (global_index - d <= next_break_forward))
1324 index_within_block -= d;
1330 *
this = Iterator(*parent, global_index - d);
1336 template <
class BlockVectorType,
bool Constness>
1337 Iterator<BlockVectorType, Constness>::Iterator(
BlockVector & parent,
1338 const size_type global_index)
1340 , global_index(global_index)
1348 if (global_index < parent.
size())
1350 const std::pair<size_type, size_type> indices =
1352 current_block = indices.first;
1353 index_within_block = indices.second;
1355 next_break_backward =
1357 next_break_forward =
1365 this->global_index = parent.
size();
1367 index_within_block = 0;
1368 next_break_backward = global_index;
1375 template <
class BlockVectorType,
bool Constness>
1377 Iterator<BlockVectorType, Constness>::move_forward()
1379 if (global_index != next_break_forward)
1380 ++index_within_block;
1385 index_within_block = 0;
1390 next_break_backward = next_break_forward + 1;
1394 next_break_forward +=
1409 template <
class BlockVectorType,
bool Constness>
1411 Iterator<BlockVectorType, Constness>::move_backward()
1413 if (global_index != next_break_backward)
1414 --index_within_block;
1415 else if (current_block != 0)
1420 index_within_block =
1425 next_break_forward = next_break_backward - 1;
1428 next_break_backward -=
1437 next_break_forward = 0;
1438 next_break_backward = 0;
1451 template <
class VectorType>
1460 template <
class VectorType>
1468 for (
unsigned int b = 0;
b <
n_blocks(); ++
b)
1481 template <
class VectorType>
1489 template <
class VectorType>
1500 template <
class VectorType>
1511 template <
class VectorType>
1519 template <
class VectorType>
1523 std::vector<size_type> sizes(
n_blocks());
1525 for (size_type i = 0; i <
n_blocks(); ++i)
1526 sizes[i] =
block(i).size();
1533 template <
class VectorType>
1538 for (
unsigned int i = 0; i <
n_blocks(); ++i)
1539 block(i).compress(operation);
1544 template <
class VectorType>
1548 return iterator(*
this, 0U);
1553 template <
class VectorType>
1557 return const_iterator(*
this, 0U);
1561 template <
class VectorType>
1565 return iterator(*
this,
size());
1570 template <
class VectorType>
1574 return const_iterator(*
this,
size());
1578 template <
class VectorType>
1582 const std::pair<size_type, size_type> local_index =
1585 return components[local_index.first].in_local_range(global_index);
1589 template <
class VectorType>
1593 for (size_type i = 0; i <
n_blocks(); ++i)
1602 template <
class VectorType>
1606 for (size_type i = 0; i <
n_blocks(); ++i)
1615 template <
class VectorType>
1622 value_type
sum = 0.;
1623 for (size_type i = 0; i <
n_blocks(); ++i)
1630 template <
class VectorType>
1635 for (size_type i = 0; i <
n_blocks(); ++i)
1643 template <
class VectorType>
1644 typename BlockVectorBase<VectorType>::value_type
1647 value_type
sum = 0.;
1650 for (size_type i = 0; i <
n_blocks(); ++i)
1660 template <
class VectorType>
1665 for (size_type i = 0; i <
n_blocks(); ++i)
1673 template <
class VectorType>
1682 template <
class VectorType>
1687 for (size_type i = 0; i <
n_blocks(); ++i)
1689 value_type newval =
components[i].linfty_norm();
1698 template <
class VectorType>
1699 typename BlockVectorBase<VectorType>::value_type
1701 const typename BlockVectorBase<VectorType>::value_type a,
1708 value_type
sum = 0.;
1709 for (size_type i = 0; i <
n_blocks(); ++i)
1717 template <
class VectorType>
1724 for (size_type i = 0; i <
n_blocks(); ++i)
1734 template <
class VectorType>
1741 for (size_type i = 0; i <
n_blocks(); ++i)
1750 template <
class VectorType>
1751 template <
typename Number>
1754 const std::vector<Number> & values)
1756 Assert(indices.size() == values.size(),
1758 add(indices.size(), indices.data(), values.data());
1763 template <
class VectorType>
1764 template <
typename Number>
1767 const Vector<Number> & values)
1769 Assert(indices.size() == values.size(),
1771 const size_type n_indices = indices.size();
1772 for (size_type i = 0; i < n_indices; ++i)
1773 (*
this)(indices[i]) += values(i);
1778 template <
class VectorType>
1779 template <
typename Number>
1782 const size_type *indices,
1783 const Number * values)
1785 for (size_type i = 0; i < n_indices; ++i)
1786 (*
this)(indices[i]) += values[i];
1791 template <
class VectorType>
1797 for (size_type i = 0; i <
n_blocks(); ++i)
1805 template <
class VectorType>
1815 for (size_type i = 0; i <
n_blocks(); ++i)
1823 template <
class VectorType>
1839 for (size_type i = 0; i <
n_blocks(); ++i)
1847 template <
class VectorType>
1857 for (size_type i = 0; i <
n_blocks(); ++i)
1865 template <
class VectorType>
1877 for (size_type i = 0; i <
n_blocks(); ++i)
1885 template <
class VectorType>
1902 for (size_type i = 0; i <
n_blocks(); ++i)
1910 template <
class VectorType>
1932 for (size_type i = 0; i <
n_blocks(); ++i)
1941 template <
class VectorType>
1942 template <
class BlockVector2>
1948 for (size_type i = 0; i <
n_blocks(); ++i)
1954 template <
class VectorType>
1969 for (size_type i = 0; i <
n_blocks(); ++i)
1977 template <
class VectorType>
1987 template <
class VectorType>
1988 template <
class BlockVector2>
1997 for (size_type i = 0; i <
n_blocks(); ++i)
2003 template <
class VectorType>
2007 for (size_type i = 0; i <
n_blocks(); ++i)
2008 block(i).update_ghost_values();
2013 template <
class VectorType>
2019 for (size_type i = 0; i <
n_blocks(); ++i)
2026 template <
class VectorType>
2032 for (size_type i = 0; i <
n_blocks(); ++i)
2039 template <
class VectorType>
2040 template <
class VectorType2>
2046 for (size_type i = 0; i <
n_blocks(); ++i)
2054 template <
class VectorType>
2060 size_type index_v = 0;
2062 for (size_type i = 0; i <
block(b).size(); ++i, ++index_v)
2063 block(b)(i) = v(index_v);
2070 template <
class VectorType>
2071 template <
class VectorType2>
2078 for (size_type i = 0; i <
n_blocks(); ++i)
2087 template <
class VectorType>
2093 for (size_type i = 0; i <
n_blocks(); ++i)
2101 template <
class VectorType>
2108 for (size_type i = 0; i <
n_blocks(); ++i)
2115 template <
class VectorType>
2116 inline typename BlockVectorBase<VectorType>::value_type
2119 const std::pair<unsigned int, size_type> local_index =
2121 return components[local_index.first](local_index.second);
2126 template <
class VectorType>
2127 inline typename BlockVectorBase<VectorType>::reference
2130 const std::pair<unsigned int, size_type> local_index =
2132 return components[local_index.first](local_index.second);
2137 template <
class VectorType>
2138 inline typename BlockVectorBase<VectorType>::value_type
2146 template <
class VectorType>
2147 inline typename BlockVectorBase<VectorType>::reference
2155 template <
typename VectorType>
2156 template <
typename OtherNumber>
2159 const std::vector<size_type> &indices,
2160 std::vector<OtherNumber> & values)
const 2162 for (size_type i = 0; i < indices.size(); ++i)
2163 values[i] =
operator()(indices[i]);
2168 template <
typename VectorType>
2169 template <
typename ForwardIterator,
typename OutputIterator>
2172 ForwardIterator indices_begin,
2173 const ForwardIterator indices_end,
2174 OutputIterator values_begin)
const 2176 while (indices_begin != indices_end)
2186 DEAL_II_NAMESPACE_CLOSE
const types::global_dof_index invalid_size_type
static yes_type check_for_block_vector(const BlockVectorBase< T > *)
bool operator>(const Iterator< BlockVectorType, OtherConstness > &i) const
#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)
bool in_local_range(const size_type global_index) const
size_type block_size(const unsigned int i) 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()
Iterator operator+(const difference_type &d) const
LinearAlgebra::distributed::Vector< Number > Vector
typename std::conditional< Constness, const typename BlockVectorType::value_type, typename BlockVectorType::value_type >::type value_type
BlockVectorBase & operator/=(const value_type factor)
value_type add_and_dot(const value_type a, const BlockVectorBase &V, const BlockVectorBase &W)
size_type total_size() const
bool is_non_negative() const
void scale(const BlockVector2 &v)
BlockVectorBase()=default
std::random_access_iterator_tag iterator_category
BlockIndices block_indices
IndexSet locally_owned_elements() const
real_type norm_sqr() const
size_type next_break_forward
T sum(const T &t, const MPI_Comm &mpi_communicator)
const BlockIndices & get_block_indices() const
#define Assert(cond, exc)
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
void reinit(const unsigned int n_blocks, const size_type n_elements_per_block)
types::global_dof_index size_type
#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
static ::ExceptionBase & ExcDifferentBlockIndices()
BlockVectorBase & operator+=(const BlockVectorBase &V)
std::vector< VectorType > components
BlockVectorBase & operator*=(const value_type factor)
SymmetricTensor< 2, dim, Number > b(const Tensor< 2, dim, Number > &F)
Vector< Number > BlockType
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 global_dof_index
unsigned int current_block
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
unsigned int n_blocks() const
BlockVectorBase & operator-=(const BlockVectorBase &V)
typename BlockType::real_type real_type
bool operator!=(const Iterator< BlockVectorType, OtherConstness > &i) const
size_type block_start(const unsigned int i) const
value_type operator()(const size_type i) const
difference_type operator-(const Iterator< BlockVectorType, OtherConstness > &i) const
real_type linfty_norm() const
bool operator>=(const Iterator< BlockVectorType, OtherConstness > &i) const
unsigned int size() const
BlockType & block(const unsigned int i)
SymmetricTensor< rank_, dim, typename ProductType< Number, OtherNumber >::type > operator-(const SymmetricTensor< rank_, dim, Number > &left, const SymmetricTensor< rank_, dim, OtherNumber > &right)
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)
std::enable_if< std::is_fundamental< T >::value, std::size_t >::type memory_consumption(const T &t)
dereference_type operator*() const
value_type mean_value() const