Reference documentation for deal.II version Git 4e68a80cad 2021-10-22 15:50:12 -0600
\(\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 - 2021 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 
24 #include <deal.II/base/mpi.h>
25 #include <deal.II/base/numbers.h>
28 
32 
33 #include <iomanip>
34 #include <memory>
35 
37 
38 // Forward declarations
39 #ifndef DOXYGEN
40 namespace LinearAlgebra
41 {
45  namespace distributed
46  {
47  template <typename>
48  class BlockVector;
49  }
50 
51  template <typename>
52  class ReadWriteVector;
53 } // namespace LinearAlgebra
54 
55 # ifdef DEAL_II_WITH_PETSC
56 namespace PETScWrappers
57 {
58  namespace MPI
59  {
60  class Vector;
61  }
62 } // namespace PETScWrappers
63 # endif
64 
65 # ifdef DEAL_II_WITH_TRILINOS
66 namespace TrilinosWrappers
67 {
68  namespace MPI
69  {
70  class Vector;
71  }
72 } // namespace TrilinosWrappers
73 # endif
74 #endif
75 
76 namespace LinearAlgebra
77 {
78  namespace distributed
79  {
247  template <typename Number, typename MemorySpace = MemorySpace::Host>
249  public Subscriptor
250  {
251  public:
253  using value_type = Number;
254  using pointer = value_type *;
255  using const_pointer = const value_type *;
256  using iterator = value_type *;
257  using const_iterator = const value_type *;
259  using const_reference = const value_type &;
262 
263  static_assert(
264  std::is_same<MemorySpace, ::MemorySpace::Host>::value ||
265  std::is_same<MemorySpace, ::MemorySpace::CUDA>::value,
266  "MemorySpace should be Host or CUDA");
267 
275  Vector();
276 
283  Vector(const Vector<Number, MemorySpace> &in_vector);
284 
292  Vector(Vector<Number, MemorySpace> &&in_vector); // NOLINT
293 
298  Vector(const size_type size);
299 
316  Vector(const IndexSet &local_range,
317  const IndexSet &ghost_indices,
318  const MPI_Comm &communicator);
319 
323  Vector(const IndexSet &local_range, const MPI_Comm &communicator);
324 
331  Vector(
332  const std::shared_ptr<const Utilities::MPI::Partitioner> &partitioner);
333 
337  virtual ~Vector() override;
338 
343  void
344  reinit(const size_type size, const bool omit_zeroing_entries = false);
345 
356  template <typename Number2>
357  void
358  reinit(const Vector<Number2, MemorySpace> &in_vector,
359  const bool omit_zeroing_entries = false);
360 
377  void
378  reinit(const IndexSet &local_range,
379  const IndexSet &ghost_indices,
380  const MPI_Comm &communicator);
381 
385  void
386  reinit(const IndexSet &local_range, const MPI_Comm &communicator);
387 
400  void
401  reinit(
402  const std::shared_ptr<const Utilities::MPI::Partitioner> &partitioner,
403  const MPI_Comm &comm_sm = MPI_COMM_SELF);
404 
424  void
425  reinit(const types::global_dof_index local_size,
426  const types::global_dof_index ghost_size,
427  const MPI_Comm & comm,
428  const MPI_Comm & comm_sm = MPI_COMM_SELF);
429 
442  void
444 
457  operator=(const Vector<Number, MemorySpace> &in_vector);
458 
470  template <typename Number2>
472  operator=(const Vector<Number2, MemorySpace> &in_vector);
473 
475 
515  virtual void
516  compress(::VectorOperation::values operation) override;
517 
539  void
540  update_ghost_values() const;
541 
559  void
560  compress_start(
561  const unsigned int communication_channel = 0,
563 
582  void
583  compress_finish(::VectorOperation::values operation);
584 
602  void
603  update_ghost_values_start(
604  const unsigned int communication_channel = 0) const;
605 
606 
614  void
615  update_ghost_values_finish() const;
616 
627  DEAL_II_DEPRECATED void
628  zero_out_ghosts() const;
629 
638  void
639  zero_out_ghost_values() const;
640 
652  bool
653  has_ghost_elements() const;
654 
669  template <typename Number2>
670  void
671  copy_locally_owned_data_from(const Vector<Number2, MemorySpace> &src);
672 
683  template <typename MemorySpace2>
684  void
685  import(const Vector<Number, MemorySpace2> &src,
686  VectorOperation::values operation);
687 
689 
694 
699  virtual void
701  const bool omit_zeroing_entries = false) override;
702 
707  operator*=(const Number factor) override;
708 
713  operator/=(const Number factor) override;
714 
719  operator+=(const VectorSpaceVector<Number> &V) override;
720 
725  operator-=(const VectorSpaceVector<Number> &V) override;
726 
738  virtual void
740  VectorOperation::values operation,
741  std::shared_ptr<const Utilities::MPI::CommunicationPatternBase>
742  communication_pattern = {}) override;
743 
747  virtual Number
748  operator*(const VectorSpaceVector<Number> &V) const override;
749 
753  virtual void
754  add(const Number a) override;
755 
759  virtual void
760  add(const Number a, const VectorSpaceVector<Number> &V) override;
761 
765  virtual void
766  add(const Number a,
767  const VectorSpaceVector<Number> &V,
768  const Number b,
769  const VectorSpaceVector<Number> &W) override;
770 
775  virtual void
776  add(const std::vector<size_type> &indices,
777  const std::vector<Number> & values);
778 
783  virtual void
784  sadd(const Number s,
785  const Number a,
786  const VectorSpaceVector<Number> &V) override;
787 
793  virtual void
794  scale(const VectorSpaceVector<Number> &scaling_factors) override;
795 
799  virtual void
800  equ(const Number a, const VectorSpaceVector<Number> &V) override;
801 
806  virtual real_type
807  l1_norm() const override;
808 
813  virtual real_type
814  l2_norm() const override;
815 
819  real_type
820  norm_sqr() const;
821 
826  virtual real_type
827  linfty_norm() const override;
828 
849  virtual Number
850  add_and_dot(const Number a,
851  const VectorSpaceVector<Number> &V,
852  const VectorSpaceVector<Number> &W) override;
853 
858  virtual size_type
859  size() const override;
860 
872  virtual ::IndexSet
873  locally_owned_elements() const override;
874 
878  virtual void
879  print(std::ostream & out,
880  const unsigned int precision = 3,
881  const bool scientific = true,
882  const bool across = true) const override;
883 
887  virtual std::size_t
888  memory_consumption() const override;
890 
895 
902  operator=(const Number s) override;
903 
908  template <typename OtherNumber>
909  void
910  add(const std::vector<size_type> & indices,
911  const ::Vector<OtherNumber> &values);
912 
917  template <typename OtherNumber>
918  void
919  add(const size_type n_elements,
920  const size_type * indices,
921  const OtherNumber *values);
922 
927  void
928  sadd(const Number s, const Vector<Number, MemorySpace> &V);
929 
931 
932 
937 
945  size_type
946  local_size() const;
947 
952  size_type
953  locally_owned_size() const;
954 
959  bool
960  in_local_range(const size_type global_index) const;
961 
972  iterator
973  begin();
974 
983  begin() const;
984 
992  iterator
993  end();
994 
1003  end() const;
1004 
1014  Number
1015  operator()(const size_type global_index) const;
1016 
1026  Number &
1027  operator()(const size_type global_index);
1028 
1036  Number
1037  operator[](const size_type global_index) const;
1045  Number &
1046  operator[](const size_type global_index);
1047 
1056  Number
1057  local_element(const size_type local_index) const;
1058 
1067  Number &
1068  local_element(const size_type local_index);
1069 
1076  Number *
1077  get_values() const;
1078 
1096  template <typename OtherNumber>
1097  void
1098  extract_subvector_to(const std::vector<size_type> &indices,
1099  std::vector<OtherNumber> & values) const;
1100 
1128  template <typename ForwardIterator, typename OutputIterator>
1129  void
1130  extract_subvector_to(ForwardIterator indices_begin,
1131  const ForwardIterator indices_end,
1132  OutputIterator values_begin) const;
1138  virtual bool
1139  all_zero() const override;
1140 
1144  virtual Number
1145  mean_value() const override;
1146 
1151  real_type
1152  lp_norm(const real_type p) const;
1154 
1159 
1164  const MPI_Comm &
1165  get_mpi_communicator() const;
1166 
1173  const std::shared_ptr<const Utilities::MPI::Partitioner> &
1174  get_partitioner() const;
1175 
1185  bool
1186  partitioners_are_compatible(
1187  const Utilities::MPI::Partitioner &part) const;
1188 
1202  bool
1203  partitioners_are_globally_compatible(
1204  const Utilities::MPI::Partitioner &part) const;
1205 
1209  void
1210  set_ghost_state(const bool ghosted) const;
1211 
1216  const std::vector<ArrayView<const Number>> &
1217  shared_vector_data() const;
1218 
1220 
1226  DeclException0(ExcVectorTypeNotCompatible);
1227 
1233  DeclException0(ExcNotAllowedForCuda);
1234 
1238  DeclException3(ExcNonMatchingElements,
1239  Number,
1240  Number,
1241  unsigned int,
1242  << "Called compress(VectorOperation::insert), but"
1243  << " the element received from a remote processor, value "
1244  << std::setprecision(16) << arg1
1245  << ", does not match with the value "
1246  << std::setprecision(16) << arg2
1247  << " on the owner processor " << arg3);
1248 
1253  ExcAccessToNonLocalElement,
1254  size_type,
1255  size_type,
1256  size_type,
1257  size_type,
1258  << "You tried to access element " << arg1
1259  << " of a distributed vector, but this element is not "
1260  << "stored on the current processor. Note: The range of "
1261  << "locally owned elements is [" << arg2 << "," << arg3
1262  << "], and there are " << arg4 << " ghost elements "
1263  << "that this vector can access."
1264  << "\n\n"
1265  << "A common source for this kind of problem is that you "
1266  << "are passing a 'fully distributed' vector into a function "
1267  << "that needs read access to vector elements that correspond "
1268  << "to degrees of freedom on ghost cells (or at least to "
1269  << "'locally active' degrees of freedom that are not also "
1270  << "'locally owned'). You need to pass a vector that has these "
1271  << "elements as ghost entries.");
1272 
1273  private:
1278  void
1279  add_local(const Number a, const VectorSpaceVector<Number> &V);
1280 
1285  void
1286  sadd_local(const Number s,
1287  const Number a,
1288  const VectorSpaceVector<Number> &V);
1289 
1293  template <typename Number2>
1294  Number
1295  inner_product_local(const Vector<Number2, MemorySpace> &V) const;
1296 
1300  real_type
1301  norm_sqr_local() const;
1302 
1306  Number
1307  mean_value_local() const;
1308 
1312  real_type
1313  l1_norm_local() const;
1314 
1318  real_type
1319  lp_norm_local(const real_type p) const;
1320 
1324  real_type
1325  linfty_norm_local() const;
1326 
1332  Number
1333  add_and_dot_local(const Number a,
1334  const Vector<Number, MemorySpace> &V,
1335  const Vector<Number, MemorySpace> &W);
1336 
1342  std::shared_ptr<const Utilities::MPI::Partitioner> partitioner;
1343 
1348 
1352  mutable ::MemorySpace::MemorySpaceData<Number, MemorySpace> data;
1353 
1358  mutable std::shared_ptr<::parallel::internal::TBBPartitioner>
1360 
1365  mutable ::MemorySpace::MemorySpaceData<Number, MemorySpace>
1367 
1375  mutable bool vector_is_ghosted;
1376 
1377 #ifdef DEAL_II_WITH_MPI
1378 
1386  std::vector<MPI_Request> compress_requests;
1387 
1392  mutable std::vector<MPI_Request> update_ghost_values_requests;
1393 #endif
1394 
1400  mutable std::mutex mutex;
1401 
1408 
1413  void
1414  clear_mpi_requests();
1415 
1419  void
1420  resize_val(const size_type new_allocated_size,
1421  const MPI_Comm &comm_sm = MPI_COMM_SELF);
1422 
1423  // Make all other vector types friends.
1424  template <typename Number2, typename MemorySpace2>
1425  friend class Vector;
1426 
1427  // Make BlockVector type friends.
1428  template <typename Number2>
1429  friend class BlockVector;
1430  };
1434  /*-------------------- Inline functions ---------------------------------*/
1435 
1436 #ifndef DOXYGEN
1437 
1438  namespace internal
1439  {
1440  template <typename Number, typename MemorySpace>
1441  struct Policy
1442  {
1443  static inline typename Vector<Number, MemorySpace>::iterator
1445  {
1446  return nullptr;
1447  }
1448 
1449  static inline typename Vector<Number, MemorySpace>::const_iterator
1450  begin(
1451  const ::MemorySpace::MemorySpaceData<Number, MemorySpace> &)
1452  {
1453  return nullptr;
1454  }
1455 
1456  static inline Number *
1457  get_values(
1459  {
1460  return nullptr;
1461  }
1462  };
1463 
1464 
1465 
1466  template <typename Number>
1467  struct Policy<Number, ::MemorySpace::Host>
1468  {
1469  static inline
1471  begin(::MemorySpace::
1472  MemorySpaceData<Number, ::MemorySpace::Host> &data)
1473  {
1474  return data.values.get();
1475  }
1476 
1477  static inline
1479  begin(const ::MemorySpace::
1480  MemorySpaceData<Number, ::MemorySpace::Host> &data)
1481  {
1482  return data.values.get();
1483  }
1484 
1485  static inline Number *
1486  get_values(::MemorySpace::
1487  MemorySpaceData<Number, ::MemorySpace::Host> &data)
1488  {
1489  return data.values.get();
1490  }
1491  };
1492 
1493 
1494 
1495  template <typename Number>
1496  struct Policy<Number, ::MemorySpace::CUDA>
1497  {
1498  static inline
1500  begin(::MemorySpace::
1501  MemorySpaceData<Number, ::MemorySpace::CUDA> &data)
1502  {
1503  return data.values_dev.get();
1504  }
1505 
1506  static inline
1508  begin(const ::MemorySpace::
1509  MemorySpaceData<Number, ::MemorySpace::CUDA> &data)
1510  {
1511  return data.values_dev.get();
1512  }
1513 
1514  static inline Number *
1515  get_values(::MemorySpace::
1516  MemorySpaceData<Number, ::MemorySpace::CUDA> &data)
1517  {
1518  return data.values_dev.get();
1519  }
1520  };
1521  } // namespace internal
1522 
1523 
1524  template <typename Number, typename MemorySpace>
1525  inline bool
1527  {
1528  return vector_is_ghosted;
1529  }
1530 
1531 
1532 
1533  template <typename Number, typename MemorySpace>
1536  {
1537  return partitioner->size();
1538  }
1539 
1540 
1541 
1542  template <typename Number, typename MemorySpace>
1545  {
1546  return locally_owned_size();
1547  }
1548 
1549 
1550 
1551  template <typename Number, typename MemorySpace>
1554  {
1555  return partitioner->locally_owned_size();
1556  }
1557 
1558 
1559 
1560  template <typename Number, typename MemorySpace>
1561  inline bool
1563  const size_type global_index) const
1564  {
1565  return partitioner->in_local_range(global_index);
1566  }
1567 
1568 
1569 
1570  template <typename Number, typename MemorySpace>
1571  inline IndexSet
1573  {
1574  IndexSet is(size());
1575 
1576  is.add_range(partitioner->local_range().first,
1577  partitioner->local_range().second);
1578 
1579  return is;
1580  }
1581 
1582 
1583 
1584  template <typename Number, typename MemorySpace>
1587  {
1589  }
1590 
1591 
1592 
1593  template <typename Number, typename MemorySpace>
1596  {
1598  }
1599 
1600 
1601 
1602  template <typename Number, typename MemorySpace>
1605  {
1607  partitioner->locally_owned_size();
1608  }
1609 
1610 
1611 
1612  template <typename Number, typename MemorySpace>
1615  {
1617  partitioner->locally_owned_size();
1618  }
1619 
1620 
1621 
1622  template <typename Number, typename MemorySpace>
1623  const std::vector<ArrayView<const Number>> &
1625  {
1626  return data.values_sm;
1627  }
1628 
1629 
1630 
1631  template <typename Number, typename MemorySpace>
1632  inline Number
1633  Vector<Number, MemorySpace>::operator()(const size_type global_index) const
1634  {
1635  Assert((std::is_same<MemorySpace, ::MemorySpace::Host>::value),
1636  ExcMessage(
1637  "This function is only implemented for the Host memory space"));
1638  Assert(
1639  partitioner->in_local_range(global_index) ||
1640  partitioner->ghost_indices().is_element(global_index),
1641  ExcAccessToNonLocalElement(global_index,
1642  partitioner->local_range().first,
1643  partitioner->local_range().second - 1,
1644  partitioner->ghost_indices().n_elements()));
1645  // do not allow reading a vector which is not in ghost mode
1646  Assert(partitioner->in_local_range(global_index) ||
1647  vector_is_ghosted == true,
1648  ExcMessage("You tried to read a ghost element of this vector, "
1649  "but it has not imported its ghost values."));
1650  return data.values[partitioner->global_to_local(global_index)];
1651  }
1652 
1653 
1654 
1655  template <typename Number, typename MemorySpace>
1656  inline Number &
1658  {
1659  Assert((std::is_same<MemorySpace, ::MemorySpace::Host>::value),
1660  ExcMessage(
1661  "This function is only implemented for the Host memory space"));
1662  Assert(
1663  partitioner->in_local_range(global_index) ||
1664  partitioner->ghost_indices().is_element(global_index),
1665  ExcAccessToNonLocalElement(global_index,
1666  partitioner->local_range().first,
1667  partitioner->local_range().second - 1,
1668  partitioner->ghost_indices().n_elements()));
1669  // we would like to prevent reading ghosts from a vector that does not
1670  // have them imported, but this is not possible because we might be in a
1671  // part of the code where the vector has enabled ghosts but is non-const
1672  // (then, the compiler picks this method according to the C++ rule book
1673  // even if a human would pick the const method when this subsequent use
1674  // is just a read)
1675  return data.values[partitioner->global_to_local(global_index)];
1676  }
1677 
1678 
1679 
1680  template <typename Number, typename MemorySpace>
1681  inline Number
1682  Vector<Number, MemorySpace>::operator[](const size_type global_index) const
1683  {
1684  return operator()(global_index);
1685  }
1686 
1687 
1688 
1689  template <typename Number, typename MemorySpace>
1690  inline Number &
1692  {
1693  return operator()(global_index);
1694  }
1695 
1696 
1697 
1698  template <typename Number, typename MemorySpace>
1699  inline Number
1701  const size_type local_index) const
1702  {
1703  Assert((std::is_same<MemorySpace, ::MemorySpace::Host>::value),
1704  ExcMessage(
1705  "This function is only implemented for the Host memory space"));
1706  AssertIndexRange(local_index,
1707  partitioner->locally_owned_size() +
1708  partitioner->n_ghost_indices());
1709  // do not allow reading a vector which is not in ghost mode
1710  Assert(local_index < locally_owned_size() || vector_is_ghosted == true,
1711  ExcMessage("You tried to read a ghost element of this vector, "
1712  "but it has not imported its ghost values."));
1713 
1714  return data.values[local_index];
1715  }
1716 
1717 
1718 
1719  template <typename Number, typename MemorySpace>
1720  inline Number &
1722  {
1723  Assert((std::is_same<MemorySpace, ::MemorySpace::Host>::value),
1724  ExcMessage(
1725  "This function is only implemented for the Host memory space"));
1726 
1727  AssertIndexRange(local_index,
1728  partitioner->locally_owned_size() +
1729  partitioner->n_ghost_indices());
1730 
1731  return data.values[local_index];
1732  }
1733 
1734 
1735 
1736  template <typename Number, typename MemorySpace>
1737  inline Number *
1739  {
1740  return internal::Policy<Number, MemorySpace>::get_values(data);
1741  }
1742 
1743 
1744 
1745  template <typename Number, typename MemorySpace>
1746  template <typename OtherNumber>
1747  inline void
1749  const std::vector<size_type> &indices,
1750  std::vector<OtherNumber> & values) const
1751  {
1752  for (size_type i = 0; i < indices.size(); ++i)
1753  values[i] = operator()(indices[i]);
1754  }
1755 
1756 
1757 
1758  template <typename Number, typename MemorySpace>
1759  template <typename ForwardIterator, typename OutputIterator>
1760  inline void
1762  ForwardIterator indices_begin,
1763  const ForwardIterator indices_end,
1764  OutputIterator values_begin) const
1765  {
1766  while (indices_begin != indices_end)
1767  {
1768  *values_begin = operator()(*indices_begin);
1769  indices_begin++;
1770  values_begin++;
1771  }
1772  }
1773 
1774 
1775 
1776  template <typename Number, typename MemorySpace>
1777  template <typename OtherNumber>
1778  inline void
1780  const std::vector<size_type> & indices,
1781  const ::Vector<OtherNumber> &values)
1782  {
1783  AssertDimension(indices.size(), values.size());
1784  for (size_type i = 0; i < indices.size(); ++i)
1785  {
1786  Assert(
1787  numbers::is_finite(values[i]),
1788  ExcMessage(
1789  "The given value is not finite but either infinite or Not A Number (NaN)"));
1790  this->operator()(indices[i]) += values(i);
1791  }
1792  }
1793 
1794 
1795 
1796  template <typename Number, typename MemorySpace>
1797  template <typename OtherNumber>
1798  inline void
1800  const size_type * indices,
1801  const OtherNumber *values)
1802  {
1803  for (size_type i = 0; i < n_elements; ++i, ++indices, ++values)
1804  {
1805  Assert(
1806  numbers::is_finite(*values),
1807  ExcMessage(
1808  "The given value is not finite but either infinite or Not A Number (NaN)"));
1809  this->operator()(*indices) += *values;
1810  }
1811  }
1812 
1813 
1814 
1815  template <typename Number, typename MemorySpace>
1816  inline const MPI_Comm &
1818  {
1819  return partitioner->get_mpi_communicator();
1820  }
1821 
1822 
1823 
1824  template <typename Number, typename MemorySpace>
1825  inline const std::shared_ptr<const Utilities::MPI::Partitioner> &
1827  {
1828  return partitioner;
1829  }
1830 
1831 
1832 
1833  template <typename Number, typename MemorySpace>
1834  inline void
1835  Vector<Number, MemorySpace>::set_ghost_state(const bool ghosted) const
1836  {
1837  vector_is_ghosted = ghosted;
1838  }
1839 
1840 #endif
1841 
1842  } // namespace distributed
1843 } // namespace LinearAlgebra
1844 
1845 
1853 template <typename Number, typename MemorySpace>
1854 inline void
1857 {
1858  u.swap(v);
1859 }
1860 
1861 
1865 template <typename Number, typename MemorySpace>
1867  : std::false_type
1868 {};
1869 
1870 
1871 
1872 namespace internal
1873 {
1874  namespace LinearOperatorImplementation
1875  {
1876  template <typename>
1877  class ReinitHelper;
1878 
1883  template <typename Number>
1884  class ReinitHelper<LinearAlgebra::distributed::Vector<Number>>
1885  {
1886  public:
1887  // A helper type-trait that leverage SFINAE to figure out if type T has
1888  // void T::get_mpi_communicator()
1889  template <typename T>
1890  struct has_get_mpi_communicator
1891  {
1892  private:
1893  static bool
1894  detect(...);
1895 
1896  template <typename U>
1897  static decltype(std::declval<U>().get_mpi_communicator())
1898  detect(const U &);
1899 
1900  public:
1901  static const bool value =
1902  !std::is_same<bool, decltype(detect(std::declval<T>()))>::value;
1903  };
1904 
1905  // A helper type-trait that leverage SFINAE to figure out if type T has
1906  // void T::locally_owned_domain_indices()
1907  template <typename T>
1908  struct has_locally_owned_domain_indices
1909  {
1910  private:
1911  static bool
1912  detect(...);
1913 
1914  template <typename U>
1915  static decltype(std::declval<U>().locally_owned_domain_indices())
1916  detect(const U &);
1917 
1918  public:
1919  static const bool value =
1920  !std::is_same<bool, decltype(detect(std::declval<T>()))>::value;
1921  };
1922 
1923  // A helper type-trait that leverage SFINAE to figure out if type T has
1924  // void T::locally_owned_range_indices()
1925  template <typename T>
1926  struct has_locally_owned_range_indices
1927  {
1928  private:
1929  static bool
1930  detect(...);
1931 
1932  template <typename U>
1933  static decltype(std::declval<U>().locally_owned_range_indices())
1934  detect(const U &);
1935 
1936  public:
1937  static const bool value =
1938  !std::is_same<bool, decltype(detect(std::declval<T>()))>::value;
1939  };
1940 
1941  // A helper type-trait that leverage SFINAE to figure out if type T has
1942  // void T::initialize_dof_vector(VectorType v)
1943  template <typename T>
1944  struct has_initialize_dof_vector
1945  {
1946  private:
1947  static bool
1948  detect(...);
1949 
1950  template <typename U>
1951  static decltype(std::declval<U>().initialize_dof_vector(
1952  std::declval<LinearAlgebra::distributed::Vector<Number> &>()))
1953  detect(const U &);
1954 
1955  public:
1956  static const bool value =
1957  !std::is_same<bool, decltype(detect(std::declval<T>()))>::value;
1958  };
1959 
1960  // Used for (Trilinos/PETSc)Wrappers::SparseMatrix
1961  template <typename MatrixType,
1962  typename std::enable_if<
1963  has_get_mpi_communicator<MatrixType>::value &&
1964  has_locally_owned_domain_indices<MatrixType>::value,
1965  MatrixType>::type * = nullptr>
1966  static void
1967  reinit_domain_vector(MatrixType & mat,
1969  bool /*omit_zeroing_entries*/)
1970  {
1971  vec.reinit(mat.locally_owned_domain_indices(),
1972  mat.get_mpi_communicator());
1973  }
1974 
1975  // Used for MatrixFree and DiagonalMatrix
1976  template <
1977  typename MatrixType,
1978  typename std::enable_if<has_initialize_dof_vector<MatrixType>::value,
1979  MatrixType>::type * = nullptr>
1980  static void
1981  reinit_domain_vector(MatrixType & mat,
1983  bool omit_zeroing_entries)
1984  {
1985  mat.initialize_dof_vector(vec);
1986  if (!omit_zeroing_entries)
1987  vec = Number();
1988  }
1989 
1990  // Used for (Trilinos/PETSc)Wrappers::SparseMatrix
1991  template <typename MatrixType,
1992  typename std::enable_if<
1993  has_get_mpi_communicator<MatrixType>::value &&
1994  has_locally_owned_range_indices<MatrixType>::value,
1995  MatrixType>::type * = nullptr>
1996  static void
1997  reinit_range_vector(MatrixType & mat,
1999  bool /*omit_zeroing_entries*/)
2000  {
2001  vec.reinit(mat.locally_owned_range_indices(),
2002  mat.get_mpi_communicator());
2003  }
2004 
2005  // Used for MatrixFree and DiagonalMatrix
2006  template <
2007  typename MatrixType,
2008  typename std::enable_if<has_initialize_dof_vector<MatrixType>::value,
2009  MatrixType>::type * = nullptr>
2010  static void
2011  reinit_range_vector(MatrixType & mat,
2013  bool omit_zeroing_entries)
2014  {
2015  mat.initialize_dof_vector(vec);
2016  if (!omit_zeroing_entries)
2017  vec = Number();
2018  }
2019  };
2020 
2021  } // namespace LinearOperatorImplementation
2022 } /* namespace internal */
2023 
2024 
2026 
2027 #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:1655
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:2047
std::shared_ptr< const Utilities::MPI::Partitioner > partitioner
#define AssertIndexRange(index, range)
Definition: exceptions.h:1720
__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
size_type locally_owned_size() const
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:537
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:1461
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:3025
#define DeclException0(Exception0)
Definition: exceptions.h:464
void swap(LinearAlgebra::distributed::Vector< Number, MemorySpace > &u, LinearAlgebra::distributed::Vector< Number, MemorySpace > &v)
#define DEAL_II_NAMESPACE_CLOSE
Definition: config.h:401
std::shared_ptr<::parallel::internal::TBBPartitioner > thread_loop_partitioner
VectorType::value_type * end(VectorType &V)
mutable ::MemorySpace::MemorySpaceData< Number, MemorySpace > import_data
const std::vector< ArrayView< const Number > > & shared_vector_data() const
__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:400
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:578
Number l1_norm(const Tensor< 2, dim, Number > &t)
Definition: tensor.h:2999
const MPI_Comm & comm
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:555
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
#define DEAL_II_DEPRECATED
Definition: config.h:160
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)