Reference documentation for deal.II version 8.4.2
parallel_vector.h
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 2011 - 2016 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__parallel_vector_h
17 #define dealii__parallel_vector_h
18 
19 #include <deal.II/base/config.h>
20 #include <deal.II/base/index_set.h>
21 #include <deal.II/base/mpi.h>
22 #include <deal.II/base/template_constraints.h>
23 #include <deal.II/base/types.h>
24 #include <deal.II/base/utilities.h>
25 #include <deal.II/base/memory_consumption.h>
26 #include <deal.II/base/partitioner.h>
27 #include <deal.II/base/thread_management.h>
28 #include <deal.II/lac/vector_view.h>
29 
30 #include <cstring>
31 #include <iomanip>
32 
33 
34 DEAL_II_NAMESPACE_OPEN
35 
36 #ifdef DEAL_II_WITH_PETSC
37 namespace PETScWrappers
38 {
39  namespace MPI
40  {
41  class Vector;
42  }
43 }
44 #endif
45 
46 #ifdef DEAL_II_WITH_TRILINOS
47 namespace TrilinosWrappers
48 {
49  namespace MPI
50  {
51  class Vector;
52  }
53 }
54 #endif
55 
56 
57 namespace parallel
58 {
59  namespace distributed
60  {
61  template <typename Number> class BlockVector;
62 
170  template <typename Number>
171  class Vector : public Subscriptor
172  {
173  public:
179  typedef Number value_type;
180  typedef value_type *pointer;
181  typedef const value_type *const_pointer;
182  typedef value_type *iterator;
183  typedef const value_type *const_iterator;
184  typedef value_type &reference;
185  typedef const value_type &const_reference;
186  typedef types::global_dof_index size_type;
187  typedef typename numbers::NumberTraits<Number>::real_type real_type;
188 
199  static const bool supports_distributed_data = true;
200 
208  Vector ();
209 
213  Vector (const Vector<Number> &in_vector);
214 
219  Vector (const size_type size);
220 
237  Vector (const IndexSet &local_range,
238  const IndexSet &ghost_indices,
239  const MPI_Comm communicator);
240 
244  Vector (const IndexSet &local_range,
245  const MPI_Comm communicator);
246 
253  Vector (const std_cxx11::shared_ptr<const Utilities::MPI::Partitioner> &partitioner);
254 
258  ~Vector ();
259 
264  void reinit (const size_type size,
265  const bool omit_zeroing_entries = false);
266 
277  template <typename Number2>
278  void reinit(const Vector<Number2> &in_vector,
279  const bool omit_zeroing_entries = false);
280 
297  void reinit (const IndexSet &local_range,
298  const IndexSet &ghost_indices,
299  const MPI_Comm communicator);
300 
304  void reinit (const IndexSet &local_range,
305  const MPI_Comm communicator);
306 
313  void reinit (const std_cxx11::shared_ptr<const Utilities::MPI::Partitioner> &partitioner);
314 
330  void swap (Vector<Number> &v);
331 
344  operator = (const Vector<Number> &in_vector);
345 
357  template <typename Number2>
359  operator = (const Vector<Number2> &in_vector);
360 
361 #ifdef DEAL_II_WITH_PETSC
362 
370  operator = (const PETScWrappers::MPI::Vector &petsc_vec);
371 #endif
372 
373 #ifdef DEAL_II_WITH_TRILINOS
374 
383  operator = (const TrilinosWrappers::MPI::Vector &trilinos_vec);
384 #endif
385 
392  void copy_from (const Vector<Number> &in_vector,
393  const bool call_update_ghost_values = false) DEAL_II_DEPRECATED;
394 
400  Vector<Number> &operator = (const Number s);
401 
424  void compress (::VectorOperation::values operation);
425 
447  void update_ghost_values () const;
448 
463  void compress_start (const unsigned int communication_channel = 0,
464  ::VectorOperation::values operation = VectorOperation::add);
465 
481  void compress_finish (::VectorOperation::values operation);
482 
497  void update_ghost_values_start (const unsigned int communication_channel = 0) const;
498 
499 
507  void update_ghost_values_finish () const;
508 
517  void zero_out_ghosts ();
518 
530  bool has_ghost_elements() const;
531 
537  bool all_zero () const;
538 
549  bool is_non_negative () const;
550 
554  template <typename Number2>
555  bool operator == (const Vector<Number2> &v) const;
556 
560  template <typename Number2>
561  bool operator != (const Vector<Number2> &v) const;
562 
566  template <typename Number2>
567  Number operator * (const Vector<Number2> &V) const;
568 
573  real_type norm_sqr () const;
574 
578  Number mean_value () const;
579 
584  real_type l1_norm () const;
585 
590  real_type l2_norm () const;
591 
597  real_type lp_norm (const real_type p) const;
598 
603  real_type linfty_norm () const;
604 
621  Number add_and_dot (const Number a,
622  const Vector<Number> &V,
623  const Vector<Number> &W);
624 
629  size_type size () const;
630 
635  size_type local_size() const;
636 
642  std::pair<size_type, size_type> local_range () const;
643 
648  bool in_local_range (const size_type global_index) const;
649 
663  IndexSet locally_owned_elements () const;
664 
670  size_type n_ghost_entries () const DEAL_II_DEPRECATED;
671 
679  const IndexSet &ghost_elements() const DEAL_II_DEPRECATED;
680 
688  bool is_ghost_entry (const types::global_dof_index global_index) const DEAL_II_DEPRECATED;
689 
697  iterator begin ();
698 
703  const_iterator begin () const;
704 
709  iterator end ();
710 
715  const_iterator end () const;
717 
718 
723 
733  Number operator () (const size_type global_index) const;
734 
744  Number &operator () (const size_type global_index);
745 
753  Number operator [] (const size_type global_index) const;
754 
762  Number &operator [] (const size_type global_index);
763 
770  template <typename OtherNumber>
771  void extract_subvector_to (const std::vector<size_type> &indices,
772  std::vector<OtherNumber> &values) const;
773 
778  template <typename ForwardIterator, typename OutputIterator>
779  void extract_subvector_to (ForwardIterator indices_begin,
780  const ForwardIterator indices_end,
781  OutputIterator values_begin) const;
782 
791  Number local_element (const size_type local_index) const;
792 
801  Number &local_element (const size_type local_index);
803 
804 
809 
813  Vector<Number> &operator += (const Vector<Number> &V);
814 
818  Vector<Number> &operator -= (const Vector<Number> &V);
819 
824  template <typename OtherNumber>
825  void add (const std::vector<size_type> &indices,
826  const std::vector<OtherNumber> &values);
827 
832  template <typename OtherNumber>
833  void add (const std::vector<size_type> &indices,
834  const ::Vector<OtherNumber> &values);
835 
841  template <typename OtherNumber>
842  void add (const size_type n_elements,
843  const size_type *indices,
844  const OtherNumber *values);
845 
850  void add (const Number s);
851 
857  void add (const Vector<Number> &V) DEAL_II_DEPRECATED;
858 
863  void add (const Number a, const Vector<Number> &V);
864 
868  void add (const Number a, const Vector<Number> &V,
869  const Number b, const Vector<Number> &W);
870 
875  void sadd (const Number s,
876  const Vector<Number> &V);
877 
881  void sadd (const Number s,
882  const Number a,
883  const Vector<Number> &V);
884 
890  void sadd (const Number s,
891  const Number a,
892  const Vector<Number> &V,
893  const Number b,
894  const Vector<Number> &W) DEAL_II_DEPRECATED;
895 
902  void sadd (const Number s,
903  const Number a,
904  const Vector<Number> &V,
905  const Number b,
906  const Vector<Number> &W,
907  const Number c,
908  const Vector<Number> &X) DEAL_II_DEPRECATED;
909 
913  Vector<Number> &operator *= (const Number factor);
914 
918  Vector<Number> &operator /= (const Number factor);
919 
925  void scale (const Vector<Number> &scaling_factors);
926 
932  template <typename Number2>
933  void scale (const Vector<Number2> &scaling_factors);
934 
938  void equ (const Number a, const Vector<Number> &u);
939 
943  template <typename Number2>
944  void equ (const Number a, const Vector<Number2> &u);
945 
951  void equ (const Number a, const Vector<Number> &u,
952  const Number b, const Vector<Number> &v) DEAL_II_DEPRECATED;
953 
959  void equ (const Number a, const Vector<Number> &u,
960  const Number b, const Vector<Number> &v,
961  const Number c, const Vector<Number> &w) DEAL_II_DEPRECATED;
962 
973  void ratio (const Vector<Number> &a,
974  const Vector<Number> &b) DEAL_II_DEPRECATED;
976 
977 
986  const MPI_Comm &get_mpi_communicator () const;
987 
994  std_cxx11::shared_ptr<const Utilities::MPI::Partitioner>
995  get_partitioner () const;
996 
1006  bool
1007  partitioners_are_compatible (const Utilities::MPI::Partitioner &part) const;
1008 
1022  bool
1023  partitioners_are_globally_compatible (const Utilities::MPI::Partitioner &part) const;
1024 
1028  void print (std::ostream &out,
1029  const unsigned int precision = 3,
1030  const bool scientific = true,
1031  const bool across = true) const;
1032 
1036  std::size_t memory_consumption () const;
1038 
1042  DeclException3 (ExcNonMatchingElements,
1043  double, double, unsigned int,
1044  << "Called compress(VectorOperation::insert), but"
1045  << " the element received from a remote processor, value "
1046  << std::setprecision(16) << arg1
1047  << ", does not match with the value "
1048  << std::setprecision(16) << arg2
1049  << " on the owner processor " << arg3);
1050 
1054  DeclException4 (ExcAccessToNonLocalElement,
1055  size_type, size_type, size_type, size_type,
1056  << "You tried to access element " << arg1
1057  << " of a distributed vector, but this element is not "
1058  << "stored on the current processor. Note: The range of "
1059  << "locally owned elements is " << arg2 << " to "
1060  << arg3 << ", and there are " << arg4 << " ghost elements "
1061  << "that this vector can access.");
1062 
1063  private:
1067  bool all_zero_local () const;
1068 
1072  bool is_non_negative_local () const;
1073 
1077  template <typename Number2>
1078  bool vectors_equal_local (const Vector<Number2> &v) const;
1079 
1083  template <typename Number2>
1084  Number inner_product_local (const Vector<Number2> &V) const;
1085 
1089  real_type norm_sqr_local () const;
1090 
1094  Number mean_value_local () const;
1095 
1099  real_type l1_norm_local () const;
1100 
1104  real_type lp_norm_local (const real_type p) const;
1105 
1109  real_type linfty_norm_local () const;
1110 
1115  Number add_and_dot_local (const Number a,
1116  const Vector<Number> &V,
1117  const Vector<Number> &W);
1118 
1124  std_cxx11::shared_ptr<const Utilities::MPI::Partitioner> partitioner;
1125 
1129  size_type allocated_size;
1130 
1134  Number *val;
1135 
1141  mutable Number *import_data;
1142 
1150  mutable bool vector_is_ghosted;
1151 
1156  VectorView<Number> vector_view;
1157 
1158 #ifdef DEAL_II_WITH_MPI
1159 
1167  std::vector<MPI_Request> compress_requests;
1168 
1173  mutable std::vector<MPI_Request> update_ghost_values_requests;
1174 #endif
1175 
1182 
1187  void clear_mpi_requests ();
1188 
1192  void resize_val (const size_type new_allocated_size);
1193 
1194  /*
1195  * Make all other vector types friends.
1196  */
1197  template <typename Number2> friend class Vector;
1198 
1202  template <typename Number2> friend class BlockVector;
1203  };
1204 
1208  /*----------------------- Inline functions ----------------------------------*/
1209 
1210 #ifndef DOXYGEN
1211 
1212  template <typename Number>
1213  inline
1215  :
1216  partitioner (new Utilities::MPI::Partitioner()),
1217  allocated_size (0),
1218  val (0),
1219  import_data (0),
1220  vector_is_ghosted (false),
1221  vector_view (0, static_cast<Number *>(0))
1222  {}
1223 
1224 
1225 
1226  template <typename Number>
1227  inline
1229  :
1230  Subscriptor(),
1231  allocated_size (0),
1232  val (0),
1233  import_data (0),
1234  vector_is_ghosted (false),
1235  vector_view (0, static_cast<Number *>(0))
1236  {
1237  reinit (v, true);
1238  vector_view = v.vector_view;
1239  zero_out_ghosts();
1240  }
1241 
1242 
1243 
1244  template <typename Number>
1245  inline
1246  Vector<Number>::Vector (const IndexSet &local_range,
1247  const IndexSet &ghost_indices,
1248  const MPI_Comm communicator)
1249  :
1250  allocated_size (0),
1251  val (0),
1252  import_data (0),
1253  vector_is_ghosted (false),
1254  vector_view (0, static_cast<Number *>(0))
1255  {
1256  reinit (local_range, ghost_indices, communicator);
1257  }
1258 
1259 
1260 
1261  template <typename Number>
1262  inline
1263  Vector<Number>::Vector (const IndexSet &local_range,
1264  const MPI_Comm communicator)
1265  :
1266  allocated_size (0),
1267  val (0),
1268  import_data (0),
1269  vector_is_ghosted (false),
1270  vector_view (0, static_cast<Number *>(0))
1271  {
1272  reinit (local_range, communicator);
1273  }
1274 
1275 
1276 
1277  template <typename Number>
1278  inline
1279  Vector<Number>::Vector (const size_type size)
1280  :
1281  allocated_size (0),
1282  val (0),
1283  import_data (0),
1284  vector_is_ghosted (false),
1285  vector_view (0, static_cast<Number *>(0))
1286  {
1287  reinit (size, false);
1288  }
1289 
1290 
1291 
1292  template <typename Number>
1293  inline
1295  Vector (const std_cxx11::shared_ptr<const Utilities::MPI::Partitioner> &partitioner)
1296  :
1297  allocated_size (0),
1298  val (0),
1299  import_data (0),
1300  vector_is_ghosted (false),
1301  vector_view (0, static_cast<Number *>(0))
1302  {
1303  reinit (partitioner);
1304  }
1305 
1306 
1307 
1308  template <typename Number>
1309  inline
1311  {
1312  resize_val(0);
1313 
1314  if (import_data != 0)
1315  delete[] import_data;
1316  import_data = 0;
1317 
1318  clear_mpi_requests();
1319  }
1320 
1321 
1322 
1323  template <typename Number>
1324  inline
1325  Vector<Number> &
1327  {
1328 #ifdef _MSC_VER
1329  return this->operator=<Number>(c);
1330 #else
1331  return this->template operator=<Number>(c);
1332 #endif
1333  }
1334 
1335 
1336 
1337  template <typename Number>
1338  template <typename Number2>
1339  inline
1340  Vector<Number> &
1342  {
1343  Assert (c.partitioner.get() != 0, ExcNotInitialized());
1344 
1345  // we update ghost values whenever one of the input or output vector
1346  // already held ghost values or when we import data from a vector with
1347  // the same local range but different ghost layout
1348  bool must_update_ghost_values = c.vector_is_ghosted;
1349 
1350  // check whether the two vectors use the same parallel partitioner. if
1351  // not, check if all local ranges are the same (that way, we can
1352  // exchange data between different parallel layouts). One variant which
1353  // is included here and necessary for compatibility with the other
1354  // distributed vector classes (Trilinos, PETSc) is the case when vector
1355  // c does not have any ghosts (constructed without ghost elements given)
1356  // but the current vector does: In that case, we need to exchange data
1357  // also when none of the two vector had updated its ghost values before.
1358  if (partitioner.get() == 0)
1359  reinit (c, true);
1360  else if (partitioner.get() != c.partitioner.get())
1361  {
1362  // local ranges are also the same if both partitioners are empty
1363  // (even if they happen to define the empty range as [0,0) or [c,c)
1364  // for some c!=0 in a different way).
1365  int local_ranges_are_identical =
1366  (local_range() == c.local_range() ||
1367  (local_range().second == local_range().first &&
1368  c.local_range().second == c.local_range().first));
1369  if ((c.partitioner->n_mpi_processes() > 1 &&
1370  Utilities::MPI::min(local_ranges_are_identical,
1371  c.partitioner->get_communicator()) == 0)
1372  ||
1373  !local_ranges_are_identical)
1374  reinit (c, true);
1375  else
1376  must_update_ghost_values |= vector_is_ghosted;
1377 
1378  must_update_ghost_values |=
1379  (c.partitioner->ghost_indices_initialized() == false &&
1380  partitioner->ghost_indices_initialized() == true);
1381  }
1382  else
1383  must_update_ghost_values |= vector_is_ghosted;
1384 
1385  // Need to explicitly downcast to ::Vector to make templated
1386  // operator= available.
1387  AssertDimension(vector_view.size(), c.vector_view.size());
1388  static_cast<::Vector<Number> &>(vector_view) = c.vector_view;
1389 
1390  if (must_update_ghost_values)
1392  else
1393  zero_out_ghosts();
1394  return *this;
1395  }
1396 
1397 
1398 
1399  template <typename Number>
1400  inline
1401  void
1402  Vector<Number>::compress (::VectorOperation::values operation)
1403  {
1404  compress_start (0, operation);
1405  compress_finish(operation);
1406  }
1407 
1408 
1409 
1410  template <typename Number>
1411  inline
1412  void
1414  {
1415  update_ghost_values_start ();
1416  update_ghost_values_finish ();
1417  }
1418 
1419 
1420 
1421  template <typename Number>
1422  inline
1423  void
1425  {
1426  std::fill_n (&val[partitioner->local_size()],
1427  partitioner->n_ghost_indices(),
1428  Number());
1429  vector_is_ghosted = false;
1430  }
1431 
1432 
1433 
1434  template <typename Number>
1435  inline
1436  bool
1438  {
1439  return vector_is_ghosted;
1440  }
1441 
1442 
1443 
1444  template <typename Number>
1445  inline
1446  bool
1448  {
1449  return partitioner->local_size()>0 ? vector_view.all_zero () : true;
1450  }
1451 
1452 
1453 
1454  template <typename Number>
1455  inline
1456  bool
1457  Vector<Number>::all_zero () const
1458  {
1459  // use int instead of bool. in order to make global reduction operations
1460  // work also when MPI_Init was not called, only call MPI_Allreduce
1461  // commands when there is more than one processor (note that reinit()
1462  // functions handle this case correctly through the job_supports_mpi()
1463  // query). this is the same in all the functions below
1464  int local_result = -static_cast<int>(all_zero_local());
1465  if (partitioner->n_mpi_processes() > 1)
1466  return -Utilities::MPI::max(local_result,
1467  partitioner->get_communicator());
1468  else
1469  return -local_result;
1470  }
1471 
1472 
1473 
1474  template <typename Number>
1475  inline
1476  bool
1478  {
1479  return partitioner->local_size()>0 ? vector_view.is_non_negative () : true;
1480  }
1481 
1482 
1483 
1484  template <typename Number>
1485  inline
1486  bool
1488  {
1489  int local_result = -static_cast<int>(is_non_negative_local());
1490  if (partitioner->n_mpi_processes() > 1)
1491  return -Utilities::MPI::max(local_result,
1492  partitioner->get_communicator());
1493  else
1494  return -local_result;
1495  }
1496 
1497 
1498 
1499  template <typename Number>
1500  template <typename Number2>
1501  inline
1502  bool
1504  {
1505  return partitioner->local_size()>0 ?
1506  vector_view.template operator == <Number2>(v.vector_view)
1507  : true;
1508  }
1509 
1510 
1511 
1512  template <typename Number>
1513  template <typename Number2>
1514  inline
1515  bool
1517  {
1518  // MPI does not support bools, so use unsigned int instead. Two vectors
1519  // are equal if the check for non-equal fails on all processors
1520  unsigned int local_result = static_cast<int>(!vectors_equal_local(v));
1521  unsigned int result =
1522  partitioner->n_mpi_processes() > 1
1523  ?
1524  Utilities::MPI::max(local_result, partitioner->get_communicator())
1525  :
1526  local_result;
1527  return result==0;
1528  }
1529 
1530 
1531 
1532  template <typename Number>
1533  template <typename Number2>
1534  inline
1535  bool
1537  {
1538  return !(operator == (v));
1539  }
1540 
1541 
1542 
1543  template <typename Number>
1544  template <typename Number2>
1545  inline
1546  Number
1548  {
1549  // on some processors, the size might be zero, which is not allowed by
1550  // the ::Vector class. Therefore, insert a check here
1551  return (partitioner->local_size()>0 ?
1552  vector_view.operator* (V.vector_view)
1553  : Number());
1554  }
1555 
1556 
1557 
1558  template <typename Number>
1559  template <typename Number2>
1560  inline
1561  Number
1563  {
1564  Number local_result = inner_product_local(V);
1565  if (partitioner->n_mpi_processes() > 1)
1566  return Utilities::MPI::sum (local_result,
1567  partitioner->get_communicator());
1568  else
1569  return local_result;
1570  }
1571 
1572 
1573 
1574  template <typename Number>
1575  inline
1576  typename Vector<Number>::real_type
1578  {
1579  return partitioner->local_size()>0 ? vector_view.norm_sqr() : real_type();
1580  }
1581 
1582 
1583 
1584  template <typename Number>
1585  inline
1586  typename Vector<Number>::real_type
1587  Vector<Number>::norm_sqr () const
1588  {
1589  real_type local_result = norm_sqr_local();
1590  if (partitioner->n_mpi_processes() > 1)
1591  return Utilities::MPI::sum(local_result,
1592  partitioner->get_communicator());
1593  else
1594  return local_result;
1595  }
1596 
1597 
1598 
1599  template <typename Number>
1600  inline
1601  Number
1603  {
1604  Assert (partitioner->size()!=0, ExcEmptyObject());
1605  return (partitioner->local_size() ?
1606  vector_view.mean_value()
1607  : Number());
1608  }
1609 
1610 
1611 
1612  template <typename Number>
1613  inline
1614  Number
1616  {
1617  Number local_result = mean_value_local();
1618  if (partitioner->n_mpi_processes() > 1)
1619  return Utilities::MPI::sum (local_result *
1620  (real_type)partitioner->local_size(),
1621  partitioner->get_communicator())
1622  /(real_type)partitioner->size();
1623  else
1624  return local_result;
1625  }
1626 
1627 
1628 
1629  template <typename Number>
1630  inline
1631  typename Vector<Number>::real_type
1633  {
1634  return partitioner->local_size() ? vector_view.l1_norm() : real_type();
1635  }
1636 
1637 
1638 
1639  template <typename Number>
1640  inline
1641  typename Vector<Number>::real_type
1642  Vector<Number>::l1_norm () const
1643  {
1644  real_type local_result = l1_norm_local();
1645  if (partitioner->n_mpi_processes() > 1)
1646  return Utilities::MPI::sum(local_result,
1647  partitioner->get_communicator());
1648  else
1649  return local_result;
1650  }
1651 
1652 
1653 
1654  template <typename Number>
1655  inline
1656  typename Vector<Number>::real_type
1657  Vector<Number>::l2_norm () const
1658  {
1659  return std::sqrt(norm_sqr());
1660  }
1661 
1662 
1663 
1664  template <typename Number>
1665  inline
1666  typename Vector<Number>::real_type
1667  Vector<Number>::lp_norm_local (const real_type p) const
1668  {
1669  return partitioner->local_size() ? vector_view.lp_norm(p) : real_type();
1670  }
1671 
1672 
1673 
1674  template <typename Number>
1675  inline
1676  typename Vector<Number>::real_type
1677  Vector<Number>::lp_norm (const real_type p) const
1678  {
1679  const real_type local_result = lp_norm_local(p);
1680  if (partitioner->n_mpi_processes() > 1)
1681  return std::pow (Utilities::MPI::sum(std::pow(local_result,p),
1682  partitioner->get_communicator()),
1683  static_cast<real_type>(1.0/p));
1684  else
1685  return local_result;
1686  }
1687 
1688 
1689 
1690  template <typename Number>
1691  inline
1692  typename Vector<Number>::real_type
1694  {
1695  return partitioner->local_size() ? vector_view.linfty_norm() : real_type();
1696  }
1697 
1698 
1699 
1700  template <typename Number>
1701  inline
1702  typename Vector<Number>::real_type
1704  {
1705  const real_type local_result = linfty_norm_local();
1706  if (partitioner->n_mpi_processes() > 1)
1707  return Utilities::MPI::max (local_result,
1708  partitioner->get_communicator());
1709  else
1710  return local_result;
1711  }
1712 
1713 
1714 
1715  template <typename Number>
1716  inline
1717  Number
1718  Vector<Number>::add_and_dot_local(const Number a,
1719  const Vector<Number> &V,
1720  const Vector<Number> &W)
1721  {
1722  // on some processors, the size might be zero, which is not allowed by
1723  // the ::Vector class. Therefore, insert a check here
1724  return (partitioner->local_size()>0 ?
1725  vector_view.add_and_dot(a, V.vector_view, W.vector_view)
1726  : Number());
1727  }
1728 
1729 
1730 
1731  template <typename Number>
1732  inline
1733  Number
1734  Vector<Number>::add_and_dot (const Number a,
1735  const Vector<Number> &V,
1736  const Vector<Number> &W)
1737  {
1738  Number local_result = add_and_dot_local(a, V, W);
1739  if (partitioner->n_mpi_processes() > 1)
1740  return Utilities::MPI::sum (local_result,
1741  partitioner->get_communicator());
1742  else
1743  return local_result;
1744  }
1745 
1746 
1747 
1748  template <typename Number>
1749  inline
1750  typename Vector<Number>::size_type
1751  Vector<Number>::size () const
1752  {
1753  return partitioner->size();
1754  }
1755 
1756 
1757 
1758  template <typename Number>
1759  inline
1760  typename Vector<Number>::size_type
1762  {
1763  return partitioner->local_size();
1764  }
1765 
1766 
1767 
1768  template <typename Number>
1769  inline
1770  std::pair<typename Vector<Number>::size_type,
1771  typename Vector<Number>::size_type>
1773  {
1774  return partitioner->local_range();
1775  }
1776 
1777 
1778 
1779  template <typename Number>
1780  inline
1781  bool
1783  (const size_type global_index) const
1784  {
1785  return partitioner->in_local_range (global_index);
1786  }
1787 
1788 
1789 
1790  template <typename Number>
1791  inline
1792  IndexSet
1794  {
1795  IndexSet is (size());
1796 
1797  is.add_range (local_range().first, local_range().second);
1798 
1799  return is;
1800  }
1801 
1802 
1803 
1804  template <typename Number>
1805  inline
1806  typename Vector<Number>::size_type
1808  {
1809  return partitioner->n_ghost_indices();
1810  }
1811 
1812 
1813 
1814  template <typename Number>
1815  inline
1816  const IndexSet &
1818  {
1819  return partitioner->ghost_indices();
1820  }
1821 
1822 
1823 
1824  template <typename Number>
1825  inline
1826  bool
1827  Vector<Number>::is_ghost_entry (const size_type global_index) const
1828  {
1829  return partitioner->is_ghost_entry (global_index);
1830  }
1831 
1832 
1833 
1834  template <typename Number>
1835  inline
1836  typename Vector<Number>::iterator
1838  {
1839  return vector_view.begin();
1840  }
1841 
1842 
1843 
1844  template <typename Number>
1845  inline
1846  typename Vector<Number>::const_iterator
1847  Vector<Number>::begin () const
1848  {
1849  return vector_view.begin();
1850  }
1851 
1852 
1853 
1854  template <typename Number>
1855  inline
1856  typename Vector<Number>::iterator
1858  {
1859  return vector_view.end();
1860  }
1861 
1862 
1863 
1864  template <typename Number>
1865  inline
1866  typename Vector<Number>::const_iterator
1867  Vector<Number>::end () const
1868  {
1869  return vector_view.end();
1870  }
1871 
1872 
1873 
1874  template <typename Number>
1875  inline
1876  Number
1877  Vector<Number>::operator() (const size_type global_index) const
1878  {
1879  Assert (in_local_range (global_index) ||
1880  partitioner->ghost_indices().is_element(global_index),
1881  ExcAccessToNonLocalElement(global_index, local_range().first,
1882  local_range().second,
1883  partitioner->ghost_indices().n_elements()));
1884  // do not allow reading a vector which is not in ghost mode
1885  Assert (in_local_range (global_index) || vector_is_ghosted == true,
1886  ExcMessage("You tried to read a ghost element of this vector, "
1887  "but it has not imported its ghost values."));
1888  return val[partitioner->global_to_local(global_index)];
1889  }
1890 
1891 
1892 
1893  template <typename Number>
1894  inline
1895  Number &
1896  Vector<Number>::operator() (const size_type global_index)
1897  {
1898  Assert (in_local_range (global_index) ||
1899  partitioner->ghost_indices().is_element(global_index),
1900  ExcAccessToNonLocalElement(global_index, local_range().first,
1901  local_range().second,
1902  partitioner->ghost_indices().n_elements()));
1903  // we would like to prevent reading ghosts from a vector that does not
1904  // have them imported, but this is not possible because we might be in a
1905  // part of the code where the vector has enabled ghosts but is non-const
1906  // (then, the compiler picks this method according to the C++ rule book
1907  // even if a human would pick the const method when this subsequent use
1908  // is just a read)
1909  return val[partitioner->global_to_local (global_index)];
1910  }
1911 
1912 
1913 
1914  template <typename Number>
1915  inline
1916  Number
1917  Vector<Number>::operator[] (const size_type global_index) const
1918  {
1919  return operator()(global_index);
1920  }
1921 
1922 
1923 
1924  template <typename Number>
1925  inline
1926  Number &
1927  Vector<Number>::operator[] (const size_type global_index)
1928  {
1929  return operator()(global_index);
1930  }
1931 
1932 
1933 
1934  template <typename Number>
1935  template <typename OtherNumber>
1936  inline
1937  void Vector<Number>::extract_subvector_to (const std::vector<size_type> &indices,
1938  std::vector<OtherNumber> &values) const
1939  {
1940  for (size_type i = 0; i < indices.size(); ++i)
1941  values[i] = operator()(indices[i]);
1942  }
1943 
1944 
1945 
1946  template <typename Number>
1947  template <typename ForwardIterator, typename OutputIterator>
1948  inline
1949  void Vector<Number>::extract_subvector_to (ForwardIterator indices_begin,
1950  const ForwardIterator indices_end,
1951  OutputIterator values_begin) const
1952  {
1953  while (indices_begin != indices_end)
1954  {
1955  *values_begin = operator()(*indices_begin);
1956  indices_begin++;
1957  values_begin++;
1958  }
1959  }
1960 
1961 
1962 
1963  template <typename Number>
1964  inline
1965  Number
1966  Vector<Number>::local_element (const size_type local_index) const
1967  {
1968  AssertIndexRange (local_index,
1969  partitioner->local_size()+
1970  partitioner->n_ghost_indices());
1971  // do not allow reading a vector which is not in ghost mode
1972  Assert (local_index < local_size() || vector_is_ghosted == true,
1973  ExcMessage("You tried to read a ghost element of this vector, "
1974  "but it has not imported its ghost values."));
1975  return val[local_index];
1976  }
1977 
1978 
1979 
1980  template <typename Number>
1981  inline
1982  Number &
1983  Vector<Number>::local_element (const size_type local_index)
1984  {
1985  AssertIndexRange (local_index,
1986  partitioner->local_size()+
1987  partitioner->n_ghost_indices());
1988  return val[local_index];
1989  }
1990 
1991 
1992 
1993  template <typename Number>
1994  inline
1995  Vector<Number> &
1996  Vector<Number>::operator = (const Number s)
1997  {
1998  // if we call Vector::operator=0, we want to zero out all the entries
1999  // plus ghosts.
2000  if (partitioner->local_size() > 0)
2001  vector_view.::template Vector<Number>::operator= (s);
2002  if (s==Number())
2003  zero_out_ghosts();
2004 
2005  return *this;
2006  }
2007 
2008 
2009 
2010  template <typename Number>
2011  inline
2012  Vector<Number> &
2014  {
2015  AssertDimension (local_size(), v.local_size());
2016 
2017  // ::Vector does not allow empty fields but this might happen on
2018  // some processors for parallel implementation
2019  if (local_size()>0)
2020  vector_view += v.vector_view;
2021 
2022  if (vector_is_ghosted)
2024 
2025  return *this;
2026  }
2027 
2028 
2029 
2030  template <typename Number>
2031  inline
2032  Vector<Number> &
2034  {
2035  AssertDimension (local_size(), v.local_size());
2036 
2037  // ::Vector does not allow empty fields but this might happen on
2038  // some processors for parallel implementation
2039  if (local_size()>0)
2040  vector_view -= v.vector_view;
2041 
2042  if (vector_is_ghosted)
2044 
2045  return *this;
2046  }
2047 
2048 
2049 
2050  template <typename Number>
2051  template <typename OtherNumber>
2052  inline
2053  void
2054  Vector<Number>::add (const std::vector<size_type> &indices,
2055  const std::vector<OtherNumber> &values)
2056  {
2057  AssertDimension (indices.size(), values.size());
2058  add (indices.size(), &indices[0], &values[0]);
2059  }
2060 
2061 
2062 
2063  template <typename Number>
2064  template <typename OtherNumber>
2065  inline
2066  void
2067  Vector<Number>::add (const std::vector<size_type> &indices,
2068  const ::Vector<OtherNumber> &values)
2069  {
2070  AssertDimension (indices.size(), values.size());
2071  add (indices.size(), &indices[0], values.begin());
2072  }
2073 
2074 
2075 
2076  template <typename Number>
2077  template <typename OtherNumber>
2078  inline
2079  void
2080  Vector<Number>::add (const size_type n_indices,
2081  const size_type *indices,
2082  const OtherNumber *values)
2083  {
2084  for (size_type i=0; i<n_indices; ++i)
2085  {
2086  Assert (numbers::is_finite(values[i]),
2087  ExcMessage("The given value is not finite but either infinite or Not A Number (NaN)"));
2088  this->operator()(indices[i]) += values[i];
2089  }
2090  }
2091 
2092 
2093 
2094  template <typename Number>
2095  inline
2096  void
2097  Vector<Number>::add (const Number a)
2098  {
2099  // ::Vector does not allow empty fields but this might happen on
2100  // some processors for parallel implementation
2101  if (local_size())
2102  vector_view.add (a);
2103 
2104  if (vector_is_ghosted)
2106  }
2107 
2108 
2109 
2110  template <typename Number>
2111  inline
2112  void
2114  {
2115  // ::Vector does not allow empty fields but this might happen on
2116  // some processors for parallel implementation
2117  if (local_size())
2118  vector_view.add (v.vector_view);
2119 
2120  if (vector_is_ghosted)
2122  }
2123 
2124 
2125 
2126  template <typename Number>
2127  inline
2128  void
2129  Vector<Number>::add (const Number a,
2130  const Vector<Number> &v)
2131  {
2132  // ::Vector does not allow empty fields but this might happen on
2133  // some processors for parallel implementation
2134  if (local_size())
2135  vector_view.add (a, v.vector_view);
2136 
2137  if (vector_is_ghosted)
2139  }
2140 
2141 
2142 
2143  template <typename Number>
2144  inline
2145  void
2146  Vector<Number>::add (const Number a,
2147  const Vector<Number> &v,
2148  const Number b,
2149  const Vector<Number> &w)
2150  {
2151  // ::Vector does not allow empty fields but this might happen on
2152  // some processors for parallel implementation
2153  if (local_size())
2154  vector_view.add (a, v.vector_view, b, w.vector_view);
2155 
2156  if (vector_is_ghosted)
2158  }
2159 
2160 
2161 
2162  template <typename Number>
2163  inline
2164  void
2165  Vector<Number>::sadd (const Number x,
2166  const Vector<Number> &v)
2167  {
2168  // ::Vector does not allow empty fields but this might happen on
2169  // some processors for parallel implementation
2170  if (local_size())
2171  vector_view.sadd (x, v.vector_view);
2172 
2173  if (vector_is_ghosted)
2175  }
2176 
2177 
2178 
2179  template <typename Number>
2180  inline
2181  void
2182  Vector<Number>::sadd (const Number x,
2183  const Number a,
2184  const Vector<Number> &v)
2185  {
2186  // ::Vector does not allow empty fields but this might happen on
2187  // some processors for parallel implementation
2188  if (local_size())
2189  vector_view.sadd (x, a, v.vector_view);
2190 
2191  if (vector_is_ghosted)
2193  }
2194 
2195 
2196 
2197  template <typename Number>
2198  inline
2199  void
2200  Vector<Number>::sadd (const Number x,
2201  const Number a,
2202  const Vector<Number> &v,
2203  const Number b,
2204  const Vector<Number> &w)
2205  {
2206  // ::Vector does not allow empty fields but this might happen on
2207  // some processors for parallel implementation
2208  if (local_size())
2209  vector_view.sadd (x, a, v.vector_view, b, w.vector_view);
2210 
2211  if (vector_is_ghosted)
2213  }
2214 
2215 
2216 
2217  template <typename Number>
2218  inline
2219  void
2220  Vector<Number>::sadd (const Number s,
2221  const Number a,
2222  const Vector<Number> &v,
2223  const Number b,
2224  const Vector<Number> &w,
2225  const Number c,
2226  const Vector<Number> &x)
2227  {
2228  // ::Vector does not allow empty fields but this might happen on
2229  // some processors for parallel implementation
2230  if (local_size())
2231  vector_view.sadd (s, a, v.vector_view, b, w.vector_view,
2232  c, x.vector_view);
2233 
2234  if (vector_is_ghosted)
2236  }
2237 
2238 
2239 
2240  template <typename Number>
2241  inline
2242  Vector<Number> &
2243  Vector<Number>::operator *= (const Number factor)
2244  {
2245  // ::Vector does not allow empty fields but this might happen on
2246  // some processors for parallel implementation
2247  if (local_size())
2248  vector_view *= factor;
2249 
2250  if (vector_is_ghosted)
2252 
2253  return *this;
2254  }
2255 
2256 
2257 
2258  template <typename Number>
2259  inline
2260  Vector<Number> &
2261  Vector<Number>::operator /= (const Number factor)
2262  {
2263  operator *= (1./factor);
2264  return *this;
2265  }
2266 
2267 
2268 
2269  template <typename Number>
2270  inline
2271  void
2272  Vector<Number>::scale (const Vector<Number> &scaling_factors)
2273  {
2274  // ::Vector does not allow empty fields but this might happen on
2275  // some processors for parallel implementation
2276  if (local_size())
2277  vector_view.scale (scaling_factors.vector_view);
2278 
2279  if (vector_is_ghosted)
2281  }
2282 
2283 
2284 
2285  template <typename Number>
2286  template <typename Number2>
2287  inline
2288  void
2289  Vector<Number>::scale (const Vector<Number2> &scaling_factors)
2290  {
2291  if (local_size())
2292  vector_view.template scale<Number2> (scaling_factors.vector_view);
2293 
2294  if (vector_is_ghosted)
2296  }
2297 
2298 
2299 
2300  template <typename Number>
2301  inline
2302  void
2303  Vector<Number>::equ (const Number a,
2304  const Vector<Number> &v)
2305  {
2306  // ::Vector does not allow empty fields but this might happen on
2307  // some processors for parallel implementation
2308  if (local_size())
2309  vector_view.equ (a, v.vector_view);
2310 
2311  if (vector_is_ghosted)
2313  }
2314 
2315 
2316 
2317  template <typename Number>
2318  template <typename Number2>
2319  inline
2320  void
2321  Vector<Number>::equ (const Number a,
2322  const Vector<Number2> &v)
2323  {
2324  // ::Vector does not allow empty fields but this might happen on
2325  // some processors for parallel implementation
2326  if (local_size())
2327  vector_view.equ (a, v.vector_view);
2328 
2329  if (vector_is_ghosted)
2331  }
2332 
2333 
2334 
2335  template <typename Number>
2336  inline
2337  void
2338  Vector<Number>::equ (const Number a,
2339  const Vector<Number> &v,
2340  const Number b,
2341  const Vector<Number> &w)
2342  {
2343  // ::Vector does not allow empty fields but this might happen on
2344  // some processors for parallel implementation
2345  if (local_size())
2346  vector_view.equ (a, v.vector_view, b, w.vector_view);
2347 
2348  if (vector_is_ghosted)
2350  }
2351 
2352 
2353 
2354  template <typename Number>
2355  inline
2356  void
2357  Vector<Number>::equ (const Number a,
2358  const Vector<Number> &v,
2359  const Number b,
2360  const Vector<Number> &w,
2361  const Number c,
2362  const Vector<Number> &x)
2363  {
2364  // ::Vector does not allow empty fields but this might happen on
2365  // some processors for parallel implementation
2366  if (local_size())
2367  vector_view.equ (a, v.vector_view, b, w.vector_view,
2368  c, x.vector_view);
2369 
2370  if (vector_is_ghosted)
2372  }
2373 
2374 
2375 
2376  template <typename Number>
2377  inline
2378  void
2380  const Vector<Number> &b)
2381  {
2382  // ::Vector does not allow empty fields but this might happen on
2383  // some processors for parallel implementation
2384  if (local_size())
2385  vector_view.ratio (a.vector_view, b.vector_view);
2386 
2387  if (vector_is_ghosted)
2389  }
2390 
2391 
2392 
2393  template <typename Number>
2394  inline
2395  const MPI_Comm &
2397  {
2398  return partitioner->get_communicator();
2399  }
2400 
2401 
2402 
2403  template <typename Number>
2404  inline
2405  std_cxx11::shared_ptr<const Utilities::MPI::Partitioner>
2407  {
2408  return partitioner;
2409  }
2410 
2411 #endif // ifndef DOXYGEN
2412 
2413  } // end of namespace distributed
2414 
2415 } // end of namespace parallel
2416 
2417 
2418 
2427 template <typename Number>
2428 inline
2431 {
2432  u.swap (v);
2433 }
2434 
2435 
2436 DEAL_II_NAMESPACE_CLOSE
2437 
2438 #endif
std_cxx11::shared_ptr< const Utilities::MPI::Partitioner > partitioner
void update_ghost_values() const
std::vector< MPI_Request > compress_requests
real_type l1_norm() const
Number add_and_dot(const Number a, const Vector< Number > &V, const Vector< Number > &W)
Number operator[](const size_type i) const
bool operator!=(const Vector< Number2 > &v) const
#define AssertDimension(dim1, dim2)
Definition: exceptions.h:1052
void sadd(const Number s, const Vector< Number > &V)
void extract_subvector_to(const std::vector< size_type > &indices, std::vector< OtherNumber > &values) const
Number operator()(const size_type i) const
std::pair< size_type, size_type > local_range() const
real_type linfty_norm() const
::ExceptionBase & ExcMessage(std::string arg1)
bool is_non_negative() const
void equ(const Number a, const Vector< Number > &u)
#define AssertIndexRange(index, range)
Definition: exceptions.h:1081
void ratio(const Vector< Number > &a, const Vector< Number > &b) DEAL_II_DEPRECATED
STL namespace.
bool is_ghost_entry(const types::global_dof_index global_index) const DEAL_II_DEPRECATED
iterator end()
Vector< Number > & operator=(const Number s)
bool is_finite(const double x)
Definition: numbers.h:255
BlockDynamicSparsityPattern BlockCompressedSparsityPattern DEAL_II_DEPRECATED
void add(const std::vector< size_type > &indices, const std::vector< OtherNumber > &values)
numbers::NumberTraits< Number >::real_type real_type
Definition: vector.h:134
VectorView< Number > vector_view
bool in_local_range(const size_type global_index) const
void scale(const Vector< Number > &scaling_factors)
Definition: types.h:30
Vector< Number > & operator+=(const Vector< Number > &V)
T sum(const T &t, const MPI_Comm &mpi_communicator)
Definition: mpi.h:611
unsigned int global_dof_index
Definition: types.h:88
#define Assert(cond, exc)
Definition: exceptions.h:294
real_type lp_norm(const real_type p) const
std::size_t size() const
virtual ~Vector()
void swap(Vector< Number > &v)
Vector< Number > & operator-=(const Vector< Number > &V)
Vector< Number > & operator*=(const Number factor)
void swap(parallel::distributed::Vector< Number > &u, parallel::distributed::Vector< Number > &v)
iterator begin()
Number operator*(const Vector< Number2 > &V) const
std::vector< MPI_Request > update_ghost_values_requests
Vector< Number > & operator/=(const Number factor)
Definition: mpi.h:55
IndexSet locally_owned_elements() const
T min(const T &t, const MPI_Comm &mpi_communicator)
Definition: mpi.h:722
bool operator==(const Vector< Number2 > &v) const
bool all_zero() const
#define DeclException4(Exception4, type1, type2, type3, type4, outsequence)
Definition: exceptions.h:572
void compress(::VectorOperation::values operation=::VectorOperation::unknown) const
virtual void reinit(const size_type N, const bool omit_zeroing_entries=false)
real_type norm_sqr() const
Number * val
Definition: vector.h:984
#define DeclException3(Exception3, type1, type2, type3, outsequence)
Definition: exceptions.h:562
real_type l2_norm() const
size_type local_size() const
Number mean_value() const
T max(const T &t, const MPI_Comm &mpi_communicator)
Definition: mpi.h:693