15#ifndef dealii_block_vector_base_h
16#define dealii_block_vector_base_h
48 using has_block_t =
decltype(std::declval<const T>().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 <
typename BlockVectorType,
bool Constness>
134 std::conditional_t<Constness,
135 const typename BlockVectorType::value_type,
136 typename BlockVectorType::value_type>;
157 std::conditional_t<Constness,
159 typename BlockVectorType::BlockType::reference>;
166 std::conditional_t<Constness, const BlockVectorType, BlockVectorType>;
261 template <
bool OtherConstness>
269 template <
bool OtherConstness>
278 template <
bool OtherConstness>
285 template <
bool OtherConstness>
292 template <
bool OtherConstness>
299 template <
bool OtherConstness>
306 template <
bool OtherConstness>
348 "Your program tried to compare iterators pointing to "
349 "different block vectors. There is no reasonable way "
395 template <
typename,
bool>
439template <
typename VectorType>
648 template <typename OtherNumber>
651 std::vector<OtherNumber> &values) const;
684 template <typename ForwardIterator, typename OutputIterator>
687 const ForwardIterator indices_end,
688 OutputIterator values_begin) const;
714 template <typename VectorType2>
722 operator=(const VectorType &v);
728 template <typename VectorType2>
837 template <typename Number>
845 template <typename Number>
854 template <typename Number>
858 const Number *values);
932 template <class BlockVector2>
939 template <class BlockVector2>
978 template <typename N,
bool C>
994 namespace BlockVectorIterators
996 template <
typename BlockVectorType,
bool Constness>
997 inline Iterator<BlockVectorType, Constness>::Iterator(
998 const Iterator<BlockVectorType, Constness> &c)
1000 , global_index(c.global_index)
1001 , current_block(c.current_block)
1002 , index_within_block(c.index_within_block)
1003 , next_break_forward(c.next_break_forward)
1004 , next_break_backward(c.next_break_backward)
1009 template <
typename BlockVectorType,
bool Constness>
1010 inline Iterator<BlockVectorType, Constness>::Iterator(
1011 const Iterator<BlockVectorType, !Constness> &c)
1013 , global_index(c.global_index)
1014 , current_block(c.current_block)
1015 , index_within_block(c.index_within_block)
1016 , next_break_forward(c.next_break_forward)
1017 , next_break_backward(c.next_break_backward)
1022 static_assert(Constness ==
true,
1023 "Constructing a non-const iterator from a const iterator "
1024 "does not make sense.");
1029 template <
typename BlockVectorType,
bool Constness>
1030 inline Iterator<BlockVectorType, Constness>::Iterator(
1038 , global_index(global_index)
1039 , current_block(current_block)
1040 , index_within_block(index_within_block)
1041 , next_break_forward(next_break_forward)
1042 , next_break_backward(next_break_backward)
1047 template <
typename BlockVectorType,
bool Constness>
1048 inline Iterator<BlockVectorType, Constness> &
1049 Iterator<BlockVectorType, Constness>::operator=(
const Iterator &c)
1052 global_index = c.global_index;
1053 index_within_block = c.index_within_block;
1054 current_block = c.current_block;
1055 next_break_forward = c.next_break_forward;
1056 next_break_backward = c.next_break_backward;
1063 template <
typename BlockVectorType,
bool Constness>
1064 inline typename Iterator<BlockVectorType, Constness>::dereference_type
1065 Iterator<BlockVectorType, Constness>::operator*()
const
1067 return parent->
block(current_block)(index_within_block);
1072 template <
typename BlockVectorType,
bool Constness>
1073 inline typename Iterator<BlockVectorType, Constness>::dereference_type
1074 Iterator<BlockVectorType, Constness>::operator[](
1075 const difference_type d)
const
1082 if ((global_index + d >= next_break_backward) &&
1083 (global_index + d <= next_break_forward))
1084 return parent->
block(current_block)(index_within_block + d);
1093 return (*parent)(global_index + d);
1098 template <
typename BlockVectorType,
bool Constness>
1099 inline Iterator<BlockVectorType, Constness> &
1100 Iterator<BlockVectorType, Constness>::operator++()
1108 template <
typename BlockVectorType,
bool Constness>
1109 inline Iterator<BlockVectorType, Constness>
1110 Iterator<BlockVectorType, Constness>::operator++(
int)
1112 const Iterator old_value = *
this;
1119 template <
typename BlockVectorType,
bool Constness>
1120 inline Iterator<BlockVectorType, Constness> &
1121 Iterator<BlockVectorType, Constness>::operator--()
1129 template <
typename BlockVectorType,
bool Constness>
1130 inline Iterator<BlockVectorType, Constness>
1131 Iterator<BlockVectorType, Constness>::operator--(
int)
1133 const Iterator old_value = *
this;
1140 template <
typename BlockVectorType,
bool Constness>
1141 template <
bool OtherConstness>
1143 Iterator<BlockVectorType, Constness>::operator==(
1144 const Iterator<BlockVectorType, OtherConstness> &i)
const
1146 Assert(parent == i.parent, ExcPointerToDifferentVectors());
1148 return (global_index == i.global_index);
1153 template <
typename BlockVectorType,
bool Constness>
1154 template <
bool OtherConstness>
1156 Iterator<BlockVectorType, Constness>::operator!=(
1157 const Iterator<BlockVectorType, OtherConstness> &i)
const
1159 Assert(parent == i.parent, ExcPointerToDifferentVectors());
1161 return (global_index != i.global_index);
1166 template <
typename BlockVectorType,
bool Constness>
1167 template <
bool OtherConstness>
1169 Iterator<BlockVectorType, Constness>::operator<(
1170 const Iterator<BlockVectorType, OtherConstness> &i)
const
1172 Assert(parent == i.parent, ExcPointerToDifferentVectors());
1174 return (global_index < i.global_index);
1179 template <
typename BlockVectorType,
bool Constness>
1180 template <
bool OtherConstness>
1182 Iterator<BlockVectorType, Constness>::operator<=(
1183 const Iterator<BlockVectorType, OtherConstness> &i)
const
1185 Assert(parent == i.parent, ExcPointerToDifferentVectors());
1187 return (global_index <= i.global_index);
1192 template <
typename BlockVectorType,
bool Constness>
1193 template <
bool OtherConstness>
1195 Iterator<BlockVectorType, Constness>::operator>(
1196 const Iterator<BlockVectorType, OtherConstness> &i)
const
1198 Assert(parent == i.parent, ExcPointerToDifferentVectors());
1200 return (global_index > i.global_index);
1205 template <
typename BlockVectorType,
bool Constness>
1206 template <
bool OtherConstness>
1208 Iterator<BlockVectorType, Constness>::operator>=(
1209 const Iterator<BlockVectorType, OtherConstness> &i)
const
1211 Assert(parent == i.parent, ExcPointerToDifferentVectors());
1213 return (global_index >= i.global_index);
1218 template <
typename BlockVectorType,
bool Constness>
1219 template <
bool OtherConstness>
1220 inline typename Iterator<BlockVectorType, Constness>::difference_type
1221 Iterator<BlockVectorType, Constness>::operator-(
1222 const Iterator<BlockVectorType, OtherConstness> &i)
const
1224 Assert(parent == i.parent, ExcPointerToDifferentVectors());
1226 return (
static_cast<signed int>(global_index) -
1227 static_cast<signed int>(i.global_index));
1232 template <
typename BlockVectorType,
bool Constness>
1233 inline Iterator<BlockVectorType, Constness>
1234 Iterator<BlockVectorType, Constness>::operator+(
1235 const difference_type &d)
const
1242 if ((global_index + d >= next_break_backward) &&
1243 (global_index + d <= next_break_forward))
1244 return Iterator(*parent,
1247 index_within_block + d,
1249 next_break_backward);
1254 return Iterator(*parent, global_index + d);
1259 template <
typename BlockVectorType,
bool Constness>
1260 inline Iterator<BlockVectorType, Constness>
1261 Iterator<BlockVectorType, Constness>::operator-(
1262 const difference_type &d)
const
1269 if ((global_index - d >= next_break_backward) &&
1270 (global_index - d <= next_break_forward))
1271 return Iterator(*parent,
1274 index_within_block - d,
1276 next_break_backward);
1281 return Iterator(*parent, global_index - d);
1286 template <
typename BlockVectorType,
bool Constness>
1287 inline Iterator<BlockVectorType, Constness> &
1288 Iterator<BlockVectorType, Constness>::operator+=(
const difference_type &d)
1295 if ((global_index + d >= next_break_backward) &&
1296 (global_index + d <= next_break_forward))
1299 index_within_block += d;
1305 *
this = Iterator(*parent, global_index + d);
1312 template <
typename BlockVectorType,
bool Constness>
1313 inline Iterator<BlockVectorType, Constness> &
1314 Iterator<BlockVectorType, Constness>::operator-=(
const difference_type &d)
1321 if ((global_index - d >= next_break_backward) &&
1322 (global_index - d <= next_break_forward))
1325 index_within_block -= d;
1331 *
this = Iterator(*parent, global_index - d);
1337 template <
typename BlockVectorType,
bool Constness>
1338 Iterator<BlockVectorType, Constness>::Iterator(
BlockVector &parent,
1341 , global_index(global_index)
1349 if (global_index < parent.
size())
1351 const std::pair<size_type, size_type> indices =
1353 current_block = indices.first;
1354 index_within_block = indices.second;
1356 next_break_backward =
1358 next_break_forward =
1366 this->global_index = parent.
size();
1368 index_within_block = 0;
1369 next_break_backward = global_index;
1376 template <
typename BlockVectorType,
bool Constness>
1378 Iterator<BlockVectorType, Constness>::move_forward()
1380 if (global_index != next_break_forward)
1381 ++index_within_block;
1386 index_within_block = 0;
1391 next_break_backward = next_break_forward + 1;
1394 if (current_block < parent->block_indices.
size())
1395 next_break_forward +=
1410 template <
typename BlockVectorType,
bool Constness>
1412 Iterator<BlockVectorType, Constness>::move_backward()
1414 if (global_index != next_break_backward)
1415 --index_within_block;
1416 else if (current_block != 0)
1421 index_within_block =
1426 next_break_forward = next_break_backward - 1;
1429 next_break_backward -=
1438 next_break_forward = 0;
1439 next_break_backward = 0;
1452template <
typename VectorType>
1461template <
typename VectorType>
1465 std::size_t local_size = 0;
1466 for (
unsigned int b = 0;
b <
n_blocks(); ++
b)
1467 local_size +=
block(b).locally_owned_size();
1473template <
typename VectorType>
1481 for (
unsigned int b = 0;
b <
n_blocks(); ++
b)
1494template <
typename VectorType>
1502template <
typename VectorType>
1513template <
typename VectorType>
1524template <
typename VectorType>
1532template <
typename VectorType>
1536 std::vector<size_type> sizes(
n_blocks());
1539 sizes[i] =
block(i).size();
1546template <
typename VectorType>
1550 for (
unsigned int i = 0; i <
n_blocks(); ++i)
1551 block(i).compress(operation);
1556template <
typename VectorType>
1565template <
typename VectorType>
1573template <
typename VectorType>
1582template <
typename VectorType>
1590template <
typename VectorType>
1594 const std::pair<size_type, size_type> local_index =
1597 return components[local_index.first].in_local_range(global_index);
1601template <
typename VectorType>
1614template <
typename VectorType>
1627template <
typename VectorType>
1643template <
typename VectorType>
1656template <
typename VectorType>
1673template <
typename VectorType>
1686template <
typename VectorType>
1695template <
typename VectorType>
1711template <
typename VectorType>
1730template <
typename VectorType>
1747template <
typename VectorType>
1763template <
typename VectorType>
1764template <
typename Number>
1767 const std::vector<Number> &values)
1771 add(indices.size(), indices.data(),
values.data());
1776template <
typename VectorType>
1777template <
typename Number>
1784 const size_type n_indices = indices.size();
1785 for (
size_type i = 0; i < n_indices; ++i)
1786 (*
this)(indices[i]) +=
values(i);
1791template <
typename VectorType>
1792template <
typename Number>
1796 const Number *values)
1798 for (
size_type i = 0; i < n_indices; ++i)
1799 (*
this)(indices[i]) += values[i];
1804template <
typename VectorType>
1818template <
typename VectorType>
1836template <
typename VectorType>
1860template <
typename VectorType>
1878template <
typename VectorType>
1898template <
typename VectorType>
1923template <
typename VectorType>
1954template <
typename VectorType>
1955template <
class BlockVector2>
1967template <
typename VectorType>
1977template <
typename VectorType>
1978template <
class BlockVector2>
1993template <
typename VectorType>
1998 block(i).update_ghost_values();
2003template <
typename VectorType>
2008 return block(0).get_mpi_communicator();
2010 return MPI_COMM_SELF;
2015template <
typename VectorType>
2028template <
typename VectorType>
2041template <
typename VectorType>
2042template <
typename VectorType2>
2056template <
typename VectorType>
2065 block(b)(i) = v(index_v);
2072template <
typename VectorType>
2073template <
typename VectorType2>
2089template <
typename VectorType>
2103template <
typename VectorType>
2119template <
typename VectorType>
2123 const std::pair<unsigned int, size_type> local_index =
2125 return components[local_index.first](local_index.second);
2130template <
typename VectorType>
2134 const std::pair<unsigned int, size_type> local_index =
2136 return components[local_index.first](local_index.second);
2141template <
typename VectorType>
2150template <
typename VectorType>
2159template <
typename VectorType>
2160template <
typename OtherNumber>
2163 const std::vector<size_type> &indices,
2164 std::vector<OtherNumber> &values)
const
2166 for (
size_type i = 0; i < indices.size(); ++i)
2167 values[i] =
operator()(indices[i]);
2172template <
typename VectorType>
2179 for (
unsigned int i = 0; i < indices.
size(); ++i)
2182 entries[i] = (*this)[indices[i]];
2188template <
typename VectorType>
2189template <
typename ForwardIterator,
typename OutputIterator>
2192 ForwardIterator indices_begin,
2193 const ForwardIterator indices_end,
2194 OutputIterator values_begin)
const
2196 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
virtual size_type size() const override
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
MPI_Comm get_mpi_communicator() const
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)
void add_indices(const ForwardIterator &begin, const ForwardIterator &end)
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)
std::conditional_t< Constness, const typename BlockVectorType::value_type, typename BlockVectorType::value_type > value_type
Iterator(const Iterator< BlockVectorType, !Constness > &c)
Iterator(const Iterator &c)
std::conditional_t< Constness, const BlockVectorType, BlockVectorType > BlockVector
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
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
Iterator & operator-=(const difference_type &d)
std::conditional_t< Constness, value_type, typename BlockVectorType::BlockType::reference > dereference_type
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_v< T >, 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)
constexpr bool has_n_blocks
decltype(std::declval< const T >().n_blocks()) has_n_blocks_t
decltype(std::declval< const T >().block(0)) has_block_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