Reference documentation for deal.II version 8.1.0
parallel_vector.h
1 // ---------------------------------------------------------------------
2 // @f$Id: parallel_vector.h 31932 2013-12-08 02:15:54Z heister @f$
3 //
4 // Copyright (C) 2011 - 2013 by the deal.II authors
5 //
6 // This file is part of the deal.II library.
7 //
8 // The deal.II library is free software; you can use it, redistribute
9 // it, and/or modify it under the terms of the GNU Lesser General
10 // Public License as published by the Free Software Foundation; either
11 // version 2.1 of the License, or (at your option) any later version.
12 // The full text of the license can be found in the file LICENSE at
13 // the top level of the deal.II distribution.
14 //
15 // ---------------------------------------------------------------------
16 
17 #ifndef __deal2__parallel_vector_h
18 #define __deal2__parallel_vector_h
19 
20 #include <deal.II/base/config.h>
21 #include <deal.II/base/index_set.h>
22 #include <deal.II/base/mpi.h>
23 #include <deal.II/base/template_constraints.h>
24 #include <deal.II/base/types.h>
25 #include <deal.II/base/utilities.h>
26 #include <deal.II/base/memory_consumption.h>
27 #include <deal.II/base/partitioner.h>
28 #include <deal.II/base/thread_management.h>
29 #include <deal.II/lac/vector_view.h>
30 
31 #include <cstring>
32 
33 
35 
36 namespace parallel
37 {
38  namespace distributed
39  {
40  template <typename Number> class BlockVector;
41 
104  template <typename Number>
105  class Vector : public Subscriptor
106  {
107  public:
113  typedef Number value_type;
114  typedef value_type *pointer;
115  typedef const value_type *const_pointer;
116  typedef value_type *iterator;
117  typedef const value_type *const_iterator;
118  typedef value_type &reference;
119  typedef const value_type &const_reference;
120  typedef types::global_dof_index size_type;
121  typedef typename numbers::NumberTraits<Number>::real_type real_type;
122 
134  static const bool supports_distributed_data = true;
135 
143  Vector ();
144 
148  Vector (const Vector<Number> &in_vector);
149 
154  Vector (const size_type size);
155 
169  Vector (const IndexSet &local_range,
170  const IndexSet &ghost_indices,
171  const MPI_Comm communicator);
172 
176  Vector (const IndexSet &local_range,
177  const MPI_Comm communicator);
178 
185  Vector (const std_cxx1x::shared_ptr<const Utilities::MPI::Partitioner> &partitioner);
186 
190  ~Vector ();
191 
196  void reinit (const size_type size,
197  const bool fast = false);
198 
208  template <typename Number2>
209  void reinit(const Vector<Number2> &in_vector,
210  const bool fast = false);
211 
225  void reinit (const IndexSet &local_range,
226  const IndexSet &ghost_indices,
227  const MPI_Comm communicator);
228 
232  void reinit (const IndexSet &local_range,
233  const MPI_Comm communicator);
234 
241  void reinit (const std_cxx1x::shared_ptr<const Utilities::MPI::Partitioner> &partitioner);
242 
258  void swap (Vector<Number> &v);
259 
265  operator = (const Vector<Number> &in_vector);
266 
271  template <typename Number2>
273  operator = (const Vector<Number2> &in_vector);
274 
279  void copy_from (const Vector<Number> &in_vector,
280  const bool call_update_ghost_values = false);
281 
287  Vector<Number> &operator = (const Number s);
288 
312  void compress (::VectorOperation::values operation);
313 
318 
337  void update_ghost_values () const;
338 
353  void compress_start (const unsigned int communication_channel = 0,
354  ::VectorOperation::values operation = VectorOperation::add);
355 
372  void compress_finish (::VectorOperation::values operation);
373 
377  void compress_finish (const bool add_ghost_data = true) DEAL_II_DEPRECATED;
378 
393  void update_ghost_values_start (const unsigned int communication_channel = 0) const;
394 
395 
403  void update_ghost_values_finish () const;
404 
413  void zero_out_ghosts ();
414 
423  bool has_ghost_elements() const;
424 
431  bool all_zero () const;
432 
443  bool is_non_negative () const;
444 
448  template <typename Number2>
449  bool operator == (const Vector<Number2> &v) const;
450 
454  template <typename Number2>
455  bool operator != (const Vector<Number2> &v) const;
456 
460  template <typename Number2>
461  Number operator * (const Vector<Number2> &V) const;
462 
467  real_type norm_sqr () const;
468 
472  Number mean_value () const;
473 
478  real_type l1_norm () const;
479 
484  real_type l2_norm () const;
485 
491  real_type lp_norm (const real_type p) const;
492 
497  real_type linfty_norm () const;
498 
503  size_type size () const;
504 
509  size_type local_size() const;
510 
516  std::pair<size_type, size_type> local_range () const;
517 
522  bool in_local_range (const size_type global_index) const;
523 
539 
543  size_type n_ghost_entries () const;
544 
550  const IndexSet &ghost_elements() const;
551 
557  bool is_ghost_entry (const types::global_dof_index global_index) const;
558 
566  iterator begin ();
567 
572  const_iterator begin () const;
573 
578  iterator end ();
579 
584  const_iterator end () const;
586 
587 
592 
602  Number operator () (const size_type global_index) const;
603 
613  Number &operator () (const size_type global_index);
614 
622  Number operator [] (const size_type global_index) const;
623 
631  Number &operator [] (const size_type global_index);
632 
643  template <typename OtherNumber>
644  void extract_subvector_to (const std::vector<size_type> &indices,
645  std::vector<OtherNumber> &values) const;
646 
651  template <typename ForwardIterator, typename OutputIterator>
652  void extract_subvector_to (ForwardIterator indices_begin,
653  const ForwardIterator indices_end,
654  OutputIterator values_begin) const;
655 
664  Number local_element (const size_type local_index) const;
665 
674  Number &local_element (const size_type local_index);
676 
677 
682 
686  Vector<Number> &operator += (const Vector<Number> &V);
687 
691  Vector<Number> &operator -= (const Vector<Number> &V);
692 
697  template <typename OtherNumber>
698  void add (const std::vector<size_type> &indices,
699  const std::vector<OtherNumber> &values);
700 
705  template <typename OtherNumber>
706  void add (const std::vector<size_type> &indices,
707  const ::Vector<OtherNumber> &values);
708 
714  template <typename OtherNumber>
715  void add (const size_type n_elements,
716  const size_type *indices,
717  const OtherNumber *values);
718 
723  void add (const Number s);
724 
728  void add (const Vector<Number> &V);
729 
734  void add (const Number a, const Vector<Number> &V);
735 
739  void add (const Number a, const Vector<Number> &V,
740  const Number b, const Vector<Number> &W);
741 
746  void sadd (const Number s,
747  const Vector<Number> &V);
748 
752  void sadd (const Number s,
753  const Number a,
754  const Vector<Number> &V);
755 
759  void sadd (const Number s,
760  const Number a,
761  const Vector<Number> &V,
762  const Number b,
763  const Vector<Number> &W);
764 
769  void sadd (const Number s,
770  const Number a,
771  const Vector<Number> &V,
772  const Number b,
773  const Vector<Number> &W,
774  const Number c,
775  const Vector<Number> &X);
776 
784  void scale (const Number factor) DEAL_II_DEPRECATED;
785 
789  Vector<Number> &operator *= (const Number factor);
790 
794  Vector<Number> &operator /= (const Number factor);
795 
801  void scale (const Vector<Number> &scaling_factors);
802 
808  template <typename Number2>
809  void scale (const Vector<Number2> &scaling_factors);
810 
814  void equ (const Number a, const Vector<Number> &u);
815 
819  template <typename Number2>
820  void equ (const Number a, const Vector<Number2> &u);
821 
825  void equ (const Number a, const Vector<Number> &u,
826  const Number b, const Vector<Number> &v);
827 
831  void equ (const Number a, const Vector<Number> &u,
832  const Number b, const Vector<Number> &v,
833  const Number c, const Vector<Number> &w);
834 
845  void ratio (const Vector<Number> &a,
846  const Vector<Number> &b);
848 
849 
858  const MPI_Comm &get_mpi_communicator () const;
859 
869  bool
870  partitioners_are_compatible (const Utilities::MPI::Partitioner &part) const;
871 
872 
876  void print (std::ostream &out,
877  const unsigned int precision = 3,
878  const bool scientific = true,
879  const bool across = true) const;
880 
884  std::size_t memory_consumption () const;
886 
887  private:
891  bool all_zero_local () const;
892 
896  bool is_non_negative_local () const;
897 
901  template <typename Number2>
902  bool vectors_equal_local (const Vector<Number2> &v) const;
903 
907  template <typename Number2>
908  Number inner_product_local (const Vector<Number2> &V) const;
909 
913  real_type norm_sqr_local () const;
914 
918  Number mean_value_local () const;
919 
923  real_type l1_norm_local () const;
924 
928  real_type lp_norm_local (const real_type p) const;
929 
933  real_type linfty_norm_local () const;
934 
940  std_cxx1x::shared_ptr<const Utilities::MPI::Partitioner> partitioner;
941 
945  size_type allocated_size;
946 
950  Number *val;
951 
957  mutable Number *import_data;
958 
966  mutable bool vector_is_ghosted;
967 
973 
974 #ifdef DEAL_II_WITH_MPI
975 
983  std::vector<MPI_Request> compress_requests;
984 
989  mutable std::vector<MPI_Request> update_ghost_values_requests;
990 #endif
991 
998 
1003  void clear_mpi_requests ();
1004 
1008  void resize_val (const size_type new_allocated_size);
1009 
1010  /*
1011  * Make all other vector types friends.
1012  */
1013  template <typename Number2> friend class Vector;
1014 
1018  template <typename Number2> friend class BlockVector;
1019  };
1020 
1024  /*----------------------- Inline functions ----------------------------------*/
1025 
1026 #ifndef DOXYGEN
1027 
1028  template <typename Number>
1029  inline
1031  :
1032  partitioner (new Utilities::MPI::Partitioner()),
1033  allocated_size (0),
1034  val (0),
1035  import_data (0),
1036  vector_is_ghosted (false),
1037  vector_view (0, static_cast<Number *>(0))
1038  {}
1039 
1040 
1041 
1042  template <typename Number>
1043  inline
1045  :
1046  Subscriptor(),
1047  allocated_size (0),
1048  val (0),
1049  import_data (0),
1050  vector_is_ghosted (false),
1051  vector_view (0, static_cast<Number *>(0))
1052  {
1053  reinit (v, true);
1054  vector_view = v.vector_view;
1055  }
1056 
1057 
1058 
1059  template <typename Number>
1060  inline
1061  Vector<Number>::Vector (const IndexSet &local_range,
1062  const IndexSet &ghost_indices,
1063  const MPI_Comm communicator)
1064  :
1065  allocated_size (0),
1066  val (0),
1067  import_data (0),
1068  vector_is_ghosted (false),
1069  vector_view (0, static_cast<Number *>(0))
1070  {
1071  reinit (local_range, ghost_indices, communicator);
1072  }
1073 
1074 
1075 
1076  template <typename Number>
1077  inline
1078  Vector<Number>::Vector (const IndexSet &local_range,
1079  const MPI_Comm communicator)
1080  :
1081  allocated_size (0),
1082  val (0),
1083  import_data (0),
1084  vector_is_ghosted (false),
1085  vector_view (0, static_cast<Number *>(0))
1086  {
1087  IndexSet ghost_indices(local_range.size());
1088  reinit (local_range, ghost_indices, communicator);
1089  }
1090 
1091 
1092 
1093  template <typename Number>
1094  inline
1095  Vector<Number>::Vector (const size_type size)
1096  :
1097  allocated_size (0),
1098  val (0),
1099  import_data (0),
1100  vector_is_ghosted (false),
1101  vector_view (0, static_cast<Number *>(0))
1102  {
1103  reinit (size, false);
1104  }
1105 
1106 
1107 
1108  template <typename Number>
1109  inline
1111  Vector (const std_cxx1x::shared_ptr<const Utilities::MPI::Partitioner> &partitioner)
1112  :
1113  allocated_size (0),
1114  val (0),
1115  import_data (0),
1116  vector_is_ghosted (false),
1117  vector_view (0, static_cast<Number *>(0))
1118  {
1119  reinit (partitioner);
1120  }
1121 
1122 
1123 
1124  template <typename Number>
1125  inline
1127  {
1128  if (val != 0)
1129  delete[] val;
1130  val = 0;
1131 
1132  if (import_data != 0)
1133  delete[] import_data;
1134  import_data = 0;
1135 
1136  clear_mpi_requests();
1137  }
1138 
1139 
1140 
1141  template <typename Number>
1142  inline
1143  Vector<Number> &
1145  {
1146  Assert (c.partitioner.get() != 0, ExcNotInitialized());
1147 
1148  // we update ghost values whenever one of the input or output vector
1149  // already held ghost values or when we import data from a vector with
1150  // the same local range but different ghost layout
1151  bool must_update_ghost_values = true;
1152 
1153  // check whether the two vectors use the same parallel partitioner. if
1154  // not, check if all local ranges are the same (that way, we can
1155  // exchange data between different parallel layouts)
1156  if (partitioner.get() == 0)
1157  reinit (c, true);
1158  else if (partitioner.get() != c.partitioner.get())
1159  {
1160  size_type local_ranges_different_loc = (local_range() !=
1161  c.local_range());
1162  if ((partitioner->n_mpi_processes() > 1 &&
1163  Utilities::MPI::max(local_ranges_different_loc,
1164  partitioner->get_communicator()) != 0)
1165  ||
1166  local_ranges_different_loc)
1167  reinit (c, true);
1168  }
1169  else
1170  must_update_ghost_values = vector_is_ghosted || c.vector_is_ghosted;
1171 
1172  vector_view = c.vector_view;
1173  if (must_update_ghost_values)
1175  return *this;
1176  }
1177 
1178 
1179 
1180  template <typename Number>
1181  template <typename Number2>
1182  inline
1183  Vector<Number> &
1185  {
1186  Assert (c.partitioner.get() != 0, ExcNotInitialized());
1187 
1188  // check whether the two vectors use the same parallel partitioner. if
1189  // not, check if all local ranges are the same (that way, we can
1190  // exchange data between different parallel layouts)
1191  if (partitioner.get() == 0)
1192  reinit (c, true);
1193  else if (partitioner.get() != c.partitioner.get())
1194  {
1195  size_type local_ranges_different_loc = (local_range() !=
1196  c.local_range());
1197  if ((partitioner->n_mpi_processes() > 1 &&
1198  Utilities::MPI::max(local_ranges_different_loc,
1199  partitioner->get_communicator()) != 0)
1200  ||
1201  local_ranges_different_loc)
1202  reinit (c, true);
1203  }
1204  vector_view.reinit (partitioner->local_size(), val);
1205 
1206  if (partitioner->local_size())
1207  vector_view.equ (1., c.vector_view);
1208 
1209  if (vector_is_ghosted || c.vector_is_ghosted)
1211  return *this;
1212  }
1213 
1214 
1215 
1216  template <typename Number>
1217  inline
1218  void
1219  Vector<Number>::compress (::VectorOperation::values operation)
1220  {
1221  compress_start (0, operation);
1222  compress_finish(operation);
1223  }
1224 
1225 
1226 
1227  template <typename Number>
1228  inline
1229  void
1231  {
1232  compress(VectorOperation::unknown);
1233  }
1234 
1235 
1236 
1237  template <typename Number>
1238  inline
1239  void
1240  Vector<Number>::compress_finish (const bool add_value)
1241  {
1242  if (add_value)
1243  compress_finish(VectorOperation::add);
1244  else
1245  compress_finish(VectorOperation::insert);
1246  }
1247 
1248 
1249 
1250  template <typename Number>
1251  inline
1252  void
1254  {
1255  update_ghost_values_start ();
1256  update_ghost_values_finish ();
1257  }
1258 
1259 
1260 
1261  template <typename Number>
1262  inline
1263  void
1265  {
1266  std::fill_n (&val[partitioner->local_size()],
1267  partitioner->n_ghost_indices(),
1268  Number());
1269  vector_is_ghosted = false;
1270  }
1271 
1272 
1273 
1274  template <typename Number>
1275  inline
1276  bool
1278  {
1279  return vector_is_ghosted;
1280  }
1281 
1282 
1283 
1284  template <typename Number>
1285  inline
1286  bool
1288  {
1289  return partitioner->local_size()>0 ? vector_view.all_zero () : true;
1290  }
1291 
1292 
1293 
1294  template <typename Number>
1295  inline
1296  bool
1297  Vector<Number>::all_zero () const
1298  {
1299  // use int instead of bool. in order to make global reduction operations
1300  // work also when MPI_Init was not called, only call MPI_Allreduce
1301  // commands when there is more than one processor (note that reinit()
1302  // functions handle this case correctly through the job_supports_mpi()
1303  // query). this is the same in all the functions below
1304  int local_result = -static_cast<int>(all_zero_local());
1305  if (partitioner->n_mpi_processes() > 1)
1306  return -Utilities::MPI::max(local_result,
1307  partitioner->get_communicator());
1308  else
1309  return -local_result;
1310  }
1311 
1312 
1313 
1314  template <typename Number>
1315  inline
1316  bool
1318  {
1319  return partitioner->local_size()>0 ? vector_view.is_non_negative () : true;
1320  }
1321 
1322 
1323 
1324  template <typename Number>
1325  inline
1326  bool
1328  {
1329  int local_result = -static_cast<int>(is_non_negative_local());
1330  if (partitioner->n_mpi_processes() > 1)
1331  return -Utilities::MPI::max(local_result,
1332  partitioner->get_communicator());
1333  else
1334  return -local_result;
1335  }
1336 
1337 
1338 
1339  template <typename Number>
1340  template <typename Number2>
1341  inline
1342  bool
1344  {
1345  return partitioner->local_size()>0 ?
1346  vector_view.template operator == <Number2>(v.vector_view)
1347  : true;
1348  }
1349 
1350 
1351 
1352  template <typename Number>
1353  template <typename Number2>
1354  inline
1355  bool
1357  {
1358  // MPI does not support bools, so use unsigned int instead. Two vectors
1359  // are equal if the check for non-equal fails on all processors
1360  unsigned int local_result = static_cast<int>(!vectors_equal_local(v));
1361  unsigned int result =
1362  partitioner->n_mpi_processes() > 1
1363  ?
1364  Utilities::MPI::max(local_result, partitioner->get_communicator())
1365  :
1366  local_result;
1367  return result==0;
1368  }
1369 
1370 
1371 
1372  template <typename Number>
1373  template <typename Number2>
1374  inline
1375  bool
1377  {
1378  return !(operator == (v));
1379  }
1380 
1381 
1382 
1383  template <typename Number>
1384  template <typename Number2>
1385  inline
1386  Number
1388  {
1389  // on some processors, the size might be zero, which is not allowed by
1390  // the ::Vector class. Therefore, insert a check here
1391  return (partitioner->local_size()>0 ?
1392  vector_view.operator* (V.vector_view)
1393  : Number());
1394  }
1395 
1396 
1397 
1398  template <typename Number>
1399  template <typename Number2>
1400  inline
1401  Number
1403  {
1404  Number local_result = inner_product_local(V);
1405  if (partitioner->n_mpi_processes() > 1)
1406  return Utilities::MPI::sum (local_result,
1407  partitioner->get_communicator());
1408  else
1409  return local_result;
1410  }
1411 
1412 
1413 
1414  template <typename Number>
1415  inline
1416  typename Vector<Number>::real_type
1418  {
1419  return partitioner->local_size()>0 ? vector_view.norm_sqr() : real_type();
1420  }
1421 
1422 
1423 
1424  template <typename Number>
1425  inline
1426  typename Vector<Number>::real_type
1427  Vector<Number>::norm_sqr () const
1428  {
1429  real_type local_result = norm_sqr_local();
1430  if (partitioner->n_mpi_processes() > 1)
1431  return Utilities::MPI::sum(local_result,
1432  partitioner->get_communicator());
1433  else
1434  return local_result;
1435  }
1436 
1437 
1438 
1439  template <typename Number>
1440  inline
1441  Number
1443  {
1444  Assert (partitioner->size()!=0, ExcEmptyObject());
1445  return (partitioner->local_size() ?
1446  vector_view.mean_value()
1447  : Number());
1448  }
1449 
1450 
1451 
1452  template <typename Number>
1453  inline
1454  Number
1456  {
1457  Number local_result = mean_value_local();
1458  if (partitioner->n_mpi_processes() > 1)
1459  return Utilities::MPI::sum (local_result *
1460  (real_type)partitioner->local_size(),
1461  partitioner->get_communicator())
1462  /(real_type)partitioner->size();
1463  else
1464  return local_result;
1465  }
1466 
1467 
1468 
1469  template <typename Number>
1470  inline
1471  typename Vector<Number>::real_type
1473  {
1474  return partitioner->local_size() ? vector_view.l1_norm() : real_type();
1475  }
1476 
1477 
1478 
1479  template <typename Number>
1480  inline
1481  typename Vector<Number>::real_type
1482  Vector<Number>::l1_norm () const
1483  {
1484  real_type local_result = l1_norm_local();
1485  if (partitioner->n_mpi_processes() > 1)
1486  return Utilities::MPI::sum(local_result,
1487  partitioner->get_communicator());
1488  else
1489  return local_result;
1490  }
1491 
1492 
1493 
1494  template <typename Number>
1495  inline
1496  typename Vector<Number>::real_type
1497  Vector<Number>::l2_norm () const
1498  {
1499  return std::sqrt(norm_sqr());
1500  }
1501 
1502 
1503 
1504  template <typename Number>
1505  inline
1506  typename Vector<Number>::real_type
1507  Vector<Number>::lp_norm_local (const real_type p) const
1508  {
1509  return partitioner->local_size() ? vector_view.lp_norm(p) : real_type();
1510  }
1511 
1512 
1513 
1514  template <typename Number>
1515  inline
1516  typename Vector<Number>::real_type
1517  Vector<Number>::lp_norm (const real_type p) const
1518  {
1519  const real_type local_result = lp_norm_local(p);
1520  if (partitioner->n_mpi_processes() > 1)
1521  return std::pow (Utilities::MPI::sum(std::pow(local_result,p),
1522  partitioner->get_communicator()),
1523  static_cast<real_type>(1.0/p));
1524  else
1525  return local_result;
1526  }
1527 
1528 
1529 
1530  template <typename Number>
1531  inline
1532  typename Vector<Number>::real_type
1534  {
1535  return partitioner->local_size() ? vector_view.linfty_norm() : real_type();
1536  }
1537 
1538 
1539 
1540  template <typename Number>
1541  inline
1542  typename Vector<Number>::real_type
1544  {
1545  const real_type local_result = linfty_norm_local();
1546  if (partitioner->n_mpi_processes() > 1)
1547  return Utilities::MPI::max (local_result,
1548  partitioner->get_communicator());
1549  else
1550  return local_result;
1551  }
1552 
1553 
1554 
1555  template <typename Number>
1556  inline
1557  typename Vector<Number>::size_type
1558  Vector<Number>::size () const
1559  {
1560  return partitioner->size();
1561  }
1562 
1563 
1564 
1565  template <typename Number>
1566  inline
1567  typename Vector<Number>::size_type
1569  {
1570  return partitioner->local_size();
1571  }
1572 
1573 
1574 
1575  template <typename Number>
1576  inline
1577  std::pair<typename Vector<Number>::size_type,
1578  typename Vector<Number>::size_type>
1580  {
1581  return partitioner->local_range();
1582  }
1583 
1584 
1585 
1586  template <typename Number>
1587  inline
1588  bool
1590  (const size_type global_index) const
1591  {
1592  return partitioner->in_local_range (global_index);
1593  }
1594 
1595 
1596 
1597  template <typename Number>
1598  inline
1599  IndexSet
1601  {
1602  IndexSet is (size());
1603 
1604  is.add_range (local_range().first, local_range().second);
1605 
1606  return is;
1607  }
1608 
1609 
1610 
1611  template <typename Number>
1612  inline
1613  typename Vector<Number>::size_type
1615  {
1616  return partitioner->n_ghost_indices();
1617  }
1618 
1619 
1620 
1621  template <typename Number>
1622  inline
1623  const IndexSet &
1625  {
1626  return partitioner->ghost_indices();
1627  }
1628 
1629 
1630 
1631  template <typename Number>
1632  inline
1633  bool
1634  Vector<Number>::is_ghost_entry (const size_type global_index) const
1635  {
1636  return partitioner->is_ghost_entry (global_index);
1637  }
1638 
1639 
1640 
1641  template <typename Number>
1642  inline
1643  typename Vector<Number>::iterator
1645  {
1646  return vector_view.begin();
1647  }
1648 
1649 
1650 
1651  template <typename Number>
1652  inline
1653  typename Vector<Number>::const_iterator
1654  Vector<Number>::begin () const
1655  {
1656  return vector_view.begin();
1657  }
1658 
1659 
1660 
1661  template <typename Number>
1662  inline
1663  typename Vector<Number>::iterator
1665  {
1666  return vector_view.end();
1667  }
1668 
1669 
1670 
1671  template <typename Number>
1672  inline
1673  typename Vector<Number>::const_iterator
1674  Vector<Number>::end () const
1675  {
1676  return vector_view.end();
1677  }
1678 
1679 
1680 
1681  template <typename Number>
1682  inline
1683  Number
1684  Vector<Number>::operator() (const size_type global_index) const
1685  {
1686  // do not allow reading a vector which is not in ghost mode
1687  Assert (in_local_range (global_index) || vector_is_ghosted == true,
1688  ExcMessage("You tried to read a ghost element of this vector, "
1689  "but it has not imported its ghost values."));
1690  return val[partitioner->global_to_local(global_index)];
1691  }
1692 
1693 
1694 
1695  template <typename Number>
1696  inline
1697  Number &
1698  Vector<Number>::operator() (const size_type global_index)
1699  {
1700  // we would like to prevent reading ghosts from a vector that does not
1701  // have them imported, but this is not possible because we might be in a
1702  // part of the code where the vector has enabled ghosts but is non-const
1703  // (then, the compiler picks this method according to the C++ rule book
1704  // even if a human would pick the const method when this subsequent use
1705  // is just a read)
1706  return val[partitioner->global_to_local (global_index)];
1707  }
1708 
1709 
1710 
1711  template <typename Number>
1712  inline
1713  Number
1714  Vector<Number>::operator[] (const size_type global_index) const
1715  {
1716  return operator()(global_index);
1717  }
1718 
1719 
1720 
1721  template <typename Number>
1722  inline
1723  Number &
1724  Vector<Number>::operator[] (const size_type global_index)
1725  {
1726  return operator()(global_index);
1727  }
1728 
1729 
1730 
1731  template <typename Number>
1732  template <typename OtherNumber>
1733  inline
1734  void Vector<Number>::extract_subvector_to (const std::vector<size_type> &indices,
1735  std::vector<OtherNumber> &values) const
1736  {
1737  for (size_type i = 0; i < indices.size(); ++i)
1738  values[i] = operator()(indices[i]);
1739  }
1740 
1741 
1742 
1743  template <typename Number>
1744  template <typename ForwardIterator, typename OutputIterator>
1745  inline
1746  void Vector<Number>::extract_subvector_to (ForwardIterator indices_begin,
1747  const ForwardIterator indices_end,
1748  OutputIterator values_begin) const
1749  {
1750  while (indices_begin != indices_end)
1751  {
1752  *values_begin = operator()(*indices_begin);
1753  indices_begin++;
1754  values_begin++;
1755  }
1756  }
1757 
1758 
1759 
1760  template <typename Number>
1761  inline
1762  Number
1763  Vector<Number>::local_element (const size_type local_index) const
1764  {
1765  AssertIndexRange (local_index,
1766  partitioner->local_size()+
1767  partitioner->n_ghost_indices());
1768  // do not allow reading a vector which is not in ghost mode
1769  Assert (local_index < local_size() || vector_is_ghosted == true,
1770  ExcMessage("You tried to read a ghost element of this vector, "
1771  "but it has not imported its ghost values."));
1772  return val[local_index];
1773  }
1774 
1775 
1776 
1777  template <typename Number>
1778  inline
1779  Number &
1780  Vector<Number>::local_element (const size_type local_index)
1781  {
1782  AssertIndexRange (local_index,
1783  partitioner->local_size()+
1784  partitioner->n_ghost_indices());
1785  return val[local_index];
1786  }
1787 
1788 
1789 
1790  template <typename Number>
1791  inline
1792  Vector<Number> &
1793  Vector<Number>::operator = (const Number s)
1794  {
1795  // if we call Vector::operator=0, we want to zero out all the entries
1796  // plus ghosts.
1797  if (partitioner->local_size() > 0)
1798  vector_view.::template Vector<Number>::operator= (s);
1799  if (s==Number())
1800  zero_out_ghosts();
1801 
1802  return *this;
1803  }
1804 
1805 
1806 
1807  template <typename Number>
1808  inline
1809  Vector<Number> &
1811  {
1812  AssertDimension (local_size(), v.local_size());
1813 
1814  // ::Vector does not allow empty fields but this might happen on
1815  // some processors for parallel implementation
1816  if (local_size()>0)
1817  vector_view += v.vector_view;
1818 
1819  if (vector_is_ghosted)
1821 
1822  return *this;
1823  }
1824 
1825 
1826 
1827  template <typename Number>
1828  inline
1829  Vector<Number> &
1831  {
1832  AssertDimension (local_size(), v.local_size());
1833 
1834  // ::Vector does not allow empty fields but this might happen on
1835  // some processors for parallel implementation
1836  if (local_size()>0)
1837  vector_view -= v.vector_view;
1838 
1839  if (vector_is_ghosted)
1841 
1842  return *this;
1843  }
1844 
1845 
1846 
1847  template <typename Number>
1848  template <typename OtherNumber>
1849  inline
1850  void
1851  Vector<Number>::add (const std::vector<size_type> &indices,
1852  const std::vector<OtherNumber> &values)
1853  {
1854  AssertDimension (indices.size(), values.size());
1855  add (indices.size(), &indices[0], &values[0]);
1856  }
1857 
1858 
1859 
1860  template <typename Number>
1861  template <typename OtherNumber>
1862  inline
1863  void
1864  Vector<Number>::add (const std::vector<size_type> &indices,
1865  const ::Vector<OtherNumber> &values)
1866  {
1867  AssertDimension (indices.size(), values.size());
1868  add (indices.size(), &indices[0], values.begin());
1869  }
1870 
1871 
1872 
1873  template <typename Number>
1874  template <typename OtherNumber>
1875  inline
1876  void
1877  Vector<Number>::add (const size_type n_indices,
1878  const size_type *indices,
1879  const OtherNumber *values)
1880  {
1881  for (size_type i=0; i<n_indices; ++i)
1882  {
1883  Assert (numbers::is_finite(values[i]),
1884  ExcMessage("The given value is not finite but either infinite or Not A Number (NaN)"));
1885  this->operator()(indices[i]) += values[i];
1886  }
1887  }
1888 
1889 
1890 
1891  template <typename Number>
1892  inline
1893  void
1894  Vector<Number>::add (const Number a)
1895  {
1896  // ::Vector does not allow empty fields but this might happen on
1897  // some processors for parallel implementation
1898  if (local_size())
1899  vector_view.add (a);
1900 
1901  if (vector_is_ghosted)
1903  }
1904 
1905 
1906 
1907  template <typename Number>
1908  inline
1909  void
1911  {
1912  // ::Vector does not allow empty fields but this might happen on
1913  // some processors for parallel implementation
1914  if (local_size())
1915  vector_view.add (v.vector_view);
1916 
1917  if (vector_is_ghosted)
1919  }
1920 
1921 
1922 
1923  template <typename Number>
1924  inline
1925  void
1926  Vector<Number>::add (const Number a,
1927  const Vector<Number> &v)
1928  {
1929  // ::Vector does not allow empty fields but this might happen on
1930  // some processors for parallel implementation
1931  if (local_size())
1932  vector_view.add (a, v.vector_view);
1933 
1934  if (vector_is_ghosted)
1936  }
1937 
1938 
1939 
1940  template <typename Number>
1941  inline
1942  void
1943  Vector<Number>::add (const Number a,
1944  const Vector<Number> &v,
1945  const Number b,
1946  const Vector<Number> &w)
1947  {
1948  // ::Vector does not allow empty fields but this might happen on
1949  // some processors for parallel implementation
1950  if (local_size())
1951  vector_view.add (a, v.vector_view, b, w.vector_view);
1952 
1953  if (vector_is_ghosted)
1955  }
1956 
1957 
1958 
1959  template <typename Number>
1960  inline
1961  void
1962  Vector<Number>::sadd (const Number x,
1963  const Vector<Number> &v)
1964  {
1965  // ::Vector does not allow empty fields but this might happen on
1966  // some processors for parallel implementation
1967  if (local_size())
1968  vector_view.sadd (x, v.vector_view);
1969 
1970  if (vector_is_ghosted)
1972  }
1973 
1974 
1975 
1976  template <typename Number>
1977  inline
1978  void
1979  Vector<Number>::sadd (const Number x,
1980  const Number a,
1981  const Vector<Number> &v)
1982  {
1983  // ::Vector does not allow empty fields but this might happen on
1984  // some processors for parallel implementation
1985  if (local_size())
1986  vector_view.sadd (x, a, v.vector_view);
1987 
1988  if (vector_is_ghosted)
1990  }
1991 
1992 
1993 
1994  template <typename Number>
1995  inline
1996  void
1997  Vector<Number>::sadd (const Number x,
1998  const Number a,
1999  const Vector<Number> &v,
2000  const Number b,
2001  const Vector<Number> &w)
2002  {
2003  // ::Vector does not allow empty fields but this might happen on
2004  // some processors for parallel implementation
2005  if (local_size())
2006  vector_view.sadd (x, a, v.vector_view, b, w.vector_view);
2007 
2008  if (vector_is_ghosted)
2010  }
2011 
2012 
2013 
2014  template <typename Number>
2015  inline
2016  void
2017  Vector<Number>::sadd (const Number s,
2018  const Number a,
2019  const Vector<Number> &v,
2020  const Number b,
2021  const Vector<Number> &w,
2022  const Number c,
2023  const Vector<Number> &x)
2024  {
2025  // ::Vector does not allow empty fields but this might happen on
2026  // some processors for parallel implementation
2027  if (local_size())
2028  vector_view.sadd (s, a, v.vector_view, b, w.vector_view,
2029  c, x.vector_view);
2030 
2031  if (vector_is_ghosted)
2033  }
2034 
2035 
2036 
2037  template <typename Number>
2038  inline
2039  void
2040  Vector<Number>::scale (const Number factor)
2041  {
2042  operator *=(factor);
2043  }
2044 
2045 
2046 
2047  template <typename Number>
2048  inline
2049  Vector<Number> &
2050  Vector<Number>::operator *= (const Number factor)
2051  {
2052  // ::Vector does not allow empty fields but this might happen on
2053  // some processors for parallel implementation
2054  if (local_size())
2055  vector_view *= factor;
2056 
2057  if (vector_is_ghosted)
2059 
2060  return *this;
2061  }
2062 
2063 
2064 
2065  template <typename Number>
2066  inline
2067  Vector<Number> &
2068  Vector<Number>::operator /= (const Number factor)
2069  {
2070  operator *= (1./factor);
2071  return *this;
2072  }
2073 
2074 
2075 
2076  template <typename Number>
2077  inline
2078  void
2079  Vector<Number>::scale (const Vector<Number> &scaling_factors)
2080  {
2081  // ::Vector does not allow empty fields but this might happen on
2082  // some processors for parallel implementation
2083  if (local_size())
2084  vector_view.scale (scaling_factors.vector_view);
2085 
2086  if (vector_is_ghosted)
2088  }
2089 
2090 
2091 
2092  template <typename Number>
2093  template <typename Number2>
2094  inline
2095  void
2096  Vector<Number>::scale (const Vector<Number2> &scaling_factors)
2097  {
2098  if (local_size())
2099  vector_view.template scale<Number2> (scaling_factors.vector_view);
2100 
2101  if (vector_is_ghosted)
2103  }
2104 
2105 
2106 
2107  template <typename Number>
2108  inline
2109  void
2110  Vector<Number>::equ (const Number a,
2111  const Vector<Number> &v)
2112  {
2113  // ::Vector does not allow empty fields but this might happen on
2114  // some processors for parallel implementation
2115  if (local_size())
2116  vector_view.equ (a, v.vector_view);
2117 
2118  if (vector_is_ghosted)
2120  }
2121 
2122 
2123 
2124  template <typename Number>
2125  template <typename Number2>
2126  inline
2127  void
2128  Vector<Number>::equ (const Number a,
2129  const Vector<Number2> &v)
2130  {
2131  // ::Vector does not allow empty fields but this might happen on
2132  // some processors for parallel implementation
2133  if (local_size())
2134  vector_view.equ (a, v.vector_view);
2135 
2136  if (vector_is_ghosted)
2138  }
2139 
2140 
2141 
2142  template <typename Number>
2143  inline
2144  void
2145  Vector<Number>::equ (const Number a,
2146  const Vector<Number> &v,
2147  const Number b,
2148  const Vector<Number> &w)
2149  {
2150  // ::Vector does not allow empty fields but this might happen on
2151  // some processors for parallel implementation
2152  if (local_size())
2153  vector_view.equ (a, v.vector_view, b, w.vector_view);
2154 
2155  if (vector_is_ghosted)
2157  }
2158 
2159 
2160 
2161  template <typename Number>
2162  inline
2163  void
2164  Vector<Number>::equ (const Number a,
2165  const Vector<Number> &v,
2166  const Number b,
2167  const Vector<Number> &w,
2168  const Number c,
2169  const Vector<Number> &x)
2170  {
2171  // ::Vector does not allow empty fields but this might happen on
2172  // some processors for parallel implementation
2173  if (local_size())
2174  vector_view.equ (a, v.vector_view, b, w.vector_view,
2175  c, x.vector_view);
2176 
2177  if (vector_is_ghosted)
2179  }
2180 
2181 
2182 
2183  template <typename Number>
2184  inline
2185  void
2187  const Vector<Number> &b)
2188  {
2189  // ::Vector does not allow empty fields but this might happen on
2190  // some processors for parallel implementation
2191  if (local_size())
2192  vector_view.ratio (a.vector_view, b.vector_view);
2193 
2194  if (vector_is_ghosted)
2196  }
2197 
2198 
2199 
2200  template <typename Number>
2201  inline
2202  const MPI_Comm &
2204  {
2205  return partitioner->get_communicator();
2206  }
2207 
2208 
2209 
2210  template <typename Number>
2211  inline
2212  bool
2214  (const Utilities::MPI::Partitioner &part) const
2215  {
2216  return partitioner->is_compatible (part);
2217  }
2218 
2219 #endif // ifndef DOXYGEN
2220 
2221  } // end of namespace distributed
2222 
2223 } // end of namespace parallel
2224 
2225 
2226 
2235 template <typename Number>
2236 inline
2239 {
2240  u.swap (v);
2241 }
2242 
2243 
2244 DEAL_II_NAMESPACE_CLOSE
2245 
2246 #endif
bool is_ghost_entry(const types::global_dof_index global_index) const
std::vector< MPI_Request > compress_requests
void add(const std::vector< size_type > &indices, const std::vector< OtherNumber > &values)
Number mean_value_local() const
real_type norm_sqr_local() const
#define AssertDimension(dim1, dim2)
Definition: exceptions.h:858
real_type linfty_norm() const
bool operator==(const BlockVectorBase< VectorType2 > &v) const
void add(const std::vector< size_type > &indices, const std::vector< Number > &values)
void compress_start(const unsigned int communication_channel=0,::VectorOperation::values operation=VectorOperation::add)
Number operator[](const size_type global_index) const
bool operator!=(const Vector< Number2 > &v) const
const IndexSet & ghost_elements() const
const MPI_Comm & get_mpi_communicator() const
types::global_dof_index size() const
Definition: index_set.h:685
void compress_finish(::VectorOperation::values operation)
std_cxx1x::shared_ptr< const Utilities::MPI::Partitioner > partitioner
::ExceptionBase & ExcMessage(std::string arg1)
void reinit(const size_type size, const bool fast=false)
real_type norm_sqr() const
std::pair< size_type, size_type > local_range() const
#define AssertIndexRange(index, range)
Definition: exceptions.h:888
void compress() DEAL_II_DEPRECATED
Vector< Number > & operator-=(const Vector< Number > &V)
void resize_val(const size_type new_allocated_size)
void ratio(const Vector< Number > &a, const Vector< Number > &b)
STL namespace.
size_type n_ghost_entries() const
Vector< Number > & operator/=(const Number factor)
Vector< Number > & operator+=(const Vector< Number > &V)
bool is_finite(const double x)
bool in_local_range(const size_type global_index) const
void reinit(const unsigned int num_blocks, const size_type block_size=0, const bool fast=false)
real_type lp_norm_local(const real_type p) const
value_type operator()(const size_type i) const
Vector< Number > & operator*=(const Number factor)
Number operator()(const size_type global_index) const
real_type l1_norm() const
bool in_local_range(const size_type global_index) const
numbers::NumberTraits< Number >::real_type real_type
Definition: vector.h:147
VectorView< Number > vector_view
void equ(const Number a, const Vector< Number > &u)
void scale(const Number factor) DEAL_II_DEPRECATED
void print(std::ostream &out, const unsigned int precision=3, const bool scientific=true, const bool across=true) const
Definition: types.h:29
T sum(const T &t, const MPI_Comm &mpi_communicator)
Definition: mpi.h:447
unsigned int global_dof_index
Definition: types.h:100
#define Assert(cond, exc)
Definition: exceptions.h:299
::ExceptionBase & ExcEmptyObject()
Vector< Number > & operator=(const Vector< Number > &in_vector)
static const bool supports_distributed_data
bool vectors_equal_local(const Vector< Number2 > &v) const
real_type l2_norm() const
BlockCompressedSparsityPattern CompressedBlockSparsityPattern DEAL_II_DEPRECATED
void swap(parallel::distributed::Vector< Number > &u, parallel::distributed::Vector< Number > &v)
Number operator*(const Vector< Number2 > &V) const
void update_ghost_values_start(const unsigned int communication_channel=0) const
void extract_subvector_to(const std::vector< size_type > &indices, std::vector< OtherNumber > &values) const
real_type linfty_norm_local() const
BlockVectorBase & operator*=(const value_type factor)
Number inner_product_local(const Vector< Number2 > &V) const
std::vector< MPI_Request > update_ghost_values_requests
Definition: mpi.h:54
void sadd(const Number s, const Vector< Number > &V)
real_type lp_norm(const real_type p) const
bool is_non_negative_local() const
Number local_element(const size_type local_index) const
bool partitioners_are_compatible(const Utilities::MPI::Partitioner &part) const
bool operator==(const Vector< Number2 > &v) const
void compress() DEAL_II_DEPRECATED
::ExceptionBase & ExcNotInitialized()
void copy_from(const Vector< Number > &in_vector, const bool call_update_ghost_values=false)
size_type local_size() const
real_type l1_norm_local() const
IndexSet locally_owned_elements() const
T max(const T &t, const MPI_Comm &mpi_communicator)
Definition: mpi.h:501