Reference documentation for deal.II version Git e7bb9ce7b3 2020-09-18 12:07:32 -0400
\(\newcommand{\dealvcentcolon}{\mathrel{\mathop{:}}}\) \(\newcommand{\dealcoloneq}{\dealvcentcolon\mathrel{\mkern-1.2mu}=}\) \(\newcommand{\jump}[1]{\left[\!\left[ #1 \right]\!\right]}\) \(\newcommand{\average}[1]{\left\{\!\left\{ #1 \right\}\!\right\}}\)
la_parallel_vector.h
Go to the documentation of this file.
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 2011 - 2020 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.md at
12 // the top level directory of deal.II.
13 //
14 // ---------------------------------------------------------------------
15 
16 #ifndef dealii_la_parallel_vector_h
17 #define dealii_la_parallel_vector_h
18 
19 #include <deal.II/base/config.h>
20 
22 #include <deal.II/base/mpi.h>
23 #include <deal.II/base/numbers.h>
26 
30 
31 #include <iomanip>
32 #include <memory>
33 
35 
36 // Forward declarations
37 #ifndef DOXYGEN
38 namespace LinearAlgebra
39 {
43  namespace distributed
44  {
45  template <typename>
46  class BlockVector;
47  }
48 
49  template <typename>
50  class ReadWriteVector;
51 } // namespace LinearAlgebra
52 
53 # ifdef DEAL_II_WITH_PETSC
54 namespace PETScWrappers
55 {
56  namespace MPI
57  {
58  class Vector;
59  }
60 } // namespace PETScWrappers
61 # endif
62 
63 # ifdef DEAL_II_WITH_TRILINOS
64 namespace TrilinosWrappers
65 {
66  namespace MPI
67  {
68  class Vector;
69  }
70 } // namespace TrilinosWrappers
71 # endif
72 #endif
73 
74 namespace LinearAlgebra
75 {
76  namespace distributed
77  {
222  template <typename Number, typename MemorySpace = MemorySpace::Host>
224  public Subscriptor
225  {
226  public:
228  using value_type = Number;
229  using pointer = value_type *;
230  using const_pointer = const value_type *;
231  using iterator = value_type *;
232  using const_iterator = const value_type *;
234  using const_reference = const value_type &;
237 
238  static_assert(
239  std::is_same<MemorySpace, ::MemorySpace::Host>::value ||
240  std::is_same<MemorySpace, ::MemorySpace::CUDA>::value,
241  "MemorySpace should be Host or CUDA");
242 
250  Vector();
251 
258  Vector(const Vector<Number, MemorySpace> &in_vector);
259 
264  Vector(const size_type size);
265 
282  Vector(const IndexSet &local_range,
283  const IndexSet &ghost_indices,
284  const MPI_Comm communicator);
285 
289  Vector(const IndexSet &local_range, const MPI_Comm communicator);
290 
297  Vector(
298  const std::shared_ptr<const Utilities::MPI::Partitioner> &partitioner);
299 
303  virtual ~Vector() override;
304 
309  void
310  reinit(const size_type size, const bool omit_zeroing_entries = false);
311 
322  template <typename Number2>
323  void
324  reinit(const Vector<Number2, MemorySpace> &in_vector,
325  const bool omit_zeroing_entries = false);
326 
343  void
344  reinit(const IndexSet &local_range,
345  const IndexSet &ghost_indices,
346  const MPI_Comm communicator);
347 
351  void
352  reinit(const IndexSet &local_range, const MPI_Comm communicator);
353 
360  void
361  reinit(
362  const std::shared_ptr<const Utilities::MPI::Partitioner> &partitioner);
363 
376  void
378 
391  operator=(const Vector<Number, MemorySpace> &in_vector);
392 
404  template <typename Number2>
406  operator=(const Vector<Number2, MemorySpace> &in_vector);
407 
409 
449  virtual void
450  compress(::VectorOperation::values operation) override;
451 
473  void
474  update_ghost_values() const;
475 
493  void
494  compress_start(
495  const unsigned int communication_channel = 0,
497 
516  void
517  compress_finish(::VectorOperation::values operation);
518 
536  void
537  update_ghost_values_start(
538  const unsigned int communication_channel = 0) const;
539 
540 
548  void
549  update_ghost_values_finish() const;
550 
559  void
560  zero_out_ghosts() const;
561 
573  bool
574  has_ghost_elements() const;
575 
590  template <typename Number2>
591  void
592  copy_locally_owned_data_from(const Vector<Number2, MemorySpace> &src);
593 
604  template <typename MemorySpace2>
605  void
606  import(const Vector<Number, MemorySpace2> &src,
607  VectorOperation::values operation);
608 
610 
615 
620  virtual void
622  const bool omit_zeroing_entries = false) override;
623 
628  operator*=(const Number factor) override;
629 
634  operator/=(const Number factor) override;
635 
640  operator+=(const VectorSpaceVector<Number> &V) override;
641 
646  operator-=(const VectorSpaceVector<Number> &V) override;
647 
659  virtual void
660  import(
662  VectorOperation::values operation,
663  std::shared_ptr<const CommunicationPatternBase> communication_pattern =
664  std::shared_ptr<const CommunicationPatternBase>()) override;
665 
669  virtual Number
670  operator*(const VectorSpaceVector<Number> &V) const override;
671 
675  virtual void
676  add(const Number a) override;
677 
681  virtual void
682  add(const Number a, const VectorSpaceVector<Number> &V) override;
683 
687  virtual void
688  add(const Number a,
690  const Number b,
691  const VectorSpaceVector<Number> &W) override;
692 
697  virtual void
698  add(const std::vector<size_type> &indices,
699  const std::vector<Number> & values);
700 
705  virtual void
706  sadd(const Number s,
707  const Number a,
708  const VectorSpaceVector<Number> &V) override;
709 
715  virtual void
716  scale(const VectorSpaceVector<Number> &scaling_factors) override;
717 
721  virtual void
722  equ(const Number a, const VectorSpaceVector<Number> &V) override;
723 
728  virtual real_type
729  l1_norm() const override;
730 
735  virtual real_type
736  l2_norm() const override;
737 
741  real_type
742  norm_sqr() const;
743 
748  virtual real_type
749  linfty_norm() const override;
750 
771  virtual Number
772  add_and_dot(const Number a,
774  const VectorSpaceVector<Number> &W) override;
775 
780  virtual size_type
781  size() const override;
782 
794  virtual ::IndexSet
795  locally_owned_elements() const override;
796 
800  virtual void
801  print(std::ostream & out,
802  const unsigned int precision = 3,
803  const bool scientific = true,
804  const bool across = true) const override;
805 
809  virtual std::size_t
810  memory_consumption() const override;
812 
817 
824  operator=(const Number s) override;
825 
830  template <typename OtherNumber>
831  void
832  add(const std::vector<size_type> & indices,
833  const ::Vector<OtherNumber> &values);
834 
839  template <typename OtherNumber>
840  void
841  add(const size_type n_elements,
842  const size_type * indices,
843  const OtherNumber *values);
844 
849  void
850  sadd(const Number s, const Vector<Number, MemorySpace> &V);
851 
853 
854 
859 
864  size_type
865  local_size() const;
866 
871  bool
872  in_local_range(const size_type global_index) const;
873 
884  iterator
885  begin();
886 
895  begin() const;
896 
904  iterator
905  end();
906 
915  end() const;
916 
926  Number
927  operator()(const size_type global_index) const;
928 
938  Number &
939  operator()(const size_type global_index);
940 
948  Number operator[](const size_type global_index) const;
956  Number &operator[](const size_type global_index);
957 
966  Number
967  local_element(const size_type local_index) const;
968 
977  Number &
978  local_element(const size_type local_index);
979 
986  Number *
987  get_values() const;
988 
1006  template <typename OtherNumber>
1007  void
1008  extract_subvector_to(const std::vector<size_type> &indices,
1009  std::vector<OtherNumber> & values) const;
1010 
1038  template <typename ForwardIterator, typename OutputIterator>
1039  void
1040  extract_subvector_to(ForwardIterator indices_begin,
1041  const ForwardIterator indices_end,
1042  OutputIterator values_begin) const;
1048  virtual bool
1049  all_zero() const override;
1050 
1054  virtual Number
1055  mean_value() const override;
1056 
1061  real_type
1062  lp_norm(const real_type p) const;
1064 
1069 
1074  const MPI_Comm &
1075  get_mpi_communicator() const;
1076 
1083  const std::shared_ptr<const Utilities::MPI::Partitioner> &
1084  get_partitioner() const;
1085 
1095  bool
1096  partitioners_are_compatible(
1097  const Utilities::MPI::Partitioner &part) const;
1098 
1112  bool
1113  partitioners_are_globally_compatible(
1114  const Utilities::MPI::Partitioner &part) const;
1115 
1119  void
1120  set_ghost_state(const bool ghosted) const;
1121 
1123 
1129  DeclException0(ExcVectorTypeNotCompatible);
1130 
1136  DeclException0(ExcNotAllowedForCuda);
1137 
1141  DeclException3(ExcNonMatchingElements,
1142  Number,
1143  Number,
1144  unsigned int,
1145  << "Called compress(VectorOperation::insert), but"
1146  << " the element received from a remote processor, value "
1147  << std::setprecision(16) << arg1
1148  << ", does not match with the value "
1149  << std::setprecision(16) << arg2
1150  << " on the owner processor " << arg3);
1151 
1155  DeclException4(ExcAccessToNonLocalElement,
1156  size_type,
1157  size_type,
1158  size_type,
1159  size_type,
1160  << "You tried to access element " << arg1
1161  << " of a distributed vector, but this element is not "
1162  << "stored on the current processor. Note: The range of "
1163  << "locally owned elements is " << arg2 << " to " << arg3
1164  << ", and there are " << arg4 << " ghost elements "
1165  << "that this vector can access.");
1166 
1167  private:
1172  void
1173  add_local(const Number a, const VectorSpaceVector<Number> &V);
1174 
1179  void
1180  sadd_local(const Number s,
1181  const Number a,
1182  const VectorSpaceVector<Number> &V);
1183 
1187  template <typename Number2>
1188  Number
1189  inner_product_local(const Vector<Number2, MemorySpace> &V) const;
1190 
1194  real_type
1195  norm_sqr_local() const;
1196 
1200  Number
1201  mean_value_local() const;
1202 
1206  real_type
1207  l1_norm_local() const;
1208 
1212  real_type
1213  lp_norm_local(const real_type p) const;
1214 
1218  real_type
1219  linfty_norm_local() const;
1220 
1226  Number
1227  add_and_dot_local(const Number a,
1229  const Vector<Number, MemorySpace> &W);
1230 
1236  std::shared_ptr<const Utilities::MPI::Partitioner> partitioner;
1237 
1242 
1246  mutable ::MemorySpace::MemorySpaceData<Number, MemorySpace> data;
1247 
1252  mutable std::shared_ptr<::parallel::internal::TBBPartitioner>
1254 
1259  mutable ::MemorySpace::MemorySpaceData<Number, MemorySpace>
1261 
1269  mutable bool vector_is_ghosted;
1270 
1271 #ifdef DEAL_II_WITH_MPI
1272 
1280  std::vector<MPI_Request> compress_requests;
1281 
1286  mutable std::vector<MPI_Request> update_ghost_values_requests;
1287 #endif
1288 
1294  mutable std::mutex mutex;
1295 
1300  void
1301  clear_mpi_requests();
1302 
1306  void
1307  resize_val(const size_type new_allocated_size);
1308 
1309  // Make all other vector types friends.
1310  template <typename Number2, typename MemorySpace2>
1311  friend class Vector;
1312 
1313  // Make BlockVector type friends.
1314  template <typename Number2>
1315  friend class BlockVector;
1316  };
1320  /*-------------------- Inline functions ---------------------------------*/
1321 
1322 #ifndef DOXYGEN
1323 
1324  namespace internal
1325  {
1326  template <typename Number, typename MemorySpace>
1327  struct Policy
1328  {
1329  static inline typename Vector<Number, MemorySpace>::iterator
1331  {
1332  return nullptr;
1333  }
1334 
1335  static inline typename Vector<Number, MemorySpace>::const_iterator
1336  begin(
1337  const ::MemorySpace::MemorySpaceData<Number, MemorySpace> &)
1338  {
1339  return nullptr;
1340  }
1341 
1342  static inline Number *
1343  get_values(
1345  {
1346  return nullptr;
1347  }
1348  };
1349 
1350 
1351 
1352  template <typename Number>
1353  struct Policy<Number, ::MemorySpace::Host>
1354  {
1355  static inline
1357  begin(::MemorySpace::
1358  MemorySpaceData<Number, ::MemorySpace::Host> &data)
1359  {
1360  return data.values.get();
1361  }
1362 
1363  static inline
1365  begin(const ::MemorySpace::
1366  MemorySpaceData<Number, ::MemorySpace::Host> &data)
1367  {
1368  return data.values.get();
1369  }
1370 
1371  static inline Number *
1372  get_values(::MemorySpace::
1373  MemorySpaceData<Number, ::MemorySpace::Host> &data)
1374  {
1375  return data.values.get();
1376  }
1377  };
1378 
1379 
1380 
1381  template <typename Number>
1382  struct Policy<Number, ::MemorySpace::CUDA>
1383  {
1384  static inline
1386  begin(::MemorySpace::
1387  MemorySpaceData<Number, ::MemorySpace::CUDA> &data)
1388  {
1389  return data.values_dev.get();
1390  }
1391 
1392  static inline
1394  begin(const ::MemorySpace::
1395  MemorySpaceData<Number, ::MemorySpace::CUDA> &data)
1396  {
1397  return data.values_dev.get();
1398  }
1399 
1400  static inline Number *
1401  get_values(::MemorySpace::
1402  MemorySpaceData<Number, ::MemorySpace::CUDA> &data)
1403  {
1404  return data.values_dev.get();
1405  }
1406  };
1407  } // namespace internal
1408 
1409 
1410  template <typename Number, typename MemorySpace>
1411  inline bool
1413  {
1414  return vector_is_ghosted;
1415  }
1416 
1417 
1418 
1419  template <typename Number, typename MemorySpace>
1422  {
1423  return partitioner->size();
1424  }
1425 
1426 
1427 
1428  template <typename Number, typename MemorySpace>
1431  {
1432  return partitioner->local_size();
1433  }
1434 
1435 
1436 
1437  template <typename Number, typename MemorySpace>
1438  inline bool
1440  const size_type global_index) const
1441  {
1442  return partitioner->in_local_range(global_index);
1443  }
1444 
1445 
1446 
1447  template <typename Number, typename MemorySpace>
1448  inline IndexSet
1450  {
1451  IndexSet is(size());
1452 
1453  is.add_range(partitioner->local_range().first,
1454  partitioner->local_range().second);
1455 
1456  return is;
1457  }
1458 
1459 
1460 
1461  template <typename Number, typename MemorySpace>
1464  {
1466  }
1467 
1468 
1469 
1470  template <typename Number, typename MemorySpace>
1473  {
1475  }
1476 
1477 
1478 
1479  template <typename Number, typename MemorySpace>
1482  {
1484  partitioner->local_size();
1485  }
1486 
1487 
1488 
1489  template <typename Number, typename MemorySpace>
1492  {
1494  partitioner->local_size();
1495  }
1496 
1497 
1498 
1499  template <typename Number, typename MemorySpace>
1500  inline Number
1501  Vector<Number, MemorySpace>::operator()(const size_type global_index) const
1502  {
1503  Assert((std::is_same<MemorySpace, ::MemorySpace::Host>::value),
1504  ExcMessage(
1505  "This function is only implemented for the Host memory space"));
1506  Assert(
1507  partitioner->in_local_range(global_index) ||
1508  partitioner->ghost_indices().is_element(global_index),
1509  ExcAccessToNonLocalElement(global_index,
1510  partitioner->local_range().first,
1511  partitioner->local_range().second,
1512  partitioner->ghost_indices().n_elements()));
1513  // do not allow reading a vector which is not in ghost mode
1514  Assert(partitioner->in_local_range(global_index) ||
1515  vector_is_ghosted == true,
1516  ExcMessage("You tried to read a ghost element of this vector, "
1517  "but it has not imported its ghost values."));
1518  return data.values[partitioner->global_to_local(global_index)];
1519  }
1520 
1521 
1522 
1523  template <typename Number, typename MemorySpace>
1524  inline Number &
1526  {
1527  Assert((std::is_same<MemorySpace, ::MemorySpace::Host>::value),
1528  ExcMessage(
1529  "This function is only implemented for the Host memory space"));
1530  Assert(
1531  partitioner->in_local_range(global_index) ||
1532  partitioner->ghost_indices().is_element(global_index),
1533  ExcAccessToNonLocalElement(global_index,
1534  partitioner->local_range().first,
1535  partitioner->local_range().second,
1536  partitioner->ghost_indices().n_elements()));
1537  // we would like to prevent reading ghosts from a vector that does not
1538  // have them imported, but this is not possible because we might be in a
1539  // part of the code where the vector has enabled ghosts but is non-const
1540  // (then, the compiler picks this method according to the C++ rule book
1541  // even if a human would pick the const method when this subsequent use
1542  // is just a read)
1543  return data.values[partitioner->global_to_local(global_index)];
1544  }
1545 
1546 
1547 
1548  template <typename Number, typename MemorySpace>
1549  inline Number Vector<Number, MemorySpace>::
1550  operator[](const size_type global_index) const
1551  {
1552  return operator()(global_index);
1553  }
1554 
1555 
1556 
1557  template <typename Number, typename MemorySpace>
1558  inline Number &Vector<Number, MemorySpace>::
1559  operator[](const size_type global_index)
1560  {
1561  return operator()(global_index);
1562  }
1563 
1564 
1565 
1566  template <typename Number, typename MemorySpace>
1567  inline Number
1569  const size_type local_index) const
1570  {
1571  Assert((std::is_same<MemorySpace, ::MemorySpace::Host>::value),
1572  ExcMessage(
1573  "This function is only implemented for the Host memory space"));
1574  AssertIndexRange(local_index,
1575  partitioner->local_size() +
1576  partitioner->n_ghost_indices());
1577  // do not allow reading a vector which is not in ghost mode
1578  Assert(local_index < local_size() || vector_is_ghosted == true,
1579  ExcMessage("You tried to read a ghost element of this vector, "
1580  "but it has not imported its ghost values."));
1581 
1582  return data.values[local_index];
1583  }
1584 
1585 
1586 
1587  template <typename Number, typename MemorySpace>
1588  inline Number &
1590  {
1591  Assert((std::is_same<MemorySpace, ::MemorySpace::Host>::value),
1592  ExcMessage(
1593  "This function is only implemented for the Host memory space"));
1594 
1595  AssertIndexRange(local_index,
1596  partitioner->local_size() +
1597  partitioner->n_ghost_indices());
1598 
1599  return data.values[local_index];
1600  }
1601 
1602 
1603 
1604  template <typename Number, typename MemorySpace>
1605  inline Number *
1607  {
1608  return internal::Policy<Number, MemorySpace>::get_values(data);
1609  }
1610 
1611 
1612 
1613  template <typename Number, typename MemorySpace>
1614  template <typename OtherNumber>
1615  inline void
1617  const std::vector<size_type> &indices,
1618  std::vector<OtherNumber> & values) const
1619  {
1620  for (size_type i = 0; i < indices.size(); ++i)
1621  values[i] = operator()(indices[i]);
1622  }
1623 
1624 
1625 
1626  template <typename Number, typename MemorySpace>
1627  template <typename ForwardIterator, typename OutputIterator>
1628  inline void
1630  ForwardIterator indices_begin,
1631  const ForwardIterator indices_end,
1632  OutputIterator values_begin) const
1633  {
1634  while (indices_begin != indices_end)
1635  {
1636  *values_begin = operator()(*indices_begin);
1637  indices_begin++;
1638  values_begin++;
1639  }
1640  }
1641 
1642 
1643 
1644  template <typename Number, typename MemorySpace>
1645  template <typename OtherNumber>
1646  inline void
1648  const std::vector<size_type> & indices,
1649  const ::Vector<OtherNumber> &values)
1650  {
1651  AssertDimension(indices.size(), values.size());
1652  for (size_type i = 0; i < indices.size(); ++i)
1653  {
1654  Assert(
1655  numbers::is_finite(values[i]),
1656  ExcMessage(
1657  "The given value is not finite but either infinite or Not A Number (NaN)"));
1658  this->operator()(indices[i]) += values(i);
1659  }
1660  }
1661 
1662 
1663 
1664  template <typename Number, typename MemorySpace>
1665  template <typename OtherNumber>
1666  inline void
1668  const size_type * indices,
1669  const OtherNumber *values)
1670  {
1671  for (size_type i = 0; i < n_elements; ++i, ++indices, ++values)
1672  {
1673  Assert(
1674  numbers::is_finite(*values),
1675  ExcMessage(
1676  "The given value is not finite but either infinite or Not A Number (NaN)"));
1677  this->operator()(*indices) += *values;
1678  }
1679  }
1680 
1681 
1682 
1683  template <typename Number, typename MemorySpace>
1684  inline const MPI_Comm &
1686  {
1687  return partitioner->get_mpi_communicator();
1688  }
1689 
1690 
1691 
1692  template <typename Number, typename MemorySpace>
1693  inline const std::shared_ptr<const Utilities::MPI::Partitioner> &
1695  {
1696  return partitioner;
1697  }
1698 
1699 
1700 
1701  template <typename Number, typename MemorySpace>
1702  inline void
1703  Vector<Number, MemorySpace>::set_ghost_state(const bool ghosted) const
1704  {
1705  vector_is_ghosted = ghosted;
1706  }
1707 
1708 #endif
1709 
1710  } // namespace distributed
1711 } // namespace LinearAlgebra
1712 
1713 
1721 template <typename Number, typename MemorySpace>
1722 inline void
1725 {
1726  u.swap(v);
1727 }
1728 
1729 
1733 template <typename Number, typename MemorySpace>
1735  : std::false_type
1736 {};
1737 
1738 
1739 
1740 namespace internal
1741 {
1742  namespace LinearOperatorImplementation
1743  {
1744  template <typename>
1745  class ReinitHelper;
1746 
1751  template <typename Number>
1752  class ReinitHelper<LinearAlgebra::distributed::Vector<Number>>
1753  {
1754  public:
1755  // A helper type-trait that leverage SFINAE to figure out if type T has
1756  // void T::get_mpi_communicator()
1757  template <typename T>
1758  struct has_get_mpi_communicator
1759  {
1760  private:
1761  static bool
1762  detect(...);
1763 
1764  template <typename U>
1765  static decltype(std::declval<U>().get_mpi_communicator())
1766  detect(const U &);
1767 
1768  public:
1769  static const bool value =
1770  !std::is_same<bool, decltype(detect(std::declval<T>()))>::value;
1771  };
1772 
1773  // A helper type-trait that leverage SFINAE to figure out if type T has
1774  // void T::locally_owned_domain_indices()
1775  template <typename T>
1776  struct has_locally_owned_domain_indices
1777  {
1778  private:
1779  static bool
1780  detect(...);
1781 
1782  template <typename U>
1783  static decltype(std::declval<U>().locally_owned_domain_indices())
1784  detect(const U &);
1785 
1786  public:
1787  static const bool value =
1788  !std::is_same<bool, decltype(detect(std::declval<T>()))>::value;
1789  };
1790 
1791  // A helper type-trait that leverage SFINAE to figure out if type T has
1792  // void T::locally_owned_range_indices()
1793  template <typename T>
1794  struct has_locally_owned_range_indices
1795  {
1796  private:
1797  static bool
1798  detect(...);
1799 
1800  template <typename U>
1801  static decltype(std::declval<U>().locally_owned_range_indices())
1802  detect(const U &);
1803 
1804  public:
1805  static const bool value =
1806  !std::is_same<bool, decltype(detect(std::declval<T>()))>::value;
1807  };
1808 
1809  // A helper type-trait that leverage SFINAE to figure out if type T has
1810  // void T::initialize_dof_vector(VectorType v)
1811  template <typename T>
1812  struct has_initialize_dof_vector
1813  {
1814  private:
1815  static bool
1816  detect(...);
1817 
1818  template <typename U>
1819  static decltype(std::declval<U>().initialize_dof_vector(
1820  std::declval<LinearAlgebra::distributed::Vector<Number> &>()))
1821  detect(const U &);
1822 
1823  public:
1824  static const bool value =
1825  !std::is_same<bool, decltype(detect(std::declval<T>()))>::value;
1826  };
1827 
1828  // Used for (Trilinos/PETSc)Wrappers::SparseMatrix
1829  template <typename MatrixType,
1830  typename std::enable_if<
1831  has_get_mpi_communicator<MatrixType>::value &&
1832  has_locally_owned_domain_indices<MatrixType>::value,
1833  MatrixType>::type * = nullptr>
1834  static void
1835  reinit_domain_vector(MatrixType & mat,
1837  bool /*omit_zeroing_entries*/)
1838  {
1839  vec.reinit(mat.locally_owned_domain_indices(),
1840  mat.get_mpi_communicator());
1841  }
1842 
1843  // Used for MatrixFree and DiagonalMatrix
1844  template <
1845  typename MatrixType,
1846  typename std::enable_if<has_initialize_dof_vector<MatrixType>::value,
1847  MatrixType>::type * = nullptr>
1848  static void
1849  reinit_domain_vector(MatrixType & mat,
1851  bool omit_zeroing_entries)
1852  {
1853  mat.initialize_dof_vector(vec);
1854  if (!omit_zeroing_entries)
1855  vec = Number();
1856  }
1857 
1858  // Used for (Trilinos/PETSc)Wrappers::SparseMatrix
1859  template <typename MatrixType,
1860  typename std::enable_if<
1861  has_get_mpi_communicator<MatrixType>::value &&
1862  has_locally_owned_range_indices<MatrixType>::value,
1863  MatrixType>::type * = nullptr>
1864  static void
1865  reinit_range_vector(MatrixType & mat,
1867  bool /*omit_zeroing_entries*/)
1868  {
1869  vec.reinit(mat.locally_owned_range_indices(),
1870  mat.get_mpi_communicator());
1871  }
1872 
1873  // Used for MatrixFree and DiagonalMatrix
1874  template <
1875  typename MatrixType,
1876  typename std::enable_if<has_initialize_dof_vector<MatrixType>::value,
1877  MatrixType>::type * = nullptr>
1878  static void
1879  reinit_range_vector(MatrixType & mat,
1881  bool omit_zeroing_entries)
1882  {
1883  mat.initialize_dof_vector(vec);
1884  if (!omit_zeroing_entries)
1885  vec = Number();
1886  }
1887  };
1888 
1889  } // namespace LinearOperatorImplementation
1890 } /* namespace internal */
1891 
1892 
1894 
1895 #endif
void reinit(MatrixBlock< MatrixType > &v, const BlockSparsityPattern &p)
Definition: matrix_block.h:618
bool in_local_range(const size_type global_index) const
#define AssertDimension(dim1, dim2)
Definition: exceptions.h:1568
std::vector< MPI_Request > update_ghost_values_requests
std::vector< value_type > l2_norm(const typename ::Triangulation< dim, spacedim >::cell_iterator &parent, const value_type parent_value)
void scale(const double scaling_factor, Triangulation< dim, spacedim > &triangulation)
Definition: grid_tools.cc:835
std::shared_ptr< const Utilities::MPI::Partitioner > partitioner
#define AssertIndexRange(index, range)
Definition: exceptions.h:1636
__global__ void add_and_dot(Number *res, Number *v1, const Number *v2, const Number *v3, const Number a, const size_type N)
static const char V
void reinit(const size_type size, const bool omit_zeroing_entries=false)
static const char U
static void reinit_range_vector(MatrixType &mat, LinearAlgebra::distributed::Vector< Number > &vec, bool omit_zeroing_entries)
bool is_finite(const double x)
Definition: numbers.h:527
Number local_element(const size_type local_index) const
void set_ghost_state(const bool ghosted) const
static ::ExceptionBase & ExcMessage(std::string arg1)
static void reinit_domain_vector(MatrixType &mat, LinearAlgebra::distributed::Vector< Number > &vec, bool)
std::string compress(const std::string &input)
Definition: utilities.cc:392
#define Assert(cond, exc)
Definition: exceptions.h:1411
static void reinit_range_vector(MatrixType &mat, LinearAlgebra::distributed::Vector< Number > &vec, bool)
Number linfty_norm(const Tensor< 2, dim, Number > &t)
Definition: tensor.h:2811
#define DeclException0(Exception0)
Definition: exceptions.h:470
void swap(LinearAlgebra::distributed::Vector< Number, MemorySpace > &u, LinearAlgebra::distributed::Vector< Number, MemorySpace > &v)
#define DEAL_II_NAMESPACE_CLOSE
Definition: config.h:363
std::shared_ptr<::parallel::internal::TBBPartitioner > thread_loop_partitioner
VectorType::value_type * end(VectorType &V)
mutable ::MemorySpace::MemorySpaceData< Number, MemorySpace > import_data
__global__ void equ(Number *val, const Number a, const Number *V_val, const size_type N)
mutable ::MemorySpace::MemorySpaceData< Number, MemorySpace > data
__global__ void sadd(const Number s, Number *val, const Number a, const Number *V_val, const size_type N)
SymmetricTensor< 2, dim, Number > b(const Tensor< 2, dim, Number > &F)
typename numbers::NumberTraits< Number >::real_type real_type
unsigned int global_dof_index
Definition: types.h:76
virtual ::IndexSet locally_owned_elements() const override
virtual size_type size() const override
void swap(Vector< Number, MemorySpace > &v)
#define DEAL_II_NAMESPACE_OPEN
Definition: config.h:362
VectorType::value_type * begin(VectorType &V)
const std::shared_ptr< const Utilities::MPI::Partitioner > & get_partitioner() const
static void reinit_domain_vector(MatrixType &mat, LinearAlgebra::distributed::Vector< Number > &vec, bool omit_zeroing_entries)
#define DeclException4(Exception4, type1, type2, type3, type4, outsequence)
Definition: exceptions.h:584
Number l1_norm(const Tensor< 2, dim, Number > &t)
Definition: tensor.h:2785
Number operator()(const size_type global_index) const
virtual void add(const Number a) override
TrilinosWrappers::types::int_type global_index(const Epetra_BlockMap &map, const ::types::global_dof_index i)
#define DeclException3(Exception3, type1, type2, type3, outsequence)
Definition: exceptions.h:561
std::enable_if< std::is_floating_point< T >::value &&std::is_floating_point< U >::value, typename ProductType< std::complex< T >, std::complex< U > >::type >::type operator*(const std::complex< T > &left, const std::complex< U > &right)
const MPI_Comm & get_mpi_communicator() const
std::vector< MPI_Request > compress_requests
void extract_subvector_to(const std::vector< size_type > &indices, std::vector< OtherNumber > &values) const
Number operator[](const size_type global_index) const
std::enable_if< std::is_fundamental< T >::value, std::size_t >::type memory_consumption(const T &t)