Reference documentation for deal.II version 8.5.1
block_vector_base.h
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 2004 - 2017 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 
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 
264  const size_type global_index);
265 
277 
278 
282  Iterator (const Iterator &c);
283 
284  private:
290  const size_type global_index,
291  const size_type current_block,
292  const size_type index_within_block,
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 
321 
327  Iterator operator ++ (int);
328 
334 
340  Iterator operator -- (int);
341 
346  template <bool OtherConstness>
348 
353  template <bool OtherConstness>
355 
361  template <bool OtherConstness>
362  bool operator < (const Iterator<BlockVectorType, OtherConstness> &i) const;
363 
367  template <bool OtherConstness>
368  bool operator <= (const Iterator<BlockVectorType, OtherConstness> &i) const;
369 
373  template <bool OtherConstness>
375 
379  template <bool OtherConstness>
381 
385  template <bool OtherConstness>
386  difference_type operator - (const Iterator<BlockVectorType, OtherConstness> &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 
422  "Your program tried to compare iterators pointing to "
423  "different block vectors. There is no reasonable way "
424  "to do this.");
425 
434  "Constructing a non-const iterator from a const "
435  "iterator does not make sense.");
437  private:
444 
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 
576  static const bool supports_distributed_data DEAL_II_DEPRECATED = !is_serial_vector<BlockType>::value;
577 
581  BlockVectorBase ();
582 
583 #ifdef DEAL_II_WITH_CXX11
584 
587  BlockVectorBase (const BlockVectorBase &V) = default;
588 
597  BlockVectorBase (BlockVectorBase &&/*V*/) = default;
598 #endif
599 
606  void collect_sizes ();
607 
618  void compress (::VectorOperation::values operation);
619 
623  BlockType &
624  block (const unsigned int i);
625 
629  const BlockType &
630  block (const unsigned int i) const;
631 
637  const BlockIndices &
638  get_block_indices () const;
639 
643  unsigned int n_blocks () const;
644 
649  std::size_t size () const;
650 
668 
672  iterator begin ();
673 
678  const_iterator begin () const;
679 
683  iterator end ();
684 
689  const_iterator end () const;
690 
694  value_type operator() (const size_type i) const;
695 
699  reference operator() (const size_type i);
700 
706  value_type operator[] (const size_type i) const;
707 
713  reference operator[] (const size_type i);
714 
721  template <typename OtherNumber>
722  void extract_subvector_to (const std::vector<size_type> &indices,
723  std::vector<OtherNumber> &values) const;
724 
729  template <typename ForwardIterator, typename OutputIterator>
730  void extract_subvector_to (ForwardIterator indices_begin,
731  const ForwardIterator indices_end,
732  OutputIterator values_begin) const;
733 
738  BlockVectorBase &operator = (const value_type s);
739 
744  operator= (const BlockVectorBase &V);
745 
746 #ifdef DEAL_II_WITH_CXX11
747 
752  BlockVectorBase &operator= (BlockVectorBase &&/*V*/) = default;
753 #endif
754 
758  template <class VectorType2>
761 
766  operator = (const VectorType &v);
767 
772  template <class VectorType2>
773  bool
775 
779  value_type operator* (const BlockVectorBase &V) const;
780 
784  real_type norm_sqr () const;
785 
789  value_type mean_value () const;
790 
794  real_type l1_norm () const;
795 
800  real_type l2_norm () const;
801 
806  real_type linfty_norm () const;
807 
826  value_type add_and_dot (const value_type a,
827  const BlockVectorBase &V,
828  const BlockVectorBase &W);
829 
834  bool in_local_range (const size_type global_index) const;
835 
841  bool all_zero () const;
842 
848  bool is_non_negative () const;
849 
854  operator += (const BlockVectorBase &V);
855 
860  operator -= (const BlockVectorBase &V);
861 
862 
867  template <typename Number>
868  void add (const std::vector<size_type> &indices,
869  const std::vector<Number> &values);
870 
875  template <typename Number>
876  void add (const std::vector<size_type> &indices,
877  const Vector<Number> &values);
878 
884  template <typename Number>
885  void add (const size_type n_elements,
886  const size_type *indices,
887  const Number *values);
888 
893  void add (const value_type s);
894 
900  void add (const BlockVectorBase &V) DEAL_II_DEPRECATED;
901 
905  void add (const value_type a, const BlockVectorBase &V);
906 
910  void add (const value_type a, const BlockVectorBase &V,
911  const value_type b, const BlockVectorBase &W);
912 
916  void sadd (const value_type s, const BlockVectorBase &V);
917 
921  void sadd (const value_type s, const value_type a, const BlockVectorBase &V);
922 
926  void sadd (const value_type s, const value_type a,
927  const BlockVectorBase &V,
928  const value_type b, const BlockVectorBase &W);
929 
933  void sadd (const value_type s, const value_type a,
934  const BlockVectorBase &V,
935  const value_type b, const BlockVectorBase &W,
936  const value_type c, const BlockVectorBase &X);
937 
941  BlockVectorBase &operator *= (const value_type factor);
942 
946  BlockVectorBase &operator /= (const value_type factor);
947 
952  template <class BlockVector2>
953  void scale (const BlockVector2 &v);
954 
958  template <class BlockVector2>
959  void equ (const value_type a, const BlockVector2 &V);
960 
964  void equ (const value_type a, const BlockVectorBase &V,
965  const value_type b, const BlockVectorBase &W);
966 
978  void update_ghost_values () const;
979 
984  std::size_t memory_consumption () const;
985 
986 protected:
990  std::vector<VectorType> components;
991 
997 
1001  template <typename N, bool C>
1002  friend class ::internal::BlockVectorIterators::Iterator;
1003 
1004  template <typename> friend class BlockVectorBase;
1005 };
1006 
1007 
1010 /*----------------------- Inline functions ----------------------------------*/
1011 
1012 
1013 #ifndef DOXYGEN
1014 namespace internal
1015 {
1016  namespace BlockVectorIterators
1017  {
1018  template <class BlockVectorType, bool Constness>
1019  inline
1021  Iterator (const Iterator<BlockVectorType,Constness> &c)
1022  :
1023  parent (c.parent),
1024  global_index (c.global_index),
1025  current_block (c.current_block),
1026  index_within_block (c.index_within_block),
1027  next_break_forward (c.next_break_forward),
1028  next_break_backward (c.next_break_backward)
1029  {}
1030 
1031 
1032 
1033  template <class BlockVectorType, bool Constness>
1034  inline
1035  Iterator<BlockVectorType,Constness>::
1036  Iterator (const Iterator<BlockVectorType,!Constness> &c)
1037  :
1038  parent (c.parent),
1039  global_index (c.global_index),
1040  current_block (c.current_block),
1041  index_within_block (c.index_within_block),
1042  next_break_forward (c.next_break_forward),
1043  next_break_backward (c.next_break_backward)
1044  {
1045  // Only permit copy-constructing const iterators from non-const
1046  // iterators, and not vice versa (i.e., Constness must always be
1047  // true). As mentioned above, try to check this at compile time if C++11
1048  // support is available.
1049 #ifdef DEAL_II_WITH_CXX11
1050  static_assert(Constness == true,
1051  "Constructing a non-const iterator from a const iterator "
1052  "does not make sense.");
1053 #else
1054  Assert(Constness == true, ExcCastingAwayConstness());
1055 #endif
1056  }
1057 
1058 
1059 
1060  template <class BlockVectorType, bool Constness>
1061  inline
1062  Iterator<BlockVectorType,Constness>::
1063  Iterator (BlockVector &parent,
1064  const size_type global_index,
1065  const size_type current_block,
1066  const size_type index_within_block,
1067  const size_type next_break_forward,
1068  const size_type next_break_backward)
1069  :
1070  parent (&parent),
1071  global_index (global_index),
1072  current_block (current_block),
1073  index_within_block (index_within_block),
1074  next_break_forward (next_break_forward),
1075  next_break_backward (next_break_backward)
1076  {
1077  }
1078 
1079 
1080 
1081  template <class BlockVectorType, bool Constness>
1082  inline
1083  Iterator<BlockVectorType,Constness> &
1084  Iterator<BlockVectorType,Constness>::
1085  operator = (const Iterator &c)
1086  {
1087  parent = c.parent;
1088  global_index = c.global_index;
1089  index_within_block = c.index_within_block;
1090  current_block = c.current_block;
1091  next_break_forward = c.next_break_forward;
1092  next_break_backward = c.next_break_backward;
1093 
1094  return *this;
1095  }
1096 
1097 
1098 
1099  template <class BlockVectorType, bool Constness>
1100  inline
1101  typename Iterator<BlockVectorType,Constness>::dereference_type
1102  Iterator<BlockVectorType,Constness>::operator * () const
1103  {
1104  return parent->block(current_block)(index_within_block);
1105  }
1106 
1107 
1108 
1109  template <class BlockVectorType, bool Constness>
1110  inline
1111  typename Iterator<BlockVectorType,Constness>::dereference_type
1112  Iterator<BlockVectorType,Constness>::operator [] (const difference_type d) const
1113  {
1114  // if the index pointed to is
1115  // still within the block we
1116  // currently point into, then we
1117  // can save the computation of
1118  // the block
1119  if ((global_index+d >= next_break_backward) &&
1120  (global_index+d <= next_break_forward))
1121  return parent->block(current_block)(index_within_block + d);
1122 
1123  // if the index is not within the
1124  // block of the block vector into
1125  // which we presently point, then
1126  // there is no way: we have to
1127  // search for the block. this can
1128  // be done through the parent
1129  // class as well.
1130  return (*parent)(global_index+d);
1131  }
1132 
1133 
1134 
1135  template <class BlockVectorType, bool Constness>
1136  inline
1137  Iterator<BlockVectorType,Constness> &
1138  Iterator<BlockVectorType,Constness>::operator ++ ()
1139  {
1140  move_forward ();
1141  return *this;
1142  }
1143 
1144 
1145 
1146  template <class BlockVectorType, bool Constness>
1147  inline
1148  Iterator<BlockVectorType,Constness>
1149  Iterator<BlockVectorType,Constness>::operator ++ (int)
1150  {
1151  const Iterator old_value = *this;
1152  move_forward ();
1153  return old_value;
1154  }
1155 
1156 
1157 
1158  template <class BlockVectorType, bool Constness>
1159  inline
1160  Iterator<BlockVectorType,Constness> &
1161  Iterator<BlockVectorType,Constness>::operator -- ()
1162  {
1163  move_backward ();
1164  return *this;
1165  }
1166 
1167 
1168 
1169  template <class BlockVectorType, bool Constness>
1170  inline
1171  Iterator<BlockVectorType,Constness>
1172  Iterator<BlockVectorType,Constness>::operator -- (int)
1173  {
1174  const Iterator old_value = *this;
1175  move_backward ();
1176  return old_value;
1177  }
1178 
1179 
1180 
1181  template <class BlockVectorType, bool Constness>
1182  template <bool OtherConstness>
1183  inline
1184  bool
1185  Iterator<BlockVectorType,Constness>::
1186  operator == (const Iterator<BlockVectorType, OtherConstness> &i) const
1187  {
1188  Assert (parent == i.parent, ExcPointerToDifferentVectors());
1189 
1190  return (global_index == i.global_index);
1191  }
1192 
1193 
1194 
1195  template <class BlockVectorType, bool Constness>
1196  template <bool OtherConstness>
1197  inline
1198  bool
1199  Iterator<BlockVectorType,Constness>::
1200  operator != (const Iterator<BlockVectorType, OtherConstness> &i) const
1201  {
1202  Assert (parent == i.parent, ExcPointerToDifferentVectors());
1203 
1204  return (global_index != i.global_index);
1205  }
1206 
1207 
1208 
1209  template <class BlockVectorType, bool Constness>
1210  template <bool OtherConstness>
1211  inline
1212  bool
1213  Iterator<BlockVectorType,Constness>::
1214  operator < (const Iterator<BlockVectorType, OtherConstness> &i) const
1215  {
1216  Assert (parent == i.parent, ExcPointerToDifferentVectors());
1217 
1218  return (global_index < i.global_index);
1219  }
1220 
1221 
1222 
1223  template <class BlockVectorType, bool Constness>
1224  template <bool OtherConstness>
1225  inline
1226  bool
1227  Iterator<BlockVectorType,Constness>::
1228  operator <= (const Iterator<BlockVectorType, OtherConstness> &i) const
1229  {
1230  Assert (parent == i.parent, ExcPointerToDifferentVectors());
1231 
1232  return (global_index <= i.global_index);
1233  }
1234 
1235 
1236 
1237  template <class BlockVectorType, bool Constness>
1238  template <bool OtherConstness>
1239  inline
1240  bool
1241  Iterator<BlockVectorType,Constness>::
1242  operator > (const Iterator<BlockVectorType, OtherConstness> &i) const
1243  {
1244  Assert (parent == i.parent, ExcPointerToDifferentVectors());
1245 
1246  return (global_index > i.global_index);
1247  }
1248 
1249 
1250 
1251  template <class BlockVectorType, bool Constness>
1252  template <bool OtherConstness>
1253  inline
1254  bool
1255  Iterator<BlockVectorType,Constness>::
1256  operator >= (const Iterator<BlockVectorType, OtherConstness> &i) const
1257  {
1258  Assert (parent == i.parent, ExcPointerToDifferentVectors());
1259 
1260  return (global_index >= i.global_index);
1261  }
1262 
1263 
1264 
1265  template <class BlockVectorType, bool Constness>
1266  template <bool OtherConstness>
1267  inline
1268  typename Iterator<BlockVectorType,Constness>::difference_type
1269  Iterator<BlockVectorType,Constness>::
1270  operator - (const Iterator<BlockVectorType, OtherConstness> &i) const
1271  {
1272  Assert (parent == i.parent, ExcPointerToDifferentVectors());
1273 
1274  return (static_cast<signed int>(global_index) -
1275  static_cast<signed int>(i.global_index));
1276  }
1277 
1278 
1279 
1280  template <class BlockVectorType, bool Constness>
1281  inline
1282  Iterator<BlockVectorType,Constness>
1283  Iterator<BlockVectorType,Constness>::
1284  operator + (const difference_type &d) const
1285  {
1286  // if the index pointed to is
1287  // still within the block we
1288  // currently point into, then we
1289  // can save the computation of
1290  // the block
1291  if ((global_index+d >= next_break_backward) &&
1292  (global_index+d <= next_break_forward))
1293  return Iterator (*parent, global_index+d, current_block,
1294  index_within_block+d,
1295  next_break_forward, next_break_backward);
1296  else
1297  // outside present block, so
1298  // have to seek new block
1299  // anyway
1300  return Iterator (*parent, global_index+d);
1301  }
1302 
1303 
1304 
1305  template <class BlockVectorType, bool Constness>
1306  inline
1307  Iterator<BlockVectorType,Constness>
1308  Iterator<BlockVectorType,Constness>::
1309  operator - (const difference_type &d) const
1310  {
1311  // if the index pointed to is
1312  // still within the block we
1313  // currently point into, then we
1314  // can save the computation of
1315  // the block
1316  if ((global_index-d >= next_break_backward) &&
1317  (global_index-d <= next_break_forward))
1318  return Iterator (*parent, global_index-d, current_block,
1319  index_within_block-d,
1320  next_break_forward, next_break_backward);
1321  else
1322  // outside present block, so
1323  // have to seek new block
1324  // anyway
1325  return Iterator (*parent, global_index-d);
1326  }
1327 
1328 
1329 
1330  template <class BlockVectorType, bool Constness>
1331  inline
1332  Iterator<BlockVectorType,Constness> &
1333  Iterator<BlockVectorType,Constness>::
1334  operator += (const difference_type &d)
1335  {
1336  // if the index pointed to is
1337  // still within the block we
1338  // currently point into, then we
1339  // can save the computation of
1340  // the block
1341  if ((global_index+d >= next_break_backward) &&
1342  (global_index+d <= next_break_forward))
1343  {
1344  global_index += d;
1345  index_within_block += d;
1346  }
1347  else
1348  // outside present block, so
1349  // have to seek new block
1350  // anyway
1351  *this = Iterator (*parent, global_index+d);
1352 
1353  return *this;
1354  }
1355 
1356 
1357 
1358  template <class BlockVectorType, bool Constness>
1359  inline
1360  Iterator<BlockVectorType,Constness> &
1361  Iterator<BlockVectorType,Constness>::
1362  operator -= (const difference_type &d)
1363  {
1364  // if the index pointed to is
1365  // still within the block we
1366  // currently point into, then we
1367  // can save the computation of
1368  // the block
1369  if ((global_index-d >= next_break_backward) &&
1370  (global_index-d <= next_break_forward))
1371  {
1372  global_index -= d;
1373  index_within_block -= d;
1374  }
1375  else
1376  // outside present block, so
1377  // have to seek new block
1378  // anyway
1379  *this = Iterator (*parent, global_index-d);
1380 
1381  return *this;
1382  }
1383 
1384 
1385  template <class BlockVectorType, bool Constness>
1386  Iterator<BlockVectorType,Constness>::
1387  Iterator (BlockVector &parent,
1388  const size_type global_index)
1389  :
1390  parent (&parent),
1391  global_index (global_index)
1392  {
1393  // find which block we are
1394  // in. for this, take into
1395  // account that it happens at
1396  // times that people want to
1397  // initialize iterators
1398  // past-the-end
1399  if (global_index < parent.size())
1400  {
1401  const std::pair<size_type, size_type>
1402  indices = parent.block_indices.global_to_local(global_index);
1403  current_block = indices.first;
1404  index_within_block = indices.second;
1405 
1406  next_break_backward
1407  = parent.block_indices.local_to_global (current_block, 0);
1408  next_break_forward
1409  = (parent.block_indices.local_to_global (current_block, 0)
1410  +parent.block_indices.block_size(current_block)-1);
1411  }
1412  else
1413  // past the end. only have one
1414  // value for this
1415  {
1416  this->global_index = parent.size ();
1417  current_block = parent.n_blocks();
1418  index_within_block = 0;
1419  next_break_backward = global_index;
1420  next_break_forward = numbers::invalid_size_type;
1421  };
1422  }
1423 
1424 
1425 
1426  template <class BlockVectorType, bool Constness>
1427  void
1428  Iterator<BlockVectorType,Constness>::move_forward ()
1429  {
1430  if (global_index != next_break_forward)
1431  ++index_within_block;
1432  else
1433  {
1434  // ok, we traverse a boundary
1435  // between blocks:
1436  index_within_block = 0;
1437  ++current_block;
1438 
1439  // break backwards is now old
1440  // break forward
1441  next_break_backward = next_break_forward+1;
1442 
1443  // compute new break forward
1444  if (current_block < parent->block_indices.size())
1445  next_break_forward
1446  += parent->block_indices.block_size(current_block);
1447  else
1448  // if we are beyond the end,
1449  // then move the next
1450  // boundary arbitrarily far
1451  // away
1452  next_break_forward = numbers::invalid_size_type;
1453  };
1454 
1455  ++global_index;
1456  }
1457 
1458 
1459 
1460  template <class BlockVectorType, bool Constness>
1461  void
1462  Iterator<BlockVectorType,Constness>::move_backward ()
1463  {
1464  if (global_index != next_break_backward)
1465  --index_within_block;
1466  else if (current_block != 0)
1467  {
1468  // ok, we traverse a boundary
1469  // between blocks:
1470  --current_block;
1471  index_within_block = parent->block_indices.block_size(current_block)-1;
1472 
1473  // break forwards is now old
1474  // break backward
1475  next_break_forward = next_break_backward-1;
1476 
1477  // compute new break forward
1478  next_break_backward
1479  -= parent->block_indices.block_size (current_block);
1480  }
1481  else
1482  // current block was 0, we now
1483  // get into unspecified terrain
1484  {
1485  --current_block;
1486  index_within_block = numbers::invalid_size_type;
1487  next_break_forward = 0;
1488  next_break_backward = 0;
1489  };
1490 
1491  --global_index;
1492  }
1493 
1494 
1495  } // namespace BlockVectorIterators
1496 
1497 } //namespace internal
1498 
1499 
1500 
1501 template <class VectorType>
1502 inline
1504 {}
1505 
1506 
1507 
1508 template <class VectorType>
1509 inline
1510 std::size_t
1512 {
1513  return block_indices.total_size();
1514 }
1515 
1516 
1517 
1518 template <class VectorType>
1519 inline
1520 IndexSet
1522 {
1523  IndexSet is (size());
1524 
1525  // copy index sets from blocks into the global one, shifted
1526  // by the appropriate amount for each block
1527  for (unsigned int b=0; b<n_blocks(); ++b)
1528  {
1529  IndexSet x = block(b).locally_owned_elements();
1530  is.add_indices(x, block_indices.block_start(b));
1531  }
1532 
1533  is.compress();
1534 
1535  return is;
1536 }
1537 
1538 
1539 
1540 template <class VectorType>
1541 inline
1542 unsigned int
1544 {
1545  return block_indices.size();
1546 }
1547 
1548 
1549 template <class VectorType>
1550 inline
1552 BlockVectorBase<VectorType>::block (const unsigned int i)
1553 {
1554  Assert(i<n_blocks(), ExcIndexRange(i,0,n_blocks()));
1555 
1556  return components[i];
1557 }
1558 
1559 
1560 
1561 template <class VectorType>
1562 inline
1564 BlockVectorBase<VectorType>::block (const unsigned int i) const
1565 {
1566  Assert(i<n_blocks(), ExcIndexRange(i,0,n_blocks()));
1567 
1568  return components[i];
1569 }
1570 
1571 
1572 
1573 template <class VectorType>
1574 inline
1575 const BlockIndices &
1577 {
1578  return block_indices;
1579 }
1580 
1581 
1582 template <class VectorType>
1583 inline
1584 void
1586 {
1587  std::vector<size_type> sizes (n_blocks());
1588 
1589  for (size_type i=0; i<n_blocks(); ++i)
1590  sizes[i] = block(i).size();
1591 
1592  block_indices.reinit(sizes);
1593 }
1594 
1595 
1596 
1597 template <class VectorType>
1598 inline
1599 void
1601 {
1602  for (unsigned int i=0; i<n_blocks(); ++i)
1603  block(i).compress (operation);
1604 }
1605 
1606 
1607 
1608 template <class VectorType>
1609 inline
1612 {
1613  return iterator(*this, 0U);
1614 }
1615 
1616 
1617 
1618 template <class VectorType>
1619 inline
1622 {
1623  return const_iterator(*this, 0U);
1624 }
1625 
1626 
1627 template <class VectorType>
1628 inline
1631 {
1632  return iterator(*this, size());
1633 }
1634 
1635 
1636 
1637 template <class VectorType>
1638 inline
1641 {
1642  return const_iterator(*this, size());
1643 }
1644 
1645 
1646 template <class VectorType>
1647 inline
1648 bool
1650 (const size_type global_index) const
1651 {
1652  const std::pair<size_type,size_type> local_index
1653  = block_indices.global_to_local (global_index);
1654 
1655  return components[local_index.first].in_local_range (global_index);
1656 }
1657 
1658 
1659 template <class VectorType>
1660 bool
1662 {
1663  for (size_type i=0; i<n_blocks(); ++i)
1664  if (components[i].all_zero() == false)
1665  return false;
1666 
1667  return true;
1668 }
1669 
1670 
1671 
1672 template <class VectorType>
1673 bool
1675 {
1676  for (size_type i=0; i<n_blocks(); ++i)
1677  if (components[i].is_non_negative() == false)
1678  return false;
1679 
1680  return true;
1681 }
1682 
1683 
1684 
1685 template <class VectorType>
1686 typename BlockVectorBase<VectorType>::value_type
1689 {
1690  Assert (n_blocks() == v.n_blocks(),
1691  ExcDimensionMismatch(n_blocks(), v.n_blocks()));
1692 
1693  value_type sum = 0.;
1694  for (size_type i=0; i<n_blocks(); ++i)
1695  sum += components[i]*v.components[i];
1696 
1697  return sum;
1698 }
1699 
1700 
1701 template <class VectorType>
1704 {
1705  real_type sum = 0.;
1706  for (size_type i=0; i<n_blocks(); ++i)
1707  sum += components[i].norm_sqr();
1708 
1709  return sum;
1710 }
1711 
1712 
1713 
1714 template <class VectorType>
1715 typename BlockVectorBase<VectorType>::value_type
1717 {
1718  value_type sum = 0.;
1719  // need to do static_cast as otherwise it won't work with value_type=complex<T>
1720  for (size_type i=0; i<n_blocks(); ++i)
1721  sum += components[i].mean_value() * static_cast<double>(components[i].size());
1722 
1723  return sum/static_cast<double>(size());
1724 }
1725 
1726 
1727 
1728 template <class VectorType>
1731 {
1732  real_type sum = 0.;
1733  for (size_type i=0; i<n_blocks(); ++i)
1734  sum += components[i].l1_norm();
1735 
1736  return sum;
1737 }
1738 
1739 
1740 
1741 template <class VectorType>
1744 {
1745  return std::sqrt(norm_sqr());
1746 }
1747 
1748 
1749 
1750 template <class VectorType>
1753 {
1754  real_type sum = 0.;
1755  for (size_type i=0; i<n_blocks(); ++i)
1756  {
1757  value_type newval = components[i].linfty_norm();
1758  if (sum<newval)
1759  sum = newval;
1760  }
1761  return sum;
1762 }
1763 
1764 
1765 
1766 template <class VectorType>
1767 typename BlockVectorBase<VectorType>::value_type
1769 add_and_dot (const typename BlockVectorBase<VectorType>::value_type a,
1770  const BlockVectorBase<VectorType> &V,
1771  const BlockVectorBase<VectorType> &W)
1772 {
1773  AssertDimension (n_blocks(), V.n_blocks());
1774  AssertDimension (n_blocks(), W.n_blocks());
1775 
1776  value_type sum = 0.;
1777  for (size_type i=0; i<n_blocks(); ++i)
1778  sum += components[i].add_and_dot(a, V.components[i], W.components[i]);
1779 
1780  return sum;
1781 }
1782 
1783 
1784 
1785 template <class VectorType>
1788 {
1789  Assert (n_blocks() == v.n_blocks(),
1790  ExcDimensionMismatch(n_blocks(), v.n_blocks()));
1791 
1792  for (size_type i=0; i<n_blocks(); ++i)
1793  {
1794  components[i] += v.components[i];
1795  }
1796 
1797  return *this;
1798 }
1799 
1800 
1801 
1802 template <class VectorType>
1805 {
1806  Assert (n_blocks() == v.n_blocks(),
1807  ExcDimensionMismatch(n_blocks(), v.n_blocks()));
1808 
1809  for (size_type i=0; i<n_blocks(); ++i)
1810  {
1811  components[i] -= v.components[i];
1812  }
1813  return *this;
1814 }
1815 
1816 
1817 
1818 template <class VectorType>
1819 template <typename Number>
1820 inline
1821 void
1822 BlockVectorBase<VectorType>::add (const std::vector<size_type> &indices,
1823  const std::vector<Number> &values)
1824 {
1825  Assert (indices.size() == values.size(),
1826  ExcDimensionMismatch(indices.size(), values.size()));
1827  add (indices.size(), &indices[0], &values[0]);
1828 }
1829 
1830 
1831 
1832 template <class VectorType>
1833 template <typename Number>
1834 inline
1835 void
1836 BlockVectorBase<VectorType>::add (const std::vector<size_type> &indices,
1837  const Vector<Number> &values)
1838 {
1839  Assert (indices.size() == values.size(),
1840  ExcDimensionMismatch(indices.size(), values.size()));
1841  const size_type n_indices = indices.size();
1842  for (size_type i=0; i<n_indices; ++i)
1843  (*this)(indices[i]) += values(i);
1844 }
1845 
1846 
1847 
1848 template <class VectorType>
1849 template <typename Number>
1850 inline
1851 void
1852 BlockVectorBase<VectorType>::add (const size_type n_indices,
1853  const size_type *indices,
1854  const Number *values)
1855 {
1856  for (size_type i=0; i<n_indices; ++i)
1857  (*this)(indices[i]) += values[i];
1858 }
1859 
1860 
1861 
1862 template <class VectorType>
1863 void BlockVectorBase<VectorType>::add (const value_type a)
1864 {
1865  AssertIsFinite(a);
1866 
1867  for (size_type i=0; i<n_blocks(); ++i)
1868  {
1869  components[i].add(a);
1870  }
1871 }
1872 
1873 
1874 
1875 template <class VectorType>
1877 {
1878  *this += v;
1879 }
1880 
1881 
1882 
1883 template <class VectorType>
1884 void BlockVectorBase<VectorType>::add (const value_type a,
1885  const BlockVectorBase<VectorType> &v)
1886 {
1887 
1888  AssertIsFinite(a);
1889 
1890  Assert (n_blocks() == v.n_blocks(),
1891  ExcDimensionMismatch(n_blocks(), v.n_blocks()));
1892 
1893  for (size_type i=0; i<n_blocks(); ++i)
1894  {
1895  components[i].add(a, v.components[i]);
1896  }
1897 }
1898 
1899 
1900 
1901 template <class VectorType>
1902 void BlockVectorBase<VectorType>::add (const value_type a,
1903  const BlockVectorBase<VectorType> &v,
1904  const value_type b,
1905  const BlockVectorBase<VectorType> &w)
1906 {
1907 
1908  AssertIsFinite(a);
1909  AssertIsFinite(b);
1910 
1911  Assert (n_blocks() == v.n_blocks(),
1912  ExcDimensionMismatch(n_blocks(), v.n_blocks()));
1913  Assert (n_blocks() == w.n_blocks(),
1914  ExcDimensionMismatch(n_blocks(), w.n_blocks()));
1915 
1916 
1917  for (size_type i=0; i<n_blocks(); ++i)
1918  {
1919  components[i].add(a, v.components[i], b, w.components[i]);
1920  }
1921 }
1922 
1923 
1924 
1925 template <class VectorType>
1926 void BlockVectorBase<VectorType>::sadd (const value_type x,
1927  const BlockVectorBase<VectorType> &v)
1928 {
1929 
1930  AssertIsFinite(x);
1931 
1932  Assert (n_blocks() == v.n_blocks(),
1933  ExcDimensionMismatch(n_blocks(), v.n_blocks()));
1934 
1935  for (size_type i=0; i<n_blocks(); ++i)
1936  {
1937  components[i].sadd(x, v.components[i]);
1938  }
1939 }
1940 
1941 
1942 
1943 template <class VectorType>
1944 void BlockVectorBase<VectorType>::sadd (const value_type x, const value_type a,
1945  const BlockVectorBase<VectorType> &v)
1946 {
1947 
1948  AssertIsFinite(x);
1949  AssertIsFinite(a);
1950 
1951  Assert (n_blocks() == v.n_blocks(),
1952  ExcDimensionMismatch(n_blocks(), v.n_blocks()));
1953 
1954  for (size_type i=0; i<n_blocks(); ++i)
1955  {
1956  components[i].sadd(x, a, v.components[i]);
1957  }
1958 }
1959 
1960 
1961 
1962 template <class VectorType>
1963 void BlockVectorBase<VectorType>::sadd (const value_type x, const value_type a,
1964  const BlockVectorBase<VectorType> &v,
1965  const value_type b,
1966  const BlockVectorBase<VectorType> &w)
1967 {
1968 
1969  AssertIsFinite(x);
1970  AssertIsFinite(a);
1971  AssertIsFinite(b);
1972 
1973  Assert (n_blocks() == v.n_blocks(),
1974  ExcDimensionMismatch(n_blocks(), v.n_blocks()));
1975  Assert (n_blocks() == w.n_blocks(),
1976  ExcDimensionMismatch(n_blocks(), w.n_blocks()));
1977 
1978  for (size_type i=0; i<n_blocks(); ++i)
1979  {
1980  components[i].sadd(x, a, v.components[i], b, w.components[i]);
1981  }
1982 }
1983 
1984 
1985 
1986 template <class VectorType>
1987 void BlockVectorBase<VectorType>::sadd (const value_type x, const value_type a,
1988  const BlockVectorBase<VectorType> &v,
1989  const value_type b,
1990  const BlockVectorBase<VectorType> &w,
1991  const value_type c,
1992  const BlockVectorBase<VectorType> &y)
1993 {
1994 
1995  AssertIsFinite(x);
1996  AssertIsFinite(a);
1997  AssertIsFinite(b);
1998  AssertIsFinite(c);
1999 
2000  Assert (n_blocks() == v.n_blocks(),
2001  ExcDimensionMismatch(n_blocks(), v.n_blocks()));
2002  Assert (n_blocks() == w.n_blocks(),
2003  ExcDimensionMismatch(n_blocks(), w.n_blocks()));
2004  Assert (n_blocks() == y.n_blocks(),
2005  ExcDimensionMismatch(n_blocks(), y.n_blocks()));
2006 
2007  for (size_type i=0; i<n_blocks(); ++i)
2008  {
2009  components[i].sadd(x, a, v.components[i],
2010  b, w.components[i], c, y.components[i]);
2011  }
2012 }
2013 
2014 
2015 
2016 template <class VectorType>
2017 template <class BlockVector2>
2018 void BlockVectorBase<VectorType>::scale (const BlockVector2 &v)
2019 {
2020  Assert (n_blocks() == v.n_blocks(),
2021  ExcDimensionMismatch(n_blocks(), v.n_blocks()));
2022  for (size_type i=0; i<n_blocks(); ++i)
2023  components[i].scale(v.block(i));
2024 }
2025 
2026 
2027 
2028 template <class VectorType>
2029 void BlockVectorBase<VectorType>::equ (const value_type a,
2030  const BlockVectorBase<VectorType> &v,
2031  const value_type b,
2032  const BlockVectorBase<VectorType> &w)
2033 {
2034 
2035  AssertIsFinite(a);
2036  AssertIsFinite(b);
2037 
2038  Assert (n_blocks() == v.n_blocks(),
2039  ExcDimensionMismatch(n_blocks(), v.n_blocks()));
2040  Assert (n_blocks() == w.n_blocks(),
2041  ExcDimensionMismatch(n_blocks(), w.n_blocks()));
2042 
2043  for (size_type i=0; i<n_blocks(); ++i)
2044  {
2045  components[i].equ( a, v.components[i], b, w.components[i]);
2046  }
2047 }
2048 
2049 
2050 
2051 template <class VectorType>
2052 std::size_t
2054 {
2055  return (MemoryConsumption::memory_consumption (this->block_indices)
2056  +
2057  MemoryConsumption::memory_consumption (this->components));
2058 }
2059 
2060 
2061 
2062 template <class VectorType>
2063 template <class BlockVector2>
2064 void BlockVectorBase<VectorType>::equ (const value_type a,
2065  const BlockVector2 &v)
2066 {
2067 
2068  AssertIsFinite(a);
2069 
2070  Assert (n_blocks() == v.n_blocks(),
2071  ExcDimensionMismatch(n_blocks(), v.n_blocks()));
2072 
2073  for (size_type i=0; i<n_blocks(); ++i)
2074  components[i].equ( a, v.components[i]);
2075 }
2076 
2077 
2078 
2079 template <class VectorType>
2081 {
2082  for (size_type i=0; i<n_blocks(); ++i)
2083  block(i).update_ghost_values ();
2084 }
2085 
2086 
2087 
2088 template <class VectorType>
2090 BlockVectorBase<VectorType>::operator = (const value_type s)
2091 {
2092 
2093  AssertIsFinite(s);
2094 
2095  for (size_type i=0; i<n_blocks(); ++i)
2096  components[i] = s;
2097 
2098  return *this;
2099 }
2100 
2101 
2102 template <class VectorType>
2105 {
2106  AssertDimension(n_blocks(), v.n_blocks());
2107 
2108  for (size_type i=0; i<n_blocks(); ++i)
2109  components[i] = v.components[i];
2110 
2111  return *this;
2112 }
2113 
2114 
2115 template <class VectorType>
2116 template <class VectorType2>
2119 {
2120  AssertDimension(n_blocks(), v.n_blocks());
2121 
2122  for (size_type i=0; i<n_blocks(); ++i)
2123  components[i] = v.components[i];
2124 
2125  return *this;
2126 }
2127 
2128 
2129 
2130 template <class VectorType>
2132 BlockVectorBase<VectorType>::operator = (const VectorType &v)
2133 {
2134  Assert (size() == v.size(),
2135  ExcDimensionMismatch(size(), v.size()));
2136 
2137  size_type index_v = 0;
2138  for (size_type b=0; b<n_blocks(); ++b)
2139  for (size_type i=0; i<block(b).size(); ++i, ++index_v)
2140  block(b)(i) = v(index_v);
2141 
2142  return *this;
2143 }
2144 
2145 
2146 
2147 template <class VectorType>
2148 template <class VectorType2>
2149 inline
2150 bool
2153 {
2154  Assert (block_indices == v.block_indices, ExcDifferentBlockIndices());
2155 
2156  for (size_type i=0; i<n_blocks(); ++i)
2157  if ( ! (components[i] == v.components[i]))
2158  return false;
2159 
2160  return true;
2161 }
2162 
2163 
2164 
2165 template <class VectorType>
2166 inline
2168 BlockVectorBase<VectorType>::operator *= (const value_type factor)
2169 {
2170 
2171  AssertIsFinite(factor);
2172 
2173  for (size_type i=0; i<n_blocks(); ++i)
2174  components[i] *= factor;
2175 
2176  return *this;
2177 }
2178 
2179 
2180 
2181 template <class VectorType>
2182 inline
2184 BlockVectorBase<VectorType>::operator /= (const value_type factor)
2185 {
2186 
2187  AssertIsFinite(factor);
2188  Assert (factor != 0., ExcDivideByZero() );
2189 
2190  for (size_type i=0; i<n_blocks(); ++i)
2191  components[i] /= factor;
2192 
2193  return *this;
2194 }
2195 
2196 
2197 template <class VectorType>
2198 inline
2199 typename BlockVectorBase<VectorType>::value_type
2200 BlockVectorBase<VectorType>::operator() (const size_type i) const
2201 {
2202  const std::pair<unsigned int,size_type> local_index
2203  = block_indices.global_to_local (i);
2204  return components[local_index.first](local_index.second);
2205 }
2206 
2207 
2208 
2209 template <class VectorType>
2210 inline
2211 typename BlockVectorBase<VectorType>::reference
2213 {
2214  const std::pair<unsigned int,size_type> local_index
2215  = block_indices.global_to_local (i);
2216  return components[local_index.first](local_index.second);
2217 }
2218 
2219 
2220 
2221 template <class VectorType>
2222 inline
2223 typename BlockVectorBase<VectorType>::value_type
2224 BlockVectorBase<VectorType>::operator[] (const size_type i) const
2225 {
2226  return operator()(i);
2227 }
2228 
2229 
2230 
2231 template <class VectorType>
2232 inline
2233 typename BlockVectorBase<VectorType>::reference
2235 {
2236  return operator()(i);
2237 }
2238 
2239 
2240 
2241 template <typename VectorType>
2242 template <typename OtherNumber>
2243 inline
2244 void BlockVectorBase<VectorType>::extract_subvector_to (const std::vector<size_type> &indices,
2245  std::vector<OtherNumber> &values) const
2246 {
2247  for (size_type i = 0; i < indices.size(); ++i)
2248  values[i] = operator()(indices[i]);
2249 }
2250 
2251 
2252 
2253 template <typename VectorType>
2254 template <typename ForwardIterator, typename OutputIterator>
2255 inline
2256 void BlockVectorBase<VectorType>::extract_subvector_to (ForwardIterator indices_begin,
2257  const ForwardIterator indices_end,
2258  OutputIterator values_begin) const
2259 {
2260  while (indices_begin != indices_end)
2261  {
2262  *values_begin = operator()(*indices_begin);
2263  indices_begin++;
2264  values_begin++;
2265  }
2266 }
2267 
2268 #endif // DOXYGEN
2269 
2270 DEAL_II_NAMESPACE_CLOSE
2271 
2272 #endif
const types::global_dof_index invalid_size_type
Definition: types.h:179
static yes_type check_for_block_vector(const BlockVectorBase< T > *)
BaseClass::value_type value_type
Definition: block_vector.h:78
bool operator>(const Iterator< BlockVectorType, OtherConstness > &i) const
std::random_access_iterator_tag iterator_type
#define AssertDimension(dim1, dim2)
Definition: exceptions.h:1146
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
dereference_type operator[](const difference_type d) const
bool operator==(const BlockVectorBase< VectorType2 > &v) const
void compress(::VectorOperation::values operation)
void scale(const double scaling_factor, Triangulation< dim, spacedim > &triangulation)
Definition: grid_tools.cc:653
bool in_local_range(const size_type global_index) const
void add_indices(const ForwardIterator &begin, const ForwardIterator &end)
Definition: index_set.h:1463
void collect_sizes()
static ::ExceptionBase & ExcCastingAwayConstness()
size_type block_size(const unsigned int i) const
static ::ExceptionBase & ExcIndexRange(int arg1, int arg2, int arg3)
static ::ExceptionBase & ExcDivideByZero()
Iterator operator+(const difference_type &d) const
BlockVectorBase & operator/=(const value_type factor)
value_type add_and_dot(const value_type a, const BlockVectorBase &V, const BlockVectorBase &W)
bool is_non_negative() const
void scale(const BlockVector2 &v)
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:313
BlockType::real_type real_type
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
std::size_t size() const
#define DeclExceptionMsg(Exception, defaulttext)
Definition: exceptions.h:553
real_type l1_norm() const
void update_ghost_values() const
size_type local_to_global(const unsigned int block, const size_type index) const
bool operator==(const Iterator< BlockVectorType, OtherConstness > &i) const
double l1_norm(const Tensor< 2, dim, Number > &t)
Definition: tensor.h:1951
static ::ExceptionBase & ExcDifferentBlockIndices()
static const bool value
SymmetricTensor< 2, dim, Number > d(const Tensor< 2, dim, Number > &F, const Tensor< 2, dim, Number > &dF_dt)
BlockVectorBase & operator+=(const BlockVectorBase &V)
std::vector< VectorType > components
SymmetricTensor< rank, dim, Number > sum(const SymmetricTensor< rank, dim, Number > &local, const MPI_Comm &mpi_communicator)
BlockVectorBase & operator*=(const value_type factor)
SymmetricTensor< 2, dim, Number > b(const Tensor< 2, dim, Number > &F)
bool all_zero() const
Types< BlockVectorType, Constness >::value_type value_type
Tensor< 2, dim, Number > w(const Tensor< 2, dim, Number > &F, const Tensor< 2, dim, Number > &dF_dt)
Iterator & operator+=(const difference_type &d)
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()
bool operator!=(const Iterator< BlockVectorType, OtherConstness > &i) const
value_type operator()(const size_type i) const
difference_type operator-(const Iterator< BlockVectorType, OtherConstness > &i) const
real_type linfty_norm() const
bool operator>=(const Iterator< BlockVectorType, OtherConstness > &i) const
BlockType & block(const unsigned int i)
iterator begin()
BlockVectorBase & operator=(const value_type s)
static ::ExceptionBase & ExcPointerToDifferentVectors()
std::pair< unsigned int, size_type > global_to_local(const size_type i) const
#define AssertIsFinite(number)
Definition: exceptions.h:1197
void equ(const value_type a, const BlockVector2 &V)
Iterator & operator=(const Iterator &c)
Iterator & operator-=(const difference_type &d)
dereference_type operator*() const
static const bool supports_distributed_data
value_type mean_value() const
Types< BlockVectorType, Constness >::BlockVector BlockVector