16 #ifndef dealii__block_vector_base_h 17 #define dealii__block_vector_base_h 20 #include <deal.II/base/config.h> 21 #include <deal.II/base/exceptions.h> 22 #include <deal.II/base/subscriptor.h> 23 #include <deal.II/base/memory_consumption.h> 24 #include <deal.II/lac/exceptions.h> 25 #include <deal.II/lac/block_indices.h> 26 #include <deal.II/lac/vector.h> 32 DEAL_II_NAMESPACE_OPEN
58 template <
typename VectorType>
98 template <
typename VectorType>
112 namespace BlockVectorIterators
118 template <
class BlockVectorType,
bool Constness>
131 template <
class BlockVectorType>
138 typedef typename BlockVectorType::BlockType
Vector;
166 template <
class BlockVectorType>
173 typedef const typename BlockVectorType::BlockType
Vector;
213 template <
class BlockVectorType,
bool Constness>
215 public std::iterator<std::random_access_iterator_tag,
216 typename Types<BlockVectorType,Constness>::value_type>
239 typedef std::ptrdiff_t difference_type;
240 typedef typename BlockVectorType::reference reference;
264 const size_type global_index);
290 const size_type global_index,
291 const size_type current_block,
292 const size_type index_within_block,
293 const size_type next_break_forward,
294 const size_type next_break_backward);
308 dereference_type operator * ()
const;
314 dereference_type operator [] (
const difference_type d)
const;
346 template <
bool _Constness>
353 template <
bool _Constness>
361 template <
bool _Constness>
362 bool operator < (const Iterator<BlockVectorType, _Constness> &i)
const;
367 template <
bool _Constness>
368 bool operator <= (const Iterator<BlockVectorType, _Constness> &i)
const;
373 template <
bool _Constness>
379 template <
bool _Constness>
385 template <
bool _Constness>
392 Iterator operator + (
const difference_type &d)
const;
398 Iterator operator - (
const difference_type &d)
const;
404 Iterator &operator += (
const difference_type &d);
410 Iterator &operator -= (
const difference_type &d);
422 "Your program tried to compare iterators pointing to " 423 "different block vectors. There is no reasonable way " 434 "Constructing a non-const iterator from a const " 435 "iterator does not make sense.");
455 size_type index_within_block;
464 size_type next_break_backward;
469 void move_forward ();
474 void move_backward ();
480 template <
typename,
bool>
525 template <
class VectorType>
544 typedef typename BlockType::value_type value_type;
545 typedef value_type *pointer;
546 typedef const value_type *const_pointer;
547 typedef ::internal::BlockVectorIterators::Iterator<BlockVectorBase,false>
iterator;
548 typedef ::internal::BlockVectorIterators::Iterator<BlockVectorBase,true>
const_iterator;
549 typedef typename BlockType::reference reference;
550 typedef typename BlockType::const_reference const_reference;
573 static const bool supports_distributed_data = BlockType::supports_distributed_data;
586 void collect_sizes ();
598 void compress (::VectorOperation::values operation);
604 block (
const unsigned int i);
610 block (
const unsigned int i)
const;
618 get_block_indices ()
const;
623 unsigned int n_blocks ()
const;
629 std::size_t size ()
const;
647 IndexSet locally_owned_elements ()
const;
658 const_iterator begin ()
const;
669 const_iterator end ()
const;
674 value_type operator() (
const size_type i)
const;
679 reference operator() (
const size_type i);
686 value_type operator[] (
const size_type i)
const;
693 reference operator[] (
const size_type i);
701 template <
typename OtherNumber>
702 void extract_subvector_to (
const std::vector<size_type> &indices,
703 std::vector<OtherNumber> &values)
const;
709 template <
typename ForwardIterator,
typename OutputIterator>
710 void extract_subvector_to (ForwardIterator indices_begin,
711 const ForwardIterator indices_end,
712 OutputIterator values_begin)
const;
729 template <
class VectorType2>
737 operator = (
const VectorType &v);
743 template <
class VectorType2>
755 real_type norm_sqr ()
const;
760 value_type mean_value ()
const;
765 real_type l1_norm ()
const;
771 real_type l2_norm ()
const;
777 real_type linfty_norm ()
const;
797 value_type add_and_dot (
const value_type a,
805 bool in_local_range (
const size_type global_index)
const;
812 bool all_zero ()
const;
819 bool is_non_negative ()
const;
838 template <
typename Number>
839 void add (
const std::vector<size_type> &indices,
840 const std::vector<Number> &values);
846 template <
typename Number>
847 void add (
const std::vector<size_type> &indices,
855 template <
typename Number>
856 void add (
const size_type n_elements,
857 const size_type *indices,
858 const Number *values);
864 void add (
const value_type s);
892 void sadd (
const value_type s,
const value_type a,
const BlockVectorBase &V);
897 void sadd (
const value_type s,
const value_type a,
904 void sadd (
const value_type s,
const value_type a,
923 template <
class BlockVector2>
924 void scale (
const BlockVector2 &v);
929 template <
class BlockVector2>
930 void equ (
const value_type a,
const BlockVector2 &V);
949 void update_ghost_values ()
const;
955 std::size_t memory_consumption ()
const;
972 template <
typename N,
bool C>
973 friend class ::internal::BlockVectorIterators::Iterator;
987 namespace BlockVectorIterators
989 template <
class BlockVectorType,
bool Constness>
991 Iterator<BlockVectorType,Constness>::
992 Iterator (
const Iterator<BlockVectorType,Constness> &c)
995 global_index (c.global_index),
996 current_block (c.current_block),
997 index_within_block (c.index_within_block),
998 next_break_forward (c.next_break_forward),
999 next_break_backward (c.next_break_backward)
1004 template <
class BlockVectorType,
bool Constness>
1006 Iterator<BlockVectorType,Constness>::
1007 Iterator (
const Iterator<BlockVectorType,!Constness> &c)
1010 global_index (c.global_index),
1011 current_block (c.current_block),
1012 index_within_block (c.index_within_block),
1013 next_break_forward (c.next_break_forward),
1014 next_break_backward (c.next_break_backward)
1020 #ifdef DEAL_II_WITH_CXX11 1021 static_assert(Constness ==
true,
1022 "Constructing a non-const iterator from a const iterator " 1023 "does not make sense.");
1025 Assert(Constness ==
true, ExcCastingAwayConstness());
1031 template <
class BlockVectorType,
bool Constness>
1033 Iterator<BlockVectorType,Constness>::
1035 const size_type global_index,
1036 const size_type current_block,
1037 const size_type index_within_block,
1038 const size_type next_break_forward,
1039 const size_type next_break_backward)
1042 global_index (global_index),
1043 current_block (current_block),
1044 index_within_block (index_within_block),
1045 next_break_forward (next_break_forward),
1046 next_break_backward (next_break_backward)
1052 template <
class BlockVectorType,
bool Constness>
1054 Iterator<BlockVectorType,Constness> &
1055 Iterator<BlockVectorType,Constness>::
1056 operator = (
const Iterator &c)
1059 global_index = c.global_index;
1060 index_within_block = c.index_within_block;
1061 current_block = c.current_block;
1062 next_break_forward = c.next_break_forward;
1063 next_break_backward = c.next_break_backward;
1070 template <
class BlockVectorType,
bool Constness>
1072 typename Iterator<BlockVectorType,Constness>::dereference_type
1073 Iterator<BlockVectorType,Constness>::operator * ()
const 1075 return parent->
block(current_block)(index_within_block);
1080 template <
class BlockVectorType,
bool Constness>
1082 typename Iterator<BlockVectorType,Constness>::dereference_type
1083 Iterator<BlockVectorType,Constness>::operator [] (
const difference_type d)
const 1090 if ((global_index+d >= next_break_backward) &&
1091 (global_index+d <= next_break_forward))
1092 return parent->block(current_block)(index_within_block + d);
1101 return (*parent)(global_index+d);
1106 template <
class BlockVectorType,
bool Constness>
1108 Iterator<BlockVectorType,Constness> &
1109 Iterator<BlockVectorType,Constness>::operator ++ ()
1117 template <
class BlockVectorType,
bool Constness>
1119 Iterator<BlockVectorType,Constness>
1120 Iterator<BlockVectorType,Constness>::operator ++ (
int)
1122 const Iterator old_value = *
this;
1129 template <
class BlockVectorType,
bool Constness>
1131 Iterator<BlockVectorType,Constness> &
1132 Iterator<BlockVectorType,Constness>::operator -- ()
1140 template <
class BlockVectorType,
bool Constness>
1142 Iterator<BlockVectorType,Constness>
1143 Iterator<BlockVectorType,Constness>::operator -- (
int)
1145 const Iterator old_value = *
this;
1152 template <
class BlockVectorType,
bool Constness>
1153 template <
bool _Constness>
1156 Iterator<BlockVectorType,Constness>::
1157 operator == (
const Iterator<BlockVectorType, _Constness> &i)
const 1159 Assert (parent == i.parent, ExcPointerToDifferentVectors());
1161 return (global_index == i.global_index);
1166 template <
class BlockVectorType,
bool Constness>
1167 template <
bool _Constness>
1170 Iterator<BlockVectorType,Constness>::
1171 operator != (
const Iterator<BlockVectorType, _Constness> &i)
const 1173 Assert (parent == i.parent, ExcPointerToDifferentVectors());
1175 return (global_index != i.global_index);
1180 template <
class BlockVectorType,
bool Constness>
1181 template <
bool _Constness>
1184 Iterator<BlockVectorType,Constness>::
1185 operator < (
const Iterator<BlockVectorType, _Constness> &i)
const 1187 Assert (parent == i.parent, ExcPointerToDifferentVectors());
1189 return (global_index < i.global_index);
1194 template <
class BlockVectorType,
bool Constness>
1195 template <
bool _Constness>
1198 Iterator<BlockVectorType,Constness>::
1199 operator <= (
const Iterator<BlockVectorType, _Constness> &i)
const 1201 Assert (parent == i.parent, ExcPointerToDifferentVectors());
1203 return (global_index <= i.global_index);
1208 template <
class BlockVectorType,
bool Constness>
1209 template <
bool _Constness>
1212 Iterator<BlockVectorType,Constness>::
1213 operator > (
const Iterator<BlockVectorType, _Constness> &i)
const 1215 Assert (parent == i.parent, ExcPointerToDifferentVectors());
1217 return (global_index > i.global_index);
1222 template <
class BlockVectorType,
bool Constness>
1223 template <
bool _Constness>
1226 Iterator<BlockVectorType,Constness>::
1227 operator >= (
const Iterator<BlockVectorType, _Constness> &i)
const 1229 Assert (parent == i.parent, ExcPointerToDifferentVectors());
1231 return (global_index >= i.global_index);
1236 template <
class BlockVectorType,
bool Constness>
1237 template <
bool _Constness>
1239 typename Iterator<BlockVectorType,Constness>::difference_type
1240 Iterator<BlockVectorType,Constness>::
1241 operator - (
const Iterator<BlockVectorType, _Constness> &i)
const 1243 Assert (parent == i.parent, ExcPointerToDifferentVectors());
1245 return (static_cast<signed int>(global_index) -
1246 static_cast<signed int>(i.global_index));
1251 template <
class BlockVectorType,
bool Constness>
1253 Iterator<BlockVectorType,Constness>
1254 Iterator<BlockVectorType,Constness>::
1255 operator + (
const difference_type &d)
const 1262 if ((global_index+d >= next_break_backward) &&
1263 (global_index+d <= next_break_forward))
1264 return Iterator (*parent, global_index+d, current_block,
1265 index_within_block+d,
1266 next_break_forward, next_break_backward);
1271 return Iterator (*parent, global_index+d);
1276 template <
class BlockVectorType,
bool Constness>
1278 Iterator<BlockVectorType,Constness>
1279 Iterator<BlockVectorType,Constness>::
1280 operator - (
const difference_type &d)
const 1287 if ((global_index-d >= next_break_backward) &&
1288 (global_index-d <= next_break_forward))
1289 return Iterator (*parent, global_index-d, current_block,
1290 index_within_block-d,
1291 next_break_forward, next_break_backward);
1296 return Iterator (*parent, global_index-d);
1301 template <
class BlockVectorType,
bool Constness>
1303 Iterator<BlockVectorType,Constness> &
1304 Iterator<BlockVectorType,Constness>::
1305 operator += (
const difference_type &d)
1312 if ((global_index+d >= next_break_backward) &&
1313 (global_index+d <= next_break_forward))
1316 index_within_block += d;
1322 *
this = Iterator (*parent, global_index+d);
1329 template <
class BlockVectorType,
bool Constness>
1331 Iterator<BlockVectorType,Constness> &
1332 Iterator<BlockVectorType,Constness>::
1333 operator -= (
const difference_type &d)
1340 if ((global_index-d >= next_break_backward) &&
1341 (global_index-d <= next_break_forward))
1344 index_within_block -= d;
1350 *
this = Iterator (*parent, global_index-d);
1356 template <
class BlockVectorType,
bool Constness>
1357 Iterator<BlockVectorType,Constness>::
1359 const size_type global_index)
1362 global_index (global_index)
1370 if (global_index < parent.
size())
1372 const std::pair<size_type, size_type>
1374 current_block = indices.first;
1375 index_within_block = indices.second;
1387 this->global_index = parent.
size ();
1389 index_within_block = 0;
1390 next_break_backward = global_index;
1397 template <
class BlockVectorType,
bool Constness>
1399 Iterator<BlockVectorType,Constness>::move_forward ()
1401 if (global_index != next_break_forward)
1402 ++index_within_block;
1407 index_within_block = 0;
1412 next_break_backward = next_break_forward+1;
1431 template <
class BlockVectorType,
bool Constness>
1433 Iterator<BlockVectorType,Constness>::move_backward ()
1435 if (global_index != next_break_backward)
1436 --index_within_block;
1437 else if (current_block != 0)
1446 next_break_forward = next_break_backward-1;
1458 next_break_forward = 0;
1459 next_break_backward = 0;
1471 template <
class VectorType>
1478 template <
class VectorType>
1488 template <
class VectorType>
1497 for (
unsigned int b=0; b<
n_blocks(); ++b)
1510 template <
class VectorType>
1519 template <
class VectorType>
1531 template <
class VectorType>
1543 template <
class VectorType>
1552 template <
class VectorType>
1557 std::vector<size_type> sizes (
n_blocks());
1559 for (size_type i=0; i<
n_blocks(); ++i)
1560 sizes[i] =
block(i).size();
1567 template <
class VectorType>
1572 for (
unsigned int i=0; i<
n_blocks(); ++i)
1573 block(i).compress (operation);
1578 template <
class VectorType>
1588 template <
class VectorType>
1597 template <
class VectorType>
1607 template <
class VectorType>
1616 template <
class VectorType>
1620 (
const size_type global_index)
const 1622 const std::pair<size_type,size_type> local_index
1625 return components[local_index.first].in_local_range (global_index);
1629 template <
class VectorType>
1633 for (size_type i=0; i<
n_blocks(); ++i)
1642 template <
class VectorType>
1646 for (size_type i=0; i<
n_blocks(); ++i)
1655 template <
class VectorType>
1656 typename BlockVectorBase<VectorType>::value_type
1663 value_type sum = 0.;
1664 for (size_type i=0; i<
n_blocks(); ++i)
1671 template <
class VectorType>
1676 for (size_type i=0; i<
n_blocks(); ++i)
1684 template <
class VectorType>
1685 typename BlockVectorBase<VectorType>::value_type
1688 value_type sum = 0.;
1689 for (size_type i=0; i<
n_blocks(); ++i)
1697 template <
class VectorType>
1702 for (size_type i=0; i<
n_blocks(); ++i)
1710 template <
class VectorType>
1719 template <
class VectorType>
1724 for (size_type i=0; i<
n_blocks(); ++i)
1726 value_type newval =
components[i].linfty_norm();
1735 template <
class VectorType>
1736 typename BlockVectorBase<VectorType>::value_type
1738 add_and_dot (
const typename BlockVectorBase<VectorType>::value_type a,
1745 value_type sum = 0.;
1746 for (size_type i=0; i<
n_blocks(); ++i)
1754 template <
class VectorType>
1761 for (size_type i=0; i<
n_blocks(); ++i)
1771 template <
class VectorType>
1778 for (size_type i=0; i<
n_blocks(); ++i)
1787 template <
class VectorType>
1788 template <
typename Number>
1792 const std::vector<Number> &values)
1794 Assert (indices.size() == values.size(),
1795 ExcDimensionMismatch(indices.size(), values.size()));
1796 add (indices.size(), &indices[0], &values[0]);
1801 template <
class VectorType>
1802 template <
typename Number>
1809 ExcDimensionMismatch(indices.size(), values.
size()));
1810 const size_type n_indices = indices.size();
1811 for (size_type i=0; i<n_indices; ++i)
1812 (*
this)(indices[i]) += values(i);
1817 template <
class VectorType>
1818 template <
typename Number>
1822 const size_type *indices,
1823 const Number *values)
1825 for (size_type i=0; i<n_indices; ++i)
1826 (*
this)(indices[i]) += values[i];
1831 template <
class VectorType>
1836 for (size_type i=0; i<
n_blocks(); ++i)
1844 template <
class VectorType>
1852 template <
class VectorType>
1862 for (size_type i=0; i<
n_blocks(); ++i)
1870 template <
class VectorType>
1886 for (size_type i=0; i<
n_blocks(); ++i)
1894 template <
class VectorType>
1904 for (size_type i=0; i<
n_blocks(); ++i)
1912 template <
class VectorType>
1923 for (size_type i=0; i<
n_blocks(); ++i)
1931 template <
class VectorType>
1947 for (size_type i=0; i<
n_blocks(); ++i)
1955 template <
class VectorType>
1976 for (size_type i=0; i<
n_blocks(); ++i)
1985 template <
class VectorType>
1986 template <
class BlockVector2>
1990 ExcDimensionMismatch(
n_blocks(), v.n_blocks()));
1991 for (size_type i=0; i<
n_blocks(); ++i)
1997 template <
class VectorType>
2012 for (size_type i=0; i<
n_blocks(); ++i)
2020 template <
class VectorType>
2024 std::size_t mem =
sizeof(this->
n_blocks());
2025 for (size_type i=0; i<this->
components.size(); ++i)
2033 template <
class VectorType>
2034 template <
class BlockVector2>
2036 const BlockVector2 &v)
2042 ExcDimensionMismatch(
n_blocks(), v.n_blocks()));
2044 for (size_type i=0; i<
n_blocks(); ++i)
2050 template <
class VectorType>
2053 for (size_type i=0; i<
n_blocks(); ++i)
2054 block(i).update_ghost_values ();
2059 template <
class VectorType>
2066 for (size_type i=0; i<
n_blocks(); ++i)
2073 template <
class VectorType>
2079 for (size_type i=0; i<
n_blocks(); ++i)
2086 template <
class VectorType>
2087 template <
class VectorType2>
2093 for (size_type i=0; i<
n_blocks(); ++i)
2101 template <
class VectorType>
2106 ExcDimensionMismatch(
size(), v.size()));
2108 size_type index_v = 0;
2109 for (size_type b=0; b<
n_blocks(); ++b)
2110 for (size_type i=0; i<
block(b).size(); ++i, ++index_v)
2111 block(b)(i) = v(index_v);
2118 template <
class VectorType>
2119 template <
class VectorType2>
2127 for (size_type i=0; i<
n_blocks(); ++i)
2136 template <
class VectorType>
2144 for (size_type i=0; i<
n_blocks(); ++i)
2152 template <
class VectorType>
2159 Assert (factor != 0., ExcDivideByZero() );
2161 for (size_type i=0; i<
n_blocks(); ++i)
2168 template <
class VectorType>
2170 typename BlockVectorBase<VectorType>::value_type
2173 const std::pair<unsigned int,size_type> local_index
2175 return components[local_index.first](local_index.second);
2180 template <
class VectorType>
2182 typename BlockVectorBase<VectorType>::reference
2185 const std::pair<unsigned int,size_type> local_index
2187 return components[local_index.first](local_index.second);
2192 template <
class VectorType>
2194 typename BlockVectorBase<VectorType>::value_type
2202 template <
class VectorType>
2204 typename BlockVectorBase<VectorType>::reference
2212 template <
typename VectorType>
2213 template <
typename OtherNumber>
2216 std::vector<OtherNumber> &values)
const 2218 for (size_type i = 0; i < indices.size(); ++i)
2219 values[i] =
operator()(indices[i]);
2224 template <
typename VectorType>
2225 template <
typename ForwardIterator,
typename OutputIterator>
2228 const ForwardIterator indices_end,
2229 OutputIterator values_begin)
const 2231 while (indices_begin != indices_end)
2241 DEAL_II_NAMESPACE_CLOSE
const types::global_dof_index invalid_size_type
static yes_type check_for_block_vector(const BlockVectorBase< T > *)
BaseClass::value_type value_type
value_type dereference_type
std::random_access_iterator_tag iterator_type
#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
bool operator==(const BlockVectorBase< VectorType2 > &v) const
void compress(::VectorOperation::values operation)
BlockVector::value_type value_type
bool in_local_range(const size_type global_index) const
Auxiliary class aiding in the handling of block structures like in BlockVector or FESystem...
size_type block_size(const unsigned int i) const
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)
Vector::reference dereference_type
#define DEAL_II_DEPRECATED
BlockIndices block_indices
IndexSet locally_owned_elements() const
real_type norm_sqr() const
size_type next_break_forward
unsigned int global_dof_index
const BlockIndices & get_block_indices() const
#define Assert(cond, exc)
BlockType::real_type real_type
void reinit(const unsigned int n_blocks, const size_type n_elements_per_block)
#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
const BlockVectorType BlockVector
BlockVectorBase & operator+=(const BlockVectorBase &V)
std::vector< VectorType > components
BlockVectorBase & operator*=(const value_type factor)
Types< BlockVectorType, Constness >::value_type value_type
unsigned int current_block
const BlockVector::value_type value_type
std_cxx11::enable_if< std_cxx11::is_fundamental< T >::value, std::size_t >::type memory_consumption(const T &t)
BlockVectorType BlockVector
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
BlockVectorType::BlockType Vector
unsigned int n_blocks() const
types::global_dof_index size_type
BlockVectorBase & operator-=(const BlockVectorBase &V)
size_type block_start(const unsigned int i) const
value_type operator()(const size_type i) const
const BlockVectorType::BlockType Vector
real_type linfty_norm() const
unsigned int size() const
BlockType & block(const unsigned int i)
BlockVectorBase & operator=(const value_type s)
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)
value_type mean_value() const
Types< BlockVectorType, Constness >::BlockVector BlockVector