16#ifndef dealii_block_vector_base_h
17#define dealii_block_vector_base_h
49 using has_block_t =
decltype(std::declval<T const>().block(0));
52 constexpr bool has_block = internal::is_supported_operation<has_block_t, T>;
59 internal::is_supported_operation<has_n_blocks_t, T>;
79template <
typename VectorType>
88 static const bool value = internal::is_block_vector<VectorType>;
93template <
typename VectorType>
103 namespace BlockVectorIterators
120 template <
class BlockVectorType,
bool Constness>
135 typename std::conditional<Constness,
136 const typename BlockVectorType::value_type,
137 typename BlockVectorType::value_type>::type;
160 typename BlockVectorType::BlockType::reference>::type;
167 conditional<Constness, const BlockVectorType, BlockVectorType>::type;
262 template <
bool OtherConstness>
270 template <
bool OtherConstness>
279 template <
bool OtherConstness>
286 template <
bool OtherConstness>
293 template <
bool OtherConstness>
300 template <
bool OtherConstness>
307 template <
bool OtherConstness>
349 "Your program tried to compare iterators pointing to "
350 "different block vectors. There is no reasonable way "
396 template <
typename,
bool>
440template <
class VectorType>
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;
711 template <class VectorType2>
719 operator=(const VectorType &v);
725 template <class VectorType2>
834 template <typename Number>
842 template <typename Number>
851 template <typename Number>
855 const Number * values);
929 template <class BlockVector2>
936 template <class BlockVector2>
967 template <typename N,
bool C>
983 namespace BlockVectorIterators
985 template <
class BlockVectorType,
bool Constness>
986 inline Iterator<BlockVectorType, Constness>::Iterator(
987 const Iterator<BlockVectorType, Constness> &c)
989 , global_index(c.global_index)
990 , current_block(c.current_block)
991 , index_within_block(c.index_within_block)
992 , next_break_forward(c.next_break_forward)
993 , next_break_backward(c.next_break_backward)
998 template <
class BlockVectorType,
bool Constness>
999 inline Iterator<BlockVectorType, Constness>::Iterator(
1000 const Iterator<BlockVectorType, !Constness> &c)
1002 , global_index(c.global_index)
1003 , current_block(c.current_block)
1004 , index_within_block(c.index_within_block)
1005 , next_break_forward(c.next_break_forward)
1006 , next_break_backward(c.next_break_backward)
1011 static_assert(Constness ==
true,
1012 "Constructing a non-const iterator from a const iterator "
1013 "does not make sense.");
1018 template <
class BlockVectorType,
bool Constness>
1019 inline Iterator<BlockVectorType, Constness>::Iterator(
1027 , global_index(global_index)
1028 , current_block(current_block)
1029 , index_within_block(index_within_block)
1030 , next_break_forward(next_break_forward)
1031 , next_break_backward(next_break_backward)
1036 template <
class BlockVectorType,
bool Constness>
1037 inline Iterator<BlockVectorType, Constness> &
1038 Iterator<BlockVectorType, Constness>::operator=(
const Iterator &c)
1041 global_index = c.global_index;
1042 index_within_block = c.index_within_block;
1043 current_block = c.current_block;
1044 next_break_forward = c.next_break_forward;
1045 next_break_backward = c.next_break_backward;
1052 template <
class BlockVectorType,
bool Constness>
1053 inline typename Iterator<BlockVectorType, Constness>::dereference_type
1054 Iterator<BlockVectorType, Constness>::operator*()
const
1056 return parent->
block(current_block)(index_within_block);
1061 template <
class BlockVectorType,
bool Constness>
1062 inline typename Iterator<BlockVectorType, Constness>::dereference_type
1063 Iterator<BlockVectorType, Constness>::operator[](
1064 const difference_type d)
const
1071 if ((global_index + d >= next_break_backward) &&
1072 (global_index + d <= next_break_forward))
1073 return parent->
block(current_block)(index_within_block + d);
1082 return (*parent)(global_index + d);
1087 template <
class BlockVectorType,
bool Constness>
1088 inline Iterator<BlockVectorType, Constness> &
1089 Iterator<BlockVectorType, Constness>::operator++()
1097 template <
class BlockVectorType,
bool Constness>
1098 inline Iterator<BlockVectorType, Constness>
1099 Iterator<BlockVectorType, Constness>::operator++(
int)
1101 const Iterator old_value = *
this;
1108 template <
class BlockVectorType,
bool Constness>
1109 inline Iterator<BlockVectorType, Constness> &
1110 Iterator<BlockVectorType, Constness>::operator--()
1118 template <
class BlockVectorType,
bool Constness>
1119 inline Iterator<BlockVectorType, Constness>
1120 Iterator<BlockVectorType, Constness>::operator--(
int)
1122 const Iterator old_value = *
this;
1129 template <
class BlockVectorType,
bool Constness>
1130 template <
bool OtherConstness>
1132 Iterator<BlockVectorType, Constness>::operator==(
1133 const Iterator<BlockVectorType, OtherConstness> &i)
const
1135 Assert(parent == i.parent, ExcPointerToDifferentVectors());
1137 return (global_index == i.global_index);
1142 template <
class BlockVectorType,
bool Constness>
1143 template <
bool OtherConstness>
1145 Iterator<BlockVectorType, Constness>::operator!=(
1146 const Iterator<BlockVectorType, OtherConstness> &i)
const
1148 Assert(parent == i.parent, ExcPointerToDifferentVectors());
1150 return (global_index != i.global_index);
1155 template <
class BlockVectorType,
bool Constness>
1156 template <
bool OtherConstness>
1158 Iterator<BlockVectorType, Constness>::operator<(
1159 const Iterator<BlockVectorType, OtherConstness> &i)
const
1161 Assert(parent == i.parent, ExcPointerToDifferentVectors());
1163 return (global_index < i.global_index);
1168 template <
class BlockVectorType,
bool Constness>
1169 template <
bool OtherConstness>
1171 Iterator<BlockVectorType, Constness>::operator<=(
1172 const Iterator<BlockVectorType, OtherConstness> &i)
const
1174 Assert(parent == i.parent, ExcPointerToDifferentVectors());
1176 return (global_index <= i.global_index);
1181 template <
class BlockVectorType,
bool Constness>
1182 template <
bool OtherConstness>
1184 Iterator<BlockVectorType, Constness>::operator>(
1185 const Iterator<BlockVectorType, OtherConstness> &i)
const
1187 Assert(parent == i.parent, ExcPointerToDifferentVectors());
1189 return (global_index > i.global_index);
1194 template <
class BlockVectorType,
bool Constness>
1195 template <
bool OtherConstness>
1197 Iterator<BlockVectorType, Constness>::operator>=(
1198 const Iterator<BlockVectorType, OtherConstness> &i)
const
1200 Assert(parent == i.parent, ExcPointerToDifferentVectors());
1202 return (global_index >= i.global_index);
1207 template <
class BlockVectorType,
bool Constness>
1208 template <
bool OtherConstness>
1209 inline typename Iterator<BlockVectorType, Constness>::difference_type
1210 Iterator<BlockVectorType, Constness>::operator-(
1211 const Iterator<BlockVectorType, OtherConstness> &i)
const
1213 Assert(parent == i.parent, ExcPointerToDifferentVectors());
1215 return (
static_cast<signed int>(global_index) -
1216 static_cast<signed int>(i.global_index));
1221 template <
class BlockVectorType,
bool Constness>
1222 inline Iterator<BlockVectorType, Constness>
1223 Iterator<BlockVectorType, Constness>::operator+(
1224 const difference_type &d)
const
1231 if ((global_index + d >= next_break_backward) &&
1232 (global_index + d <= next_break_forward))
1233 return Iterator(*parent,
1236 index_within_block + d,
1238 next_break_backward);
1243 return Iterator(*parent, global_index + d);
1248 template <
class BlockVectorType,
bool Constness>
1249 inline Iterator<BlockVectorType, Constness>
1250 Iterator<BlockVectorType, Constness>::operator-(
1251 const difference_type &d)
const
1258 if ((global_index - d >= next_break_backward) &&
1259 (global_index - d <= next_break_forward))
1260 return Iterator(*parent,
1263 index_within_block - d,
1265 next_break_backward);
1270 return Iterator(*parent, global_index - d);
1275 template <
class BlockVectorType,
bool Constness>
1276 inline Iterator<BlockVectorType, Constness> &
1277 Iterator<BlockVectorType, Constness>::operator+=(
const difference_type &d)
1284 if ((global_index + d >= next_break_backward) &&
1285 (global_index + d <= next_break_forward))
1288 index_within_block += d;
1294 *
this = Iterator(*parent, global_index + d);
1301 template <
class BlockVectorType,
bool Constness>
1302 inline Iterator<BlockVectorType, Constness> &
1303 Iterator<BlockVectorType, Constness>::operator-=(
const difference_type &d)
1310 if ((global_index - d >= next_break_backward) &&
1311 (global_index - d <= next_break_forward))
1314 index_within_block -= d;
1320 *
this = Iterator(*parent, global_index - d);
1326 template <
class BlockVectorType,
bool Constness>
1327 Iterator<BlockVectorType, Constness>::Iterator(
BlockVector & parent,
1330 , global_index(global_index)
1338 if (global_index < parent.
size())
1340 const std::pair<size_type, size_type> indices =
1342 current_block = indices.first;
1343 index_within_block = indices.second;
1345 next_break_backward =
1347 next_break_forward =
1355 this->global_index = parent.
size();
1357 index_within_block = 0;
1358 next_break_backward = global_index;
1365 template <
class BlockVectorType,
bool Constness>
1367 Iterator<BlockVectorType, Constness>::move_forward()
1369 if (global_index != next_break_forward)
1370 ++index_within_block;
1375 index_within_block = 0;
1380 next_break_backward = next_break_forward + 1;
1383 if (current_block < parent->block_indices.
size())
1384 next_break_forward +=
1399 template <
class BlockVectorType,
bool Constness>
1401 Iterator<BlockVectorType, Constness>::move_backward()
1403 if (global_index != next_break_backward)
1404 --index_within_block;
1405 else if (current_block != 0)
1410 index_within_block =
1415 next_break_forward = next_break_backward - 1;
1418 next_break_backward -=
1427 next_break_forward = 0;
1428 next_break_backward = 0;
1441template <
class VectorType>
1450template <
class VectorType>
1454 std::size_t local_size = 0;
1455 for (
unsigned int b = 0;
b <
n_blocks(); ++
b)
1456 local_size +=
block(b).locally_owned_size();
1462template <
class VectorType>
1470 for (
unsigned int b = 0;
b <
n_blocks(); ++
b)
1483template <
class VectorType>
1491template <
class VectorType>
1502template <
class VectorType>
1513template <
class VectorType>
1521template <
class VectorType>
1525 std::vector<size_type> sizes(
n_blocks());
1528 sizes[i] =
block(i).size();
1535template <
class VectorType>
1539 for (
unsigned int i = 0; i <
n_blocks(); ++i)
1540 block(i).compress(operation);
1545template <
class VectorType>
1554template <
class VectorType>
1562template <
class VectorType>
1571template <
class VectorType>
1579template <
class VectorType>
1583 const std::pair<size_type, size_type> local_index =
1586 return components[local_index.first].in_local_range(global_index);
1590template <
class VectorType>
1603template <
class VectorType>
1616template <
class VectorType>
1632template <
class VectorType>
1645template <
class VectorType>
1662template <
class VectorType>
1675template <
class VectorType>
1684template <
class VectorType>
1700template <
class VectorType>
1719template <
class VectorType>
1736template <
class VectorType>
1752template <
class VectorType>
1753template <
typename Number>
1756 const std::vector<Number> & values)
1760 add(indices.size(), indices.data(),
values.data());
1765template <
class VectorType>
1766template <
typename Number>
1773 const size_type n_indices = indices.size();
1774 for (
size_type i = 0; i < n_indices; ++i)
1775 (*
this)(indices[i]) +=
values(i);
1780template <
class VectorType>
1781template <
typename Number>
1785 const Number * values)
1787 for (
size_type i = 0; i < n_indices; ++i)
1788 (*
this)(indices[i]) += values[i];
1793template <
class VectorType>
1807template <
class VectorType>
1825template <
class VectorType>
1849template <
class VectorType>
1867template <
class VectorType>
1887template <
class VectorType>
1912template <
class VectorType>
1943template <
class VectorType>
1944template <
class BlockVector2>
1956template <
class VectorType>
1966template <
class VectorType>
1967template <
class BlockVector2>
1982template <
class VectorType>
1987 block(i).update_ghost_values();
1992template <
class VectorType>
2005template <
class VectorType>
2018template <
class VectorType>
2019template <
class VectorType2>
2033template <
class VectorType>
2042 block(b)(i) = v(index_v);
2049template <
class VectorType>
2050template <
class VectorType2>
2066template <
class VectorType>
2080template <
class VectorType>
2096template <
class VectorType>
2100 const std::pair<unsigned int, size_type> local_index =
2102 return components[local_index.first](local_index.second);
2107template <
class VectorType>
2111 const std::pair<unsigned int, size_type> local_index =
2113 return components[local_index.first](local_index.second);
2118template <
class VectorType>
2127template <
class VectorType>
2136template <
typename VectorType>
2137template <
typename OtherNumber>
2140 const std::vector<size_type> &indices,
2141 std::vector<OtherNumber> & values)
const
2143 for (
size_type i = 0; i < indices.size(); ++i)
2144 values[i] =
operator()(indices[i]);
2149template <
typename VectorType>
2150template <
typename ForwardIterator,
typename OutputIterator>
2153 ForwardIterator indices_begin,
2154 const ForwardIterator indices_end,
2155 OutputIterator values_begin)
const
2157 while (indices_begin != indices_end)
size_type block_size(const unsigned int i) const
size_type total_size() const
void reinit(const unsigned int n_blocks, const size_type n_elements_per_block)
unsigned int size() const
size_type local_to_global(const unsigned int block, const size_type index) const
size_type block_start(const unsigned int i) const
std::pair< unsigned int, size_type > global_to_local(const size_type i) const
BlockVectorBase & operator+=(const BlockVectorBase &V)
BlockVectorBase()=default
void extract_subvector_to(const std::vector< size_type > &indices, std::vector< OtherNumber > &values) const
value_type mean_value() const
void add(const std::vector< size_type > &indices, const std::vector< Number > &values)
::internal::BlockVectorIterators::Iterator< BlockVectorBase, false > iterator
BlockVectorBase & operator/=(const value_type factor)
unsigned int n_blocks() const
real_type norm_sqr() const
const value_type * const_pointer
typename BlockType::const_reference const_reference
void update_ghost_values() const
std::size_t memory_consumption() const
real_type l1_norm() const
types::global_dof_index size_type
real_type linfty_norm() const
value_type add_and_dot(const value_type a, const BlockVectorBase &V, const BlockVectorBase &W)
typename BlockType::value_type value_type
value_type operator*(const BlockVectorBase &V) const
void compress(VectorOperation::values operation)
BlockVectorBase & operator=(const value_type s)
BlockVectorBase & operator*=(const value_type factor)
void sadd(const value_type s, const BlockVectorBase &V)
std::vector< VectorType > components
bool in_local_range(const size_type global_index) const
::internal::BlockVectorIterators::Iterator< BlockVectorBase, true > const_iterator
BlockVectorBase(BlockVectorBase &&) noexcept=default
BlockVectorBase(const BlockVectorBase &)=default
typename BlockType::reference reference
value_type operator[](const size_type i) const
BlockIndices block_indices
typename BlockType::real_type real_type
void scale(const BlockVector2 &v)
BlockType & block(const unsigned int i)
real_type l2_norm() const
value_type operator()(const size_type i) const
IndexSet locally_owned_elements() const
bool is_non_negative() const
BlockVectorBase & operator-=(const BlockVectorBase &V)
friend class ::internal::BlockVectorIterators::Iterator
bool operator==(const BlockVectorBase< VectorType2 > &v) const
std::size_t locally_owned_size() const
const BlockIndices & get_block_indices() const
void equ(const value_type a, const BlockVector2 &V)
bool operator==(const Iterator< BlockVectorType, OtherConstness > &i) const
dereference_type operator[](const difference_type d) const
Iterator & operator=(const Iterator &c)
bool operator<(const Iterator< BlockVectorType, OtherConstness > &i) const
Iterator(BlockVector &parent, const size_type global_index, const size_type current_block, const size_type index_within_block, const size_type next_break_forward, const size_type next_break_backward)
Iterator(const Iterator< BlockVectorType, !Constness > &c)
Iterator(const Iterator &c)
dereference_type operator*() const
Iterator operator-(const difference_type &d) const
difference_type operator-(const Iterator< BlockVectorType, OtherConstness > &i) const
std::random_access_iterator_tag iterator_category
typename std::conditional< Constness, value_type, typename BlockVectorType::BlockType::reference >::type dereference_type
Iterator(BlockVector &parent, const size_type global_index)
size_type next_break_forward
bool operator>=(const Iterator< BlockVectorType, OtherConstness > &i) const
unsigned int current_block
typename std::conditional< Constness, const typename BlockVectorType::value_type, typename BlockVectorType::value_type >::type value_type
Iterator & operator-=(const difference_type &d)
size_type next_break_backward
std::ptrdiff_t difference_type
size_type index_within_block
bool operator<=(const Iterator< BlockVectorType, OtherConstness > &i) const
typename BlockVectorType::reference reference
Iterator operator+(const difference_type &d) const
Iterator & operator+=(const difference_type &d)
bool operator!=(const Iterator< BlockVectorType, OtherConstness > &i) const
bool operator>(const Iterator< BlockVectorType, OtherConstness > &i) const
#define DEAL_II_NAMESPACE_OPEN
#define DEAL_II_NAMESPACE_CLOSE
#define Assert(cond, exc)
static ::ExceptionBase & ExcPointerToDifferentVectors()
#define AssertIsFinite(number)
#define AssertDimension(dim1, dim2)
#define AssertIndexRange(index, range)
#define DeclExceptionMsg(Exception, defaulttext)
static ::ExceptionBase & ExcDivideByZero()
static ::ExceptionBase & ExcDifferentBlockIndices()
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
std::enable_if_t< std::is_fundamental< T >::value, std::size_t > memory_consumption(const T &t)
Tensor< 2, dim, Number > w(const Tensor< 2, dim, Number > &F, const Tensor< 2, dim, Number > &dF_dt)
SymmetricTensor< 2, dim, Number > b(const Tensor< 2, dim, Number > &F)
T sum(const T &t, const MPI_Comm mpi_communicator)
decltype(std::declval< T const >().block(0)) has_block_t
constexpr bool has_n_blocks
decltype(std::declval< T const >().n_blocks()) has_n_blocks_t
constexpr bool is_block_vector
const types::global_dof_index invalid_size_type
::VectorizedArray< Number, width > sqrt(const ::VectorizedArray< Number, width > &)
unsigned int global_dof_index