Reference documentation for deal.II version 8.4.2
block_vector_base.h
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 2004 - 2015 by the deal.II authors
4 //
5 // This file is part of the deal.II library.
6 //
7 // The deal.II library is free software; you can use it, redistribute
8 // it, and/or modify it under the terms of the GNU Lesser General
9 // Public License as published by the Free Software Foundation; either
10 // version 2.1 of the License, or (at your option) any later version.
11 // The full text of the license can be found in the file LICENSE at
12 // the top level of the deal.II distribution.
13 //
14 // ---------------------------------------------------------------------
15 
16 #ifndef dealii__block_vector_base_h
17 #define dealii__block_vector_base_h
18 
19 
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>
27 #include <vector>
28 #include <iterator>
29 #include <cmath>
30 #include <cstddef>
31 
32 DEAL_II_NAMESPACE_OPEN
33 
34 
39 template <typename> class BlockVectorBase;
40 
41 
58 template <typename VectorType>
60 {
61 private:
62  struct yes_type
63  {
64  char c[1];
65  };
66  struct no_type
67  {
68  char c[2];
69  };
70 
75  template <typename T>
76  static yes_type check_for_block_vector (const BlockVectorBase<T> *);
77 
82  static no_type check_for_block_vector (...);
83 
84 public:
90  static const bool value = (sizeof(check_for_block_vector
91  ((VectorType *)0))
92  ==
93  sizeof(yes_type));
94 };
95 
96 
97 // instantiation of the static member
98 template <typename VectorType>
100 
101 
102 
103 
104 namespace internal
105 {
106 
112  namespace BlockVectorIterators
113  {
118  template <class BlockVectorType, bool Constness>
119  struct Types
120  {
121  };
122 
123 
124 
131  template <class BlockVectorType>
132  struct Types<BlockVectorType,false>
133  {
138  typedef typename BlockVectorType::BlockType Vector;
139 
144  typedef BlockVectorType BlockVector;
145 
150 
155  typedef typename Vector::reference dereference_type;
156  };
157 
158 
159 
166  template <class BlockVectorType>
167  struct Types<BlockVectorType,true>
168  {
173  typedef const typename BlockVectorType::BlockType Vector;
174 
179  typedef const BlockVectorType BlockVector;
180 
185  typedef const typename BlockVector::value_type value_type;
186 
192  typedef value_type dereference_type;
193  };
194 
195 
213  template <class BlockVectorType, bool Constness>
214  class Iterator :
215  public std::iterator<std::random_access_iterator_tag,
216  typename Types<BlockVectorType,Constness>::value_type>
217  {
218  public:
223 
229  typedef
232 
238  typedef std::random_access_iterator_tag iterator_type;
239  typedef std::ptrdiff_t difference_type;
240  typedef typename BlockVectorType::reference reference;
241  typedef value_type *pointer;
242 
243  typedef
245  dereference_type;
246 
251  typedef
254 
263  Iterator (BlockVector &parent,
264  const size_type global_index);
265 
277 
278 
283 
284  private:
289  Iterator (BlockVector &parent,
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);
295 
296  public:
297 
301  Iterator &operator = (const Iterator &c);
302 
308  dereference_type operator * () const;
309 
314  dereference_type operator [] (const difference_type d) const;
315 
320  Iterator &operator ++ ();
321 
327  Iterator operator ++ (int);
328 
333  Iterator &operator -- ();
334 
340  Iterator operator -- (int);
341 
346  template <bool _Constness>
347  bool operator == (const Iterator<BlockVectorType, _Constness> &i) const;
348 
353  template <bool _Constness>
354  bool operator != (const Iterator<BlockVectorType, _Constness> &i) const;
355 
361  template <bool _Constness>
362  bool operator < (const Iterator<BlockVectorType, _Constness> &i) const;
363 
367  template <bool _Constness>
368  bool operator <= (const Iterator<BlockVectorType, _Constness> &i) const;
369 
373  template <bool _Constness>
374  bool operator > (const Iterator<BlockVectorType, _Constness> &i) const;
375 
379  template <bool _Constness>
380  bool operator >= (const Iterator<BlockVectorType, _Constness> &i) const;
381 
385  template <bool _Constness>
386  difference_type operator - (const Iterator<BlockVectorType, _Constness> &i) const;
387 
392  Iterator operator + (const difference_type &d) const;
393 
398  Iterator operator - (const difference_type &d) const;
399 
404  Iterator &operator += (const difference_type &d);
405 
410  Iterator &operator -= (const difference_type &d);
411 
421  DeclExceptionMsg (ExcPointerToDifferentVectors,
422  "Your program tried to compare iterators pointing to "
423  "different block vectors. There is no reasonable way "
424  "to do this.");
425 
433  DeclExceptionMsg (ExcCastingAwayConstness,
434  "Constructing a non-const iterator from a const "
435  "iterator does not make sense.");
437  private:
444 
448  size_type global_index;
449 
454  unsigned int current_block;
455  size_type index_within_block;
456 
464  size_type next_break_backward;
465 
469  void move_forward ();
470 
474  void move_backward ();
475 
476 
480  template <typename, bool>
481  friend class Iterator;
482  };
483  } // namespace BlockVectorIterators
484 } // namespace internal
485 
486 
525 template <class VectorType>
526 class BlockVectorBase : public Subscriptor
527 {
528 public:
532  typedef VectorType BlockType;
533 
534  /*
535  * Declare standard types used in
536  * all containers. These types
537  * parallel those in the
538  * <tt>C++</tt> standard
539  * libraries
540  * <tt>std::vector<...></tt>
541  * class. This includes iterator
542  * types.
543  */
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;
551  typedef types::global_dof_index size_type;
552 
562  typedef typename BlockType::real_type real_type;
563 
573  static const bool supports_distributed_data = BlockType::supports_distributed_data;
574 
578  BlockVectorBase ();
579 
586  void collect_sizes ();
587 
598  void compress (::VectorOperation::values operation);
599 
603  BlockType &
604  block (const unsigned int i);
605 
609  const BlockType &
610  block (const unsigned int i) const;
611 
617  const BlockIndices &
618  get_block_indices () const;
619 
623  unsigned int n_blocks () const;
624 
629  std::size_t size () const;
630 
647  IndexSet locally_owned_elements () const;
648 
652  iterator begin ();
653 
658  const_iterator begin () const;
659 
663  iterator end ();
664 
669  const_iterator end () const;
670 
674  value_type operator() (const size_type i) const;
675 
679  reference operator() (const size_type i);
680 
686  value_type operator[] (const size_type i) const;
687 
693  reference operator[] (const size_type i);
694 
701  template <typename OtherNumber>
702  void extract_subvector_to (const std::vector<size_type> &indices,
703  std::vector<OtherNumber> &values) const;
704 
709  template <typename ForwardIterator, typename OutputIterator>
710  void extract_subvector_to (ForwardIterator indices_begin,
711  const ForwardIterator indices_end,
712  OutputIterator values_begin) const;
713 
718  BlockVectorBase &operator = (const value_type s);
719 
724  operator= (const BlockVectorBase &V);
725 
729  template <class VectorType2>
731  operator= (const BlockVectorBase<VectorType2> &V);
732 
737  operator = (const VectorType &v);
738 
743  template <class VectorType2>
744  bool
745  operator == (const BlockVectorBase<VectorType2> &v) const;
746 
750  value_type operator* (const BlockVectorBase &V) const;
751 
755  real_type norm_sqr () const;
756 
760  value_type mean_value () const;
761 
765  real_type l1_norm () const;
766 
771  real_type l2_norm () const;
772 
777  real_type linfty_norm () const;
778 
797  value_type add_and_dot (const value_type a,
798  const BlockVectorBase &V,
799  const BlockVectorBase &W);
800 
805  bool in_local_range (const size_type global_index) const;
806 
812  bool all_zero () const;
813 
819  bool is_non_negative () const;
820 
825  operator += (const BlockVectorBase &V);
826 
831  operator -= (const BlockVectorBase &V);
832 
833 
838  template <typename Number>
839  void add (const std::vector<size_type> &indices,
840  const std::vector<Number> &values);
841 
846  template <typename Number>
847  void add (const std::vector<size_type> &indices,
848  const Vector<Number> &values);
849 
855  template <typename Number>
856  void add (const size_type n_elements,
857  const size_type *indices,
858  const Number *values);
859 
864  void add (const value_type s);
865 
871  void add (const BlockVectorBase &V) DEAL_II_DEPRECATED;
872 
876  void add (const value_type a, const BlockVectorBase &V);
877 
881  void add (const value_type a, const BlockVectorBase &V,
882  const value_type b, const BlockVectorBase &W);
883 
887  void sadd (const value_type s, const BlockVectorBase &V);
888 
892  void sadd (const value_type s, const value_type a, const BlockVectorBase &V);
893 
897  void sadd (const value_type s, const value_type a,
898  const BlockVectorBase &V,
899  const value_type b, const BlockVectorBase &W);
900 
904  void sadd (const value_type s, const value_type a,
905  const BlockVectorBase &V,
906  const value_type b, const BlockVectorBase &W,
907  const value_type c, const BlockVectorBase &X);
908 
912  BlockVectorBase &operator *= (const value_type factor);
913 
917  BlockVectorBase &operator /= (const value_type factor);
918 
923  template <class BlockVector2>
924  void scale (const BlockVector2 &v);
925 
929  template <class BlockVector2>
930  void equ (const value_type a, const BlockVector2 &V);
931 
935  void equ (const value_type a, const BlockVectorBase &V,
936  const value_type b, const BlockVectorBase &W);
937 
949  void update_ghost_values () const;
950 
955  std::size_t memory_consumption () const;
956 
957 protected:
961  std::vector<VectorType> components;
962 
968 
972  template <typename N, bool C>
973  friend class ::internal::BlockVectorIterators::Iterator;
974 
975  template <typename> friend class BlockVectorBase;
976 };
977 
978 
981 /*----------------------- Inline functions ----------------------------------*/
982 
983 
984 #ifndef DOXYGEN
985 namespace internal
986 {
987  namespace BlockVectorIterators
988  {
989  template <class BlockVectorType, bool Constness>
990  inline
991  Iterator<BlockVectorType,Constness>::
992  Iterator (const Iterator<BlockVectorType,Constness> &c)
993  :
994  parent (c.parent),
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)
1000  {}
1001 
1002 
1003 
1004  template <class BlockVectorType, bool Constness>
1005  inline
1006  Iterator<BlockVectorType,Constness>::
1007  Iterator (const Iterator<BlockVectorType,!Constness> &c)
1008  :
1009  parent (c.parent),
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)
1015  {
1016  // Only permit copy-constructing const iterators from non-const
1017  // iterators, and not vice versa (i.e., Constness must always be
1018  // true). As mentioned above, try to check this at compile time if C++11
1019  // support is available.
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.");
1024 #else
1025  Assert(Constness == true, ExcCastingAwayConstness());
1026 #endif
1027  }
1028 
1029 
1030 
1031  template <class BlockVectorType, bool Constness>
1032  inline
1033  Iterator<BlockVectorType,Constness>::
1034  Iterator (BlockVector &parent,
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)
1040  :
1041  parent (&parent),
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)
1047  {
1048  }
1049 
1050 
1051 
1052  template <class BlockVectorType, bool Constness>
1053  inline
1054  Iterator<BlockVectorType,Constness> &
1055  Iterator<BlockVectorType,Constness>::
1056  operator = (const Iterator &c)
1057  {
1058  parent = c.parent;
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;
1064 
1065  return *this;
1066  }
1067 
1068 
1069 
1070  template <class BlockVectorType, bool Constness>
1071  inline
1072  typename Iterator<BlockVectorType,Constness>::dereference_type
1073  Iterator<BlockVectorType,Constness>::operator * () const
1074  {
1075  return parent->block(current_block)(index_within_block);
1076  }
1077 
1078 
1079 
1080  template <class BlockVectorType, bool Constness>
1081  inline
1082  typename Iterator<BlockVectorType,Constness>::dereference_type
1083  Iterator<BlockVectorType,Constness>::operator [] (const difference_type d) const
1084  {
1085  // if the index pointed to is
1086  // still within the block we
1087  // currently point into, then we
1088  // can save the computation of
1089  // the block
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);
1093 
1094  // if the index is not within the
1095  // block of the block vector into
1096  // which we presently point, then
1097  // there is no way: we have to
1098  // search for the block. this can
1099  // be done through the parent
1100  // class as well.
1101  return (*parent)(global_index+d);
1102  }
1103 
1104 
1105 
1106  template <class BlockVectorType, bool Constness>
1107  inline
1108  Iterator<BlockVectorType,Constness> &
1109  Iterator<BlockVectorType,Constness>::operator ++ ()
1110  {
1111  move_forward ();
1112  return *this;
1113  }
1114 
1115 
1116 
1117  template <class BlockVectorType, bool Constness>
1118  inline
1119  Iterator<BlockVectorType,Constness>
1120  Iterator<BlockVectorType,Constness>::operator ++ (int)
1121  {
1122  const Iterator old_value = *this;
1123  move_forward ();
1124  return old_value;
1125  }
1126 
1127 
1128 
1129  template <class BlockVectorType, bool Constness>
1130  inline
1131  Iterator<BlockVectorType,Constness> &
1132  Iterator<BlockVectorType,Constness>::operator -- ()
1133  {
1134  move_backward ();
1135  return *this;
1136  }
1137 
1138 
1139 
1140  template <class BlockVectorType, bool Constness>
1141  inline
1142  Iterator<BlockVectorType,Constness>
1143  Iterator<BlockVectorType,Constness>::operator -- (int)
1144  {
1145  const Iterator old_value = *this;
1146  move_backward ();
1147  return old_value;
1148  }
1149 
1150 
1151 
1152  template <class BlockVectorType, bool Constness>
1153  template <bool _Constness>
1154  inline
1155  bool
1156  Iterator<BlockVectorType,Constness>::
1157  operator == (const Iterator<BlockVectorType, _Constness> &i) const
1158  {
1159  Assert (parent == i.parent, ExcPointerToDifferentVectors());
1160 
1161  return (global_index == i.global_index);
1162  }
1163 
1164 
1165 
1166  template <class BlockVectorType, bool Constness>
1167  template <bool _Constness>
1168  inline
1169  bool
1170  Iterator<BlockVectorType,Constness>::
1171  operator != (const Iterator<BlockVectorType, _Constness> &i) const
1172  {
1173  Assert (parent == i.parent, ExcPointerToDifferentVectors());
1174 
1175  return (global_index != i.global_index);
1176  }
1177 
1178 
1179 
1180  template <class BlockVectorType, bool Constness>
1181  template <bool _Constness>
1182  inline
1183  bool
1184  Iterator<BlockVectorType,Constness>::
1185  operator < (const Iterator<BlockVectorType, _Constness> &i) const
1186  {
1187  Assert (parent == i.parent, ExcPointerToDifferentVectors());
1188 
1189  return (global_index < i.global_index);
1190  }
1191 
1192 
1193 
1194  template <class BlockVectorType, bool Constness>
1195  template <bool _Constness>
1196  inline
1197  bool
1198  Iterator<BlockVectorType,Constness>::
1199  operator <= (const Iterator<BlockVectorType, _Constness> &i) const
1200  {
1201  Assert (parent == i.parent, ExcPointerToDifferentVectors());
1202 
1203  return (global_index <= i.global_index);
1204  }
1205 
1206 
1207 
1208  template <class BlockVectorType, bool Constness>
1209  template <bool _Constness>
1210  inline
1211  bool
1212  Iterator<BlockVectorType,Constness>::
1213  operator > (const Iterator<BlockVectorType, _Constness> &i) const
1214  {
1215  Assert (parent == i.parent, ExcPointerToDifferentVectors());
1216 
1217  return (global_index > i.global_index);
1218  }
1219 
1220 
1221 
1222  template <class BlockVectorType, bool Constness>
1223  template <bool _Constness>
1224  inline
1225  bool
1226  Iterator<BlockVectorType,Constness>::
1227  operator >= (const Iterator<BlockVectorType, _Constness> &i) const
1228  {
1229  Assert (parent == i.parent, ExcPointerToDifferentVectors());
1230 
1231  return (global_index >= i.global_index);
1232  }
1233 
1234 
1235 
1236  template <class BlockVectorType, bool Constness>
1237  template <bool _Constness>
1238  inline
1239  typename Iterator<BlockVectorType,Constness>::difference_type
1240  Iterator<BlockVectorType,Constness>::
1241  operator - (const Iterator<BlockVectorType, _Constness> &i) const
1242  {
1243  Assert (parent == i.parent, ExcPointerToDifferentVectors());
1244 
1245  return (static_cast<signed int>(global_index) -
1246  static_cast<signed int>(i.global_index));
1247  }
1248 
1249 
1250 
1251  template <class BlockVectorType, bool Constness>
1252  inline
1253  Iterator<BlockVectorType,Constness>
1254  Iterator<BlockVectorType,Constness>::
1255  operator + (const difference_type &d) const
1256  {
1257  // if the index pointed to is
1258  // still within the block we
1259  // currently point into, then we
1260  // can save the computation of
1261  // the block
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);
1267  else
1268  // outside present block, so
1269  // have to seek new block
1270  // anyway
1271  return Iterator (*parent, global_index+d);
1272  }
1273 
1274 
1275 
1276  template <class BlockVectorType, bool Constness>
1277  inline
1278  Iterator<BlockVectorType,Constness>
1279  Iterator<BlockVectorType,Constness>::
1280  operator - (const difference_type &d) const
1281  {
1282  // if the index pointed to is
1283  // still within the block we
1284  // currently point into, then we
1285  // can save the computation of
1286  // the block
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);
1292  else
1293  // outside present block, so
1294  // have to seek new block
1295  // anyway
1296  return Iterator (*parent, global_index-d);
1297  }
1298 
1299 
1300 
1301  template <class BlockVectorType, bool Constness>
1302  inline
1303  Iterator<BlockVectorType,Constness> &
1304  Iterator<BlockVectorType,Constness>::
1305  operator += (const difference_type &d)
1306  {
1307  // if the index pointed to is
1308  // still within the block we
1309  // currently point into, then we
1310  // can save the computation of
1311  // the block
1312  if ((global_index+d >= next_break_backward) &&
1313  (global_index+d <= next_break_forward))
1314  {
1315  global_index += d;
1316  index_within_block += d;
1317  }
1318  else
1319  // outside present block, so
1320  // have to seek new block
1321  // anyway
1322  *this = Iterator (*parent, global_index+d);
1323 
1324  return *this;
1325  }
1326 
1327 
1328 
1329  template <class BlockVectorType, bool Constness>
1330  inline
1331  Iterator<BlockVectorType,Constness> &
1332  Iterator<BlockVectorType,Constness>::
1333  operator -= (const difference_type &d)
1334  {
1335  // if the index pointed to is
1336  // still within the block we
1337  // currently point into, then we
1338  // can save the computation of
1339  // the block
1340  if ((global_index-d >= next_break_backward) &&
1341  (global_index-d <= next_break_forward))
1342  {
1343  global_index -= d;
1344  index_within_block -= d;
1345  }
1346  else
1347  // outside present block, so
1348  // have to seek new block
1349  // anyway
1350  *this = Iterator (*parent, global_index-d);
1351 
1352  return *this;
1353  }
1354 
1355 
1356  template <class BlockVectorType, bool Constness>
1357  Iterator<BlockVectorType,Constness>::
1358  Iterator (BlockVector &parent,
1359  const size_type global_index)
1360  :
1361  parent (&parent),
1362  global_index (global_index)
1363  {
1364  // find which block we are
1365  // in. for this, take into
1366  // account that it happens at
1367  // times that people want to
1368  // initialize iterators
1369  // past-the-end
1370  if (global_index < parent.size())
1371  {
1372  const std::pair<size_type, size_type>
1373  indices = parent.block_indices.global_to_local(global_index);
1374  current_block = indices.first;
1375  index_within_block = indices.second;
1376 
1377  next_break_backward
1378  = parent.block_indices.local_to_global (current_block, 0);
1379  next_break_forward
1380  = (parent.block_indices.local_to_global (current_block, 0)
1381  +parent.block_indices.block_size(current_block)-1);
1382  }
1383  else
1384  // past the end. only have one
1385  // value for this
1386  {
1387  this->global_index = parent.size ();
1388  current_block = parent.n_blocks();
1389  index_within_block = 0;
1390  next_break_backward = global_index;
1391  next_break_forward = numbers::invalid_size_type;
1392  };
1393  }
1394 
1395 
1396 
1397  template <class BlockVectorType, bool Constness>
1398  void
1399  Iterator<BlockVectorType,Constness>::move_forward ()
1400  {
1401  if (global_index != next_break_forward)
1402  ++index_within_block;
1403  else
1404  {
1405  // ok, we traverse a boundary
1406  // between blocks:
1407  index_within_block = 0;
1408  ++current_block;
1409 
1410  // break backwards is now old
1411  // break forward
1412  next_break_backward = next_break_forward+1;
1413 
1414  // compute new break forward
1415  if (current_block < parent->block_indices.size())
1416  next_break_forward
1417  += parent->block_indices.block_size(current_block);
1418  else
1419  // if we are beyond the end,
1420  // then move the next
1421  // boundary arbitrarily far
1422  // away
1423  next_break_forward = numbers::invalid_size_type;
1424  };
1425 
1426  ++global_index;
1427  }
1428 
1429 
1430 
1431  template <class BlockVectorType, bool Constness>
1432  void
1433  Iterator<BlockVectorType,Constness>::move_backward ()
1434  {
1435  if (global_index != next_break_backward)
1436  --index_within_block;
1437  else if (current_block != 0)
1438  {
1439  // ok, we traverse a boundary
1440  // between blocks:
1441  --current_block;
1442  index_within_block = parent->block_indices.block_size(current_block)-1;
1443 
1444  // break forwards is now old
1445  // break backward
1446  next_break_forward = next_break_backward-1;
1447 
1448  // compute new break forward
1449  next_break_backward
1450  -= parent->block_indices.block_size (current_block);
1451  }
1452  else
1453  // current block was 0, we now
1454  // get into unspecified terrain
1455  {
1456  --current_block;
1457  index_within_block = numbers::invalid_size_type;
1458  next_break_forward = 0;
1459  next_break_backward = 0;
1460  };
1461 
1462  --global_index;
1463  }
1464 
1465 
1466  } // namespace BlockVectorIterators
1467 
1468 } //namespace internal
1469 
1470 
1471 template <class VectorType>
1472 inline
1474 {}
1475 
1476 
1477 
1478 template <class VectorType>
1479 inline
1480 std::size_t
1482 {
1483  return block_indices.total_size();
1484 }
1485 
1486 
1487 
1488 template <class VectorType>
1489 inline
1490 IndexSet
1492 {
1493  IndexSet is (size());
1494 
1495  // copy index sets from blocks into the global one, shifted
1496  // by the appropriate amount for each block
1497  for (unsigned int b=0; b<n_blocks(); ++b)
1498  {
1499  IndexSet x = block(b).locally_owned_elements();
1500  is.add_indices(x, block_indices.block_start(b));
1501  }
1502 
1503  is.compress();
1504 
1505  return is;
1506 }
1507 
1508 
1509 
1510 template <class VectorType>
1511 inline
1512 unsigned int
1514 {
1515  return block_indices.size();
1516 }
1517 
1518 
1519 template <class VectorType>
1520 inline
1522 BlockVectorBase<VectorType>::block (const unsigned int i)
1523 {
1524  Assert(i<n_blocks(), ExcIndexRange(i,0,n_blocks()));
1525 
1526  return components[i];
1527 }
1528 
1529 
1530 
1531 template <class VectorType>
1532 inline
1534 BlockVectorBase<VectorType>::block (const unsigned int i) const
1535 {
1536  Assert(i<n_blocks(), ExcIndexRange(i,0,n_blocks()));
1537 
1538  return components[i];
1539 }
1540 
1541 
1542 
1543 template <class VectorType>
1544 inline
1545 const BlockIndices &
1547 {
1548  return block_indices;
1549 }
1550 
1551 
1552 template <class VectorType>
1553 inline
1554 void
1556 {
1557  std::vector<size_type> sizes (n_blocks());
1558 
1559  for (size_type i=0; i<n_blocks(); ++i)
1560  sizes[i] = block(i).size();
1561 
1562  block_indices.reinit(sizes);
1563 }
1564 
1565 
1566 
1567 template <class VectorType>
1568 inline
1569 void
1570 BlockVectorBase<VectorType>::compress (::VectorOperation::values operation)
1571 {
1572  for (unsigned int i=0; i<n_blocks(); ++i)
1573  block(i).compress (operation);
1574 }
1575 
1576 
1577 
1578 template <class VectorType>
1579 inline
1582 {
1583  return iterator(*this, 0U);
1584 }
1585 
1586 
1587 
1588 template <class VectorType>
1589 inline
1592 {
1593  return const_iterator(*this, 0U);
1594 }
1595 
1596 
1597 template <class VectorType>
1598 inline
1601 {
1602  return iterator(*this, size());
1603 }
1604 
1605 
1606 
1607 template <class VectorType>
1608 inline
1611 {
1612  return const_iterator(*this, size());
1613 }
1614 
1615 
1616 template <class VectorType>
1617 inline
1618 bool
1620 (const size_type global_index) const
1621 {
1622  const std::pair<size_type,size_type> local_index
1623  = block_indices.global_to_local (global_index);
1624 
1625  return components[local_index.first].in_local_range (global_index);
1626 }
1627 
1628 
1629 template <class VectorType>
1630 bool
1632 {
1633  for (size_type i=0; i<n_blocks(); ++i)
1634  if (components[i].all_zero() == false)
1635  return false;
1636 
1637  return true;
1638 }
1639 
1640 
1641 
1642 template <class VectorType>
1643 bool
1645 {
1646  for (size_type i=0; i<n_blocks(); ++i)
1647  if (components[i].is_non_negative() == false)
1648  return false;
1649 
1650  return true;
1651 }
1652 
1653 
1654 
1655 template <class VectorType>
1656 typename BlockVectorBase<VectorType>::value_type
1659 {
1660  Assert (n_blocks() == v.n_blocks(),
1661  ExcDimensionMismatch(n_blocks(), v.n_blocks()));
1662 
1663  value_type sum = 0.;
1664  for (size_type i=0; i<n_blocks(); ++i)
1665  sum += components[i]*v.components[i];
1666 
1667  return sum;
1668 }
1669 
1670 
1671 template <class VectorType>
1674 {
1675  real_type sum = 0.;
1676  for (size_type i=0; i<n_blocks(); ++i)
1677  sum += components[i].norm_sqr();
1678 
1679  return sum;
1680 }
1681 
1682 
1683 
1684 template <class VectorType>
1685 typename BlockVectorBase<VectorType>::value_type
1687 {
1688  value_type sum = 0.;
1689  for (size_type i=0; i<n_blocks(); ++i)
1690  sum += components[i].mean_value() * components[i].size();
1691 
1692  return sum/size();
1693 }
1694 
1695 
1696 
1697 template <class VectorType>
1700 {
1701  real_type sum = 0.;
1702  for (size_type i=0; i<n_blocks(); ++i)
1703  sum += components[i].l1_norm();
1704 
1705  return sum;
1706 }
1707 
1708 
1709 
1710 template <class VectorType>
1713 {
1714  return std::sqrt(norm_sqr());
1715 }
1716 
1717 
1718 
1719 template <class VectorType>
1722 {
1723  real_type sum = 0.;
1724  for (size_type i=0; i<n_blocks(); ++i)
1725  {
1726  value_type newval = components[i].linfty_norm();
1727  if (sum<newval)
1728  sum = newval;
1729  }
1730  return sum;
1731 }
1732 
1733 
1734 
1735 template <class VectorType>
1736 typename BlockVectorBase<VectorType>::value_type
1738 add_and_dot (const typename BlockVectorBase<VectorType>::value_type a,
1739  const BlockVectorBase<VectorType> &V,
1740  const BlockVectorBase<VectorType> &W)
1741 {
1744 
1745  value_type sum = 0.;
1746  for (size_type i=0; i<n_blocks(); ++i)
1747  sum += components[i].add_and_dot(a, V.components[i], W.components[i]);
1748 
1749  return sum;
1750 }
1751 
1752 
1753 
1754 template <class VectorType>
1757 {
1758  Assert (n_blocks() == v.n_blocks(),
1759  ExcDimensionMismatch(n_blocks(), v.n_blocks()));
1760 
1761  for (size_type i=0; i<n_blocks(); ++i)
1762  {
1763  components[i] += v.components[i];
1764  }
1765 
1766  return *this;
1767 }
1768 
1769 
1770 
1771 template <class VectorType>
1774 {
1775  Assert (n_blocks() == v.n_blocks(),
1776  ExcDimensionMismatch(n_blocks(), v.n_blocks()));
1777 
1778  for (size_type i=0; i<n_blocks(); ++i)
1779  {
1780  components[i] -= v.components[i];
1781  }
1782  return *this;
1783 }
1784 
1785 
1786 
1787 template <class VectorType>
1788 template <typename Number>
1789 inline
1790 void
1791 BlockVectorBase<VectorType>::add (const std::vector<size_type> &indices,
1792  const std::vector<Number> &values)
1793 {
1794  Assert (indices.size() == values.size(),
1795  ExcDimensionMismatch(indices.size(), values.size()));
1796  add (indices.size(), &indices[0], &values[0]);
1797 }
1798 
1799 
1800 
1801 template <class VectorType>
1802 template <typename Number>
1803 inline
1804 void
1805 BlockVectorBase<VectorType>::add (const std::vector<size_type> &indices,
1806  const Vector<Number> &values)
1807 {
1808  Assert (indices.size() == values.size(),
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);
1813 }
1814 
1815 
1816 
1817 template <class VectorType>
1818 template <typename Number>
1819 inline
1820 void
1821 BlockVectorBase<VectorType>::add (const size_type n_indices,
1822  const size_type *indices,
1823  const Number *values)
1824 {
1825  for (size_type i=0; i<n_indices; ++i)
1826  (*this)(indices[i]) += values[i];
1827 }
1828 
1829 
1830 
1831 template <class VectorType>
1832 void BlockVectorBase<VectorType>::add (const value_type a)
1833 {
1834  AssertIsFinite(a);
1835 
1836  for (size_type i=0; i<n_blocks(); ++i)
1837  {
1838  components[i].add(a);
1839  }
1840 }
1841 
1842 
1843 
1844 template <class VectorType>
1846 {
1847  *this += v;
1848 }
1849 
1850 
1851 
1852 template <class VectorType>
1853 void BlockVectorBase<VectorType>::add (const value_type a,
1854  const BlockVectorBase<VectorType> &v)
1855 {
1856 
1857  AssertIsFinite(a);
1858 
1859  Assert (n_blocks() == v.n_blocks(),
1860  ExcDimensionMismatch(n_blocks(), v.n_blocks()));
1861 
1862  for (size_type i=0; i<n_blocks(); ++i)
1863  {
1864  components[i].add(a, v.components[i]);
1865  }
1866 }
1867 
1868 
1869 
1870 template <class VectorType>
1871 void BlockVectorBase<VectorType>::add (const value_type a,
1872  const BlockVectorBase<VectorType> &v,
1873  const value_type b,
1874  const BlockVectorBase<VectorType> &w)
1875 {
1876 
1877  AssertIsFinite(a);
1878  AssertIsFinite(b);
1879 
1880  Assert (n_blocks() == v.n_blocks(),
1881  ExcDimensionMismatch(n_blocks(), v.n_blocks()));
1882  Assert (n_blocks() == w.n_blocks(),
1883  ExcDimensionMismatch(n_blocks(), w.n_blocks()));
1884 
1885 
1886  for (size_type i=0; i<n_blocks(); ++i)
1887  {
1888  components[i].add(a, v.components[i], b, w.components[i]);
1889  }
1890 }
1891 
1892 
1893 
1894 template <class VectorType>
1895 void BlockVectorBase<VectorType>::sadd (const value_type x,
1896  const BlockVectorBase<VectorType> &v)
1897 {
1898 
1899  AssertIsFinite(x);
1900 
1901  Assert (n_blocks() == v.n_blocks(),
1902  ExcDimensionMismatch(n_blocks(), v.n_blocks()));
1903 
1904  for (size_type i=0; i<n_blocks(); ++i)
1905  {
1906  components[i].sadd(x, v.components[i]);
1907  }
1908 }
1909 
1910 
1911 
1912 template <class VectorType>
1913 void BlockVectorBase<VectorType>::sadd (const value_type x, const value_type a,
1914  const BlockVectorBase<VectorType> &v)
1915 {
1916 
1917  AssertIsFinite(x);
1918  AssertIsFinite(a);
1919 
1920  Assert (n_blocks() == v.n_blocks(),
1921  ExcDimensionMismatch(n_blocks(), v.n_blocks()));
1922 
1923  for (size_type i=0; i<n_blocks(); ++i)
1924  {
1925  components[i].sadd(x, a, v.components[i]);
1926  }
1927 }
1928 
1929 
1930 
1931 template <class VectorType>
1932 void BlockVectorBase<VectorType>::sadd (const value_type x, const value_type a,
1933  const BlockVectorBase<VectorType> &v,
1934  const value_type b,
1935  const BlockVectorBase<VectorType> &w)
1936 {
1937 
1938  AssertIsFinite(x);
1939  AssertIsFinite(a);
1940  AssertIsFinite(b);
1941 
1942  Assert (n_blocks() == v.n_blocks(),
1943  ExcDimensionMismatch(n_blocks(), v.n_blocks()));
1944  Assert (n_blocks() == w.n_blocks(),
1945  ExcDimensionMismatch(n_blocks(), w.n_blocks()));
1946 
1947  for (size_type i=0; i<n_blocks(); ++i)
1948  {
1949  components[i].sadd(x, a, v.components[i], b, w.components[i]);
1950  }
1951 }
1952 
1953 
1954 
1955 template <class VectorType>
1956 void BlockVectorBase<VectorType>::sadd (const value_type x, const value_type a,
1957  const BlockVectorBase<VectorType> &v,
1958  const value_type b,
1959  const BlockVectorBase<VectorType> &w,
1960  const value_type c,
1961  const BlockVectorBase<VectorType> &y)
1962 {
1963 
1964  AssertIsFinite(x);
1965  AssertIsFinite(a);
1966  AssertIsFinite(b);
1967  AssertIsFinite(c);
1968 
1969  Assert (n_blocks() == v.n_blocks(),
1970  ExcDimensionMismatch(n_blocks(), v.n_blocks()));
1971  Assert (n_blocks() == w.n_blocks(),
1972  ExcDimensionMismatch(n_blocks(), w.n_blocks()));
1973  Assert (n_blocks() == y.n_blocks(),
1974  ExcDimensionMismatch(n_blocks(), y.n_blocks()));
1975 
1976  for (size_type i=0; i<n_blocks(); ++i)
1977  {
1978  components[i].sadd(x, a, v.components[i],
1979  b, w.components[i], c, y.components[i]);
1980  }
1981 }
1982 
1983 
1984 
1985 template <class VectorType>
1986 template <class BlockVector2>
1987 void BlockVectorBase<VectorType>::scale (const BlockVector2 &v)
1988 {
1989  Assert (n_blocks() == v.n_blocks(),
1990  ExcDimensionMismatch(n_blocks(), v.n_blocks()));
1991  for (size_type i=0; i<n_blocks(); ++i)
1992  components[i].scale(v.block(i));
1993 }
1994 
1995 
1996 
1997 template <class VectorType>
1998 void BlockVectorBase<VectorType>::equ (const value_type a,
1999  const BlockVectorBase<VectorType> &v,
2000  const value_type b,
2001  const BlockVectorBase<VectorType> &w)
2002 {
2003 
2004  AssertIsFinite(a);
2005  AssertIsFinite(b);
2006 
2007  Assert (n_blocks() == v.n_blocks(),
2008  ExcDimensionMismatch(n_blocks(), v.n_blocks()));
2009  Assert (n_blocks() == w.n_blocks(),
2010  ExcDimensionMismatch(n_blocks(), w.n_blocks()));
2011 
2012  for (size_type i=0; i<n_blocks(); ++i)
2013  {
2014  components[i].equ( a, v.components[i], b, w.components[i]);
2015  }
2016 }
2017 
2018 
2019 
2020 template <class VectorType>
2021 std::size_t
2023 {
2024  std::size_t mem = sizeof(this->n_blocks());
2025  for (size_type i=0; i<this->components.size(); ++i)
2028  return mem;
2029 }
2030 
2031 
2032 
2033 template <class VectorType>
2034 template <class BlockVector2>
2035 void BlockVectorBase<VectorType>::equ (const value_type a,
2036  const BlockVector2 &v)
2037 {
2038 
2039  AssertIsFinite(a);
2040 
2041  Assert (n_blocks() == v.n_blocks(),
2042  ExcDimensionMismatch(n_blocks(), v.n_blocks()));
2043 
2044  for (size_type i=0; i<n_blocks(); ++i)
2045  components[i].equ( a, v.components[i]);
2046 }
2047 
2048 
2049 
2050 template <class VectorType>
2052 {
2053  for (size_type i=0; i<n_blocks(); ++i)
2054  block(i).update_ghost_values ();
2055 }
2056 
2057 
2058 
2059 template <class VectorType>
2061 BlockVectorBase<VectorType>::operator = (const value_type s)
2062 {
2063 
2064  AssertIsFinite(s);
2065 
2066  for (size_type i=0; i<n_blocks(); ++i)
2067  components[i] = s;
2068 
2069  return *this;
2070 }
2071 
2072 
2073 template <class VectorType>
2076 {
2078 
2079  for (size_type i=0; i<n_blocks(); ++i)
2080  components[i] = v.components[i];
2081 
2082  return *this;
2083 }
2084 
2085 
2086 template <class VectorType>
2087 template <class VectorType2>
2090 {
2092 
2093  for (size_type i=0; i<n_blocks(); ++i)
2094  components[i] = v.components[i];
2095 
2096  return *this;
2097 }
2098 
2099 
2100 
2101 template <class VectorType>
2103 BlockVectorBase<VectorType>::operator = (const VectorType &v)
2104 {
2105  Assert (size() == v.size(),
2106  ExcDimensionMismatch(size(), v.size()));
2107 
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);
2112 
2113  return *this;
2114 }
2115 
2116 
2117 
2118 template <class VectorType>
2119 template <class VectorType2>
2120 inline
2121 bool
2124 {
2125  Assert (block_indices == v.block_indices, ExcDifferentBlockIndices());
2126 
2127  for (size_type i=0; i<n_blocks(); ++i)
2128  if ( ! (components[i] == v.components[i]))
2129  return false;
2130 
2131  return true;
2132 }
2133 
2134 
2135 
2136 template <class VectorType>
2137 inline
2139 BlockVectorBase<VectorType>::operator *= (const value_type factor)
2140 {
2141 
2142  AssertIsFinite(factor);
2143 
2144  for (size_type i=0; i<n_blocks(); ++i)
2145  components[i] *= factor;
2146 
2147  return *this;
2148 }
2149 
2150 
2151 
2152 template <class VectorType>
2153 inline
2155 BlockVectorBase<VectorType>::operator /= (const value_type factor)
2156 {
2157 
2158  AssertIsFinite(factor);
2159  Assert (factor != 0., ExcDivideByZero() );
2160 
2161  for (size_type i=0; i<n_blocks(); ++i)
2162  components[i] /= factor;
2163 
2164  return *this;
2165 }
2166 
2167 
2168 template <class VectorType>
2169 inline
2170 typename BlockVectorBase<VectorType>::value_type
2171 BlockVectorBase<VectorType>::operator() (const size_type i) const
2172 {
2173  const std::pair<unsigned int,size_type> local_index
2175  return components[local_index.first](local_index.second);
2176 }
2177 
2178 
2179 
2180 template <class VectorType>
2181 inline
2182 typename BlockVectorBase<VectorType>::reference
2184 {
2185  const std::pair<unsigned int,size_type> local_index
2187  return components[local_index.first](local_index.second);
2188 }
2189 
2190 
2191 
2192 template <class VectorType>
2193 inline
2194 typename BlockVectorBase<VectorType>::value_type
2195 BlockVectorBase<VectorType>::operator[] (const size_type i) const
2196 {
2197  return operator()(i);
2198 }
2199 
2200 
2201 
2202 template <class VectorType>
2203 inline
2204 typename BlockVectorBase<VectorType>::reference
2206 {
2207  return operator()(i);
2208 }
2209 
2210 
2211 
2212 template <typename VectorType>
2213 template <typename OtherNumber>
2214 inline
2215 void BlockVectorBase<VectorType>::extract_subvector_to (const std::vector<size_type> &indices,
2216  std::vector<OtherNumber> &values) const
2217 {
2218  for (size_type i = 0; i < indices.size(); ++i)
2219  values[i] = operator()(indices[i]);
2220 }
2221 
2222 
2223 
2224 template <typename VectorType>
2225 template <typename ForwardIterator, typename OutputIterator>
2226 inline
2227 void BlockVectorBase<VectorType>::extract_subvector_to (ForwardIterator indices_begin,
2228  const ForwardIterator indices_end,
2229  OutputIterator values_begin) const
2230 {
2231  while (indices_begin != indices_end)
2232  {
2233  *values_begin = operator()(*indices_begin);
2234  indices_begin++;
2235  values_begin++;
2236  }
2237 }
2238 
2239 #endif // DOXYGEN
2240 
2241 DEAL_II_NAMESPACE_CLOSE
2242 
2243 #endif
const types::global_dof_index invalid_size_type
Definition: types.h:173
static yes_type check_for_block_vector(const BlockVectorBase< T > *)
BaseClass::value_type value_type
Definition: block_vector.h:78
std::random_access_iterator_tag iterator_type
#define AssertDimension(dim1, dim2)
Definition: exceptions.h:1052
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)
bool in_local_range(const size_type global_index) const
Auxiliary class aiding in the handling of block structures like in BlockVector or FESystem...
Definition: block_indices.h:54
void collect_sizes()
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)
#define DEAL_II_DEPRECATED
Definition: config.h:88
BlockIndices block_indices
IndexSet locally_owned_elements() const
real_type norm_sqr() const
std::size_t size() const
unsigned int global_dof_index
Definition: types.h:88
const BlockIndices & get_block_indices() const
#define Assert(cond, exc)
Definition: exceptions.h:294
BlockType::real_type real_type
void reinit(const unsigned int n_blocks, const size_type n_elements_per_block)
std::size_t size() const
#define DeclExceptionMsg(Exception, defaulttext)
Definition: exceptions.h:533
real_type l1_norm() const
void update_ghost_values() const
size_type local_to_global(const unsigned int block, const size_type index) const
static const bool value
BlockVectorBase & operator+=(const BlockVectorBase &V)
std::vector< VectorType > components
BlockVectorBase & operator*=(const value_type factor)
bool all_zero() const
Types< BlockVectorType, Constness >::value_type value_type
std_cxx11::enable_if< std_cxx11::is_fundamental< T >::value, std::size_t >::type memory_consumption(const T &t)
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)
iterator end()
size_type block_start(const unsigned int i) const
value_type operator()(const size_type i) const
real_type linfty_norm() const
unsigned int size() const
BlockType & block(const unsigned int i)
iterator begin()
BlockVectorBase & operator=(const value_type s)
std::pair< unsigned int, size_type > global_to_local(const size_type i) const
#define AssertIsFinite(number)
Definition: exceptions.h:1096
void equ(const value_type a, const BlockVector2 &V)
value_type mean_value() const
Types< BlockVectorType, Constness >::BlockVector BlockVector