Reference documentation for deal.II version Git ede8f93e86 2020-12-03 14:59:20 -0700
\(\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 
23 #include <deal.II/base/mpi.h>
24 #include <deal.II/base/numbers.h>
27 
31 
32 #include <iomanip>
33 #include <memory>
34 
36 
37 // Forward declarations
38 #ifndef DOXYGEN
39 namespace LinearAlgebra
40 {
44  namespace distributed
45  {
46  template <typename>
47  class BlockVector;
48  }
49 
50  template <typename>
51  class ReadWriteVector;
52 } // namespace LinearAlgebra
53 
54 # ifdef DEAL_II_WITH_PETSC
55 namespace PETScWrappers
56 {
57  namespace MPI
58  {
59  class Vector;
60  }
61 } // namespace PETScWrappers
62 # endif
63 
64 # ifdef DEAL_II_WITH_TRILINOS
65 namespace TrilinosWrappers
66 {
67  namespace MPI
68  {
69  class Vector;
70  }
71 } // namespace TrilinosWrappers
72 # endif
73 #endif
74 
75 namespace LinearAlgebra
76 {
77  namespace distributed
78  {
242  template <typename Number, typename MemorySpace = MemorySpace::Host>
244  public Subscriptor
245  {
246  public:
248  using value_type = Number;
249  using pointer = value_type *;
250  using const_pointer = const value_type *;
251  using iterator = value_type *;
252  using const_iterator = const value_type *;
254  using const_reference = const value_type &;
257 
258  static_assert(
259  std::is_same<MemorySpace, ::MemorySpace::Host>::value ||
260  std::is_same<MemorySpace, ::MemorySpace::CUDA>::value,
261  "MemorySpace should be Host or CUDA");
262 
270  Vector();
271 
278  Vector(const Vector<Number, MemorySpace> &in_vector);
279 
284  Vector(const size_type size);
285 
302  Vector(const IndexSet &local_range,
303  const IndexSet &ghost_indices,
304  const MPI_Comm &communicator);
305 
309  Vector(const IndexSet &local_range, const MPI_Comm &communicator);
310 
317  Vector(
318  const std::shared_ptr<const Utilities::MPI::Partitioner> &partitioner);
319 
323  virtual ~Vector() override;
324 
329  void
330  reinit(const size_type size, const bool omit_zeroing_entries = false);
331 
342  template <typename Number2>
343  void
344  reinit(const Vector<Number2, MemorySpace> &in_vector,
345  const bool omit_zeroing_entries = false);
346 
363  void
364  reinit(const IndexSet &local_range,
365  const IndexSet &ghost_indices,
366  const MPI_Comm &communicator);
367 
371  void
372  reinit(const IndexSet &local_range, const MPI_Comm &communicator);
373 
385  void
386  reinit(
387  const std::shared_ptr<const Utilities::MPI::Partitioner> &partitioner,
388  const MPI_Comm &comm_sm = MPI_COMM_SELF);
389 
408  void
409  reinit(const types::global_dof_index local_size,
410  const types::global_dof_index ghost_size,
411  const MPI_Comm & comm,
412  const MPI_Comm & comm_sm = MPI_COMM_SELF);
413 
426  void
428 
441  operator=(const Vector<Number, MemorySpace> &in_vector);
442 
454  template <typename Number2>
456  operator=(const Vector<Number2, MemorySpace> &in_vector);
457 
459 
499  virtual void
500  compress(::VectorOperation::values operation) override;
501 
523  void
524  update_ghost_values() const;
525 
543  void
544  compress_start(
545  const unsigned int communication_channel = 0,
547 
566  void
567  compress_finish(::VectorOperation::values operation);
568 
586  void
587  update_ghost_values_start(
588  const unsigned int communication_channel = 0) const;
589 
590 
598  void
599  update_ghost_values_finish() const;
600 
609  void
610  zero_out_ghosts() const;
611 
623  bool
624  has_ghost_elements() const;
625 
640  template <typename Number2>
641  void
642  copy_locally_owned_data_from(const Vector<Number2, MemorySpace> &src);
643 
654  template <typename MemorySpace2>
655  void
656  import(const Vector<Number, MemorySpace2> &src,
657  VectorOperation::values operation);
658 
660 
665 
670  virtual void
672  const bool omit_zeroing_entries = false) override;
673 
678  operator*=(const Number factor) override;
679 
684  operator/=(const Number factor) override;
685 
690  operator+=(const VectorSpaceVector<Number> &V) override;
691 
696  operator-=(const VectorSpaceVector<Number> &V) override;
697 
709  virtual void
710  import(
712  VectorOperation::values operation,
713  std::shared_ptr<const CommunicationPatternBase> communication_pattern =
714  std::shared_ptr<const CommunicationPatternBase>()) override;
715 
719  virtual Number
720  operator*(const VectorSpaceVector<Number> &V) const override;
721 
725  virtual void
726  add(const Number a) override;
727 
731  virtual void
732  add(const Number a, const VectorSpaceVector<Number> &V) override;
733 
737  virtual void
738  add(const Number a,
740  const Number b,
741  const VectorSpaceVector<Number> &W) override;
742 
747  virtual void
748  add(const std::vector<size_type> &indices,
749  const std::vector<Number> & values);
750 
755  virtual void
756  sadd(const Number s,
757  const Number a,
758  const VectorSpaceVector<Number> &V) override;
759 
765  virtual void
766  scale(const VectorSpaceVector<Number> &scaling_factors) override;
767 
771  virtual void
772  equ(const Number a, const VectorSpaceVector<Number> &V) override;
773 
778  virtual real_type
779  l1_norm() const override;
780 
785  virtual real_type
786  l2_norm() const override;
787 
791  real_type
792  norm_sqr() const;
793 
798  virtual real_type
799  linfty_norm() const override;
800 
821  virtual Number
822  add_and_dot(const Number a,
824  const VectorSpaceVector<Number> &W) override;
825 
830  virtual size_type
831  size() const override;
832 
844  virtual ::IndexSet
845  locally_owned_elements() const override;
846 
850  virtual void
851  print(std::ostream & out,
852  const unsigned int precision = 3,
853  const bool scientific = true,
854  const bool across = true) const override;
855 
859  virtual std::size_t
860  memory_consumption() const override;
862 
867 
874  operator=(const Number s) override;
875 
880  template <typename OtherNumber>
881  void
882  add(const std::vector<size_type> & indices,
883  const ::Vector<OtherNumber> &values);
884 
889  template <typename OtherNumber>
890  void
891  add(const size_type n_elements,
892  const size_type * indices,
893  const OtherNumber *values);
894 
899  void
900  sadd(const Number s, const Vector<Number, MemorySpace> &V);
901 
903 
904 
909 
914  size_type
915  local_size() const;
916 
921  bool
922  in_local_range(const size_type global_index) const;
923 
934  iterator
935  begin();
936 
945  begin() const;
946 
954  iterator
955  end();
956 
965  end() const;
966 
976  Number
977  operator()(const size_type global_index) const;
978 
988  Number &
989  operator()(const size_type global_index);
990 
998  Number operator[](const size_type global_index) const;
1006  Number &operator[](const size_type global_index);
1007 
1016  Number
1017  local_element(const size_type local_index) const;
1018 
1027  Number &
1028  local_element(const size_type local_index);
1029 
1036  Number *
1037  get_values() const;
1038 
1056  template <typename OtherNumber>
1057  void
1058  extract_subvector_to(const std::vector<size_type> &indices,
1059  std::vector<OtherNumber> & values) const;
1060 
1088  template <typename ForwardIterator, typename OutputIterator>
1089  void
1090  extract_subvector_to(ForwardIterator indices_begin,
1091  const ForwardIterator indices_end,
1092  OutputIterator values_begin) const;
1098  virtual bool
1099  all_zero() const override;
1100 
1104  virtual Number
1105  mean_value() const override;
1106 
1111  real_type
1112  lp_norm(const real_type p) const;
1114 
1119 
1124  const MPI_Comm &
1125  get_mpi_communicator() const;
1126 
1133  const std::shared_ptr<const Utilities::MPI::Partitioner> &
1134  get_partitioner() const;
1135 
1145  bool
1146  partitioners_are_compatible(
1147  const Utilities::MPI::Partitioner &part) const;
1148 
1162  bool
1163  partitioners_are_globally_compatible(
1164  const Utilities::MPI::Partitioner &part) const;
1165 
1169  void
1170  set_ghost_state(const bool ghosted) const;
1171 
1176  const std::vector<ArrayView<const Number>> &
1177  shared_vector_data() const;
1178 
1180 
1186  DeclException0(ExcVectorTypeNotCompatible);
1187 
1193  DeclException0(ExcNotAllowedForCuda);
1194 
1198  DeclException3(ExcNonMatchingElements,
1199  Number,
1200  Number,
1201  unsigned int,
1202  << "Called compress(VectorOperation::insert), but"
1203  << " the element received from a remote processor, value "
1204  << std::setprecision(16) << arg1
1205  << ", does not match with the value "
1206  << std::setprecision(16) << arg2
1207  << " on the owner processor " << arg3);
1208 
1212  DeclException4(ExcAccessToNonLocalElement,
1213  size_type,
1214  size_type,
1215  size_type,
1216  size_type,
1217  << "You tried to access element " << arg1
1218  << " of a distributed vector, but this element is not "
1219  << "stored on the current processor. Note: The range of "
1220  << "locally owned elements is " << arg2 << " to " << arg3
1221  << ", and there are " << arg4 << " ghost elements "
1222  << "that this vector can access.");
1223 
1224  private:
1229  void
1230  add_local(const Number a, const VectorSpaceVector<Number> &V);
1231 
1236  void
1237  sadd_local(const Number s,
1238  const Number a,
1239  const VectorSpaceVector<Number> &V);
1240 
1244  template <typename Number2>
1245  Number
1246  inner_product_local(const Vector<Number2, MemorySpace> &V) const;
1247 
1251  real_type
1252  norm_sqr_local() const;
1253 
1257  Number
1258  mean_value_local() const;
1259 
1263  real_type
1264  l1_norm_local() const;
1265 
1269  real_type
1270  lp_norm_local(const real_type p) const;
1271 
1275  real_type
1276  linfty_norm_local() const;
1277 
1283  Number
1284  add_and_dot_local(const Number a,
1286  const Vector<Number, MemorySpace> &W);
1287 
1293  std::shared_ptr<const Utilities::MPI::Partitioner> partitioner;
1294 
1299 
1303  mutable ::MemorySpace::MemorySpaceData<Number, MemorySpace> data;
1304 
1309  mutable std::shared_ptr<::parallel::internal::TBBPartitioner>
1311 
1316  mutable ::MemorySpace::MemorySpaceData<Number, MemorySpace>
1318 
1326  mutable bool vector_is_ghosted;
1327 
1328 #ifdef DEAL_II_WITH_MPI
1329 
1337  std::vector<MPI_Request> compress_requests;
1338 
1343  mutable std::vector<MPI_Request> update_ghost_values_requests;
1344 #endif
1345 
1351  mutable std::mutex mutex;
1352 
1357 
1362  void
1363  clear_mpi_requests();
1364 
1368  void
1369  resize_val(const size_type new_allocated_size,
1370  const MPI_Comm &comm_sm = MPI_COMM_SELF);
1371 
1372  // Make all other vector types friends.
1373  template <typename Number2, typename MemorySpace2>
1374  friend class Vector;
1375 
1376  // Make BlockVector type friends.
1377  template <typename Number2>
1378  friend class BlockVector;
1379  };
1383  /*-------------------- Inline functions ---------------------------------*/
1384 
1385 #ifndef DOXYGEN
1386 
1387  namespace internal
1388  {
1389  template <typename Number, typename MemorySpace>
1390  struct Policy
1391  {
1392  static inline typename Vector<Number, MemorySpace>::iterator
1394  {
1395  return nullptr;
1396  }
1397 
1398  static inline typename Vector<Number, MemorySpace>::const_iterator
1399  begin(
1400  const ::MemorySpace::MemorySpaceData<Number, MemorySpace> &)
1401  {
1402  return nullptr;
1403  }
1404 
1405  static inline Number *
1406  get_values(
1408  {
1409  return nullptr;
1410  }
1411  };
1412 
1413 
1414 
1415  template <typename Number>
1416  struct Policy<Number, ::MemorySpace::Host>
1417  {
1418  static inline
1420  begin(::MemorySpace::
1421  MemorySpaceData<Number, ::MemorySpace::Host> &data)
1422  {
1423  return data.values.get();
1424  }
1425 
1426  static inline
1428  begin(const ::MemorySpace::
1429  MemorySpaceData<Number, ::MemorySpace::Host> &data)
1430  {
1431  return data.values.get();
1432  }
1433 
1434  static inline Number *
1435  get_values(::MemorySpace::
1436  MemorySpaceData<Number, ::MemorySpace::Host> &data)
1437  {
1438  return data.values.get();
1439  }
1440  };
1441 
1442 
1443 
1444  template <typename Number>
1445  struct Policy<Number, ::MemorySpace::CUDA>
1446  {
1447  static inline
1449  begin(::MemorySpace::
1450  MemorySpaceData<Number, ::MemorySpace::CUDA> &data)
1451  {
1452  return data.values_dev.get();
1453  }
1454 
1455  static inline
1457  begin(const ::MemorySpace::
1458  MemorySpaceData<Number, ::MemorySpace::CUDA> &data)
1459  {
1460  return data.values_dev.get();
1461  }
1462 
1463  static inline Number *
1464  get_values(::MemorySpace::
1465  MemorySpaceData<Number, ::MemorySpace::CUDA> &data)
1466  {
1467  return data.values_dev.get();
1468  }
1469  };
1470  } // namespace internal
1471 
1472 
1473  template <typename Number, typename MemorySpace>
1474  inline bool
1476  {
1477  return vector_is_ghosted;
1478  }
1479 
1480 
1481 
1482  template <typename Number, typename MemorySpace>
1485  {
1486  return partitioner->size();
1487  }
1488 
1489 
1490 
1491  template <typename Number, typename MemorySpace>
1494  {
1495  return partitioner->local_size();
1496  }
1497 
1498 
1499 
1500  template <typename Number, typename MemorySpace>
1501  inline bool
1503  const size_type global_index) const
1504  {
1505  return partitioner->in_local_range(global_index);
1506  }
1507 
1508 
1509 
1510  template <typename Number, typename MemorySpace>
1511  inline IndexSet
1513  {
1514  IndexSet is(size());
1515 
1516  is.add_range(partitioner->local_range().first,
1517  partitioner->local_range().second);
1518 
1519  return is;
1520  }
1521 
1522 
1523 
1524  template <typename Number, typename MemorySpace>
1527  {
1529  }
1530 
1531 
1532 
1533  template <typename Number, typename MemorySpace>
1536  {
1538  }
1539 
1540 
1541 
1542  template <typename Number, typename MemorySpace>
1545  {
1547  partitioner->local_size();
1548  }
1549 
1550 
1551 
1552  template <typename Number, typename MemorySpace>
1555  {
1557  partitioner->local_size();
1558  }
1559 
1560 
1561 
1562  template <typename Number, typename MemorySpace>
1563  const std::vector<ArrayView<const Number>> &
1565  {
1566  return data.values_sm;
1567  }
1568 
1569 
1570 
1571  template <typename Number, typename MemorySpace>
1572  inline Number
1573  Vector<Number, MemorySpace>::operator()(const size_type global_index) const
1574  {
1575  Assert((std::is_same<MemorySpace, ::MemorySpace::Host>::value),
1576  ExcMessage(
1577  "This function is only implemented for the Host memory space"));
1578  Assert(
1579  partitioner->in_local_range(global_index) ||
1580  partitioner->ghost_indices().is_element(global_index),
1581  ExcAccessToNonLocalElement(global_index,
1582  partitioner->local_range().first,
1583  partitioner->local_range().second,
1584  partitioner->ghost_indices().n_elements()));
1585  // do not allow reading a vector which is not in ghost mode
1586  Assert(partitioner->in_local_range(global_index) ||
1587  vector_is_ghosted == true,
1588  ExcMessage("You tried to read a ghost element of this vector, "
1589  "but it has not imported its ghost values."));
1590  return data.values[partitioner->global_to_local(global_index)];
1591  }
1592 
1593 
1594 
1595  template <typename Number, typename MemorySpace>
1596  inline Number &
1598  {
1599  Assert((std::is_same<MemorySpace, ::MemorySpace::Host>::value),
1600  ExcMessage(
1601  "This function is only implemented for the Host memory space"));
1602  Assert(
1603  partitioner->in_local_range(global_index) ||
1604  partitioner->ghost_indices().is_element(global_index),
1605  ExcAccessToNonLocalElement(global_index,
1606  partitioner->local_range().first,
1607  partitioner->local_range().second,
1608  partitioner->ghost_indices().n_elements()));
1609  // we would like to prevent reading ghosts from a vector that does not
1610  // have them imported, but this is not possible because we might be in a
1611  // part of the code where the vector has enabled ghosts but is non-const
1612  // (then, the compiler picks this method according to the C++ rule book
1613  // even if a human would pick the const method when this subsequent use
1614  // is just a read)
1615  return data.values[partitioner->global_to_local(global_index)];
1616  }
1617 
1618 
1619 
1620  template <typename Number, typename MemorySpace>
1621  inline Number Vector<Number, MemorySpace>::
1622  operator[](const size_type global_index) const
1623  {
1624  return operator()(global_index);
1625  }
1626 
1627 
1628 
1629  template <typename Number, typename MemorySpace>
1630  inline Number &Vector<Number, MemorySpace>::
1631  operator[](const size_type global_index)
1632  {
1633  return operator()(global_index);
1634  }
1635 
1636 
1637 
1638  template <typename Number, typename MemorySpace>
1639  inline Number
1641  const size_type local_index) const
1642  {
1643  Assert((std::is_same<MemorySpace, ::MemorySpace::Host>::value),
1644  ExcMessage(
1645  "This function is only implemented for the Host memory space"));
1646  AssertIndexRange(local_index,
1647  partitioner->local_size() +
1648  partitioner->n_ghost_indices());
1649  // do not allow reading a vector which is not in ghost mode
1650  Assert(local_index < local_size() || vector_is_ghosted == true,
1651  ExcMessage("You tried to read a ghost element of this vector, "
1652  "but it has not imported its ghost values."));
1653 
1654  return data.values[local_index];
1655  }
1656 
1657 
1658 
1659  template <typename Number, typename MemorySpace>
1660  inline Number &
1662  {
1663  Assert((std::is_same<MemorySpace, ::MemorySpace::Host>::value),
1664  ExcMessage(
1665  "This function is only implemented for the Host memory space"));
1666 
1667  AssertIndexRange(local_index,
1668  partitioner->local_size() +
1669  partitioner->n_ghost_indices());
1670 
1671  return data.values[local_index];
1672  }
1673 
1674 
1675 
1676  template <typename Number, typename MemorySpace>
1677  inline Number *
1679  {
1680  return internal::Policy<Number, MemorySpace>::get_values(data);
1681  }
1682 
1683 
1684 
1685  template <typename Number, typename MemorySpace>
1686  template <typename OtherNumber>
1687  inline void
1689  const std::vector<size_type> &indices,
1690  std::vector<OtherNumber> & values) const
1691  {
1692  for (size_type i = 0; i < indices.size(); ++i)
1693  values[i] = operator()(indices[i]);
1694  }
1695 
1696 
1697 
1698  template <typename Number, typename MemorySpace>
1699  template <typename ForwardIterator, typename OutputIterator>
1700  inline void
1702  ForwardIterator indices_begin,
1703  const ForwardIterator indices_end,
1704  OutputIterator values_begin) const
1705  {
1706  while (indices_begin != indices_end)
1707  {
1708  *values_begin = operator()(*indices_begin);
1709  indices_begin++;
1710  values_begin++;
1711  }
1712  }
1713 
1714 
1715 
1716  template <typename Number, typename MemorySpace>
1717  template <typename OtherNumber>
1718  inline void
1720  const std::vector<size_type> & indices,
1721  const ::Vector<OtherNumber> &values)
1722  {
1723  AssertDimension(indices.size(), values.size());
1724  for (size_type i = 0; i < indices.size(); ++i)
1725  {
1726  Assert(
1727  numbers::is_finite(values[i]),
1728  ExcMessage(
1729  "The given value is not finite but either infinite or Not A Number (NaN)"));
1730  this->operator()(indices[i]) += values(i);
1731  }
1732  }
1733 
1734 
1735 
1736  template <typename Number, typename MemorySpace>
1737  template <typename OtherNumber>
1738  inline void
1740  const size_type * indices,
1741  const OtherNumber *values)
1742  {
1743  for (size_type i = 0; i < n_elements; ++i, ++indices, ++values)
1744  {
1745  Assert(
1746  numbers::is_finite(*values),
1747  ExcMessage(
1748  "The given value is not finite but either infinite or Not A Number (NaN)"));
1749  this->operator()(*indices) += *values;
1750  }
1751  }
1752 
1753 
1754 
1755  template <typename Number, typename MemorySpace>
1756  inline const MPI_Comm &
1758  {
1759  return partitioner->get_mpi_communicator();
1760  }
1761 
1762 
1763 
1764  template <typename Number, typename MemorySpace>
1765  inline const std::shared_ptr<const Utilities::MPI::Partitioner> &
1767  {
1768  return partitioner;
1769  }
1770 
1771 
1772 
1773  template <typename Number, typename MemorySpace>
1774  inline void
1775  Vector<Number, MemorySpace>::set_ghost_state(const bool ghosted) const
1776  {
1777  vector_is_ghosted = ghosted;
1778  }
1779 
1780 #endif
1781 
1782  } // namespace distributed
1783 } // namespace LinearAlgebra
1784 
1785 
1793 template <typename Number, typename MemorySpace>
1794 inline void
1797 {
1798  u.swap(v);
1799 }
1800 
1801 
1805 template <typename Number, typename MemorySpace>
1807  : std::false_type
1808 {};
1809 
1810 
1811 
1812 namespace internal
1813 {
1814  namespace LinearOperatorImplementation
1815  {
1816  template <typename>
1817  class ReinitHelper;
1818 
1823  template <typename Number>
1824  class ReinitHelper<LinearAlgebra::distributed::Vector<Number>>
1825  {
1826  public:
1827  // A helper type-trait that leverage SFINAE to figure out if type T has
1828  // void T::get_mpi_communicator()
1829  template <typename T>
1830  struct has_get_mpi_communicator
1831  {
1832  private:
1833  static bool
1834  detect(...);
1835 
1836  template <typename U>
1837  static decltype(std::declval<U>().get_mpi_communicator())
1838  detect(const U &);
1839 
1840  public:
1841  static const bool value =
1842  !std::is_same<bool, decltype(detect(std::declval<T>()))>::value;
1843  };
1844 
1845  // A helper type-trait that leverage SFINAE to figure out if type T has
1846  // void T::locally_owned_domain_indices()
1847  template <typename T>
1848  struct has_locally_owned_domain_indices
1849  {
1850  private:
1851  static bool
1852  detect(...);
1853 
1854  template <typename U>
1855  static decltype(std::declval<U>().locally_owned_domain_indices())
1856  detect(const U &);
1857 
1858  public:
1859  static const bool value =
1860  !std::is_same<bool, decltype(detect(std::declval<T>()))>::value;
1861  };
1862 
1863  // A helper type-trait that leverage SFINAE to figure out if type T has
1864  // void T::locally_owned_range_indices()
1865  template <typename T>
1866  struct has_locally_owned_range_indices
1867  {
1868  private:
1869  static bool
1870  detect(...);
1871 
1872  template <typename U>
1873  static decltype(std::declval<U>().locally_owned_range_indices())
1874  detect(const U &);
1875 
1876  public:
1877  static const bool value =
1878  !std::is_same<bool, decltype(detect(std::declval<T>()))>::value;
1879  };
1880 
1881  // A helper type-trait that leverage SFINAE to figure out if type T has
1882  // void T::initialize_dof_vector(VectorType v)
1883  template <typename T>
1884  struct has_initialize_dof_vector
1885  {
1886  private:
1887  static bool
1888  detect(...);
1889 
1890  template <typename U>
1891  static decltype(std::declval<U>().initialize_dof_vector(
1892  std::declval<LinearAlgebra::distributed::Vector<Number> &>()))
1893  detect(const U &);
1894 
1895  public:
1896  static const bool value =
1897  !std::is_same<bool, decltype(detect(std::declval<T>()))>::value;
1898  };
1899 
1900  // Used for (Trilinos/PETSc)Wrappers::SparseMatrix
1901  template <typename MatrixType,
1902  typename std::enable_if<
1903  has_get_mpi_communicator<MatrixType>::value &&
1904  has_locally_owned_domain_indices<MatrixType>::value,
1905  MatrixType>::type * = nullptr>
1906  static void
1907  reinit_domain_vector(MatrixType & mat,
1909  bool /*omit_zeroing_entries*/)
1910  {
1911  vec.reinit(mat.locally_owned_domain_indices(),
1912  mat.get_mpi_communicator());
1913  }
1914 
1915  // Used for MatrixFree and DiagonalMatrix
1916  template <
1917  typename MatrixType,
1918  typename std::enable_if<has_initialize_dof_vector<MatrixType>::value,
1919  MatrixType>::type * = nullptr>
1920  static void
1921  reinit_domain_vector(MatrixType & mat,
1923  bool omit_zeroing_entries)
1924  {
1925  mat.initialize_dof_vector(vec);
1926  if (!omit_zeroing_entries)
1927  vec = Number();
1928  }
1929 
1930  // Used for (Trilinos/PETSc)Wrappers::SparseMatrix
1931  template <typename MatrixType,
1932  typename std::enable_if<
1933  has_get_mpi_communicator<MatrixType>::value &&
1934  has_locally_owned_range_indices<MatrixType>::value,
1935  MatrixType>::type * = nullptr>
1936  static void
1937  reinit_range_vector(MatrixType & mat,
1939  bool /*omit_zeroing_entries*/)
1940  {
1941  vec.reinit(mat.locally_owned_range_indices(),
1942  mat.get_mpi_communicator());
1943  }
1944 
1945  // Used for MatrixFree and DiagonalMatrix
1946  template <
1947  typename MatrixType,
1948  typename std::enable_if<has_initialize_dof_vector<MatrixType>::value,
1949  MatrixType>::type * = nullptr>
1950  static void
1951  reinit_range_vector(MatrixType & mat,
1953  bool omit_zeroing_entries)
1954  {
1955  mat.initialize_dof_vector(vec);
1956  if (!omit_zeroing_entries)
1957  vec = Number();
1958  }
1959  };
1960 
1961  } // namespace LinearOperatorImplementation
1962 } /* namespace internal */
1963 
1964 
1966 
1967 #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:1623
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:951
std::shared_ptr< const Utilities::MPI::Partitioner > partitioner
#define AssertIndexRange(index, range)
Definition: exceptions.h:1691
__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:1466
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:2816
#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:372
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
*braid_SplitCommworld & comm
void swap(Vector< Number, MemorySpace > &v)
#define DEAL_II_NAMESPACE_OPEN
Definition: config.h:371
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:2790
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)