16#ifndef dealii_block_vector_base_h
17#define dealii_block_vector_base_h
48 using has_block_t =
decltype(std::declval<T const>().block(0));
51 constexpr bool has_block = internal::is_supported_operation<has_block_t, T>;
58 internal::is_supported_operation<has_n_blocks_t, T>;
78template <
typename VectorType>
87 static const bool value = internal::is_block_vector<VectorType>;
92template <
typename VectorType>
102 namespace BlockVectorIterators
119 template <
class BlockVectorType,
bool Constness>
134 typename std::conditional<Constness,
135 const typename BlockVectorType::value_type,
136 typename BlockVectorType::value_type>::type;
152 typename BlockVectorType::BlockType::reference>::type;
159 conditional<Constness, const BlockVectorType, BlockVectorType>::type;
254 template <
bool OtherConstness>
262 template <
bool OtherConstness>
271 template <
bool OtherConstness>
278 template <
bool OtherConstness>
285 template <
bool OtherConstness>
292 template <
bool OtherConstness>
299 template <
bool OtherConstness>
341 "Your program tried to compare iterators pointing to "
342 "different block vectors. There is no reasonable way "
388 template <
typename,
bool>
432template <
class VectorType>
641 template <typename OtherNumber>
644 std::vector<OtherNumber> & values) const;
673 template <typename ForwardIterator, typename OutputIterator>
676 const ForwardIterator indices_end,
677 OutputIterator values_begin) const;
703 template <class VectorType2>
711 operator=(const VectorType &v);
717 template <class VectorType2>
826 template <typename Number>
834 template <typename Number>
843 template <typename Number>
847 const Number * values);
921 template <class BlockVector2>
928 template <class BlockVector2>
959 template <typename N,
bool C>
975 namespace BlockVectorIterators
977 template <
class BlockVectorType,
bool Constness>
978 inline Iterator<BlockVectorType, Constness>::Iterator(
979 const Iterator<BlockVectorType, Constness> &c)
981 , global_index(c.global_index)
982 , current_block(c.current_block)
983 , index_within_block(c.index_within_block)
984 , next_break_forward(c.next_break_forward)
985 , next_break_backward(c.next_break_backward)
990 template <
class BlockVectorType,
bool Constness>
991 inline Iterator<BlockVectorType, Constness>::Iterator(
992 const Iterator<BlockVectorType, !Constness> &c)
994 , global_index(c.global_index)
995 , current_block(c.current_block)
996 , index_within_block(c.index_within_block)
997 , next_break_forward(c.next_break_forward)
998 , next_break_backward(c.next_break_backward)
1003 static_assert(Constness ==
true,
1004 "Constructing a non-const iterator from a const iterator "
1005 "does not make sense.");
1010 template <
class BlockVectorType,
bool Constness>
1011 inline Iterator<BlockVectorType, Constness>::Iterator(
1019 , global_index(global_index)
1020 , current_block(current_block)
1021 , index_within_block(index_within_block)
1022 , next_break_forward(next_break_forward)
1023 , next_break_backward(next_break_backward)
1028 template <
class BlockVectorType,
bool Constness>
1029 inline Iterator<BlockVectorType, Constness> &
1030 Iterator<BlockVectorType, Constness>::operator=(
const Iterator &c)
1033 global_index = c.global_index;
1034 index_within_block = c.index_within_block;
1035 current_block = c.current_block;
1036 next_break_forward = c.next_break_forward;
1037 next_break_backward = c.next_break_backward;
1044 template <
class BlockVectorType,
bool Constness>
1045 inline typename Iterator<BlockVectorType, Constness>::dereference_type
1046 Iterator<BlockVectorType, Constness>::operator*()
const
1048 return parent->
block(current_block)(index_within_block);
1053 template <
class BlockVectorType,
bool Constness>
1054 inline typename Iterator<BlockVectorType, Constness>::dereference_type
1055 Iterator<BlockVectorType, Constness>::operator[](
1056 const difference_type d)
const
1063 if ((global_index + d >= next_break_backward) &&
1064 (global_index + d <= next_break_forward))
1065 return parent->
block(current_block)(index_within_block + d);
1074 return (*parent)(global_index + d);
1079 template <
class BlockVectorType,
bool Constness>
1080 inline Iterator<BlockVectorType, Constness> &
1081 Iterator<BlockVectorType, Constness>::operator++()
1089 template <
class BlockVectorType,
bool Constness>
1090 inline Iterator<BlockVectorType, Constness>
1091 Iterator<BlockVectorType, Constness>::operator++(
int)
1093 const Iterator old_value = *
this;
1100 template <
class BlockVectorType,
bool Constness>
1101 inline Iterator<BlockVectorType, Constness> &
1102 Iterator<BlockVectorType, Constness>::operator--()
1110 template <
class BlockVectorType,
bool Constness>
1111 inline Iterator<BlockVectorType, Constness>
1112 Iterator<BlockVectorType, Constness>::operator--(
int)
1114 const Iterator old_value = *
this;
1121 template <
class BlockVectorType,
bool Constness>
1122 template <
bool OtherConstness>
1124 Iterator<BlockVectorType, Constness>::operator==(
1125 const Iterator<BlockVectorType, OtherConstness> &i)
const
1127 Assert(parent == i.parent, ExcPointerToDifferentVectors());
1129 return (global_index == i.global_index);
1134 template <
class BlockVectorType,
bool Constness>
1135 template <
bool OtherConstness>
1137 Iterator<BlockVectorType, Constness>::operator!=(
1138 const Iterator<BlockVectorType, OtherConstness> &i)
const
1140 Assert(parent == i.parent, ExcPointerToDifferentVectors());
1142 return (global_index != i.global_index);
1147 template <
class BlockVectorType,
bool Constness>
1148 template <
bool OtherConstness>
1150 Iterator<BlockVectorType, Constness>::operator<(
1151 const Iterator<BlockVectorType, OtherConstness> &i)
const
1153 Assert(parent == i.parent, ExcPointerToDifferentVectors());
1155 return (global_index < i.global_index);
1160 template <
class BlockVectorType,
bool Constness>
1161 template <
bool OtherConstness>
1163 Iterator<BlockVectorType, Constness>::operator<=(
1164 const Iterator<BlockVectorType, OtherConstness> &i)
const
1166 Assert(parent == i.parent, ExcPointerToDifferentVectors());
1168 return (global_index <= i.global_index);
1173 template <
class BlockVectorType,
bool Constness>
1174 template <
bool OtherConstness>
1176 Iterator<BlockVectorType, Constness>::operator>(
1177 const Iterator<BlockVectorType, OtherConstness> &i)
const
1179 Assert(parent == i.parent, ExcPointerToDifferentVectors());
1181 return (global_index > i.global_index);
1186 template <
class BlockVectorType,
bool Constness>
1187 template <
bool OtherConstness>
1189 Iterator<BlockVectorType, Constness>::operator>=(
1190 const Iterator<BlockVectorType, OtherConstness> &i)
const
1192 Assert(parent == i.parent, ExcPointerToDifferentVectors());
1194 return (global_index >= i.global_index);
1199 template <
class BlockVectorType,
bool Constness>
1200 template <
bool OtherConstness>
1201 inline typename Iterator<BlockVectorType, Constness>::difference_type
1202 Iterator<BlockVectorType, Constness>::operator-(
1203 const Iterator<BlockVectorType, OtherConstness> &i)
const
1205 Assert(parent == i.parent, ExcPointerToDifferentVectors());
1207 return (
static_cast<signed int>(global_index) -
1208 static_cast<signed int>(i.global_index));
1213 template <
class BlockVectorType,
bool Constness>
1214 inline Iterator<BlockVectorType, Constness>
1215 Iterator<BlockVectorType, Constness>::operator+(
1216 const difference_type &d)
const
1223 if ((global_index + d >= next_break_backward) &&
1224 (global_index + d <= next_break_forward))
1225 return Iterator(*parent,
1228 index_within_block + d,
1230 next_break_backward);
1235 return Iterator(*parent, global_index + d);
1240 template <
class BlockVectorType,
bool Constness>
1241 inline Iterator<BlockVectorType, Constness>
1242 Iterator<BlockVectorType, Constness>::operator-(
1243 const difference_type &d)
const
1250 if ((global_index - d >= next_break_backward) &&
1251 (global_index - d <= next_break_forward))
1252 return Iterator(*parent,
1255 index_within_block - d,
1257 next_break_backward);
1262 return Iterator(*parent, global_index - d);
1267 template <
class BlockVectorType,
bool Constness>
1268 inline Iterator<BlockVectorType, Constness> &
1269 Iterator<BlockVectorType, Constness>::operator+=(
const difference_type &d)
1276 if ((global_index + d >= next_break_backward) &&
1277 (global_index + d <= next_break_forward))
1280 index_within_block += d;
1286 *
this = Iterator(*parent, global_index + d);
1293 template <
class BlockVectorType,
bool Constness>
1294 inline Iterator<BlockVectorType, Constness> &
1295 Iterator<BlockVectorType, Constness>::operator-=(
const difference_type &d)
1302 if ((global_index - d >= next_break_backward) &&
1303 (global_index - d <= next_break_forward))
1306 index_within_block -= d;
1312 *
this = Iterator(*parent, global_index - d);
1318 template <
class BlockVectorType,
bool Constness>
1319 Iterator<BlockVectorType, Constness>::Iterator(
BlockVector & parent,
1322 , global_index(global_index)
1330 if (global_index < parent.
size())
1332 const std::pair<size_type, size_type> indices =
1334 current_block = indices.first;
1335 index_within_block = indices.second;
1337 next_break_backward =
1339 next_break_forward =
1347 this->global_index = parent.
size();
1349 index_within_block = 0;
1350 next_break_backward = global_index;
1357 template <
class BlockVectorType,
bool Constness>
1359 Iterator<BlockVectorType, Constness>::move_forward()
1361 if (global_index != next_break_forward)
1362 ++index_within_block;
1367 index_within_block = 0;
1372 next_break_backward = next_break_forward + 1;
1375 if (current_block < parent->block_indices.
size())
1376 next_break_forward +=
1391 template <
class BlockVectorType,
bool Constness>
1393 Iterator<BlockVectorType, Constness>::move_backward()
1395 if (global_index != next_break_backward)
1396 --index_within_block;
1397 else if (current_block != 0)
1402 index_within_block =
1407 next_break_forward = next_break_backward - 1;
1410 next_break_backward -=
1419 next_break_forward = 0;
1420 next_break_backward = 0;
1433template <
class VectorType>
1442template <
class VectorType>
1446 std::size_t local_size = 0;
1447 for (
unsigned int b = 0;
b <
n_blocks(); ++
b)
1448 local_size +=
block(b).locally_owned_size();
1454template <
class VectorType>
1462 for (
unsigned int b = 0;
b <
n_blocks(); ++
b)
1475template <
class VectorType>
1483template <
class VectorType>
1494template <
class VectorType>
1505template <
class VectorType>
1513template <
class VectorType>
1517 std::vector<size_type> sizes(
n_blocks());
1520 sizes[i] =
block(i).size();
1527template <
class VectorType>
1532 for (
unsigned int i = 0; i <
n_blocks(); ++i)
1533 block(i).compress(operation);
1538template <
class VectorType>
1547template <
class VectorType>
1555template <
class VectorType>
1564template <
class VectorType>
1572template <
class VectorType>
1576 const std::pair<size_type, size_type> local_index =
1579 return components[local_index.first].in_local_range(global_index);
1583template <
class VectorType>
1596template <
class VectorType>
1609template <
class VectorType>
1625template <
class VectorType>
1638template <
class VectorType>
1655template <
class VectorType>
1668template <
class VectorType>
1677template <
class VectorType>
1693template <
class VectorType>
1712template <
class VectorType>
1729template <
class VectorType>
1745template <
class VectorType>
1746template <
typename Number>
1749 const std::vector<Number> & values)
1753 add(indices.size(), indices.data(),
values.data());
1758template <
class VectorType>
1759template <
typename Number>
1766 const size_type n_indices = indices.size();
1767 for (
size_type i = 0; i < n_indices; ++i)
1768 (*
this)(indices[i]) +=
values(i);
1773template <
class VectorType>
1774template <
typename Number>
1778 const Number * values)
1780 for (
size_type i = 0; i < n_indices; ++i)
1781 (*
this)(indices[i]) += values[i];
1786template <
class VectorType>
1800template <
class VectorType>
1818template <
class VectorType>
1842template <
class VectorType>
1860template <
class VectorType>
1880template <
class VectorType>
1905template <
class VectorType>
1936template <
class VectorType>
1937template <
class BlockVector2>
1949template <
class VectorType>
1959template <
class VectorType>
1960template <
class BlockVector2>
1975template <
class VectorType>
1980 block(i).update_ghost_values();
1985template <
class VectorType>
1998template <
class VectorType>
2011template <
class VectorType>
2012template <
class VectorType2>
2026template <
class VectorType>
2035 block(b)(i) = v(index_v);
2042template <
class VectorType>
2043template <
class VectorType2>
2059template <
class VectorType>
2073template <
class VectorType>
2089template <
class VectorType>
2093 const std::pair<unsigned int, size_type> local_index =
2095 return components[local_index.first](local_index.second);
2100template <
class VectorType>
2104 const std::pair<unsigned int, size_type> local_index =
2106 return components[local_index.first](local_index.second);
2111template <
class VectorType>
2120template <
class VectorType>
2129template <
typename VectorType>
2130template <
typename OtherNumber>
2133 const std::vector<size_type> &indices,
2134 std::vector<OtherNumber> & values)
const
2136 for (
size_type i = 0; i < indices.size(); ++i)
2137 values[i] =
operator()(indices[i]);
2142template <
typename VectorType>
2143template <
typename ForwardIterator,
typename OutputIterator>
2146 ForwardIterator indices_begin,
2147 const ForwardIterator indices_end,
2148 OutputIterator values_begin)
const
2150 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
#define DEAL_II_NAMESPACE_OPEN
#define DEAL_II_NAMESPACE_CLOSE
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
BlockVectorBase & operator=(const value_type s)
#define Assert(cond, exc)
BlockVectorBase & operator*=(const value_type factor)
void sadd(const value_type s, const BlockVectorBase &V)
std::vector< VectorType > components
static ::ExceptionBase & ExcPointerToDifferentVectors()
bool in_local_range(const size_type global_index) const
#define AssertIsFinite(number)
::internal::BlockVectorIterators::Iterator< BlockVectorBase, true > const_iterator
BlockVectorBase(BlockVectorBase &&) noexcept=default
#define AssertDimension(dim1, dim2)
BlockVectorBase(const BlockVectorBase &)=default
typename BlockType::reference reference
size_type next_break_forward
value_type operator[](const size_type i) const
unsigned int current_block
BlockIndices block_indices
#define AssertIndexRange(index, range)
#define DeclExceptionMsg(Exception, defaulttext)
typename BlockType::real_type real_type
void scale(const BlockVector2 &v)
void compress(::VectorOperation::values operation)
BlockType & block(const unsigned int i)
static ::ExceptionBase & ExcDivideByZero()
static ::ExceptionBase & ExcDifferentBlockIndices()
real_type l2_norm() const
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
value_type operator()(const size_type i) const
size_type next_break_backward
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
size_type index_within_block
void equ(const value_type a, const BlockVector2 &V)
decltype(std::declval< T const >().block(0)) has_block_t
constexpr bool has_n_blocks
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)
bool operator>=(const Iterator< BlockVectorType, OtherConstness > &i) const
decltype(std::declval< T const >().n_blocks()) has_n_blocks_t
typename std::conditional< Constness, const typename BlockVectorType::value_type, typename BlockVectorType::value_type >::type value_type
Iterator & operator-=(const difference_type &d)
std::ptrdiff_t difference_type
constexpr bool is_block_vector
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
std::enable_if< std::is_fundamental< T >::value, std::size_t >::type 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)
const types::global_dof_index invalid_size_type
::VectorizedArray< Number, width > sqrt(const ::VectorizedArray< Number, width > &)
unsigned int global_dof_index